NotificationQuery: Add support for history related queries

refs #9009
This commit is contained in:
Johannes Meyer 2015-06-10 13:10:28 +02:00
parent 41ee39d48f
commit 51a3213fca
3 changed files with 132 additions and 5 deletions

View File

@ -26,6 +26,13 @@ class HostnotificationQuery extends IdoQuery
'host_name' => 'ho.name1', 'host_name' => 'ho.name1',
'object_type' => '(\'host\')' 'object_type' => '(\'host\')'
), ),
'history' => array(
'type' => "('notify')",
'timestamp' => 'UNIX_TIMESTAMP(hn.start_time)',
'object_id' => 'hn.object_id',
'state' => 'hn.state',
'output' => null
),
'contactnotifications' => array( 'contactnotifications' => array(
'contact' => 'cno.name1 COLLATE latin1_general_ci', 'contact' => 'cno.name1 COLLATE latin1_general_ci',
'notification_contact_name' => 'cno.name1', 'notification_contact_name' => 'cno.name1',
@ -63,6 +70,31 @@ class HostnotificationQuery extends IdoQuery
*/ */
protected function joinBaseTables() protected function joinBaseTables()
{ {
switch ($this->ds->getDbType()) {
case 'mysql':
$concattedContacts = "GROUP_CONCAT("
. "cno.name1 ORDER BY cno.name1 SEPARATOR ', '"
. ") COLLATE latin1_general_ci";
break;
case 'pgsql':
// TODO: Find a way to order the contact alias list:
$concattedContacts = "ARRAY_TO_STRING(ARRAY_AGG(cno.name1), ', ')";
break;
case 'oracle':
// TODO: This is only valid for Oracle >= 11g Release 2
$concattedContacts = "LISTAGG(cno.name1, ', ') WITHIN GROUP (ORDER BY cno.name1)";
// Alternatives:
//
// RTRIM(XMLAGG(XMLELEMENT(e, column_name, ',').EXTRACT('//text()')),
//
// not supported and not documented but works since 10.1,
// however it is NOT always present:
// WM_CONCAT(c.alias)
break;
}
$this->columnMap['history']['output'] = "('[' || $concattedContacts || '] ' || hn.output)";
$this->select->from( $this->select->from(
array('hn' => $this->prefix . 'notifications'), array('hn' => $this->prefix . 'notifications'),
array() array()
@ -80,6 +112,15 @@ class HostnotificationQuery extends IdoQuery
$this->joinedVirtualTables['notifications'] = true; $this->joinedVirtualTables['notifications'] = true;
} }
/**
* Join virtual table history
*/
protected function joinHistory()
{
$this->requireVirtualTable('contactnotifications');
$this->group(array('hn.notification_id', 'ho.name1'));
}
/** /**
* Join contact notifications * Join contact notifications
*/ */
@ -95,6 +136,7 @@ class HostnotificationQuery extends IdoQuery
'cno.object_id = cn.contact_object_id', 'cno.object_id = cn.contact_object_id',
array() array()
); );
$this->group(array('cn.contactnotification_id', 'ho.name1'));
} }
/** /**
@ -134,7 +176,10 @@ class HostnotificationQuery extends IdoQuery
'hgo.objecttype_id = ?', 'hgo.objecttype_id = ?',
3 3
); );
$this->group(array('hn.notification_id', 'ho.name1'));
if (! $this->hasJoinedVirtualTable('contactnotifications')) {
$this->group(array('hn.notification_id', 'ho.name1'));
}
} }
/** /**
@ -184,7 +229,7 @@ class HostnotificationQuery extends IdoQuery
{ {
$this->select->join( $this->select->join(
array('s' => $this->prefix . 'services'), array('s' => $this->prefix . 'services'),
's.host_object_id = h.host_object_id', 's.host_object_id = ho.object_id',
array() array()
)->join( )->join(
array('so' => $this->prefix . 'objects'), array('so' => $this->prefix . 'objects'),
@ -198,6 +243,9 @@ class HostnotificationQuery extends IdoQuery
'so.objecttype_id = ?', 'so.objecttype_id = ?',
2 2
); );
$this->group(array('hn.notification_id', 'ho.name1'));
if (! $this->hasJoinedVirtualTable('contactnotifications')) {
$this->group(array('hn.notification_id', 'ho.name1'));
}
} }
} }

View File

@ -27,6 +27,13 @@ class NotificationQuery extends IdoQuery
'acknowledgement_comment_data' => 'n.acknowledgement_comment_data', 'acknowledgement_comment_data' => 'n.acknowledgement_comment_data',
'object_type' => 'n.object_type' 'object_type' => 'n.object_type'
), ),
'history' => array(
'type' => 'n.type',
'timestamp' => 'n.timestamp',
'object_id' => 'n.object_id',
'state' => 'n.state',
'output' => 'n.output'
),
'hosts' => array( 'hosts' => array(
'host_display_name' => 'n.host_display_name', 'host_display_name' => 'n.host_display_name',
'host_name' => 'n.host_name' 'host_name' => 'n.host_name'
@ -52,6 +59,13 @@ class NotificationQuery extends IdoQuery
*/ */
protected $subQueries = array(); protected $subQueries = array();
/**
* Whether to additionally select all history columns
*
* @var bool
*/
protected $fetchHistoryColumns = false;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -65,6 +79,17 @@ class NotificationQuery extends IdoQuery
$this->joinedVirtualTables['notifications'] = true; $this->joinedVirtualTables['notifications'] = true;
} }
/**
* Join history related columns and tables
*/
protected function joinHistory()
{
// TODO: Ensure that one is selecting the history columns first...
$this->fetchHistoryColumns = true;
$this->requireVirtualTable('hosts');
$this->requireVirtualTable('services');
}
/** /**
* Join hosts * Join hosts
*/ */
@ -73,6 +98,9 @@ class NotificationQuery extends IdoQuery
$columns = array_keys( $columns = array_keys(
$this->columnMap['notifications'] + $this->columnMap['hosts'] + $this->columnMap['services'] $this->columnMap['notifications'] + $this->columnMap['hosts'] + $this->columnMap['services']
); );
if ($this->fetchHistoryColumns) {
$columns = array_merge($columns, array_keys($this->columnMap['history']));
}
$hosts = $this->createSubQuery('hostnotification', $columns); $hosts = $this->createSubQuery('hostnotification', $columns);
$this->subQueries[] = $hosts; $this->subQueries[] = $hosts;
$this->notificationQuery->union(array($hosts), Zend_Db_Select::SQL_UNION_ALL); $this->notificationQuery->union(array($hosts), Zend_Db_Select::SQL_UNION_ALL);
@ -86,6 +114,9 @@ class NotificationQuery extends IdoQuery
$columns = array_keys( $columns = array_keys(
$this->columnMap['notifications'] + $this->columnMap['hosts'] + $this->columnMap['services'] $this->columnMap['notifications'] + $this->columnMap['hosts'] + $this->columnMap['services']
); );
if ($this->fetchHistoryColumns) {
$columns = array_merge($columns, array_keys($this->columnMap['history']));
}
$services = $this->createSubQuery('servicenotification', $columns); $services = $this->createSubQuery('servicenotification', $columns);
$this->subQueries[] = $services; $this->subQueries[] = $services;
$this->notificationQuery->union(array($services), Zend_Db_Select::SQL_UNION_ALL); $this->notificationQuery->union(array($services), Zend_Db_Select::SQL_UNION_ALL);

View File

@ -30,6 +30,13 @@ class ServicenotificationQuery extends IdoQuery
'service_host' => 'so.name1 COLLATE latin1_general_ci', 'service_host' => 'so.name1 COLLATE latin1_general_ci',
'service_host_name' => 'so.name1' 'service_host_name' => 'so.name1'
), ),
'history' => array(
'type' => "('notify')",
'timestamp' => 'UNIX_TIMESTAMP(sn.start_time)',
'object_id' => 'sn.object_id',
'state' => 'sn.state',
'output' => null
),
'contactnotifications' => array( 'contactnotifications' => array(
'contact' => 'cno.name1 COLLATE latin1_general_ci', 'contact' => 'cno.name1 COLLATE latin1_general_ci',
'notification_contact_name' => 'cno.name1', 'notification_contact_name' => 'cno.name1',
@ -64,6 +71,31 @@ class ServicenotificationQuery extends IdoQuery
*/ */
protected function joinBaseTables() protected function joinBaseTables()
{ {
switch ($this->ds->getDbType()) {
case 'mysql':
$concattedContacts = "GROUP_CONCAT("
. "cno.name1 ORDER BY cno.name1 SEPARATOR ', '"
. ") COLLATE latin1_general_ci";
break;
case 'pgsql':
// TODO: Find a way to order the contact alias list:
$concattedContacts = "ARRAY_TO_STRING(ARRAY_AGG(cno.name1), ', ')";
break;
case 'oracle':
// TODO: This is only valid for Oracle >= 11g Release 2
$concattedContacts = "LISTAGG(cno.name1, ', ') WITHIN GROUP (ORDER BY cno.name1)";
// Alternatives:
//
// RTRIM(XMLAGG(XMLELEMENT(e, column_name, ',').EXTRACT('//text()')),
//
// not supported and not documented but works since 10.1,
// however it is NOT always present:
// WM_CONCAT(c.alias)
break;
}
$this->columnMap['history']['output'] = "('[' || $concattedContacts || '] ' || sn.output)";
$this->select->from( $this->select->from(
array('sn' => $this->prefix . 'notifications'), array('sn' => $this->prefix . 'notifications'),
array() array()
@ -81,6 +113,15 @@ class ServicenotificationQuery extends IdoQuery
$this->joinedVirtualTables['notifications'] = true; $this->joinedVirtualTables['notifications'] = true;
} }
/**
* Join virtual table history
*/
protected function joinHistory()
{
$this->requireVirtualTable('contactnotifications');
$this->group(array('sn.notification_id', 'so.name2', 'so.name1'));
}
/** /**
* Join contact notifications * Join contact notifications
*/ */
@ -96,6 +137,7 @@ class ServicenotificationQuery extends IdoQuery
'cno.object_id = cn.contact_object_id', 'cno.object_id = cn.contact_object_id',
array() array()
); );
$this->group(array('cn.contactnotification_id', 'so.name2', 'so.name1'));
} }
/** /**
@ -136,7 +178,6 @@ class ServicenotificationQuery extends IdoQuery
'hgo.objecttype_id = ?', 'hgo.objecttype_id = ?',
3 3
); );
$this->group(array('sn.notification_id', 'so.name2', 'so.name1'));
} }
/** /**
@ -177,7 +218,10 @@ class ServicenotificationQuery extends IdoQuery
'sgo.objecttype_id = ?', 'sgo.objecttype_id = ?',
4 4
); );
$this->group(array('sn.notification_id', 'so.name2', 'so.name1'));
if (! $this->hasJoinedVirtualTable('contactnotifications')) {
$this->group(array('sn.notification_id', 'so.name2', 'so.name1'));
}
} }
/** /**
@ -190,5 +234,9 @@ class ServicenotificationQuery extends IdoQuery
's.service_object_id = so.object_id', 's.service_object_id = so.object_id',
array() array()
); );
if (! $this->hasJoinedVirtualTable('contactnotifications')) {
$this->group(array('sn.notification_id', 'so.name2', 'so.name1'));
}
} }
} }