Merge pull request #3457 from Icinga/feature/proper-results-when-filtering-for-linked-objects-2934
Proper results when filtering for linked objects
This commit is contained in:
commit
dab9fea0d4
|
@ -23,6 +23,11 @@ class ContactgroupQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hosts', 'members', 'services');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -187,4 +192,23 @@ class ContactgroupQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$this->requireVirtualTable('hosts');
|
||||
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$this->requireVirtualTable('services');
|
||||
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class HostcommentQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'services');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -179,4 +184,19 @@ class HostcommentQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class HostcommenthistoryQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'services');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -171,4 +176,19 @@ class HostcommenthistoryQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@ class HostcontactQuery extends IdoQuery
|
|||
|
||||
protected $groupOrigin = ['contactgroups', 'hosts', 'services'];
|
||||
|
||||
protected $subQueryTargets = [
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
];
|
||||
|
||||
protected $columnMap = [
|
||||
'contactgroups' => [
|
||||
'contactgroup' => 'cgo.name1 COLLATE latin1_general_ci',
|
||||
|
@ -189,6 +194,8 @@ class HostcontactQuery extends IdoQuery
|
|||
*/
|
||||
protected function joinServices()
|
||||
{
|
||||
$this->joinHosts();
|
||||
|
||||
$this->select->joinLeft(
|
||||
['s' => $this->prefix . 'services'],
|
||||
's.host_object_id = ho.object_id',
|
||||
|
@ -216,4 +223,23 @@ class HostcontactQuery extends IdoQuery
|
|||
[]
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$this->requireVirtualTable('hosts');
|
||||
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$this->requireVirtualTable('services');
|
||||
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class HostdowntimeQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'servicegroups', 'services');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -185,4 +190,19 @@ class HostdowntimeQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class HostdowntimestarthistoryQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'services');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -180,4 +185,19 @@ class HostdowntimestarthistoryQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class HostflappingstarthistoryQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'services');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -170,4 +175,19 @@ class HostflappingstarthistoryQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
use Icinga\Exception\NotImplementedError;
|
||||
|
||||
/**
|
||||
* Query for host groups
|
||||
*/
|
||||
|
@ -18,6 +20,11 @@ class HostgroupQuery extends IdoQuery
|
|||
|
||||
protected $groupOrigin = array('members');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
protected $columnMap = array(
|
||||
'hostgroups' => array(
|
||||
'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci',
|
||||
|
@ -223,4 +230,31 @@ class HostgroupQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
if (! $and) {
|
||||
// IN AND NOT IN works for OR filters w/o subquery joins
|
||||
throw new NotImplementedError('');
|
||||
} else {
|
||||
// Propagate that the "parent" query has to be filtered as well
|
||||
$additionalFilter = clone $filter;
|
||||
}
|
||||
|
||||
$this->requireVirtualTable('members');
|
||||
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$this->requireVirtualTable('members');
|
||||
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@ class HostnotificationQuery extends IdoQuery
|
|||
*/
|
||||
protected $allowCustomVars = true;
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -232,4 +237,19 @@ class HostnotificationQuery extends IdoQuery
|
|||
|
||||
return $group;
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,11 @@ class HoststatehistoryQuery extends IdoQuery
|
|||
'hard_state' => 1
|
||||
);
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -186,4 +191,19 @@ class HoststatehistoryQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,11 @@ class HoststatusQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'servicegroups', 'services');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -292,4 +297,19 @@ class HoststatusQuery extends IdoQuery
|
|||
'unhandled_service_count'
|
||||
));
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 'ho.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['s.host_object_id', 'ho.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use Icinga\Data\Db\DbQuery;
|
|||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Data\Filter\FilterExpression;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Exception\NotImplementedError;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Exception\QueryException;
|
||||
use Icinga\Web\Session;
|
||||
|
@ -149,6 +150,13 @@ abstract class IdoQuery extends DbQuery
|
|||
*/
|
||||
protected $groupOrigin = array();
|
||||
|
||||
/**
|
||||
* Map of table names to query names for which to create subquery filters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $subQueryTargets = array();
|
||||
|
||||
/**
|
||||
* The primary key column for the instances table
|
||||
*
|
||||
|
@ -492,6 +500,160 @@ abstract class IdoQuery extends DbQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the given query so that it can be linked to the parent
|
||||
*
|
||||
* @param IdoQuery $query
|
||||
* @param string $name
|
||||
* @param FilterExpression $filter The filter which initiated the sub query
|
||||
* @param bool $and Whether it's an AND filter
|
||||
* @param bool $negate Whether it's an != filter
|
||||
* @param FilterExpression $additionalFilter Filters which should be applied to the "parent" query
|
||||
*
|
||||
* @return array The first value is their, the second our key column
|
||||
*
|
||||
* @throws NotImplementedError In case the given query is unknown
|
||||
*/
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
throw new NotImplementedError('Query "%s" is unknown', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a sub-query filter for the given filter expression
|
||||
*
|
||||
* @param FilterExpression $filter
|
||||
* @param string $queryName
|
||||
*
|
||||
* @return Filter
|
||||
*
|
||||
* @throws QueryException
|
||||
*/
|
||||
protected function createSubQueryFilter(FilterExpression $filter, $queryName)
|
||||
{
|
||||
$expr = $filter->getExpression();
|
||||
$op = $filter->getSign();
|
||||
|
||||
if ($op === '=' && ! is_array($expr) && $op !== '!=') {
|
||||
// We're joining a subquery only if the filter is enclosed in parentheses or if it's a != filter,
|
||||
// e.g. hostgroup_name=(linux...), hostgroup_name!=linux, hostgroup_name!=(linux...)
|
||||
throw new NotImplementedError('');
|
||||
}
|
||||
|
||||
$subQuery = $this->createSubQuery($queryName);
|
||||
$subQuery->setIsSubQuery();
|
||||
|
||||
$subQueryFilter = clone $filter;
|
||||
|
||||
if ($op === '!=') {
|
||||
$negate = true;
|
||||
if (! is_array($expr)) {
|
||||
// We assume that expression is an array later on but we'll support subquery joins for != filters
|
||||
// which are not enclosed in parentheses
|
||||
$expr = [$expr];
|
||||
}
|
||||
} else {
|
||||
$negate = false;
|
||||
}
|
||||
|
||||
if (count($expr) === 1 && strpos($expr[0], '&') !== false) {
|
||||
// Our current filter implementation does not specify & as a control character so the count of the
|
||||
// expression array is always one in this case
|
||||
$expr = explode('&', $expr[0]);
|
||||
$subQueryFilter->setExpression($expr);
|
||||
$and = true;
|
||||
} else {
|
||||
// Or filters are respected by our filter implementation. No special handling needed here
|
||||
$and = false;
|
||||
}
|
||||
|
||||
$additional = null;
|
||||
|
||||
list($theirs, $ours) = $this->joinSubQuery($subQuery, $queryName, $subQueryFilter, $and, $negate, $additional);
|
||||
|
||||
$zendSelect = $subQuery->select();
|
||||
$fromPart = $zendSelect->getPart($zendSelect::FROM);
|
||||
$zendSelect->reset($zendSelect::FROM);
|
||||
|
||||
foreach ($fromPart as $correlationName => $joinOptions) {
|
||||
if (isset($joinOptions['joinCondition'])) {
|
||||
$joinOptions['joinCondition'] = preg_replace(
|
||||
'/(?<=^|\s)\w+(?=\.)/',
|
||||
'sub_$0',
|
||||
$joinOptions['joinCondition']
|
||||
);
|
||||
}
|
||||
|
||||
$name = ['sub_' . $correlationName => $joinOptions['tableName']];
|
||||
switch ($joinOptions['joinType']) {
|
||||
case $zendSelect::FROM:
|
||||
$zendSelect->from($name);
|
||||
break;
|
||||
case $zendSelect::INNER_JOIN:
|
||||
$zendSelect->joinInner($name, $joinOptions['joinCondition'], null);
|
||||
break;
|
||||
case $zendSelect::LEFT_JOIN:
|
||||
$zendSelect->joinLeft($name, $joinOptions['joinCondition'], null);
|
||||
break;
|
||||
default:
|
||||
// TODO: Add support for other join types if required?
|
||||
throw new QueryException(
|
||||
'Unsupported join type %s. Cannot create subquery filter.',
|
||||
$joinOptions['joinType']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($and || $negate && ! $and) {
|
||||
// Having is only required for AND and != filters,
|
||||
// e.g. hostgroup_name=(ping&linux), hostgroup_name!=ping, hostgroup_name!=(ping|linux)
|
||||
$groups = $subQuery->getGroup();
|
||||
$group = $groups[0];
|
||||
$group = preg_replace('/(?<=^|\s)\w+(?=\.)/', 'sub_$0', $group);
|
||||
|
||||
$cnt = count($expr);
|
||||
|
||||
$subQuery->select()->having("COUNT(DISTINCT $group) >= $cnt");
|
||||
}
|
||||
|
||||
$subQueryFilter->setColumn(preg_replace(
|
||||
'/(?<=^|\s)\w+(?=\.)/',
|
||||
'sub_$0',
|
||||
$subQuery->aliasToColumnName($filter->getColumn())
|
||||
));
|
||||
|
||||
if ($negate) {
|
||||
// != will be NOT EXISTS later
|
||||
$subQueryFilter = $subQueryFilter->setSign('=');
|
||||
}
|
||||
|
||||
$subQueryFilter = $subQueryFilter->andFilter(Filter::where(
|
||||
preg_replace('/(?<=^|\s)\w+(?=\.)/', 'sub_$0', $theirs),
|
||||
new Zend_Db_Expr($ours)
|
||||
));
|
||||
|
||||
$subQuery
|
||||
->setFilter($subQueryFilter)
|
||||
->clearGroupingRules()
|
||||
->select()
|
||||
->reset('columns')
|
||||
->columns([new Zend_Db_Expr('1')]);
|
||||
|
||||
// EXISTS is the column name because without any column $this->isCustomVar() fails badly otherwise.
|
||||
// Additionally it bypasses the non-required optimizations made by our filter rendering implementation.
|
||||
$exists = new FilterExpression($negate ? 'NOT EXISTS' : 'EXISTS', '', new Zend_Db_Expr($subQuery));
|
||||
|
||||
if ($additional !== null) {
|
||||
$alias = $additional->getColumn();
|
||||
$this->requireColumn($alias);
|
||||
$additional->setColumn($this->aliasToColumnName($alias));
|
||||
|
||||
return Filter::matchAll($exists, $additional);
|
||||
}
|
||||
|
||||
return $exists;
|
||||
}
|
||||
|
||||
protected function requireFilterColumns(Filter $filter)
|
||||
{
|
||||
if ($filter instanceof FilterExpression) {
|
||||
|
@ -500,6 +662,16 @@ abstract class IdoQuery extends DbQuery
|
|||
}
|
||||
|
||||
$alias = $filter->getColumn();
|
||||
|
||||
$virtualTable = $this->aliasToTableName($alias);
|
||||
if (isset($this->subQueryTargets[$virtualTable])) {
|
||||
try {
|
||||
return $this->createSubQueryFilter($filter, $this->subQueryTargets[$virtualTable]);
|
||||
} catch (NotImplementedError $e) {
|
||||
// We don't want to create subquery filters in all cases
|
||||
}
|
||||
}
|
||||
|
||||
$this->requireColumn($alias);
|
||||
|
||||
if ($this->isCustomvar($alias)) {
|
||||
|
@ -519,8 +691,12 @@ abstract class IdoQuery extends DbQuery
|
|||
|
||||
$filter->setColumn($column);
|
||||
} else {
|
||||
foreach ($filter->filters() as $filter) {
|
||||
$this->requireFilterColumns($filter);
|
||||
foreach ($filter->filters() as $child) {
|
||||
$replacement = $this->requireFilterColumns($child);
|
||||
if ($replacement !== null) {
|
||||
// setId($child->getId()) is performed because replaceById() doesn't already do it
|
||||
$filter->replaceById($child->getId(), $replacement->setId($child->getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -531,8 +707,7 @@ abstract class IdoQuery extends DbQuery
|
|||
public function addFilter(Filter $filter)
|
||||
{
|
||||
$filter = clone $filter;
|
||||
$this->requireFilterColumns($filter);
|
||||
return parent::addFilter($filter);
|
||||
return parent::addFilter($this->requireFilterColumns($filter) ?: $filter);
|
||||
}
|
||||
|
||||
public function where($condition, $value = null)
|
||||
|
|
|
@ -23,6 +23,11 @@ class ServicecommentQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'servicegroups');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -193,4 +198,21 @@ class ServicecommentQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$this->requireVirtualTable('services');
|
||||
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 's.host_object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class ServicecommenthistoryQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'servicegroups', 'services');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -169,4 +174,19 @@ class ServicecommenthistoryQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['so.object_id', 'so.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@ class ServicecontactQuery extends IdoQuery
|
|||
|
||||
protected $groupOrigin = ['contactgroups', 'hosts', 'services'];
|
||||
|
||||
protected $subQueryTargets = [
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
];
|
||||
|
||||
protected $columnMap = [
|
||||
'contactgroups' => [
|
||||
'contactgroup' => 'cgo.name1 COLLATE latin1_general_ci',
|
||||
|
@ -212,4 +217,19 @@ class ServicecontactQuery extends IdoQuery
|
|||
[]
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 's.host_object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class ServicedowntimeQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'servicegroups');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -199,4 +204,19 @@ class ServicedowntimeQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['so.object_id', 'so.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class ServicedowntimestarthistoryQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'servicegroups');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -178,4 +183,19 @@ class ServicedowntimestarthistoryQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['so.object_id', 'so.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class ServiceflappingstarthistoryQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'servicegroups');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -169,4 +174,19 @@ class ServiceflappingstarthistoryQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['so.object_id', 'so.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
use Icinga\Exception\NotImplementedError;
|
||||
|
||||
class ServicegroupQuery extends IdoQuery
|
||||
{
|
||||
protected $groupBase = array(
|
||||
'servicegroups' => array('sgo.object_id, sg.servicegroup_id'),
|
||||
'servicegroups' => array('sgo.object_id', 'sg.servicegroup_id'),
|
||||
'servicestatus' => array('ss.servicestatus_id', 'hs.hoststatus_id')
|
||||
);
|
||||
|
||||
|
@ -14,6 +16,11 @@ class ServicegroupQuery extends IdoQuery
|
|||
|
||||
protected $allowCustomVars = true;
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
protected $columnMap = array(
|
||||
'hostgroups' => array(
|
||||
'hostgroup_name' => 'hgo.name1'
|
||||
|
@ -178,4 +185,29 @@ class ServicegroupQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$this->requireVirtualTable('members');
|
||||
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['so.object_id', 'so.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
if (! $and) {
|
||||
// IN AND NOT IN for OR filters works w/o subquery joins
|
||||
throw new NotImplementedError('');
|
||||
} else {
|
||||
// Propagate that the "parent" query has to be filtered as well
|
||||
$additionalFilter = clone $filter;
|
||||
}
|
||||
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@ class ServicenotificationQuery extends IdoQuery
|
|||
*/
|
||||
protected $allowCustomVars = true;
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -233,4 +238,21 @@ class ServicenotificationQuery extends IdoQuery
|
|||
|
||||
return $group;
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$this->requireVirtualTable('services');
|
||||
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 's.host_object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,11 @@ class ServicestatehistoryQuery extends IdoQuery
|
|||
'hard_state' => 1
|
||||
);
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -184,4 +189,19 @@ class ServicestatehistoryQuery extends IdoQuery
|
|||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('services');
|
||||
|
||||
return ['so.object_id', 'so.object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ class ServicestatusQuery extends IdoQuery
|
|||
*/
|
||||
protected $groupOrigin = array('hostgroups', 'servicegroups');
|
||||
|
||||
protected $subQueryTargets = array(
|
||||
'hostgroups' => 'hostgroup',
|
||||
'servicegroups' => 'servicegroup'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -413,4 +418,19 @@ class ServicestatusQuery extends IdoQuery
|
|||
parent::registerGroupColumns($alias, $table, $groupedColumns, $groupedTables);
|
||||
}
|
||||
}
|
||||
|
||||
protected function joinSubQuery(IdoQuery $query, $name, $filter, $and, $negate, &$additionalFilter)
|
||||
{
|
||||
if ($name === 'hostgroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['hgm.host_object_id', 's.host_object_id'];
|
||||
} elseif ($name === 'servicegroup') {
|
||||
$query->joinVirtualTable('members');
|
||||
|
||||
return ['sgm.service_object_id', 'so.object_id'];
|
||||
}
|
||||
|
||||
return parent::joinSubQuery($query, $name, $filter, $and, $negate, $additionalFilter);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue