IdoQuery: Add prototype for dynamic GROUP BY clauses
This commit is contained in:
parent
386447b847
commit
1169793213
|
@ -3,13 +3,14 @@
|
|||
|
||||
namespace Icinga\Data\Db;
|
||||
|
||||
use Icinga\Data\SimpleQuery;
|
||||
use Icinga\Data\Filter\FilterChain;
|
||||
use Icinga\Data\Filter\FilterOr;
|
||||
use Icinga\Data\Filter\FilterAnd;
|
||||
use Icinga\Data\Filter\FilterNot;
|
||||
use Icinga\Exception\QueryException;
|
||||
use Zend_Db_Select;
|
||||
use Icinga\Data\Filter\FilterAnd;
|
||||
use Icinga\Data\Filter\FilterChain;
|
||||
use Icinga\Data\Filter\FilterNot;
|
||||
use Icinga\Data\Filter\FilterOr;
|
||||
use Icinga\Data\SimpleQuery;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Exception\QueryException;
|
||||
|
||||
/**
|
||||
* Database query class
|
||||
|
@ -428,6 +429,35 @@ class DbQuery extends SimpleQuery
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the alias used for joining the given table
|
||||
*
|
||||
* @param string $table
|
||||
*
|
||||
* @return string|null null in case no alias is being used
|
||||
*
|
||||
* @throws ProgrammingError In case the given table has not been joined
|
||||
*/
|
||||
public function getJoinedTableAlias($table)
|
||||
{
|
||||
$fromPart = $this->select->getPart(Zend_Db_Select::FROM);
|
||||
if (isset($fromPart[$table])) {
|
||||
if ($fromPart[$table]['joinType'] === Zend_Db_Select::FROM) {
|
||||
throw new ProgrammingError('Table "%s" has not been joined', $table);
|
||||
}
|
||||
|
||||
return; // No alias in use
|
||||
}
|
||||
|
||||
foreach ($fromPart as $alias => $options) {
|
||||
if ($options['tableName'] === $table && $options['joinType'] !== Zend_Db_Select::FROM) {
|
||||
return $alias;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ProgrammingError('Table "%s" has not been joined', $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an INNER JOIN table and colums to the query
|
||||
*
|
||||
|
|
|
@ -10,6 +10,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\Web\Session;
|
||||
|
||||
|
@ -46,24 +47,31 @@ abstract class IdoQuery extends DbQuery
|
|||
/**
|
||||
* The prefix to use
|
||||
*
|
||||
* @var String
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* The alias name for the index column
|
||||
* An array to map aliases to table names
|
||||
*
|
||||
* @var String
|
||||
* @var array
|
||||
*/
|
||||
protected $idxAliasColumn;
|
||||
|
||||
/**
|
||||
* The table containing the index column alias
|
||||
* An array to map aliases to column names
|
||||
*
|
||||
* @var String
|
||||
* @var array
|
||||
*/
|
||||
protected $idxAliasTable;
|
||||
|
||||
/**
|
||||
* An array to map custom aliases to aliases
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $idxCustomAliases;
|
||||
|
||||
/**
|
||||
* The column map containing all filterable columns
|
||||
*
|
||||
|
@ -111,53 +119,235 @@ abstract class IdoQuery extends DbQuery
|
|||
protected $joinedVirtualTables = array();
|
||||
|
||||
/**
|
||||
* The primary field name for the object table
|
||||
* The primary key column for the instances table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $instance_id = 'instance_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the objects table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $object_id = 'object_id';
|
||||
|
||||
/**
|
||||
* The primary field name for the IDO host table
|
||||
* The primary key column for the acknowledgements table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $host_id = 'host_id';
|
||||
protected $acknowledgement_id = 'acknowledgement_id';
|
||||
|
||||
/**
|
||||
* The primary field name for the IDO hostgroup table
|
||||
* The primary key column for the commenthistory table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $hostgroup_id = 'hostgroup_id';
|
||||
protected $commenthistory_id = 'commenthistory_id';
|
||||
|
||||
/**
|
||||
* The primary field name for the IDO service table
|
||||
* The primary key column for the contactnotifications table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $service_id = 'service_id';
|
||||
protected $contactnotification_id = 'contactnotification_id';
|
||||
|
||||
/**
|
||||
* The primary field name for the IDO serviegroup table
|
||||
* The primary key column for the downtimehistory table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $downtimehistory_id = 'downtimehistory_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the flappinghistory table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $flappinghistory_id = 'flappinghistory_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the notifications table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $notification_id = 'notification_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the statehistory table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $statehistory_id = 'statehistory_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the comments table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $comment_id = 'comment_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the customvariablestatus table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $customvariablestatus_id = 'customvariablestatus_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the hoststatus table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $hoststatus_id = 'hoststatus_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the programstatus table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $programstatus_id = 'programstatus_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the runtimevariables table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $runtimevariable_id = 'runtimevariable_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the scheduleddowntime table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $scheduleddowntime_id = 'scheduleddowntime_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the servicestatus table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $servicestatus_id = 'servicestatus_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the contactstatus table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contactstatus_id = 'contactstatus_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the commands table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $command_id = 'command_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the contactgroup_members table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contactgroup_member_id = 'contactgroup_member_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the contactgroups table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contactgroup_id = 'contactgroup_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the contacts table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contact_id = 'contact_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the customvariables table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $customvariable_id = 'customvariable_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the host_contactgroups table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $host_contactgroup_id = 'host_contactgroup_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the host_contacts table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $host_contact_id = 'host_contact_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the hostgroup_members table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $hostgroup_member_id = 'hostgroup_member_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the hostgroups table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $hostgroup_id = 'hostgroup_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the hosts table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $host_id = 'host_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the service_contactgroup table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $service_contactgroup_id = 'service_contactgroup_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the service_contact table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $service_contact_id = 'service_contact_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the servicegroup_members table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $servicegroup_member_id = 'servicegroup_member_id';
|
||||
|
||||
/**
|
||||
* The primary key column for the servicegroups table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $servicegroup_id = 'servicegroup_id';
|
||||
|
||||
/**
|
||||
* The primary field name for the IDO contact table
|
||||
* The primary key column for the services table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contact_id = 'contact_id';
|
||||
protected $service_id = 'service_id';
|
||||
|
||||
/**
|
||||
* The primary field name for the IDO contactgroup table
|
||||
* The primary key column for the timeperiods table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contactgroup_id = 'contactgroup_id';
|
||||
protected $timeperiod_id = 'timeperiod_id';
|
||||
|
||||
/**
|
||||
* An array containing Column names that cause an aggregation of the query
|
||||
|
@ -483,6 +673,8 @@ abstract class IdoQuery extends DbQuery
|
|||
}
|
||||
if (is_int($alias)) {
|
||||
$alias = $col;
|
||||
} else {
|
||||
$this->idxCustomAliases[$alias] = $col;
|
||||
}
|
||||
|
||||
$resolvedColumns[$alias] = preg_replace('|\n|', ' ', $name);
|
||||
|
@ -688,6 +880,11 @@ abstract class IdoQuery extends DbQuery
|
|||
return $this->idxAliasColumn[$alias];
|
||||
}
|
||||
|
||||
public function customAliasToAlias($alias)
|
||||
{
|
||||
return $this->idxCustomAliases[$alias];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sub query
|
||||
*
|
||||
|
@ -714,12 +911,55 @@ abstract class IdoQuery extends DbQuery
|
|||
*/
|
||||
public function columns(array $columns)
|
||||
{
|
||||
$this->idxCustomAliases = array();
|
||||
$this->columns = $this->resolveColumns($columns);
|
||||
// TODO: we need to refresh our select!
|
||||
// $this->select->columns($columns);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function _getGroup()
|
||||
{
|
||||
throw new NotImplementedError('Does not work in its current state but will, probably, in the future');
|
||||
|
||||
// TODO: order by??
|
||||
$group = parent::getGroup();
|
||||
if (! empty($group) && $this->ds->getDbType() === 'pgsql') {
|
||||
$group = is_array($group) ? $group : array($group);
|
||||
foreach ($this->columns as $alias => $column) {
|
||||
if ($column instanceof Zend_Db_Expr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: What if $alias is neither a native nor a custom alias???
|
||||
$table = $this->aliasToTableName(
|
||||
$this->hasAliasName($alias) ? $alias : $this->customAliasToAlias($alias)
|
||||
);
|
||||
|
||||
// TODO: We cannot rely on the underlying select here, tables may be joined multiple times with
|
||||
// different aliases so the only way to get the correct alias here is to register such by ourself
|
||||
// for each virtual column (We may also inspect $column for the alias but this will probably lead
|
||||
// to false positives.. AND prevents custom implementations from providing their own "mapping")
|
||||
if (($tableAlias = $this->getJoinedTableAlias($this->prefix . $table)) === null) {
|
||||
$tableAlias = $table;
|
||||
}
|
||||
|
||||
// TODO: Same issue as with identifying table aliases; Our virtual tables are not named exactly how
|
||||
// they are in the IDO. We definitely need to register aliases explicitly (hint: DbRepository
|
||||
// is already providing such..)
|
||||
$aliasedPk = $tableAlias . '.' . $this->getPrimaryKeyColumn($table);
|
||||
if (! in_array($aliasedPk, $group)) {
|
||||
$group[] = $aliasedPk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
// TODO: Move this away, see note related to $idoVersion var
|
||||
protected function getIdoVersion()
|
||||
{
|
||||
|
@ -745,4 +985,90 @@ abstract class IdoQuery extends DbQuery
|
|||
}
|
||||
return self::$idoVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the primary key column for the given table name
|
||||
*
|
||||
* @param string $table
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws ProgrammingError In case $table is unknown
|
||||
*/
|
||||
protected function getPrimaryKeyColumn($table)
|
||||
{
|
||||
// TODO: For god's sake, make this being a mapping
|
||||
// (instead of matching a ton of properties using a ridiculous long switch case)
|
||||
switch ($table)
|
||||
{
|
||||
case 'instances':
|
||||
return $this->instance_id;
|
||||
case 'objects':
|
||||
return $this->object_id;
|
||||
case 'acknowledgements':
|
||||
return $this->acknowledgement_id;
|
||||
case 'commenthistory':
|
||||
return $this->commenthistory_id;
|
||||
case 'contactnotifiations':
|
||||
return $this->contactnotification_id;
|
||||
case 'downtimehistory':
|
||||
return $this->downtimehistory_id;
|
||||
case 'flappinghistory':
|
||||
return $this->flappinghistory_id;
|
||||
case 'notifications':
|
||||
return $this->notification_id;
|
||||
case 'statehistory':
|
||||
return $this->statehistory_id;
|
||||
case 'comments':
|
||||
return $this->comment_id;
|
||||
case 'customvariablestatus':
|
||||
return $this->customvariablestatus_id;
|
||||
case 'hoststatus':
|
||||
return $this->hoststatus_id;
|
||||
case 'programstatus':
|
||||
return $this->programstatus_id;
|
||||
case 'runtimevariables':
|
||||
return $this->runtimevariable_id;
|
||||
case 'scheduleddowntime':
|
||||
return $this->scheduleddowntime_id;
|
||||
case 'servicestatus':
|
||||
return $this->servicestatus_id;
|
||||
case 'contactstatus':
|
||||
return $this->contactstatus_id;
|
||||
case 'commands':
|
||||
return $this->command_id;
|
||||
case 'contactgroup_members':
|
||||
return $this->contactgroup_member_id;
|
||||
case 'contactgroups':
|
||||
return $this->contactgroup_id;
|
||||
case 'contacts':
|
||||
return $this->contact_id;
|
||||
case 'customvariables':
|
||||
return $this->customvariable_id;
|
||||
case 'host_contactgroups':
|
||||
return $this->host_contactgroup_id;
|
||||
case 'host_contacts':
|
||||
return $this->host_contact_id;
|
||||
case 'hostgroup_members':
|
||||
return $this->hostgroup_member_id;
|
||||
case 'hostgroups':
|
||||
return $this->hostgroup_id;
|
||||
case 'hosts':
|
||||
return $this->host_id;
|
||||
case 'service_contactgroups':
|
||||
return $this->service_contactgroup_id;
|
||||
case 'service_contacts':
|
||||
return $this->service_contact_id;
|
||||
case 'servicegroup_members':
|
||||
return $this->servicegroup_member_id;
|
||||
case 'servicegroups':
|
||||
return $this->servicegroup_id;
|
||||
case 'services':
|
||||
return $this->service_id;
|
||||
case 'timeperiods':
|
||||
return $this->timeperiod_id;
|
||||
default:
|
||||
throw new ProgrammingError('Cannot provide a primary key column. Table "%s" is unknown', $table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue