Merge branch 'bugfix/monitoring-list-dup-entries-7057'

refs #7057
refs #7344
This commit is contained in:
Alexander Fuhr 2014-10-08 12:47:24 +02:00
commit f77a0e919a
6 changed files with 133 additions and 57 deletions

View File

@ -96,14 +96,14 @@ class DbQuery extends SimpleQuery
public function getSelectQuery() public function getSelectQuery()
{ {
$select = $this->dbSelect(); $select = $this->dbSelect();
// Add order fields to select for postgres distinct queries (#6351) // Add order fields to select for postgres distinct queries (#6351)
if ($this->hasOrder() if ($this->hasOrder()
&& $this->getDatasource()->getDbType() === 'pgsql' && $this->getDatasource()->getDbType() === 'pgsql'
&& $select->getPart(Zend_Db_Select::DISTINCT) === true) { && $select->getPart(Zend_Db_Select::DISTINCT) === true) {
foreach ($this->getOrder() as $fieldAndDirection) { foreach ($this->getOrder() as $fieldAndDirection) {
list($alias, $field) = explode('.', $fieldAndDirection[0]); if (array_search($fieldAndDirection[0], $this->columns) === false) {
$this->columns[$field] = $fieldAndDirection[0]; $this->columns[] = $fieldAndDirection[0];
}
} }
} }
@ -264,6 +264,7 @@ class DbQuery extends SimpleQuery
$this->applyFilterSql($count); $this->applyFilterSql($count);
if ($this->useSubqueryCount) { if ($this->useSubqueryCount) {
$count->columns($this->columns);
$columns = array('cnt' => 'COUNT(*)'); $columns = array('cnt' => 'COUNT(*)');
return $this->db->select()->from($count, $columns); return $this->db->select()->from($count, $columns);
} }

View File

@ -79,7 +79,7 @@ class GroupSummaryQuery extends IdoQuery
} }
$union = $this->db->select()->union(array($hosts, $services), Zend_Db_Select::SQL_UNION_ALL); $union = $this->db->select()->union(array($hosts, $services), Zend_Db_Select::SQL_UNION_ALL);
$this->select->from(array('statussummary' => $union), array($groupColumn))->group(array($groupColumn)); $this->select->from(array('statussummary' => $union), array())->group(array($groupColumn));
$this->joinedVirtualTables = array( $this->joinedVirtualTables = array(
'servicestatussummary' => true, 'servicestatussummary' => true,

View File

@ -8,6 +8,29 @@ use Zend_Db_Expr;
class StatusQuery extends IdoQuery class StatusQuery extends IdoQuery
{ {
/**
* This mode represents whether we are in HostStatus or ServiceStatus
*
* Implemented for `distinct as workaround
*
* @TODO Subject to change, see #7344
*
* @var string
*/
protected $mode;
/**
* Sets the mode of the current query
*
* @TODO Subject to change, see #7344
*
* @param string $mode
*/
public function setMode($mode)
{
$this->mode = $mode;
}
protected $allowCustomVars = true; protected $allowCustomVars = true;
protected $columnMap = array( protected $columnMap = array(
@ -430,6 +453,12 @@ class StatusQuery extends IdoQuery
array() array()
); );
// @TODO Subject to change, see #7344
if ($this->mode === 'host' || $this->mode === 'service') {
$this->useSubqueryCount = true;
$this->distinct();
}
return $this; return $this;
} }
@ -449,7 +478,11 @@ class StatusQuery extends IdoQuery
. ' AND hgo.is_active = 1', . ' AND hgo.is_active = 1',
array() array()
); );
// @TODO Subject to change, see #7344
if ($this->mode === 'service') {
$this->distinct();
$this->useSubqueryCount = true;
}
return $this; return $this;
} }
@ -471,6 +504,14 @@ class StatusQuery extends IdoQuery
array() array()
); );
// @TODO Subject to change, see #7344
if ($this->mode === 'host' || $this->mode === 'service') {
$this->distinct();
}
if ($this->mode === 'host') {
$this->useSubqueryCount = true;
}
return $this; return $this;
} }

View File

@ -7,7 +7,6 @@ namespace Icinga\Module\Monitoring\DataView;
use Countable; use Countable;
use Icinga\Data\Filter\Filter; use Icinga\Data\Filter\Filter;
use Icinga\Data\Filter\FilterMatch; use Icinga\Data\Filter\FilterMatch;
use Icinga\Data\SimpleQuery;
use Icinga\Data\Browsable; use Icinga\Data\Browsable;
use Icinga\Data\PivotTable; use Icinga\Data\PivotTable;
use Icinga\Data\Sortable; use Icinga\Data\Sortable;
@ -26,9 +25,9 @@ abstract class DataView implements Browsable, Countable, Filterable, Sortable
/** /**
* The query used to populate the view * The query used to populate the view
* *
* @var SimpleQuery * @var \Icinga\Data\SimpleQuery
*/ */
private $query; protected $query;
protected $filter; protected $filter;
@ -39,8 +38,8 @@ abstract class DataView implements Browsable, Countable, Filterable, Sortable
/** /**
* Create a new view * Create a new view
* *
* @param SimpleQuery $query Which backend to query * @param ConnectionInterface $connection
* @param array $columns Select columns * @param array $columns
*/ */
public function __construct(ConnectionInterface $connection, array $columns = null) public function __construct(ConnectionInterface $connection, array $columns = null)
{ {
@ -48,6 +47,18 @@ abstract class DataView implements Browsable, Countable, Filterable, Sortable
$queryClass = $connection->getQueryClass($this->getQueryName()); $queryClass = $connection->getQueryClass($this->getQueryName());
$this->query = new $queryClass($this->connection->getResource(), $columns); $this->query = new $queryClass($this->connection->getResource(), $columns);
$this->filter = Filter::matchAll(); $this->filter = Filter::matchAll();
$this->init();
}
/**
* Initializer for `distinct purposes
*
* Implemented for `distinct as workaround
*
* @TODO Subject to change, see #7344
*/
public function init()
{
} }
/** /**
@ -194,9 +205,10 @@ public function dump()
* Sort the rows, according to the specified sort column and order * Sort the rows, according to the specified sort column and order
* *
* @param string $column Sort column * @param string $column Sort column
* @param int $order Sort order, one of the SORT_ constants * @param string $order Sort order, one of the SORT_ constants
* *
* @return self * @return $this
* @throws QueryException If the sort column is not allowed
* @see DataView::SORT_ASC * @see DataView::SORT_ASC
* @see DataView::SORT_DESC * @see DataView::SORT_DESC
* @deprecated Use DataView::order() instead * @deprecated Use DataView::order() instead
@ -204,9 +216,11 @@ public function dump()
public function sort($column = null, $order = null) public function sort($column = null, $order = null)
{ {
$sortRules = $this->getSortRules(); $sortRules = $this->getSortRules();
if ($sortRules !== null) {
if ($column === null) { if ($column === null) {
// Use first available sort rule as default
if (empty($sortRules)) {
return $this;
}
$sortColumns = reset($sortRules); $sortColumns = reset($sortRules);
if (! isset($sortColumns['columns'])) { if (! isset($sortColumns['columns'])) {
$sortColumns['columns'] = array(key($sortRules)); $sortColumns['columns'] = array(key($sortRules));
@ -225,8 +239,8 @@ public function dump()
}; };
} }
$order = $order === null ? (isset($sortColumns['order']) ? $sortColumns['order'] : self::SORT_ASC) : $order; $order = $order === null ? (isset($sortColumns['order']) ? $sortColumns['order'] : static::SORT_ASC) : $order;
$order = (strtoupper($order) === self::SORT_ASC) ? 'ASC' : 'DESC'; $order = (strtoupper($order) === static::SORT_ASC) ? 'ASC' : 'DESC';
foreach ($sortColumns['columns'] as $column) { foreach ($sortColumns['columns'] as $column) {
if (! $this->isValidFilterTarget($column)) { if (! $this->isValidFilterTarget($column)) {
@ -239,7 +253,6 @@ public function dump()
$this->query->order($column, $order); $this->query->order($column, $order);
} }
$this->isSorted = true; $this->isSorted = true;
}
return $this; return $this;
} }
@ -250,7 +263,7 @@ public function dump()
*/ */
public function getSortRules() public function getSortRules()
{ {
return null; return array();
} }
/** /**
@ -259,7 +272,7 @@ public function dump()
* @param string $column * @param string $column
* @param string $direction * @param string $direction
* *
* @return self * @return $this
*/ */
public function order($column = null, $direction = null) public function order($column = null, $direction = null)
{ {
@ -294,7 +307,7 @@ public function dump()
/** /**
* Return the query which was created in the constructor * Return the query which was created in the constructor
* *
* @return mixed * @return \Icinga\Data\SimpleQuery
*/ */
public function getQuery() public function getQuery()
{ {
@ -365,6 +378,9 @@ public function dump()
*/ */
public function paginate($itemsPerPage = null, $pageNumber = null) public function paginate($itemsPerPage = null, $pageNumber = null)
{ {
if (! $this->isSorted) {
$this->order();
}
return $this->query->paginate($itemsPerPage, $pageNumber); return $this->query->paginate($itemsPerPage, $pageNumber);
} }

View File

@ -6,6 +6,14 @@ namespace Icinga\Module\Monitoring\DataView;
class HostStatus extends DataView class HostStatus extends DataView
{ {
/**
* @see DataView::init()
*/
public function init()
{
$this->query->setMode('host');
}
/** /**
* Retrieve columns provided by this view * Retrieve columns provided by this view
* *

View File

@ -6,6 +6,16 @@ namespace Icinga\Module\Monitoring\DataView;
class ServiceStatus extends DataView class ServiceStatus extends DataView
{ {
/**
* Sets the mode for `distinct as workaround
*
* @TODO Subject to change, see #7344
*/
public function init()
{
$this->query->setMode('service');
}
/** /**
* Retrieve columns provided by this view * Retrieve columns provided by this view
* *