Merge branch 'bugfix/unnecessary-joins-8614'

fixes #8614
This commit is contained in:
Eric Lippmann 2015-03-12 16:47:10 +01:00
commit be041435d3
12 changed files with 252 additions and 197 deletions

View File

@ -282,8 +282,8 @@ class Monitoring_ListController extends Controller
'is_fixed' => 'downtime_is_fixed',
'is_in_effect' => 'downtime_is_in_effect',
'entry_time' => 'downtime_entry_time',
'host' => 'downtime_host',
'service' => 'downtime_service',
'host' => 'host_name',
'service' => 'service_description',
'host_state' => 'downtime_host_state',
'service_state' => 'downtime_service_state',
'host_display_name',

View File

@ -22,6 +22,9 @@ class CommentQuery extends IdoQuery
'comment_service' => 'so.name2 COLLATE latin1_general_ci',
'service' => 'so.name2 COLLATE latin1_general_ci', // #7278, #7279
'comment_objecttype' => "CASE WHEN ho.object_id IS NOT NULL THEN 'host' ELSE CASE WHEN so.object_id IS NOT NULL THEN 'service' ELSE NULL END END",
'service_description' => 'so.name2',
'host_name' => 'CASE WHEN ho.name1 IS NULL THEN so.name1 ELSE ho.name1 END',
'service_host_name' => 'so.name1'
),
'hosts' => array(
'host_display_name' => 'CASE WHEN sh.display_name IS NOT NULL THEN sh.display_name ELSE h.display_name END'

View File

@ -7,41 +7,39 @@ class ContactQuery extends IdoQuery
{
protected $columnMap = array(
'contacts' => array(
'contact_id' => 'c.contact_id',
'contact_name' => 'co.name1 COLLATE latin1_general_ci',
'contact_alias' => 'c.alias COLLATE latin1_general_ci',
'contact_email' => 'c.email_address COLLATE latin1_general_ci',
'contact_pager' => 'c.pager_address',
'contact_object_id' => 'c.contact_object_id',
'contact_has_host_notfications' => 'c.host_notifications_enabled',
'contact_has_service_notfications' => 'c.service_notifications_enabled',
'contact_can_submit_commands' => 'c.can_submit_commands',
'contact_notify_service_recovery' => 'c.notify_service_recovery',
'contact_notify_service_warning' => 'c.notify_service_warning',
'contact_notify_service_critical' => 'c.notify_service_critical',
'contact_notify_service_unknown' => 'c.notify_service_unknown',
'contact_notify_service_flapping' => 'c.notify_service_flapping',
'contact_notify_service_downtime' => 'c.notify_service_recovery',
'contact_notify_host_recovery' => 'c.notify_host_recovery',
'contact_notify_host_down' => 'c.notify_host_down',
'contact_notify_host_unreachable' => 'c.notify_host_unreachable',
'contact_notify_host_flapping' => 'c.notify_host_flapping',
'contact_notify_host_downtime' => 'c.notify_host_downtime',
'contact_id' => 'c.contact_id',
'contact_name' => 'co.name1 COLLATE latin1_general_ci',
'contact_alias' => 'c.alias COLLATE latin1_general_ci',
'contact_email' => 'c.email_address COLLATE latin1_general_ci',
'contact_pager' => 'c.pager_address',
'contact_object_id' => 'c.contact_object_id',
'contact_has_host_notfications' => 'c.host_notifications_enabled',
'contact_has_service_notfications' => 'c.service_notifications_enabled',
'contact_can_submit_commands' => 'c.can_submit_commands',
'contact_notify_service_recovery' => 'c.notify_service_recovery',
'contact_notify_service_warning' => 'c.notify_service_warning',
'contact_notify_service_critical' => 'c.notify_service_critical',
'contact_notify_service_unknown' => 'c.notify_service_unknown',
'contact_notify_service_flapping' => 'c.notify_service_flapping',
'contact_notify_service_downtime' => 'c.notify_service_recovery',
'contact_notify_host_recovery' => 'c.notify_host_recovery',
'contact_notify_host_down' => 'c.notify_host_down',
'contact_notify_host_unreachable' => 'c.notify_host_unreachable',
'contact_notify_host_flapping' => 'c.notify_host_flapping',
'contact_notify_host_downtime' => 'c.notify_host_downtime'
),
'timeperiods' => array(
'contact_notify_host_timeperiod' => 'ht.alias COLLATE latin1_general_ci',
'contact_notify_host_timeperiod' => 'ht.alias COLLATE latin1_general_ci',
'contact_notify_service_timeperiod' => 'st.alias COLLATE latin1_general_ci'
),
'hosts' => array(
'host_object_id' => 'ho.object_id',
'host_name' => 'ho.name1 COLLATE latin1_general_ci',
'host' => 'ho.name1 COLLATE latin1_general_ci',
'host' => 'ho.name1 COLLATE latin1_general_ci',
'host_name' => 'ho.name1',
),
'services' => array(
'service_object_id' => 'so.object_id',
'service_host_name' => 'so.name1 COLLATE latin1_general_ci',
'service' => 'so.name1 COLLATE latin1_general_ci',
'service_description' => 'so.name2 COLLATE latin1_general_ci',
'service' => 'so.name1 COLLATE latin1_general_ci',
'service_description' => 'so.name2',
'service_host_name' => 'so.name1',
)
);

View File

@ -33,13 +33,13 @@ class ContactgroupQuery extends IdoQuery
'contact_notify_host_downtime' => 'c.notify_host_downtime',
),
'hosts' => array(
'host' => 'ho.name1',
'host' => 'ho.name1 COLLATE latin1_general_ci',
'host_name' => 'ho.name1'
),
'services' => array(
'service' => 'so.name2 COLLATE latin1_general_ci',
'service_description' => 'so.name2 COLLATE latin1_general_ci',
'service_host_name' => 'so.name1 COLLATE latin1_general_ci'
'service_description' => 'so.name2',
'service_host_name' => 'so.name1'
)
);
@ -95,10 +95,10 @@ class ContactgroupQuery extends IdoQuery
protected function joinServices()
{
$scgSub = $this->db->select()->distinct()->from(
$this->prefix . 'service_contactgroups',
array('contactgroup_object_id', 'service_id')
);
// $scgSub = $this->db->select()->distinct()->from(
// $this->prefix . 'service_contactgroups',
// array('contactgroup_object_id', 'service_id')
// );
/*
This subselect is a workaround for a fucking stupid bug. Other tables

View File

@ -3,8 +3,14 @@
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
/**
* Query for host and service downtimes
*/
class DowntimeQuery extends IdoQuery
{
/**
* {@inheritdoc}
*/
protected $columnMap = array(
'downtime' => array(
'downtime_author' => 'sd.author_name',
@ -21,22 +27,32 @@ class DowntimeQuery extends IdoQuery
'downtime_duration' => 'sd.duration',
'downtime_is_in_effect' => 'sd.is_in_effect',
'downtime_internal_id' => 'sd.internal_downtime_id',
'downtime_objecttype' => "CASE WHEN ho.object_id IS NULL THEN 'service' ELSE 'host' END",
'downtime_host' => 'CASE WHEN ho.name1 IS NULL THEN so.name1 ELSE ho.name1 END COLLATE latin1_general_ci', // #7278, #7279
'host' => 'CASE WHEN ho.name1 IS NULL THEN so.name1 ELSE ho.name1 END COLLATE latin1_general_ci',
'host_name' => 'CASE WHEN ho.name1 IS NULL THEN so.name1 ELSE ho.name1 END',
'downtime_service' => 'so.name2 COLLATE latin1_general_ci',
'service' => 'so.name2 COLLATE latin1_general_ci', // #7278, #7279
'downtime_objecttype' => "CASE WHEN ho.object_id IS NOT NULL THEN 'host' ELSE CASE WHEN so.object_id IS NOT NULL THEN 'service' ELSE NULL END END",
'downtime_host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
'downtime_service_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE ss.current_state END'
'service_description' => 'so.name2',
'service_host_name' => 'so.name1'
),
'hosts' => array(
'host_display_name' => 'CASE WHEN sh.display_name IS NOT NULL THEN sh.display_name ELSE h.display_name END'
'host_display_name' => 'CASE WHEN h.display_name IS NULL THEN sh.display_name ELSE h.display_name END'
),
'hoststatus' => array(
'downtime_host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END'
),
'services' => array(
'service_display_name' => 's.display_name'
),
'servicestatus' => array(
'downtime_service_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE ss.current_state END'
)
);
/**
* {@inheritdoc}
*/
protected function joinBaseTables()
{
$this->select->from(
@ -53,19 +69,14 @@ class DowntimeQuery extends IdoQuery
'sd.object_id = so.object_id AND so.is_active = 1 AND so.objecttype_id = 2',
array()
);
$this->select->joinLeft(
array('hs' => $this->prefix . 'hoststatus'),
'ho.object_id = hs.host_object_id',
array()
);
$this->select->joinLeft(
array('ss' => $this->prefix . 'servicestatus'),
'so.object_id = ss.service_object_id',
array()
);
$this->joinedVirtualTables = array('downtime' => true);
}
/**
* Join downtimes' hosts
*
* @return $this
*/
protected function joinHosts()
{
$this->select->joinLeft(
@ -76,6 +87,26 @@ class DowntimeQuery extends IdoQuery
return $this;
}
/**
* Join downtimes' hosts' status
*
* @return $this
*/
protected function joinHoststatus()
{
$this->select->joinLeft(
array('hs' => $this->prefix . 'hoststatus'),
'ho.object_id = hs.host_object_id',
array()
);
return $this;
}
/**
* Join downtimes' services
*
* @return $this
*/
protected function joinServices()
{
$this->select->joinLeft(
@ -90,4 +121,19 @@ class DowntimeQuery extends IdoQuery
);
return $this;
}
/**
* Join downtimes' services' status
*
* @return $this
*/
protected function joinServicestatus()
{
$this->select->joinLeft(
array('ss' => $this->prefix . 'servicestatus'),
'so.object_id = ss.service_object_id',
array()
);
return $this;
}
}

View File

@ -6,10 +6,23 @@ namespace Icinga\Module\Monitoring\Backend\Ido\Query;
use Zend_Db_Select;
use Icinga\Data\Filter\Filter;
/**
* Query for event history
*/
class EventHistoryQuery extends IdoQuery
{
/**
* Subqueries used for the event history query
*
* @type IdoQuery[]
*
* @see EventHistoryQuery::joinBaseTables() For the used subqueries.
*/
protected $subQueries = array();
/**
* {@inheritdoc}
*/
protected $columnMap = array(
'eventhistory' => array(
'cnt_notification' => "SUM(CASE eh.type WHEN 'notify' THEN 1 ELSE 0 END)",
@ -41,8 +54,14 @@ class EventHistoryQuery extends IdoQuery
)
);
/**
* {@inheritdoc}
*/
protected $useSubqueryCount = true;
/**
* {@inheritdoc}
*/
protected function joinBaseTables()
{
$columns = array(
@ -77,15 +96,20 @@ class EventHistoryQuery extends IdoQuery
$this->joinedVirtualTables = array('eventhistory' => true);
}
/**
* {@inheritdoc}
*/
public function order($columnOrAlias, $dir = null)
{
foreach ($this->subQueries as $sub) {
$sub->requireColumn($columnOrAlias);
}
return parent::order($columnOrAlias, $dir);
}
/**
* {@inheritdoc}
*/
public function addFilter(Filter $filter)
{
foreach ($this->subQueries as $sub) {
@ -94,6 +118,9 @@ class EventHistoryQuery extends IdoQuery
return $this;
}
/**
* {@inheritdoc}
*/
public function where($condition, $value = null)
{
$this->requireColumn($condition);
@ -103,6 +130,11 @@ class EventHistoryQuery extends IdoQuery
return $this;
}
/**
* Join host groups
*
* @return $this
*/
protected function joinHostgroups()
{
$this->select->join(
@ -121,6 +153,11 @@ class EventHistoryQuery extends IdoQuery
return $this;
}
/**
* Join hosts
*
* @return $this
*/
protected function joinHosts()
{
$this->select->joinLeft(
@ -131,6 +168,11 @@ class EventHistoryQuery extends IdoQuery
return $this;
}
/**
* Join services
*
* @return $this
*/
protected function joinServices()
{
$this->select->joinLeft(

View File

@ -9,9 +9,7 @@ namespace Icinga\Module\Monitoring\DataView;
class Comment extends DataView
{
/**
* Retrieve columns provided by this view
*
* @return array
* {@inheritdoc}
*/
public function getColumns()
{
@ -34,9 +32,7 @@ class Comment extends DataView
}
/**
* Retrieve default sorting rules for particular columns. These involve sort order and potential additional to sort
*
* @return array
* {@inheritdoc}
*/
public function getSortRules()
{

View File

@ -33,7 +33,10 @@ class Downtime extends DataView
'downtime_host_state',
'downtime_service_state',
'host_display_name',
'service_display_name'
'service_display_name',
'host_name',
'service_host_name',
'service_description'
);
}

View File

@ -89,49 +89,46 @@ class Host extends MonitoredObject
protected function getDataView()
{
$columns = array(
'host_name',
'host_display_name',
'host_alias',
'host_address',
'host_state',
'host_state_type',
'host_handled',
'host_in_downtime',
'host_acknowledged',
'host_last_state_change',
'host_last_notification',
'host_last_check',
'host_next_check',
'host_action_url',
'host_active_checks_enabled',
'host_active_checks_enabled_changed',
'host_address',
'host_alias',
'host_check_command',
'host_check_execution_time',
'host_check_latency',
'host_check_source',
'host_output',
'host_long_output',
'host_check_command',
'host_perfdata',
'host_passive_checks_enabled',
'host_passive_checks_enabled_changed',
'host_obsessing',
'host_obsessing_changed',
'host_notifications_enabled',
'host_notifications_enabled_changed',
'host_current_check_attempt',
'host_current_notification_number',
'host_display_name',
'host_event_handler_enabled',
'host_event_handler_enabled_changed',
'host_flap_detection_enabled',
'host_flap_detection_enabled_changed',
'host_active_checks_enabled',
'host_active_checks_enabled_changed',
'host_current_check_attempt',
'host_max_check_attempts',
'host_current_notification_number',
'host_percent_state_change',
'host_handled',
'host_in_downtime',
'host_is_flapping',
'host_action_url',
'host_last_check',
'host_last_notification',
'host_last_state_change',
'host_long_output',
'host_max_check_attempts',
'host_name',
'host_next_check',
'host_notes_url',
'host_modified_host_attributes',
'host_problem',
'host_process_performance_data',
'process_perfdata' => 'host_process_performance_data'
'host_notifications_enabled',
'host_notifications_enabled_changed',
'host_obsessing',
'host_obsessing_changed',
'host_output',
'host_passive_checks_enabled',
'host_passive_checks_enabled_changed',
'host_percent_state_change',
'host_perfdata',
'host_process_perfdata' => 'host_process_performance_data',
'host_state',
'host_state_type'
);
if ($this->backend->getType() === 'livestatus') {
$columns[] = 'host_contacts';

View File

@ -253,10 +253,13 @@ abstract class MonitoredObject implements Filterable
'type' => 'comment_type',
))
->where('comment_type', array('comment', 'ack'))
->where('comment_objecttype', $this->type)
->where('comment_host', $this->host_name);
->where('comment_objecttype', $this->type);
if ($this->type === self::TYPE_SERVICE) {
$comments->where('comment_service', $this->service_description);
$comments
->where('service_host_name', $this->host_name)
->where('service_description', $this->service_description);
} else {
$comments->where('host_name', $this->host_name);
}
$this->comments = $comments->getQuery()->fetchAll();
return $this;
@ -281,16 +284,18 @@ abstract class MonitoredObject implements Filterable
'is_flexible' => 'downtime_is_flexible',
'is_fixed' => 'downtime_is_fixed',
'is_in_effect' => 'downtime_is_in_effect',
'entry_time' => 'downtime_entry_time',
'host' => 'downtime_host',
'service' => 'downtime_service'
'entry_time' => 'downtime_entry_time'
))
->where('downtime_objecttype', $this->type)
->where('downtime_host', $this->host_name)
->order('downtime_is_in_effect', 'DESC')
->order('downtime_scheduled_start', 'ASC');
if ($this->type === self::TYPE_SERVICE) {
$downtimes->where('downtime_service', $this->service_description);
$downtimes
->where('service_host_name', $this->host_name)
->where('service_description', $this->service_description);
} else {
$downtimes
->where('host_name', $this->host_name);
}
$this->downtimes = $downtimes->getQuery()->fetchAll();
return $this;
@ -385,8 +390,9 @@ abstract class MonitoredObject implements Filterable
'contact_pager',
));
if ($this->type === self::TYPE_SERVICE) {
$contacts->where('service_host_name', $this->host_name);
$contacts->where('service_description', $this->service_description);
$contacts
->where('service_host_name', $this->host_name)
->where('service_description', $this->service_description);
} else {
$contacts->where('host_name', $this->host_name);
}
@ -426,10 +432,13 @@ abstract class MonitoredObject implements Filterable
$contactsGroups = $this->backend->select()->from('contactgroup', array(
'contactgroup_name',
'contactgroup_alias'
))
->where('host_name', $this->host_name);
));
if ($this->type === self::TYPE_SERVICE) {
$contactsGroups->where('service_description', $this->service_description);
$contactsGroups
->where('service_host_name', $this->host_name)
->where('service_description', $this->service_description);
} else {
$contactsGroups->where('host_name', $this->host_name);
}
$this->contactgroups = $contactsGroups->getQuery()->fetchAll();
return $this;
@ -455,7 +464,6 @@ abstract class MonitoredObject implements Filterable
'output',
'type'
))
->order('timestamp', 'DESC')
->where('host_name', $this->host_name);
if ($this->type === self::TYPE_SERVICE) {
$eventHistory->where('service_description', $this->service_description);

View File

@ -106,94 +106,55 @@ class Service extends MonitoredObject
protected function getDataView()
{
return $this->backend->select()->from('serviceStatus', array(
'host_name',
'host_display_name',
'host_state',
'host_state_type',
'host_last_state_change',
'host_address',
'host_problem',
'host_handled',
'service_description',
'service_display_name',
'service_state',
'service_in_downtime',
'service_acknowledged',
'service_handled',
'service_unhandled',
'service_output',
'service_last_state_change',
'service_icon_image',
'service_long_output',
'service_is_flapping',
'service_state_type',
'service_severity',
'service_last_check',
'service_notifications_enabled',
'service_notifications_enabled_changed',
'service_action_url',
'service_notes_url',
'service_last_check',
'service_next_check',
'service_attempt',
'service_last_notification',
'service_check_command',
'service_check_source',
'service_current_notification_number',
'host_icon_image',
'host_acknowledged',
'host_output',
'host_long_output',
'host_in_downtime',
'host_is_flapping',
'host_last_check',
'host_notifications_enabled',
'host_unhandled_services',
'host_action_url',
'host_notes_url',
'host_display_name',
'host_alias',
'host_ipv4',
'host_severity',
'host_perfdata',
'host_active_checks_enabled',
'host_address',
'host_alias',
'host_display_name',
'host_handled',
'host_in_downtime',
'host_last_state_change',
'host_name',
'host_notifications_enabled',
'host_passive_checks_enabled',
'host_last_hard_state',
'host_last_hard_state_change',
'host_last_time_up',
'host_last_time_down',
'host_last_time_unreachable',
'host_modified_host_attributes',
'host',
'service',
'service_hard_state',
'service_problem',
'service_perfdata',
'host_state',
'service_acknowledged',
'service_action_url',
'service_active_checks_enabled',
'service_active_checks_enabled_changed',
'service_passive_checks_enabled',
'service_passive_checks_enabled_changed',
'service_last_hard_state',
'service_last_hard_state_change',
'service_last_time_ok',
'service_last_time_warning',
'service_last_time_critical',
'service_last_time_unknown',
'service_attempt',
'service_check_command',
'service_check_execution_time',
'service_check_latency',
'service_current_check_attempt',
'service_max_check_attempts',
'service_obsessing',
'service_obsessing_changed',
'service_check_source',
'service_current_notification_number',
'service_description',
'service_display_name',
'service_event_handler_enabled',
'service_event_handler_enabled_changed',
'service_flap_detection_enabled',
'service_flap_detection_enabled_changed',
'service_modified_service_attributes',
'service_process_performance_data',
'process_perfdata' => 'service_process_performance_data',
'service_handled',
'service_in_downtime',
'service_is_flapping',
'service_last_check',
'service_last_notification',
'service_last_state_change',
'service_long_output',
'service_next_check',
'service_notes_url',
'service_notifications_enabled',
'service_notifications_enabled_changed',
'service_obsessing',
'service_obsessing_changed',
'service_output',
'service_passive_checks_enabled',
'service_passive_checks_enabled_changed',
'service_percent_state_change',
'service_host_name'
'service_perfdata',
'service_process_perfdata' => 'service_process_performance_data',
'service_state',
'service_state_type'
))
->where('host_name', $this->host->getName())
->where('service_description', $this->service);

View File

@ -73,27 +73,28 @@ abstract class MonitoredObjectController extends Controller
}
}
}
if (count($this->object->comments) > 0 && $auth->hasPermission('monitoring/command/comment/delete')) {
$delCommentForm = new DeleteCommentCommandForm();
$delCommentForm
->setObjects($this->object)
->handleRequest();
$this->view->delCommentForm = $delCommentForm;
}
if (count($this->object->downtimes > 0) && $auth->hasPermission('monitoring/command/downtime/delete')) {
$delDowntimeForm = new DeleteDowntimeCommandForm();
$delDowntimeForm
->setObjects($this->object)
->handleRequest();
$this->view->delDowntimeForm = $delDowntimeForm;
}
$this->object->populate();
$toggleFeaturesForm = new ToggleObjectFeaturesCommandForm();
$toggleFeaturesForm
->load($this->object)
->setObjects($this->object)
->handleRequest();
$this->view->toggleFeaturesForm = $toggleFeaturesForm;
$this->view->object = $this->object->populate();
if (! empty($this->object->comments) && $auth->hasPermission('monitoring/command/comment/delete')) {
$delCommentForm = new DeleteCommentCommandForm();
$delCommentForm
->setObjects($this->object)
->handleRequest();
$this->view->delCommentForm = $delCommentForm;
}
if (! empty($this->object->downtimes) && $auth->hasPermission('monitoring/command/downtime/delete')) {
$delDowntimeForm = new DeleteDowntimeCommandForm();
$delDowntimeForm
->setObjects($this->object)
->handleRequest();
$this->view->delDowntimeForm = $delDowntimeForm;
}
$this->view->object = $this->object;
}
/**