Merge branch 'feature/ido-4255'

resolves #4255
This commit is contained in:
Eric Lippmann 2013-09-17 15:16:33 +02:00
commit f3a47553f8
50 changed files with 1286 additions and 421 deletions

View File

@ -83,7 +83,8 @@ class DbAdapterFactory implements ConfigAwareFactory
private static $defaultZendDbAdapterOptions = array(
Zend_Db::AUTO_QUOTE_IDENTIFIERS => false,
Zend_Db::CASE_FOLDING => Zend_Db::CASE_LOWER,
Zend_Db::FETCH_MODE => Zend_Db::FETCH_OBJ
// Zend_Db::FETCH_MODE => Zend_Db::FETCH_OBJ
'fetchMode' => Zend_Db::FETCH_OBJ
);
/**

View File

@ -149,12 +149,12 @@ class Manager
$this->enabledDirs = array();
while (false !== ($file = readdir($fh))) {
if ($file[0] === '.') {
if ($file[0] === '.' || $file === 'README') {
continue;
}
$link = $this->enableDir . '/' . $file;
if (!is_link($link)) {
if (! is_link($link)) {
Logger::warn(
'Found invalid module in enabledModule directory "%s": "%s" is not a symlink',
$this->enableDir,

View File

@ -274,7 +274,10 @@ class Module
$this->app->getLoader()->registerNamespace('Icinga\\Module\\' . $moduleName, $moduleLibraryDir);
if (is_dir($this->getFormDir())) {
$this->app->getLoader()->registerNamespace('Icinga\\Module\\' . $moduleName. '\\Form', $this->getFormDir());
$this->app->getLoader()->registerNamespace(
'Icinga\\Module\\' . $moduleName. '\\Form',
$this->getFormDir()
);
}
}

View File

@ -4,7 +4,7 @@ namespace Icinga\Data;
use Icinga\Exception;
abstract class AbstractQuery
abstract class AbstractQuery implements QueryInterface
{
/**
* Sort ascending
@ -72,6 +72,17 @@ abstract class AbstractQuery
$this->init();
}
public function addColumn($name, $alias = null)
{
// TODO: Fail if adding column twice, but allow same col with new alias
if ($alias === null) {
$this->columns[] = $name;
} else {
$this->columns[$alias] = $name;
}
return $this;
}
public function getDatasource()
{
return $this->ds;
@ -158,7 +169,7 @@ abstract class AbstractQuery
$col = substr($col, 0, $pos);
}
} else {
if (strtoupper($dir) === 'DESC') {
if ($dir === self::SORT_DESC || strtoupper($dir) === 'DESC') {
$dir = self::SORT_DESC;
} else {
$dir = self::SORT_ASC;

View File

@ -1,8 +1,10 @@
<?php
namespace Icinga\Data;
namespace Icinga\Data\DataArray;
class ArrayDatasource implements DatasourceInterface
use Icinga\Data\DatasourceInterface;
class Datasource implements DatasourceInterface
{
protected $data;
@ -17,16 +19,16 @@ class ArrayDatasource implements DatasourceInterface
}
/**
* Instantiate an ArrayQuery object
* Instantiate a Query object
*
* @return ArrayQuery
* @return Query
*/
public function select()
{
return new ArrayQuery($this);
return new Query($this);
}
public function fetchColumn(ArrayQuery $query)
public function fetchColumn(Query $query)
{
$result = array();
foreach ($this->getResult($query) as $row) {
@ -36,7 +38,7 @@ class ArrayDatasource implements DatasourceInterface
return $result;
}
public function fetchPairs(ArrayQuery $query)
public function fetchPairs(Query $query)
{
$result = array();
$keys = null;
@ -52,19 +54,19 @@ class ArrayDatasource implements DatasourceInterface
return $result;
}
public function fetchAll(ArrayQuery $query)
public function fetchAll(Query $query)
{
$result = $this->getResult($query);
return $result;
}
public function count(ArrayQuery $query)
public function count(Query $query)
{
$this->createResult($query);
return $query->getCount();
}
protected function createResult(ArrayQuery $query)
protected function createResult(Query $query)
{
if ($query->hasResult()) {
return $this;
@ -109,7 +111,7 @@ class ArrayDatasource implements DatasourceInterface
return $this;
}
protected function getResult(ArrayQuery $query)
protected function getResult(Query $query)
{
if (! $query->hasResult()) {
$this->createResult($query);

View File

@ -1,8 +1,10 @@
<?php
namespace Icinga\Data;
namespace Icinga\Data\DataArray;
class ArrayQuery extends AbstractQuery
use Icinga\Data\AbstractQuery;
class Query extends AbstractQuery
{
/**
* Remember the last count

View File

@ -117,6 +117,7 @@ class Connection implements DatasourceInterface
} else {
$this->dbType = strtolower(get_class($this->db->getConnection()));
}
$this->db->setFetchMode(Zend_Db::FETCH_OBJ);
if ($this->dbType === null) {
Logger::warn('Could not determine database type');

View File

@ -32,6 +32,12 @@ class Query extends AbstractQuery
*/
protected $countColumns;
protected $uglySlowConservativeCount = false;
protected $countCache;
protected $maxCount;
protected function init()
{
$this->db = $this->ds->getConnection()->getDb();
@ -62,6 +68,7 @@ class Query extends AbstractQuery
{
$this->beforeCreatingCountQuery();
$this->beforeCreatingSelectQuery();
$this->selectQuery = clone($this->baseQuery);
$this->selectQuery->columns($this->columns);
if ($this->hasOrder()) {
@ -74,6 +81,20 @@ class Query extends AbstractQuery
}
}
if ($this->uglySlowConservativeCount) {
$query = clone($this->selectQuery);
if ($this->maxCount === null) {
$this->countQuery = $this->db->select()->from(
$query,
'COUNT(*)'
);
} else {
$this->countQuery = $this->db->select()->from(
$query->reset('order')->limit($this->maxCount),
'COUNT(*)'
);
}
} else {
$this->countQuery = clone($this->baseQuery);
if ($this->countColumns === null) {
$this->countColumns = array('cnt' => 'COUNT(*)');
@ -81,6 +102,8 @@ class Query extends AbstractQuery
$this->countQuery->columns($this->countColumns);
}
}
protected function beforeCreatingCountQuery()
{
}
@ -91,7 +114,10 @@ class Query extends AbstractQuery
public function count()
{
return $this->db->fetchOne($this->getCountQuery());
if ($this->countCache === null) {
$this->countCache = $this->db->fetchOne($this->getCountQuery());
}
return $this->countCache;
}
public function fetchAll()
@ -104,6 +130,11 @@ class Query extends AbstractQuery
return $this->db->fetchRow($this->getSelectQuery());
}
public function fetchColumn()
{
return $this->db->fetchCol($this->getSelectQuery());
}
public function fetchOne()
{
return $this->db->fetchOne($this->getSelectQuery());

View File

@ -37,7 +37,7 @@ class Filter extends ArrayIterator
}
/**
* Get filtere as key-value array
* Get filter as key-value array
*
* @return array
*/

View File

@ -0,0 +1,135 @@
<?php
namespace Icinga\Data;
class PivotTable
{
protected $query;
protected $verticalColumn;
protected $horizontalColumn;
protected $limit;
protected $offset;
protected $verticalLimit;
protected $horizontalLimit;
public function __construct(QueryInterface $query, $verticalColumn, $horizontalColumn)
{
$this->query = $query;
$this->verticalColumn = $verticalColumn;
$this->horizontalColumn = $horizontalColumn;
}
public function limit($limit = null, $offset = null)
{
$this->limit = $limit;
$this->offset = $offset;
return $this;
}
public function getLimit()
{
if ($this->limit === null) {
return 20;
}
return $this->limit;
}
public function getOffset()
{
if ($this->limit === null) {
return 20;
}
return $this->offset;
}
public function verticalLimit($limit = null, $offset = null)
{
// TODO: Trigger limit by calling $this->limit()?
if ($limit === null) {
$limit = $this->getLimit();
}
if ($offset === null) {
$offset = $this->getOffset();
}
$this->verticalLimit = $limit;
$this->verticalOffset = $offset;
return $this;
}
public function paginateVertical($limit = null, $offset = null)
{
$this->verticalLimit($limit, $offset);
return Paginator($this);
}
public function getVerticalLimit()
{
if ($this->verticalLimit === null) {
return 20;
}
return $this->verticalLimit;
}
public function getVerticalOffset()
{
if ($this->verticalLimit === null) {
return 20;
}
return $this->verticalOffset;
}
/**
* Fetch all columns
*/
public function fetchAll()
{
$xcol = $this->horizontalColumn;
$ycol = $this->verticalColumn;
$queryX = clone($this->query);
$queryX->columns($xcol);
if ($this->limit !== null) {
$queryX->limit($this->getLimit(), $this->getOffset());
}
$queryX->limit(40);
$listX = $queryX->fetchColumn();
$queryY = clone($this->query);
$queryY->columns($ycol);
if ($this->verticalLimit !== null) {
$queryY->limit($this->getVerticalLimit(), $this->getVerticalOffset());
}
$queryY->limit(50);
$listY = $queryY->fetchColumn();
// TODO: resetOrder
$this->query
->where($ycol, $listY)
->where($xcol, $listX)
->order($ycol)
->order($xcol);
$pivot = array();
$emptyrow = (object) array();
foreach ($this->query->listColumns() as $col) {
$emptyrow->$col = null;
}
foreach ($listY as $y) {
foreach ($listX as $x) {
$row = clone($emptyrow);
$row->$xcol = $x;
$row->$ycol = $y;
$pivot[$y][$x] = $row;
}
}
foreach ($this->query->fetchAll() as $row) {
$pivot[$row->$ycol][$row->$xcol] = $row;
}
return $pivot;
}
}

View File

@ -0,0 +1,162 @@
<?php
namespace Icinga\Data;
use Countable;
interface QueryInterface extends Countable
{
/**
* Constructor
*
* @param DatasourceInterface $ds Your data source
*/
public function __construct(DatasourceInterface $ds, $columns = null);
public function getDatasource();
/**
* Choose a table and the colums you are interested in
*
* Query will return all available columns if none are given here
*
* @return self
*/
public function from($table, $columns = null);
public function columns($columns);
/**
* Use once or multiple times to filter result set
*
* Multiple where calls will be combined by a logical AND operation
*
* @param string $key Column or backend-specific search expression
* @param string $val Search value, must be escaped automagically
*
* @return self
*/
public function where($key, $val = null);
/**
* Sort query result by the given column name
*
* Sort direction can be ascending (self::SORT_ASC, being the default)
* or descending (self::SORT_DESC).
*
* Preferred usage:
* <code>
* $query->sort('column_name ASC')
* </code>
*
* @param string $col Column, may contain direction separated by space
* @param int $dir Sort direction
*
* @return self
*/
public function order($col, $dir = null);
/**
* Limit the result set
*
* @param int $count Return not more than that many rows
* @param int $offset Result starts with this row
*
* @return self
*/
public function limit($count = null, $offset = null);
/**
* Wheter at least one order column has been applied to this Query
*
* @return bool
*/
public function hasOrder();
/**
* Wheter a limit has been applied to this Query
*
* @return bool
*/
public function hasLimit();
/**
* Wheter a starting offset been applied to this Query
*
* @return bool
*/
public function hasOffset();
/**
* Get the query limit
*
* @return int|null
*/
public function getLimit();
/**
* Get the query starting offset
*
* @return int|null
*/
public function getOffset();
/**
* Get the columns that have been asked for with this query
*
* @return array
*/
public function listColumns();
public function getColumns();
/**
* Get the filters that have been applied to this query
*
* @return array
*/
public function listFilters();
/**
* Fetch result as an array of objects
*
* @return array
*/
public function fetchAll();
/**
* Fetch first result row
*
* @return object
*/
public function fetchRow();
/**
* Fetch first result column
*
* @return array
*/
public function fetchColumn();
/**
* Fetch first column value from first result row
*
* @return mixed
*/
public function fetchOne();
/**
* Fetch result as a key/value pair array
*
* @return array
*/
public function fetchPairs();
/**
* Return a pagination adapter for this query
*
* @return \Zend_Paginator
*/
public function paginate($limit = null, $page = null);
}

View File

@ -6,17 +6,14 @@ use TCPDF;
use Icinga\Web\Url;
use Icinga\Application\Icinga;
// $_SERVER['DOCUMENT_ROOT'] = '/';
$_SERVER['DOCUMENT_ROOT'] = Icinga::app()->getApplicationDir() . '/../public';
define('K_TCPDF_EXTERNAL_CONFIG', true);
//define('K_PATH_URL', 'http://net-test-icinga-vm1.adm.netways.de/develop/'); // ???
// define('K_PATH_URL', '/var/www/net-test-icinga-vm1.adm.netways.de/develop/public'); // ???
define('K_PATH_URL', (string) Url::fromPath('/') === '/' ? '' : (string) Url::fromPath('/')); // ???'/'));
define('K_PATH_URL', (string) Url::create('/'));
define('K_PATH_MAIN', dirname(ICINGA_LIBDIR) . '/public');
define('K_PATH_FONTS', ICINGA_LIBDIR . '/vendor/tcpdf/fonts/');
define('K_PATH_CACHE', ICINGA_LIBDIR . '/vendor/tcpdf/cache/');
define('K_PATH_URL_CACHE', ICINGA_LIBDIR . '/vendor/tcpdf/cache/');
// define('K_PATH_CACHE', ICINGA_LIBDIR . '/vendor/tcpdf/cache/');
// define('K_PATH_URL_CACHE', ICINGA_LIBDIR . '/vendor/tcpdf/cache/');
define('K_PATH_CACHE', '/tmp/');
define('K_PATH_URL_CACHE', '/tmp/');
//define('K_PATH_IMAGES', K_PATH_MAIN . 'images/'); // ???
define('K_PATH_IMAGES', dirname(ICINGA_LIBDIR) . '/public'); // ???
define('K_BLANK_IMAGE', K_PATH_IMAGES.'_blank.png'); // COULD be anything?
@ -41,6 +38,7 @@ class Pdf extends TCPDF
$diskcache = false,
$pdfa = false
) {
unset($_SERVER['DOCUMENT_ROOT']);
parent::__construct(
$orientation,
$unit,

View File

@ -151,9 +151,14 @@ class IniStore implements LoadInterface, FlushObserverInterface
*/
private function createDefaultIniFile()
{
touch($this->preferencesFile);
// TODO: We should be able to work without preferences. Also we shouldn't store any
// prefs as long as we didn't change some.
if (! is_writable($this->configPath) || touch($this->preferencesFile) === false) {
throw new ConfigurationError(
sprintf('Unable to store "%s"', $this->preferencesFile)
);
}
chmod($this->preferencesFile, 0664);
}
/**

View File

@ -28,11 +28,13 @@
namespace Icinga\Web\Paginator\Adapter;
use Zend_Paginator_Adapter_Interface;
/**
* @see Zend_Paginator_Adapter_Interface
*/
class QueryAdapter implements \Zend_Paginator_Adapter_Interface
class QueryAdapter implements Zend_Paginator_Adapter_Interface
{
/**
* Array
@ -53,9 +55,7 @@ class QueryAdapter implements \Zend_Paginator_Adapter_Interface
*
* @param array $query Query to paginate
*/
// TODO: Re-add abstract Query type as soon as a more generic one
// is available. Should fit Protocol-Queries too.
// public function __construct(\Icinga\Backend\Query $query)
// TODO: This might be ready for (QueryInterface $query)
public function __construct($query)
{
$this->query = $query;

View File

@ -244,10 +244,14 @@ class Monitoring_ListController extends ActionController
-1,
PREG_SPLIT_NO_EMPTY
);
if (empty($extra)) {
$cols = $columns;
} else {
$cols = array_merge($columns, $extra);
}
$this->view->extraColumns = $extra;
$query = $this->backend->select()
->from($view, array_merge($columns, $extra))
->from($view, $cols)
->applyRequest($this->_request);
$this->handleFormatRequest($query);
return $query;

View File

@ -1,5 +1,4 @@
<?php
// @codingStandardsIgnoreStart
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
@ -27,6 +26,7 @@
*/
// {{{ICINGA_LICENSE_HEADER}}}
// @codingStandardsIgnoreStart
use \Icinga\Module\Monitoring\Backend;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Hook;
@ -199,7 +199,6 @@ class Monitoring_ShowController extends ActionController
->fetchPairs();
Benchmark::measure('Service action done');
$object = $this->view->object->prefetch();
$this->prepareGrapherHook();
}
/**
@ -300,7 +299,6 @@ class Monitoring_ShowController extends ActionController
->where('object_type', 'host')
->fetchPairs();
$this->view->object->prefetch();
$this->prepareGrapherHook();
}
/**
@ -356,21 +354,6 @@ class Monitoring_ShowController extends ActionController
));
}
protected function prepareGrapherHook()
{
if ($grapher = Hook::get('grapher')) {
$object = $this->view->object;
if ($grapher->hasGraph(
$object->host_name,
$object->service_description
)) {
$this->view->preview_image = $grapher->getPreviewImage(
$object->host_name,
$object->service_description
);
}
}
}
/**
* Creating tabs for this controller
* @return \Icinga\Web\Widget\AbstractWidget
@ -444,5 +427,4 @@ class Monitoring_ShowController extends ActionController
}
}
// @codingStandardsIgnoreEnd

View File

@ -18,8 +18,15 @@ use Icinga\Data\Db\Connection;
*
* Other possible (history-related) indexes, still subject to tests:
* CREATE INDEX web2_index ON icinga_statehistory (object_id, state_time DESC);
* CREATE INDEX web2_index ON icinga_notifications (object_id, instance_id, start_time DESC);
* CREATE INDEX web2_index ON icinga_downtimehistory (object_id, actual_start_time, actual_end_time);
* CREATE INDEX web2_time ON icinga_statehistory (state_time DESC);
* CREATE INDEX web2_index ON icinga_notifications (object_id, start_time DESC);
* CREATE INDEX web2_start ON icinga_downtimehistory (actual_start_time);
* CREATE INDEX web2_end ON icinga_downtimehistory (actual_end_time);
* CREATE INDEX web2_index ON icinga_commenthistory (object_id, comment_time);
* CREATE INDEX web2_object ON icinga_commenthistory (object_id);
* CREATE INDEX web2_time ON icinga_commenthistory (comment_time DESC);
*
* CREATE INDEX web2_notification_contact ON icinga_contactnotifications (contact_object_id, notification_id);
*
* These should be unique:
* CREATE INDEX web2_index ON icinga_host_contacts (host_id, contact_object_id);

View File

@ -20,12 +20,21 @@ abstract class AbstractQuery extends Query
protected $object_id = 'object_id';
protected $host_id = 'host_id';
protected $service_id = 'service_id';
protected $hostgroup_id = 'hostgroup_id';
protected $service_id = 'service_id';
protected $servicegroup_id = 'servicegroup_id';
protected $contact_id = 'contact_id';
protected $contactgroup_id = 'contactgroup_id';
protected $aggregateColumnIdx = array();
protected $allowCustomVars = false;
protected function isAggregateColumn($column)
{
return array_key_exists($column, $this->aggregateColumnIdx);
}
protected function init()
{
parent::init();
@ -33,7 +42,9 @@ abstract class AbstractQuery extends Query
$this->prefix = $this->ds->getPrefix();
if ($this->ds->getConnection()->getDbType() === 'oracle') {
$this->object_id = $this->host_id = $this->service_id = $this->hostgroup_id = $this->servicegroup_id = 'id'; // REALLY?
$this->object_id = $this->host_id = $this->service_id
= $this->hostgroup_id = $this->servicegroup_id
= $this->contact_id = $this->contactgroup_id = 'id'; // REALLY?
foreach ($this->columnMap as $table => & $columns) {
foreach ($columns as $key => & $value) {
$value = preg_replace('/UNIX_TIMESTAMP/', 'localts2unixts', $value);
@ -45,12 +56,13 @@ abstract class AbstractQuery extends Query
foreach ($this->columnMap as $table => & $columns) {
foreach ($columns as $key => & $value) {
$value = preg_replace('/ COLLATE .+$/', '', $value);
$value = preg_replace('/inet_aton\(([[:word:].]+)\)/i', '$1::inet - \'0.0.0.0\'', $value);
}
}
}
$this->prepareAliasIndexes();
$this->joinBaseTables();
$this->prepareAliasIndexes();
}
protected function isCustomVar($alias)
@ -103,7 +115,21 @@ abstract class AbstractQuery extends Query
protected function getDefaultColumns()
{
return $this->columnMap['hostgroups'];
$table = array_shift(array_keys($this->columnMap));
return array_keys($this->columnMap[$table]);
}
protected function joinBaseTables()
{
reset($this->columnMap);
$table = key($this->columnMap);
$this->baseQuery = $this->db->select()->from(
array($table => $this->prefix . $table),
array()
);
$this->joinedVirtualTables = array($table => true);
}
protected function beforeCreatingCountQuery()
@ -121,18 +147,12 @@ abstract class AbstractQuery extends Query
protected function applyAllFilters()
{
$filters = array();
// TODO: Handle $special in a more generic way
$special = array('hostgroups', 'servicegroups');
foreach ($this->filters as $f) {
$alias = $f[0];
$value = $f[1];
$this->requireColumn($alias);
if ($alias === 'hostgroups') {
$col = 'hg.alias';
} elseif ($alias === 'servicegroups') {
$col = 'sg.alias';
} elseif ($this->isCustomvar($alias)) {
if ($this->isCustomvar($alias)) {
$col = $this->getCustomvarColumnName($alias);
} elseif ($this->hasAliasName($alias)) {
$col = $this->aliasToColumnName($alias);
@ -141,9 +161,19 @@ abstract class AbstractQuery extends Query
'If you finished here, code has been messed up'
);
}
$func = 'filter' . ucfirst($alias);
if (method_exists($this, $func)) {
$this->$func($value);
return;
}
if ($this->isAggregateColumn($alias)) {
$this->baseQuery->having($this->prepareFilterStringForColumn($col, $value));
} else {
$this->baseQuery->where($this->prepareFilterStringForColumn($col, $value));
}
}
}
public function order($col, $dir = null)
{
@ -257,6 +287,15 @@ abstract class AbstractQuery extends Query
return $this->customVars[$customvar] . '.varvalue';
}
protected function createSubQuery($queryName, $columns = array())
{
$class = '\\'
. substr(__CLASS__, 0, strrpos(__CLASS__, '\\') + 1)
. ucfirst($queryName) . 'Query';
$query = new $class($this->ds, $columns);
return $query;
}
protected function customvarNameToTypeName($customvar)
{
// TODO: Improve this:
@ -279,8 +318,11 @@ abstract class AbstractQuery extends Query
$or = array();
$and = array();
if (! is_array($value) && strpos($value, ',') !== false) {
$value = preg_split('~,~', $value, -1, PREG_SPLIT_NO_EMPTY);
if (
! is_array($value) &&
(strpos($value, ',') !== false || strpos($value, '|') !== false)
) {
$value = preg_split('~[,|]~', $value, -1, PREG_SPLIT_NO_EMPTY);
}
if (! is_array($value)) {
$value = array($value);
@ -292,38 +334,56 @@ abstract class AbstractQuery extends Query
// TODO: REALLY??
continue;
}
// Value starting with minus: negation
if ($val[0] === '-') {
$not = false;
$force = false;
$op = '=';
$wildcard = false;
if ($val[0] === '-' || $val[0] === '!') {
// Value starting with minus or !: negation
$val = substr($val, 1);
if (strpos($val, '*') === false) {
$and[] = $this->db->quoteInto($column . ' != ?', $val);
} else {
$and[] = $this->db->quoteInto(
$column . ' NOT LIKE ?',
str_replace('*', '%', $val)
);
$not = true;
}
} elseif ($val[0] === '+') { // Value starting with +: enforces AND
if ($val[0] === '+') {
// Value starting with +: enforces AND
// TODO: depends on correct URL handling, not given in all
// ZF versions
// ZF versions.
$val = substr($val, 1);
if (strpos($val, '*') === false) {
$and[] = $this->db->quoteInto($column . ' = ?', $val);
} else {
$and[] = $this->db->quoteInto(
$column . ' LIKE ?',
str_replace('*', '%', $val)
);
$force = true;
}
} else { // All others ar ORs:
if (strpos($val, '*') === false) {
$or[] = $this->db->quoteInto($column . ' = ?', $val);
} else {
$or[] = $this->db->quoteInto(
$column . ' LIKE ?',
str_replace('*', '%', $val)
);
if ($val[0] === '<' || $val[0] === '>') {
$op = $val[0];
$val = substr($val, 1);
}
if (strpos($val, '*') !== false) {
$wildcard = true;
$val = str_replace('*', '%', $val);
}
$operator = null;
switch ($op) {
case '=':
if ($not) {
$operator = $wildcard ? 'NOT LIKE' : '!=';
} else {
$operator = $wildcard ? 'LIKE' : '=';
}
break;
case '>':
$operator = $not ? '<=' : '>';
break;
case '<':
$operator = $not ? '>=' : '<';
break;
default:
throw new ProgrammingError("'$op' is not a valid operator");
}
if ($not || $force) {
$and[] = $this->db->quoteInto($column . ' ' . $operator . ' ?', $val);
} else {
$or[] = $this->db->quoteInto($column . ' ' . $operator . ' ?', $val);
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
use Zend_Db_Select;
class AllcontactsQuery extends AbstractQuery
{
protected $columnMap = array(
'contacts' => array(
'contact_name' => 'c.contact_name',
'host_object_id' => 'c.host_object_id',
'host_name' => 'c.host_name',
'service_object_id' => 'c.service_object_id',
'service_host_name' => 'c.service_host_name',
'service_description' => 'c.service_description',
'contact_alias' => 'c.contact_alias',
'contact_email' => 'c.contact_email',
'contact_pager' => 'c.contact_pager',
'contact_has_host_notfications' => 'c.contact_has_host_notfications',
'contact_has_service_notfications' => 'c.contact_has_service_notfications',
'contact_can_submit_commands' => 'c.contact_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',
)
);
protected $contacts;
protected $contactgroups;
protected $uglySlowConservativeCount = true;
protected function requireColumn($alias)
{
$this->contacts->addColumn($alias);
$this->contactgroups->addColumn($alias);
return parent::requireColumn($alias);
}
protected function joinBaseTables()
{
$this->contacts = $this->createSubQuery(
'contact',
array('contact_name')
);
$this->contactgroups = $this->createSubQuery(
'contactgroup',
array('contact_name')
);
$sub = $this->db->select()->union(
array($this->contacts, $this->contactgroups),
Zend_Db_Select::SQL_UNION_ALL
);
$this->baseQuery = $this->db->select()->distinct()->from(
array('c' => $sub),
array()
);
$this->joinedVirtualTables = array('contacts' => true);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
class CommenthistoryQuery extends AbstractQuery
{
protected $columnMap = array(
'commenthistory' => array(
'state_time' => 'comment_time',
'timestamp' => 'UNIX_TIMESTAMP(comment_time)',
'raw_timestamp' => 'comment_time',
'object_id' => 'object_id',
'type' => "(CASE entry_type WHEN 1 THEN 'comment' WHEN 2 THEN 'dt_comment' WHEN 3 THEN 'flapping' WHEN 4 THEN 'ack' END)",
'state' => '(NULL)',
'state_type' => '(NULL)',
'output' => "('[' || author_name || '] ' || comment_data)",
'attempt' => '(NULL)',
'max_attempts' => '(NULL)',
)
);
}

View File

@ -4,17 +4,35 @@ namespace Icinga\Module\Monitoring\Backend\Ido\Query;
class ContactQuery extends AbstractQuery
{
// TODO: join host/service timeperiod
protected $columnMap = array(
'contacts' => array(
'contact_name' => 'co.name1 COLLATE latin1_general_ci',
'contact_alias' => 'c.alias',
'contact_email' => 'c.email_address',
'contact_pager' => 'c.pager_address',
'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',
),
'hosts' => array(
'host_object_id' => 'ho.object_id',
'host_name' => 'ho.name1 COLLATE latin1_general_ci',
),
'services' => array(
'service_object_id' => 'so.object_id',
'service_host_name' => 'so.name1 COLLATE latin1_general_ci',
'service_description' => 'so.name2 COLLATE latin1_general_ci',
)

View File

@ -11,15 +11,35 @@ class ContactgroupQuery extends AbstractQuery
),
'contacts' => array(
'contact_name' => 'co.name1 COLLATE latin1_general_ci',
'contact_alias' => 'c.alias',
'contact_email' => 'c.email_address',
'contact_pager' => 'c.pager_address',
'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',
),
'hosts' => array(
'host_object_id' => 'ho.object_id',
'host_name' => 'ho.name1',
),
'services' => array(
'service_object_id' => 'so.object_id',
'service_host_name' => 'so.name1 COLLATE latin1_general_ci',
'service_description' => 'so.name2 COLLATE latin1_general_ci',
)
);
protected $uglySlowConservativeCount = true;
protected function joinBaseTables()
{
@ -38,7 +58,7 @@ class ContactgroupQuery extends AbstractQuery
protected function joinContacts()
{
$this->baseQuery->join(
$this->baseQuery->distinct()->join(
array('cgm' => $this->prefix . 'contactgroup_members'),
'cgm.contactgroup_id = cg.contactgroup_id',
array()
@ -46,12 +66,16 @@ class ContactgroupQuery extends AbstractQuery
array('co' => $this->prefix . 'objects'),
'cgm.contact_object_id = co.object_id AND co.is_active = 1',
array()
)->join(
array('c' => $this->prefix . 'contacts'),
'c.contact_object_id = co.object_id',
array()
);
}
protected function joinHosts()
{
$this->baseQuery->join(
$this->baseQuery->distinct()->join(
array('hcg' => $this->prefix . 'host_contactgroups'),
'hcg.contactgroup_object_id = cg.contactgroup_object_id',
array()

View File

@ -0,0 +1,22 @@
<?php
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
class DowntimeendhistoryQuery extends AbstractQuery
{
protected $columnMap = array(
'downtimehistory' => array(
'state_time' => 'actual_end_time',
'timestamp' => 'UNIX_TIMESTAMP(actual_end_time)',
'raw_timestamp' => 'actual_end_time',
'object_id' => 'object_id',
'type' => "('dt_end')",
'state' => '(NULL)',
'state_type' => '(NULL)',
'output' => "('[' || author_name || '] ' || comment_data)",
'attempt' => '(NULL)',
'max_attempts' => '(NULL)',
)
);
}

View File

@ -0,0 +1,22 @@
<?php
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
class DowntimestarthistoryQuery extends AbstractQuery
{
protected $columnMap = array(
'downtimehistory' => array(
'state_time' => 'actual_start_time',
'timestamp' => 'UNIX_TIMESTAMP(actual_start_time)',
'raw_timestamp' => 'actual_start_time',
'object_id' => 'object_id',
'type' => "('dt_end')",
'state' => '(NULL)',
'state_type' => '(NULL)',
'output' => "('[' || author_name || '] ' || comment_data)",
'attempt' => '(NULL)',
'max_attempts' => '(NULL)',
)
);
}

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
use \Zend_Db_Select;
use Icinga\Exception\ProgrammingError;
class EventHistoryQuery extends AbstractQuery
@ -10,195 +11,73 @@ class EventHistoryQuery extends AbstractQuery
protected $columnMap = array(
'eventhistory' => array(
'cnt_notification' => "SUM(CASE eh.type WHEN 'notify' THEN 1 ELSE 0 END)",
'cnt_hard_state' => "SUM(CASE eh.type WHEN 'hard_state' THEN 1 ELSE 0 END)",
'cnt_soft_state' => "SUM(CASE eh.type WHEN 'hard_state' THEN 1 ELSE 0 END)",
'cnt_downtime_start' => "SUM(CASE eh.type WHEN 'dt_start' THEN 1 ELSE 0 END)",
'cnt_downtime_end' => "SUM(CASE eh.type WHEN 'dt_end' THEN 1 ELSE 0 END)",
'host' => 'eho.name1 COLLATE latin1_general_ci',
'service' => 'eho.name2 COLLATE latin1_general_ci',
'host_name' => 'eho.name1 COLLATE latin1_general_ci',
'service_description' => 'eho.name2 COLLATE latin1_general_ci',
'object_type' => "CASE WHEN eho.objecttype_id = 1 THEN 'host' ELSE 'service' END",
'timestamp' => 'UNIX_TIMESTAMP(eh.state_time)',
'raw_timestamp' => 'eh.state_time',
'timestamp' => 'eh.timestamp',
'raw_timestamp' => 'eh.raw_timestamp',
'state' => 'eh.state',
// 'last_state' => 'eh.last_state',
// 'last_hard_state' => 'eh.last_hard_state',
'attempt' => 'eh.attempt',
'max_attempts' => 'eh.max_attempts',
'output' => 'eh.output', // we do not want long_output
'problems' => 'CASE WHEN eh.state = 0 OR eh.state IS NULL THEN 0 ELSE 1 END',
//'problems' => 'CASE WHEN eh.state = 0 OR eh.state IS NULL THEN 0 ELSE 1 END',
'type' => 'eh.type',
)
),
'hostgroups' => array(
'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci',
),
);
protected function getDefaultColumns()
{
return $this->columnMap['eventhistory'];
}
protected $uglySlowConservativeCount = true;
protected $maxCount = 1000;
protected function joinBaseTables()
{
$start = date('Y-m-d H:i:s', time() - 3600 * 24 * 30);
// $start = date('Y-m-d H:i:s', time() - 3600 * 24 * 1);
$start = date('Y-m-d H:i:s', time() - 3600 * 24 * 2);
$end = date('Y-m-d H:i:s');
$start = null;
$end = null;
$history = $this->db->select()->from(
$this->prefix . 'statehistory',
array(
'state_time' => 'state_time',
'object_id' => 'object_id',
'type' => "(CASE WHEN state_type = 1 THEN 'hard_state' ELSE 'soft_state' END)",
'state' => 'state',
'state_type' => 'state_type',
'output' => 'output',
'attempt' => 'current_check_attempt',
'max_attempts' => 'max_check_attempts',
)
// TODO: $this->dbTime(...)
//$start = null;
//$end = null;
$columns = array(
'raw_timestamp',
'timestamp',
'object_id',
'type',
'output',
'state',
'state_type',
'attempt',
'max_attempts',
);
if ($start !== null) {
$history->where('state_time >= ?', $start);
}
// ->where('state_type = 1') ??
if ($end !== null) {
$history->where('state_time <= ?', $end);
}
$dt_start = $this->db->select()->from(
$this->prefix . 'downtimehistory',
array(
'state_time' => 'actual_start_time',
'object_id' => 'object_id',
'type' => "('dt_start')",
'state' => '(NULL)',
'state_type' => '(NULL)',
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
'output' => "('[' || author_name || '] ' || comment_data)",
'attempt' => '(NULL)',
'max_attempts' => '(NULL)',
)
);
if ($start !== null) {
$dt_start->where('actual_start_time >= ?', $start);
}
if ($end !== null) {
$dt_start->where('actual_start_time <= ?', $end);
}
// TODO: check was_cancelled
$dt_end = $this->db->select()->from(
$this->prefix . 'downtimehistory',
array(
'state_time' => 'actual_end_time',
'object_id' => 'object_id',
'type' => "('dt_end')",
'state' => '(NULL)',
'state_type' => '(NULL)',
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
'output' => "('[' || author_name || '] ' || comment_data)",
'attempt' => '(NULL)',
'max_attempts' => '(NULL)',
)
);
if ($start !== null) {
$dt_end->where('actual_end_time >= ?', $start);
}
if ($end !== null) {
$dt_end->where('actual_end_time <= ?', $end);
}
$comments = $this->db->select()->from(
$this->prefix . 'commenthistory',
array(
'state_time' => 'comment_time',
'object_id' => 'object_id',
'type' => "(CASE entry_type WHEN 1 THEN 'comment' WHEN 2 THEN 'dt_comment' WHEN 3 THEN 'flapping' WHEN 4 THEN 'ack' END)",
'state' => '(NULL)',
'state_type' => '(NULL)',
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
'output' => "('[' || author_name || '] ' || comment_data)",
'attempt' => '(NULL)',
'max_attempts' => '(NULL)',
)
);
if ($start !== null) {
$comments->where('comment_time >= ?', $start);
}
if ($end !== null) {
$comments->where('comment_time <= ?', $end);
}
// This is one of the db-specific workarounds that could be abstracted
// in a better way:
switch ($this->ds->getConnection()->getDbType()) {
case 'mysql':
$concat_contacts = "GROUP_CONCAT(c.alias ORDER BY c.alias SEPARATOR ', ')";
break;
case 'pgsql':
// TODO: Find a way to "ORDER" these:
$concat_contacts = "ARRAY_TO_STRING(ARRAY_AGG(c.alias), ', ')";
break;
case 'oracle':
// TODO: This is only valid for Oracle >= 11g Release 2.
$concat_contacts = "LISTAGG(c.alias, ', ') WITHIN GROUP (ORDER BY c.alias)";
// 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;
default:
die('Not yet'); // TODO: Proper Exception
}
$cndetails = $this->db->select()->from(
array('cn' => $this->prefix . 'contactnotifications'),
array(
'notification_id' => 'notification_id',
'cnt' => 'COUNT(*)',
'contacts' => $concat_contacts
)
)->join(
array('c' => $this->prefix . 'contacts'),
'cn.contact_object_id = c.contact_object_id',
array()
)->group('notification_id');
$notifications = $this->db->select()->from(
array('n' => $this->prefix . 'notifications'),
array(
'state_time' => 'start_time',
'object_id' => 'object_id',
'type' => "('notify')",
'state' => 'state',
'state_type' => '(NULL)',
// 'output' => "CONCAT('[', cndetails.contacts, '] ', n.output)",
'output' => "('[' || cndetails.contacts || '] ' || n.output)",
'attempt' => '(NULL)',
'max_attempts' => '(NULL)',
)
)->join(
array('cndetails' => $cndetails),
'cndetails.notification_id = n.notification_id',
array()
);
if ($start !== null) {
$notifications->where('start_time >= ?', $start);
}
if ($end !== null) {
$notifications->where('start_time <= ?', $end);
}
$this->subQueries = array(
$history,
$dt_start,
$dt_end,
$comments,
$notifications
$this->createSubQuery('Statehistory', $columns),
$this->createSubQuery('Downtimestarthistory', $columns),
$this->createSubQuery('Downtimeendhistory', $columns),
$this->createSubQuery('Commenthistory', $columns),
$this->createSubQuery('Notificationhistory', $columns)
);
$sub = $this->db->select()->union($this->subQueries, \Zend_Db_Select::SQL_UNION_ALL);
if ($start) {
foreach ($this->subQueries as $query) {
$query->where('raw_timestamp', '>' . $start);
}
}
if ($end) {
foreach ($this->subQueries as $query) {
$query->where('raw_timestamp', '<' . $start);
}
}
$sub = $this->db->select()->union($this->subQueries, Zend_Db_Select::SQL_UNION_ALL);
$this->baseQuery = $this->db->select()->from(
array('eho' => $this->prefix . 'objects'),
array()
@ -213,58 +92,24 @@ class EventHistoryQuery extends AbstractQuery
$this->joinedVirtualTables = array('eventhistory' => true);
}
// TODO: This duplicates code from AbstractQuery
protected function applyAllFilters()
protected function joinHostgroups()
{
$filters = array();
$host = null;
$service = null;
foreach ($this->filters as $f) {
$alias = $f[0];
$value = $f[1];
$this->requireColumn($alias);
if ($this->hasAliasName($alias)) {
$col = $this->aliasToColumnName($alias);
} else {
throw new ProgrammingError(
'If you finished here, code has been messed up'
$this->baseQuery->join(
array('hgm' => $this->prefix . 'hostgroup_members'),
'hgm.host_object_id = eho.object_id',
array()
)->join(
array('hg' => $this->prefix . 'hostgroups'),
"hgm.hostgroup_id = hg.$this->hostgroup_id",
array()
)->join(
array('hgo' => $this->prefix . 'objects'),
'hgo.' . $this->object_id. ' = hg.hostgroup_object_id'
. ' AND hgo.is_active = 1',
array()
);
return $this;
}
if (in_array($alias, array('host', 'host_name'))) {
$host = $value;
continue;
}
if (in_array($alias, array('service', 'service_description'))) {
$service = $value;
continue;
}
$this->baseQuery->where($this->prepareFilterStringForColumn($col, $value));
}
$objectQuery = $this->db->select()->from(
$this->prefix . 'objects',
$this->object_id
)->where('is_active = 1');
if ($service === '*') {
$objectQuery->where('name1 = ?', $host)
->where('objecttype_id IN (1, 2)');
} elseif ($service) {
$objectQuery->where('name1 = ?', $host)
->where('name2 = ?', $service)
->where('objecttype_id = 2');
} else {
$objectQuery->where('name1 = ?', $host)
->where('objecttype_id = 1');
}
$objectId = $this->db->fetchCol($objectQuery);
foreach ($this->subQueries as $query) {
$query->where('object_id IN (?)', $objectId);
}
}
}

View File

@ -6,6 +6,7 @@ class HostgroupQuery extends AbstractQuery
{
protected $columnMap = array(
'hostgroups' => array(
'hostgroups' => 'hgo.name1 COLLATE latin1_general_ci',
'hostgroup_name' => 'hgo.name1 COLLATE latin1_general_ci',
'hostgroup_alias' => 'hg.alias',
'id' => 'hg.hostgroup_id',

View File

@ -17,6 +17,9 @@ class HoststatusQuery extends AbstractQuery
'host_icon_image' => 'h.icon_image',
),
'hoststatus' => array(
'problems' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
'handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END',
'unhandled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) = 0 THEN 1 ELSE 0 END',
'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
'host_output' => 'hs.output',
'host_long_output' => 'hs.long_output',
@ -72,10 +75,42 @@ class HoststatusQuery extends AbstractQuery
END',
),
'hostgroups' => array(
'hostgroups' => 'hgo.name1',
'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci',
),
'contactgroups' => array(
'contactgroup' => 'contactgroup',
),
'contacts' => array(
'contact' => 'hco.name1 COLLATE latin1_general_ci',
),
'services' => array(
'services_cnt' => 'SUM(1)',
'services_ok' => 'SUM(CASE WHEN ss.current_state = 0 THEN 1 ELSE 0 END)',
'services_warning' => 'SUM(CASE WHEN ss.current_state = 1 THEN 1 ELSE 0 END)',
'services_critical' => 'SUM(CASE WHEN ss.current_state = 2 THEN 1 ELSE 0 END)',
'services_unknown' => 'SUM(CASE WHEN ss.current_state = 3 THEN 1 ELSE 0 END)',
'services_pending' => 'SUM(CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 1 ELSE 0 END)',
'services_problem' => 'SUM(CASE WHEN ss.current_state > 0 THEN 1 ELSE 0 END)',
'services_problem_handled' => 'SUM(CASE WHEN ss.current_state > 0 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
'services_problem_unhandled' => 'SUM(CASE WHEN ss.current_state > 0 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
'services_warning_handled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
'services_critical_handled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
'services_unknown_handled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
'services_warning_unhandled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
'services_critical_unhandled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
'services_unknown_unhandled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
),
);
protected $aggregateColumnIdx = array(
'services_cnt' => true,
'services_problem' => true,
'services_problem_handled' => true,
'services_problem_unhandled' => true,
);
protected $hcgSub;
protected function getDefaultColumns()
{
return $this->columnMap['hosts']
@ -128,6 +163,14 @@ class HoststatusQuery extends AbstractQuery
"so.$this->object_id = ss.service_object_id",
array()
);
foreach ($this->columns as $col) {
$real = $this->aliasToColumnName($col);
if (substr($real, 0, 4) === 'SUM(') {
continue;
}
$this->baseQuery->group($real);
}
$this->uglySlowConservativeCount = true;
}
protected function joinHostgroups()
@ -139,6 +182,121 @@ class HoststatusQuery extends AbstractQuery
}
}
protected function joinContacts()
{
$this->hcgcSub = $this->db->select()->distinct()->from(
array('hcgc' => $this->prefix . 'host_contactgroups'),
array('host_name' => 'ho.name1')
)->join(
array('cgo' => $this->prefix . 'objects'),
'hcg.contactgroup_object_id = cgo.' . $this->object_id
. ' AND cgo.is_active = 1',
array()
)->join(
array('h' => $this->prefix . 'hosts'),
'hcg.host_id = h.host_id',
array()
)->join(
array('ho' => $this->prefix . 'objects'),
'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1',
array()
);
$this->baseQuery->join(
array('hcg' => $this->hcgSub),
'hcg.host_name = ho.name1',
array()
);
return $this;
}
/*
protected function joinContacts()
{
$this->baseQuery->join(
array('hc' => $this->prefix . 'host_contacts'),
'hc.host_id = h.host_id',
array()
)->join(
array('hco' => $this->prefix . 'objects'),
'hco.' . $this->object_id. ' = hc.contact_object_id'
. ' AND hco.is_active = 1',
array()
);
$this->baseQuery->join(
array('hcg' => $this->prefix . 'host_contactgroups'),
'hcg.host_id = h.host_id',
array()
)->join(
array('hcgo' => $this->prefix . 'objects'),
'hcgo.' . $this->object_id. ' = hcg.contactgroup_object_id'
. ' AND hcgo.is_active = 1',
array()
);
$this->baseQuery->join(
array('cgm' => $this->prefix . 'contactgroup_members'),
'cgm.contactgroup_id = cg.contactgroup_id',
array()
)->join(
array('co' => $this->prefix . 'objects'),
'cgm.contact_object_id = co.object_id AND co.is_active = 1',
array()
);
}
return $this;
}
*/
protected function filterContactgroup($value)
{
$this->hcgSub->where(
$this->prepareFilterStringForColumn(
'cgo.name1 COLLATE latin1_general_ci',
$value
)
);
return $this;
}
protected function createContactgroupFilterSubselect()
{
die((string) $this->db->select()->distinct()->from(
array('hcg' => $this->prefix . 'host_contactgroups'),
array('object_id' => 'ho.object_id')
)->join(
array('cgo' => $this->prefix . 'objects'),
'hcg.contactgroup_object_id = cgo.' . $this->object_id
. ' AND cgo.is_active = 1',
array()
)->join(
array('h' => $this->prefix . 'hosts'),
'hcg.host_id = h.host_id',
array()
)->join(
array('ho' => $this->prefix . 'objects'),
'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1',
array()
));
}
protected function joinContactgroups()
{
$this->hcgSub = $this->createContactgroupFilterSubselect();
$this->baseQuery->join(
array('hcg' => $this->hcgSub),
'hcg.object_id = ho.object_id',
array()
);
return $this;
}
protected function joinHostHostgroups()
{
$this->baseQuery->join(
@ -149,6 +307,11 @@ class HoststatusQuery extends AbstractQuery
array('hg' => $this->prefix . 'hostgroups'),
"hgm.hostgroup_id = hg.$this->hostgroup_id",
array()
)->join(
array('hgo' => $this->prefix . 'objects'),
'hgo.' . $this->object_id. ' = hg.hostgroup_object_id'
. ' AND hgo.is_active = 1',
array()
);
return $this;
@ -176,6 +339,7 @@ class HoststatusQuery extends AbstractQuery
protected function joinServicegroups()
{
// TODO: Only hosts with services having such servicegroups
$this->requireVirtualTable('services');
$this->baseQuery->join(
array('sgm' => $this->prefix . 'servicegroup_members'),

View File

@ -119,7 +119,7 @@ class NotificationQuery extends AbstractQuery
array(
'cmd_m' => $this->prefix . 'contactnotificationmethods'
),
'cmd_c.notification_id = cmd_m.contactnotification_id',
'cmd_c.contactnotification_id = cmd_m.contactnotification_id',
array()
);
$this->baseQuery->join(

View File

@ -0,0 +1,87 @@
<?php
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
class NotificationhistoryQuery extends AbstractQuery
{
protected $columnMap = array(
'history' => array(
'timestamp' => 'UNIX_TIMESTAMP(n.start_time)',
'raw_timestamp' => 'n.start_time',
'state_time' => 'n.start_time',
'object_id' => 'object_id',
'type' => "('notify')",
'state' => 'state',
'state_type' => '(NULL)',
'output' => null,
'attempt' => '(NULL)',
'max_attempts' => '(NULL)',
)
);
protected function joinBaseTables()
{
//"('[' || cndetails.contacts || '] ' || n.output)"
// This is one of the db-specific workarounds that could be abstracted
// in a better way:
switch ($this->ds->getConnection()->getDbType()) {
case 'mysql':
$concat_contacts = "GROUP_CONCAT(c.alias ORDER BY c.alias SEPARATOR ', ')";
break;
case 'pgsql':
// TODO: Find a way to "ORDER" these:
$concat_contacts = "ARRAY_TO_STRING(ARRAY_AGG(c.alias), ', ')";
break;
case 'oracle':
// TODO: This is only valid for Oracle >= 11g Release 2.
$concat_contacts = "LISTAGG(c.alias, ', ') WITHIN GROUP (ORDER BY c.alias)";
// 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;
default:
die('Not yet'); // TODO: Proper Exception
}
$this->columnMap['history']['output'] = "('[' || $concat_contacts || '] ' || n.output)";
/*
$cndetails = $this->db->select()->from(
array('cn' => $this->prefix . 'contactnotifications'),
array(
'notification_id' => 'notification_id',
'cnt' => 'COUNT(*)',
'contacts' => $concat_contacts
)
)->join(
array('c' => $this->prefix . 'contacts'),
'cn.contact_object_id = c.contact_object_id',
array()
)->group('notification_id');
*/
$this->baseQuery = $this->db->select()->from(
array('n' => $this->prefix . 'notifications'),
array()
)->join(
array('cn' => $this->prefix . 'contactnotifications'),
'cn.notification_id = n.notification_id',
array()
)->joinLeft(
array('c' => $this->prefix . 'contacts'),
'cn.contact_object_id = c.contact_object_id',
array()
)->group('cn.notification_id')
/*->join(
array('cndetails' => $cndetails),
'cndetails.notification_id = n.notification_id',
array()
)*/
;
$this->joinedVirtualTables = array('history' => true);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
class StatehistoryQuery extends AbstractQuery
{
protected $columnMap = array(
'statehistory' => array(
'raw_timestamp' => 'state_time',
'timestamp' => 'UNIX_TIMESTAMP(state_time)',
'state_time' => 'state_time',
'object_id' => 'object_id',
'type' => "(CASE WHEN state_type = 1 THEN 'hard_state' ELSE 'soft_state' END)",
'state' => 'state',
'state_type' => 'state_type',
'output' => 'output',
'attempt' => 'current_check_attempt',
'max_attempts' => 'max_check_attempts',
)
);
}

View File

@ -32,23 +32,26 @@ class StatusQuery extends AbstractQuery
'host_does_active_checks' => 'hs.active_checks_enabled',
'host_accepts_passive_checks' => 'hs.passive_checks_enabled',
'host_last_state_change' => 'UNIX_TIMESTAMP(hs.last_state_change)',
'host_last_hard_state' => 'hs.last_hard_state',
'host_last_hard_state_change' => 'UNIX_TIMESTAMP(hs.last_hard_state_change)',
'host_check_command' => 'hs.check_command',
'host_last_check' => 'UNIX_TIMESTAMP(hs.last_check)',
'host_next_check' => 'CASE hs.should_be_scheduled WHEN 1 THEN UNIX_TIMESTAMP(hs.next_check) ELSE NULL END',
'host_check_execution_time' => 'hs.execution_time',
'host_check_latency' => 'hs.latency',
'host_problem' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
'host_notifications_enabled' => 'hs.notifications_enabled',
'host_last_time_up' => 'UNIX_TIMESTAMP(hs.last_time_up)',
'host_last_time_down' => 'UNIX_TIMESTAMP(hs.last_time_down)',
'host_last_time_unreachable' => 'UNIX_TIMESTAMP(hs.last_time_unreachable)',
'host_current_check_attempt' => 'hs.current_check_attempt',
'host_max_check_attempts' => 'hs.max_check_attempts',
'host_attempt' => 'hs.current_check_attempt || \'/\' || hs.max_check_attempts',
'host_last_check' => 'hs.last_check',
'host_next_check' => 'hs.next_check',
'host_check_type' => 'hs.check_type',
'host_last_hard_state_change' => 'hs.last_hard_state_change',
'host_last_hard_state' => 'hs.last_hard_state',
'host_last_time_up' => 'hs.last_time_up',
'host_last_time_down' => 'hs.last_time_down',
'host_last_time_unreachable' => 'hs.last_time_unreachable',
'host_state_type' => 'hs.state_type',
'host_last_notification' => 'hs.last_notification',
'host_next_notification' => 'hs.next_notification',
'host_no_more_notifications' => 'hs.no_more_notifications',
'host_notifications_enabled' => 'hs.notifications_enabled',
'host_problem_has_been_acknowledged' => 'hs.problem_has_been_acknowledged',
'host_acknowledgement_type' => 'hs.acknowledgement_type',
'host_current_notification_number' => 'hs.current_notification_number',
@ -58,8 +61,6 @@ class StatusQuery extends AbstractQuery
'host_flap_detection_enabled' => 'hs.flap_detection_enabled',
'host_is_flapping' => 'hs.is_flapping',
'host_percent_state_change' => 'hs.percent_state_change',
'host_check_latency' => 'hs.latency',
'host_check_execution_time' => 'hs.execution_time',
'host_scheduled_downtime_depth' => 'hs.scheduled_downtime_depth',
'host_failure_prediction_enabled' => 'hs.failure_prediction_enabled',
'host_process_performance_data' => 'hs.process_performance_data',
@ -71,7 +72,6 @@ class StatusQuery extends AbstractQuery
'host_retry_check_interval' => 'hs.retry_check_interval',
'host_check_timeperiod_object_id' => 'hs.check_timeperiod_object_id',
'host_status_update_time' => 'hs.status_update_time',
'host_problem' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
'host_severity' => 'CASE WHEN hs.current_state = 0
THEN
CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL
@ -122,12 +122,14 @@ class StatusQuery extends AbstractQuery
),
'servicestatus' => array(
'service_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE ss.current_state END',
'service_hard_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE CASE WHEN ss.state_type = 1 THEN ss.current_state ELSE ss.last_hard_state END END',
'service_state_type' => 'ss.state_type',
'service_output' => 'ss.output',
'service_long_output' => 'ss.long_output',
'service_perfdata' => 'ss.perfdata',
'service_acknowledged' => 'ss.problem_has_been_acknowledged',
'service_in_downtime' => 'CASE WHEN (ss.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
'service_handled' => 'CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END',
'service_handled' => 'CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 THEN 1 ELSE 0 END',
'service_does_active_checks' => 'ss.active_checks_enabled',
'service_accepts_passive_checks' => 'ss.passive_checks_enabled',
'service_last_state_change' => 'UNIX_TIMESTAMP(ss.last_state_change)',
@ -144,7 +146,6 @@ class StatusQuery extends AbstractQuery
'service_check_type' => 'ss.check_type',
'service_last_hard_state_change' => 'ss.last_hard_state_change',
'service_last_hard_state' => 'ss.last_hard_state',
'service_state_type' => 'ss.state_type',
'service_last_notification' => 'ss.last_notification',
'service_next_notification' => 'ss.next_notification',
'service_no_more_notifications' => 'ss.no_more_notifications',
@ -184,6 +185,7 @@ class StatusQuery extends AbstractQuery
'status' => array(
'service_problems' => 'CASE WHEN ss.current_state = 0 THEN 0 ELSE 1 END',
'service_handled' => 'CASE WHEN ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0 THEN 1 ELSE 0 END',
'service_unhandled' => 'CASE WHEN ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0 THEN 1 ELSE 0 END',
'service_severity' => 'CASE WHEN ss.current_state = 0
THEN
CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL
@ -219,21 +221,6 @@ class StatusQuery extends AbstractQuery
),
);
public function group($col)
{
$this->baseQuery->group($col);
}
protected function getDefaultColumns()
{
return $this->columnMap['hosts'];
/*
+ $this->columnMap['services']
+ $this->columnMap['hoststatus']
+ $this->columnMap['servicestatus']
;*/
}
protected function joinBaseTables()
{
// TODO: Shall we always add hostobject?
@ -273,16 +260,15 @@ class StatusQuery extends AbstractQuery
array()
)->join(
array('so' => $this->prefix . 'objects'),
'so.'.$this->object_id.' = s.service_object_id AND so.is_active = 1',
'so.' . $this->object_id . ' = s.service_object_id AND so.is_active = 1',
array()
)->joinLeft(
array('ss' => $this->prefix . 'servicestatus'),
'so.'.$this->object_id.' = ss.service_object_id',
'so.' . $this->object_id . ' = ss.service_object_id',
array()
);
}
// TODO: Test this one, doesn't seem to work right now
protected function joinHostgroups()
{
if ($this->hasJoinedVirtualTable('services')) {
@ -300,7 +286,7 @@ class StatusQuery extends AbstractQuery
array()
)->join(
array('hg' => $this->prefix . 'hostgroups'),
'hgm.hostgroup_id = hg'.$this->hostgroup_id,
'hgm.hostgroup_id = hg' . $this->hostgroup_id,
array()
);
@ -348,6 +334,8 @@ class StatusQuery extends AbstractQuery
return $this;
}
// TODO: This will be obsolete once status is based on the new hoststatus, offering much more
// columns in a more efficient way
protected function joinServiceproblemsummary()
{
$this->baseQuery->joinleft(
@ -363,6 +351,7 @@ class StatusQuery extends AbstractQuery
);
}
// TODO: Terribly slow. As I have no idea of how to fix this we should remove it.
protected function joinLasthostcomment()
{
$this->baseQuery->joinleft(
@ -375,6 +364,7 @@ class StatusQuery extends AbstractQuery
);
}
// TODO: Terribly slow. As I have no idea of how to fix this we should remove it.
protected function joinLastservicecomment()
{
$this->baseQuery->joinleft(

View File

@ -6,7 +6,7 @@ use Icinga\Data\AbstractQuery;
use Icinga\Data\Filter;
/**
* MonitoringView provides consistent views to our Icinga Backends
* AbstractView provides consistent views to our Icinga Backends
*
* TODO: * This could be renamed to AbstractView
* * We might need more complex filters (let's do the simple ones first)
@ -32,7 +32,7 @@ use Icinga\Data\Filter;
* * you can (and should) use a defined set of columns when issueing a query
* * you can use proper alias names to have an influence on column names
* in the result set
* * the MonitoringView behaves like any Query object and provides useful
* * the AbstractView behaves like any Query object and provides useful
* methods such as fetchAll, count, fetchPairs and so on
*
* If you want to fill a dropdown form element with all your hostgroups
@ -48,11 +48,11 @@ use Icinga\Data\Filter;
* $formElement->setMultiOptions($pairs);
* </code>
*
* MonitoringView is a proxy to your Backend Query. While both are Query objects
* AbstractView is a proxy to your Backend Query. While both are Query objects
* providing partially the same interface, they are not directly related to
* each other.
*/
class MonitoringView extends AbstractQuery
class AbstractView extends AbstractQuery
{
/**
* Stores the backend-specific Query Object
@ -89,6 +89,16 @@ class MonitoringView extends AbstractQuery
*/
protected $sortDefaults = array();
/**
* Filters that will be enforced (e.g. AND for SQL), will be used for auth
* restrictions
*
* TODO: rename to enforcedFilters?
*
* @var Array
*/
protected $forcedFilters = array();
/**
* Whether this view provides a specific column name
*
@ -100,6 +110,12 @@ class MonitoringView extends AbstractQuery
return in_array($column, $this->availableColumns);
}
// TODO: Not sure about this yet
public function getDefaultColumns()
{
return $this->availableColumns;
}
/**
* Get a list of all available column names
*
@ -139,7 +155,7 @@ class MonitoringView extends AbstractQuery
return $this->order(
// TODO: Use first sortDefaults entry if available, fall back to
// column if not
$request->getParam('sort', $this->availableColumns[0]),
$request->getParam('sort', $this->getDefaultSortColumn()),
$request->getParam('dir')
);
}
@ -177,8 +193,9 @@ class MonitoringView extends AbstractQuery
}
// TODO: applyAuthFilters(Auth $auth = null)
// MonitoringView will enforce restrictions as provided by the Auth
// backend
// AbstractView will enforce restrictions as provided by the Auth
// backend. Those filters work like normal ones and have to be stored
// by applyAuthFilters to $this->forcedFilters
/**
* Apply an array of filters. This might become obsolete or even improved
@ -209,6 +226,26 @@ class MonitoringView extends AbstractQuery
return new Filter($this->filters);
}
public function hasSingleSortColumn()
{
return count($this->order_columns) === 1;
}
public function getFirstSortColumn()
{
return $this->order_columns[0];
}
protected function getDefaultSortColumn()
{
if (empty($this->sortDefaults)) {
return $this->availableColumns[0];
} else {
reset($this->sortDefaults);
return key($this->sortDefaults);
}
}
/**
* Default sort direction for given column, ASCending if not defined
*
@ -244,6 +281,9 @@ class MonitoringView extends AbstractQuery
foreach ($this->filters as $f) {
$query->where($f[0], $f[1]);
}
foreach ($this->forcedFilters as $col => $filter) {
$query->where($col, $filter);
}
foreach ($this->order_columns as $col) {
if (isset($this->sortDefaults[$col[0]]['columns'])) {

View File

@ -0,0 +1,50 @@
<?php
namespace Icinga\Module\Monitoring\View;
class AllcontactsView extends AbstractView
{
protected $query;
protected $availableColumns = array(
'host_name',
'contact_name',
'contact_alias',
'contact_email',
'contact_pager',
'contact_notify_hosts',
'contact_notify_services',
'contact_has_host_notfications',
'contact_has_service_notfications',
'contact_can_submit_commands',
'contact_notify_service_recovery',
'contact_notify_service_warning',
'contact_notify_service_critical',
'contact_notify_service_unknown',
'contact_notify_service_flapping',
'contact_notify_service_downtime',
'contact_notify_host_recovery',
'contact_notify_host_down',
'contact_notify_host_unreachable',
'contact_notify_host_flapping',
'contact_notify_host_downtime',
'host_object_id',
'host_name',
'service_object_id',
'service_host_name',
'service_description',
/* 'contact_alias',
'contact_email',
'contact_pager',
'contact_notify_hosts',
'contact_notify_services',
*/
);
/*
protected $sortDefaults = array(
'contact_alias' => array(
'default_dir' => self::SORT_ASC
)
);*/
}

View File

@ -2,7 +2,7 @@
namespace Icinga\Module\Monitoring\View;
class CommentView extends MonitoringView
class CommentView extends AbstractView
{
protected $query;

View File

@ -2,16 +2,36 @@
namespace Icinga\Module\Monitoring\View;
class ContactView extends MonitoringView
class ContactView extends AbstractView
{
protected $query;
protected $availableColumns = array(
'contact_name',
'contact_alias',
'contact_email',
'contact_pager',
'contact_notify_hosts',
'contact_notify_services',
'contact_has_host_notfications',
'contact_has_service_notfications',
'contact_can_submit_commands',
'contact_notify_service_recovery',
'contact_notify_service_warning',
'contact_notify_service_critical',
'contact_notify_service_unknown',
'contact_notify_service_flapping',
'contact_notify_service_downtime',
'contact_notify_host_recovery',
'contact_notify_host_down',
'contact_notify_host_unreachable',
'contact_notify_host_flapping',
'contact_notify_host_downtime',
'host_object_id',
'host_name',
'service_object_id',
'service_host_name',
'service_description',
);
protected $specialFilters = array();

View File

@ -2,13 +2,37 @@
namespace Icinga\Module\Monitoring\View;
class ContactgroupView extends MonitoringView
class ContactgroupView extends AbstractView
{
protected $query;
protected $availableColumns = array(
'contactgroup_name',
'contactgroup_alias',
'contact_name',
'contact_alias',
'contact_email',
'contact_pager',
'contact_notify_hosts',
'contact_notify_services',
'contact_has_host_notfications',
'contact_has_service_notfications',
'contact_can_submit_commands',
'contact_notify_service_recovery',
'contact_notify_service_warning',
'contact_notify_service_critical',
'contact_notify_service_unknown',
'contact_notify_service_flapping',
'contact_notify_service_downtime',
'contact_notify_host_recovery',
'contact_notify_host_down',
'contact_notify_host_unreachable',
'contact_notify_host_flapping',
'contact_notify_host_downtime',
'host_object_id',
'host_name',
'service_description'
);

View File

@ -2,7 +2,7 @@
namespace Icinga\Module\Monitoring\View;
class CustomvarView extends MonitoringView
class CustomvarView extends AbstractView
{
protected $query;

View File

@ -27,7 +27,7 @@ namespace Icinga\Module\Monitoring\View;
/**
* Class DowntimeView
*/
class DowntimeView extends MonitoringView
class DowntimeView extends AbstractView
{
/**
* Query object

View File

@ -2,7 +2,7 @@
namespace Icinga\Module\Monitoring\View;
class EventHistoryView extends MonitoringView
class EventHistoryView extends AbstractView
{
protected $query;
@ -21,7 +21,9 @@ class EventHistoryView extends MonitoringView
'type'
);
protected $specialFilters = array();
protected $specialFilters = array(
'hostgroup',
);
protected $sortDefaults = array(
'raw_timestamp' => array(

View File

@ -2,11 +2,12 @@
namespace Icinga\Module\Monitoring\View;
class HostgroupView extends MonitoringView
class HostgroupView extends AbstractView
{
protected $query;
protected $availableColumns = array(
'hostgroups',
'hostgroup_name',
'hostgroup_alias',
);

View File

@ -2,7 +2,7 @@
namespace Icinga\Module\Monitoring\View;
class HoststatusView extends MonitoringView
class HoststatusView extends AbstractView
{
protected $query;
protected $searchColumn = 'host';
@ -37,11 +37,19 @@ class HoststatusView extends MonitoringView
'host_last_time_up',
'host_last_time_down',
'host_last_time_unreachable',
// Services
'services_cnt',
'services_problem',
'services_problem_handled',
'services_problem_unhandled',
);
protected $specialFilters = array(
'hostgroups',
'servicegroups'
'hostgroup',
'servicegroup',
'contact',
'contactgroup',
);
protected $sortDefaults = array(

View File

@ -28,7 +28,7 @@ namespace Icinga\Module\Monitoring\View;
/**
* NotificationView
*/
class NotificationView extends MonitoringView
class NotificationView extends AbstractView
{
/**
* Available columns provided by this view

View File

@ -2,7 +2,7 @@
namespace Icinga\Module\Monitoring\View;
class ServicegroupView extends MonitoringView
class ServicegroupView extends AbstractView
{
protected $query;

View File

@ -0,0 +1,25 @@
<?php
namespace Icinga\Monitoring\View;
use Icinga\Module\Monitoring\View\AbstractView;
class StatehistoryView extends AbstractView
{
protected $availableColumns = array(
'raw_timestamp',
'timestamp',
'state',
'attempt',
'max_attempts',
'output',
'type'
);
protected $sortDefaults = array(
'timestamp' => array(
'columns' => array('raw_timestamp'),
'default_dir' => self::SORT_DESC
),
);
}

View File

@ -2,7 +2,7 @@
namespace Icinga\Module\Monitoring\View;
class StatusView extends MonitoringView
class StatusView extends AbstractView
{
protected $query;
// protected $searchColumn = 'host'; -> besser in der Query, 'search' mitgeben

View File

@ -170,7 +170,7 @@ abstract class MonitoringControllerTest extends Zend_Test_PHPUnit_ControllerTest
private function requireViews()
{
$module = $this->moduleDir;
require_once($module.'library/Monitoring/View/MonitoringView.php');
require_once($module.'library/Monitoring/View/AbstractView.php');
$this->requireFolder('library/Monitoring/View/');
}

View File

@ -10,7 +10,7 @@ $less = new lessc;
$cssdir = dirname(__FILE__) . '/css';
echo $less->compileFile($cssdir . '/base.less');
foreach ($app->moduleManager()->getLoadedModules() as $name => $module) {
foreach ($app->getModuleManager()->getLoadedModules() as $name => $module) {
if ($module->hasCss()) {
echo $less->compile(
'.icinga-module.module-'

View File

@ -1,6 +1,7 @@
<?php
namespace Tests\Icinga\Protocol\Statusdat;
require_once("../../library/Icinga/Data/QueryInterface.php");
require_once("../../library/Icinga/Data/AbstractQuery.php");
require_once("../../library/Icinga/Protocol/Statusdat/Query.php");
require_once(dirname(__FILE__)."/ReaderMock.php");

View File

@ -20,7 +20,7 @@ require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Quer
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat.php';
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/StatusQuery.php';
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/DataView/HostStatusView.php';
require_once '../../modules/monitoring/library/Monitoring/View/MonitoringView.php';
require_once '../../modules/monitoring/library/Monitoring/View/AbstractView.php';
require_once '../../modules/monitoring/library/Monitoring/View/StatusView.php';
require_once '../../library/Icinga/Protocol/AbstractQuery.php';

View File

@ -24,7 +24,7 @@ require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Quer
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat.php';
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/StatusQuery.php';
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/DataView/HostStatusView.php';
require_once '../../modules/monitoring/library/Monitoring/View/MonitoringView.php';
require_once '../../modules/monitoring/library/Monitoring/View/AbstractView.php';
require_once '../../modules/monitoring/library/Monitoring/View/StatusView.php';
require_once '../../library/Icinga/Web/Paginator/ScrollingStyle/SlidingWithBorder.php';