mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-21 04:44:25 +02:00
DbRepository: Consider table aliases while handling statement columns
Usually not required as there are no aliases for statements possible but since we cannot differentiate everywhere what type of column we're processing it is safer to always handle such. fixes #9553
This commit is contained in:
parent
56c4fdf8a1
commit
caca219aa1
@ -497,19 +497,24 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
/**
|
/**
|
||||||
* Return the name of the conversion method for the given alias or column name and context
|
* Return the name of the conversion method for the given alias or column name and context
|
||||||
*
|
*
|
||||||
* @param array|string $table The datasource's table
|
* If a query column or a filter column, which is part of a query filter, needs to be converted,
|
||||||
|
* you'll need to pass $query, otherwise the column is considered a statement column.
|
||||||
|
*
|
||||||
|
* @param string $table The datasource's table
|
||||||
* @param string $name The alias or column name for which to return a conversion method
|
* @param string $name The alias or column name for which to return a conversion method
|
||||||
* @param string $context The context of the conversion: persist or retrieve
|
* @param string $context The context of the conversion: persist or retrieve
|
||||||
|
* @param RepositoryQuery $query If given the column is considered a query column,
|
||||||
|
* statement column otherwise
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
* @throws ProgrammingError In case a conversion rule is found but not any conversion method
|
* @throws ProgrammingError In case a conversion rule is found but not any conversion method
|
||||||
*/
|
*/
|
||||||
protected function getConverter($table, $name, $context)
|
protected function getConverter($table, $name, $context, RepositoryQuery $query = null)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
$this->validateQueryColumnAssociation($table, $name)
|
($query !== null && $this->validateQueryColumnAssociation($table, $name))
|
||||||
|| $this->validateStatementColumnAssociation($table, $name)
|
|| ($query === null && $this->validateStatementColumnAssociation($table, $name))
|
||||||
) {
|
) {
|
||||||
$table = $this->removeTablePrefix($this->clearTableAlias($table));
|
$table = $this->removeTablePrefix($this->clearTableAlias($table));
|
||||||
} else {
|
} else {
|
||||||
@ -519,7 +524,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getConverter($table, $name, $context);
|
return parent::getConverter($table, $name, $context, $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -650,7 +655,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
* Attempts to join the given column from a different table if its association to the given table cannot be
|
* Attempts to join the given column from a different table if its association to the given table cannot be
|
||||||
* verified.
|
* verified.
|
||||||
*
|
*
|
||||||
* @param string $table The table where to look for the column or alias
|
* @param array|string $table The table where to look for the column or alias
|
||||||
* @param string $name The name or alias of the column to validate
|
* @param string $name The name or alias of the column to validate
|
||||||
* @param RepositoryQuery $query An optional query to pass as context,
|
* @param RepositoryQuery $query An optional query to pass as context,
|
||||||
* if not given no join will be attempted
|
* if not given no join will be attempted
|
||||||
@ -662,7 +667,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
public function requireQueryColumn($table, $name, RepositoryQuery $query = null)
|
public function requireQueryColumn($table, $name, RepositoryQuery $query = null)
|
||||||
{
|
{
|
||||||
if ($query === null || $this->validateQueryColumnAssociation($table, $name)) {
|
if ($query === null || $this->validateQueryColumnAssociation($table, $name)) {
|
||||||
return parent::requireQueryColumn($table, $name, $query);
|
return parent::requireQueryColumn($this->removeTablePrefix($this->clearTableAlias($table)), $name, $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->joinColumn($name, $table, $query);
|
return $this->joinColumn($name, $table, $query);
|
||||||
@ -674,7 +679,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
* Attempts to join the given column from a different table if its association to the given table cannot be
|
* Attempts to join the given column from a different table if its association to the given table cannot be
|
||||||
* verified.
|
* verified.
|
||||||
*
|
*
|
||||||
* @param string $table The table where to look for the column or alias
|
* @param array|string $table The table where to look for the column or alias
|
||||||
* @param string $name The name or alias of the column to validate
|
* @param string $name The name or alias of the column to validate
|
||||||
* @param RepositoryQuery $query An optional query to pass as context,
|
* @param RepositoryQuery $query An optional query to pass as context,
|
||||||
* if not given the column is considered being used for a statement filter
|
* if not given the column is considered being used for a statement filter
|
||||||
@ -690,7 +695,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->validateQueryColumnAssociation($table, $name)) {
|
if ($this->validateQueryColumnAssociation($table, $name)) {
|
||||||
return parent::requireFilterColumn($table, $name, $query);
|
return parent::requireFilterColumn($this->removeTablePrefix($this->clearTableAlias($table)), $name, $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->joinColumn($name, $table, $query);
|
return $this->joinColumn($name, $table, $query);
|
||||||
@ -699,7 +704,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
/**
|
/**
|
||||||
* Return the statement column name for the given alias or null in case the alias does not exist
|
* Return the statement column name for the given alias or null in case the alias does not exist
|
||||||
*
|
*
|
||||||
* @param string $table
|
* @param array|string $table
|
||||||
* @param string $alias
|
* @param string $alias
|
||||||
*
|
*
|
||||||
* @return string|null
|
* @return string|null
|
||||||
@ -711,7 +716,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
return $statementAliasColumnMap[$alias];
|
return $statementAliasColumnMap[$alias];
|
||||||
}
|
}
|
||||||
|
|
||||||
$prefixedAlias = $this->removeTablePrefix($table) . '.' . $alias;
|
$prefixedAlias = $this->removeTablePrefix($this->clearTableAlias($table)) . '.' . $alias;
|
||||||
if (isset($statementAliasColumnMap[$prefixedAlias])) {
|
if (isset($statementAliasColumnMap[$prefixedAlias])) {
|
||||||
return $statementAliasColumnMap[$prefixedAlias];
|
return $statementAliasColumnMap[$prefixedAlias];
|
||||||
}
|
}
|
||||||
@ -720,7 +725,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
/**
|
/**
|
||||||
* Return the alias for the given statement column name or null in case the statement column does not exist
|
* Return the alias for the given statement column name or null in case the statement column does not exist
|
||||||
*
|
*
|
||||||
* @param string $table
|
* @param array|string $table
|
||||||
* @param string $column
|
* @param string $column
|
||||||
*
|
*
|
||||||
* @return string|null
|
* @return string|null
|
||||||
@ -732,7 +737,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
return $statementColumnAliasMap[$column];
|
return $statementColumnAliasMap[$column];
|
||||||
}
|
}
|
||||||
|
|
||||||
$prefixedColumn = $this->removeTablePrefix($table) . '.' . $column;
|
$prefixedColumn = $this->removeTablePrefix($this->clearTableAlias($table)) . '.' . $column;
|
||||||
if (isset($statementColumnAliasMap[$prefixedColumn])) {
|
if (isset($statementColumnAliasMap[$prefixedColumn])) {
|
||||||
return $statementColumnAliasMap[$prefixedColumn];
|
return $statementColumnAliasMap[$prefixedColumn];
|
||||||
}
|
}
|
||||||
@ -741,14 +746,14 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
/**
|
/**
|
||||||
* Return whether the given alias or statement column name is available in the given table
|
* Return whether the given alias or statement column name is available in the given table
|
||||||
*
|
*
|
||||||
* @param string $table
|
* @param array|string $table
|
||||||
* @param string $alias
|
* @param string $alias
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function validateStatementColumnAssociation($table, $alias)
|
public function validateStatementColumnAssociation($table, $alias)
|
||||||
{
|
{
|
||||||
$tableName = $this->removeTablePrefix($table);
|
$tableName = $this->removeTablePrefix($this->clearTableAlias($table));
|
||||||
|
|
||||||
$statementAliasTableMap = $this->getStatementAliasTableMap();
|
$statementAliasTableMap = $this->getStatementAliasTableMap();
|
||||||
if (isset($statementAliasTableMap[$alias])) {
|
if (isset($statementAliasTableMap[$alias])) {
|
||||||
@ -767,7 +772,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
/**
|
/**
|
||||||
* Return whether the given column name or alias of the given table is a valid statement column
|
* Return whether the given column name or alias of the given table is a valid statement column
|
||||||
*
|
*
|
||||||
* @param string $table The table where to look for the column or alias
|
* @param array|string $table The table where to look for the column or alias
|
||||||
* @param string $name The column name or alias to check
|
* @param string $name The column name or alias to check
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
@ -779,7 +784,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
&& $this->reassembleStatementColumnAlias($table, $name) === null)
|
&& $this->reassembleStatementColumnAlias($table, $name) === null)
|
||||||
|| !$this->validateStatementColumnAssociation($table, $name)
|
|| !$this->validateStatementColumnAssociation($table, $name)
|
||||||
) {
|
) {
|
||||||
return parent::hasStatementColumn($table, $name);
|
return parent::hasStatementColumn($this->removeTablePrefix($this->clearTableAlias($table)), $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -788,7 +793,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
/**
|
/**
|
||||||
* Validate that the given column is a valid statement column and return it or the actual name if it's an alias
|
* Validate that the given column is a valid statement column and return it or the actual name if it's an alias
|
||||||
*
|
*
|
||||||
* @param string $table The table for which to require the column
|
* @param array|string $table The table for which to require the column
|
||||||
* @param string $name The name or alias of the column to validate
|
* @param string $name The name or alias of the column to validate
|
||||||
*
|
*
|
||||||
* @return string The given column's name
|
* @return string The given column's name
|
||||||
@ -802,11 +807,15 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||||||
} elseif (($alias = $this->reassembleStatementColumnAlias($table, $name)) !== null) {
|
} elseif (($alias = $this->reassembleStatementColumnAlias($table, $name)) !== null) {
|
||||||
$column = $name;
|
$column = $name;
|
||||||
} else {
|
} else {
|
||||||
return parent::requireStatementColumn($table, $name);
|
return parent::requireStatementColumn($this->removeTablePrefix($this->clearTableAlias($table)), $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $this->validateStatementColumnAssociation($table, $alias)) {
|
if (! $this->validateStatementColumnAssociation($table, $alias)) {
|
||||||
throw new StatementException('Statement column "%s" not found in table "%s"', $name, $table);
|
throw new StatementException(
|
||||||
|
'Statement column "%s" not found in table "%s"',
|
||||||
|
$name,
|
||||||
|
$this->removeTablePrefix($this->clearTableAlias($table))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $column;
|
return $column;
|
||||||
|
@ -494,12 +494,15 @@ abstract class Repository implements Selectable
|
|||||||
* @param string $table The table where to persist the value
|
* @param string $table The table where to persist the value
|
||||||
* @param string $name The alias or column name
|
* @param string $name The alias or column name
|
||||||
* @param mixed $value The value to convert
|
* @param mixed $value The value to convert
|
||||||
|
* @param RepositoryQuery $query An optional query to pass as context
|
||||||
|
* (Directly passed through to $this->getConverter)
|
||||||
*
|
*
|
||||||
* @return mixed If conversion was possible, the converted value, otherwise the unchanged value
|
* @return mixed If conversion was possible, the converted value,
|
||||||
|
* otherwise the unchanged value
|
||||||
*/
|
*/
|
||||||
public function persistColumn($table, $name, $value)
|
public function persistColumn($table, $name, $value, RepositoryQuery $query = null)
|
||||||
{
|
{
|
||||||
$converter = $this->getConverter($table, $name, 'persist');
|
$converter = $this->getConverter($table, $name, 'persist', $query);
|
||||||
if ($converter !== null) {
|
if ($converter !== null) {
|
||||||
$value = $this->$converter($value);
|
$value = $this->$converter($value);
|
||||||
}
|
}
|
||||||
@ -513,12 +516,15 @@ abstract class Repository implements Selectable
|
|||||||
* @param string $table The table the value has been fetched from
|
* @param string $table The table the value has been fetched from
|
||||||
* @param string $name The alias or column name
|
* @param string $name The alias or column name
|
||||||
* @param mixed $value The value to convert
|
* @param mixed $value The value to convert
|
||||||
|
* @param RepositoryQuery $query An optional query to pass as context
|
||||||
|
* (Directly passed through to $this->getConverter)
|
||||||
*
|
*
|
||||||
* @return mixed If conversion was possible, the converted value, otherwise the unchanged value
|
* @return mixed If conversion was possible, the converted value,
|
||||||
|
* otherwise the unchanged value
|
||||||
*/
|
*/
|
||||||
public function retrieveColumn($table, $name, $value)
|
public function retrieveColumn($table, $name, $value, RepositoryQuery $query = null)
|
||||||
{
|
{
|
||||||
$converter = $this->getConverter($table, $name, 'retrieve');
|
$converter = $this->getConverter($table, $name, 'retrieve', $query);
|
||||||
if ($converter !== null) {
|
if ($converter !== null) {
|
||||||
$value = $this->$converter($value);
|
$value = $this->$converter($value);
|
||||||
}
|
}
|
||||||
@ -532,12 +538,14 @@ abstract class Repository implements Selectable
|
|||||||
* @param string $table The datasource's table
|
* @param string $table The datasource's table
|
||||||
* @param string $name The alias or column name for which to return a conversion method
|
* @param string $name The alias or column name for which to return a conversion method
|
||||||
* @param string $context The context of the conversion: persist or retrieve
|
* @param string $context The context of the conversion: persist or retrieve
|
||||||
|
* @param RepositoryQuery $query An optional query to pass as context
|
||||||
|
* (unused by the base implementation)
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
* @throws ProgrammingError In case a conversion rule is found but not any conversion method
|
* @throws ProgrammingError In case a conversion rule is found but not any conversion method
|
||||||
*/
|
*/
|
||||||
protected function getConverter($table, $name, $context)
|
protected function getConverter($table, $name, $context, RepositoryQuery $query = null)
|
||||||
{
|
{
|
||||||
$conversionRules = $this->getConversionRules();
|
$conversionRules = $this->getConversionRules();
|
||||||
if (! isset($conversionRules[$table])) {
|
if (! isset($conversionRules[$table])) {
|
||||||
|
@ -153,7 +153,7 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
{
|
{
|
||||||
$this->query->where(
|
$this->query->where(
|
||||||
$this->repository->requireFilterColumn($this->target, $column, $this),
|
$this->repository->requireFilterColumn($this->target, $column, $this),
|
||||||
$this->repository->persistColumn($this->target, $column, $value)
|
$this->repository->persistColumn($this->target, $column, $value, $this)
|
||||||
);
|
);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -401,7 +401,7 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
if ($result !== false && $this->repository->providesValueConversion($this->target)) {
|
if ($result !== false && $this->repository->providesValueConversion($this->target)) {
|
||||||
$columns = $this->getColumns();
|
$columns = $this->getColumns();
|
||||||
$column = isset($columns[0]) ? $columns[0] : key($columns);
|
$column = isset($columns[0]) ? $columns[0] : key($columns);
|
||||||
return $this->repository->retrieveColumn($this->target, $column, $result);
|
return $this->repository->retrieveColumn($this->target, $column, $result, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@ -425,7 +425,7 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
$alias = $column;
|
$alias = $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result->$alias = $this->repository->retrieveColumn($this->target, $alias, $result->$alias);
|
$result->$alias = $this->repository->retrieveColumn($this->target, $alias, $result->$alias, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,7 +450,7 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
$column = is_int($aliases[0]) ? $columns[0] : $aliases[0];
|
$column = is_int($aliases[0]) ? $columns[0] : $aliases[0];
|
||||||
if ($this->repository->providesValueConversion($this->target, $column)) {
|
if ($this->repository->providesValueConversion($this->target, $column)) {
|
||||||
foreach ($results as & $value) {
|
foreach ($results as & $value) {
|
||||||
$value = $this->repository->retrieveColumn($this->target, $column, $value);
|
$value = $this->repository->retrieveColumn($this->target, $column, $value, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,8 +483,13 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
) {
|
) {
|
||||||
$newResults = array();
|
$newResults = array();
|
||||||
foreach ($results as $colOneValue => $colTwoValue) {
|
foreach ($results as $colOneValue => $colTwoValue) {
|
||||||
$colOneValue = $this->repository->retrieveColumn($this->target, $colOne, $colOneValue);
|
$colOneValue = $this->repository->retrieveColumn($this->target, $colOne, $colOneValue, $this);
|
||||||
$newResults[$colOneValue] = $this->repository->retrieveColumn($this->target, $colTwo, $colTwoValue);
|
$newResults[$colOneValue] = $this->repository->retrieveColumn(
|
||||||
|
$this->target,
|
||||||
|
$colTwo,
|
||||||
|
$colTwoValue,
|
||||||
|
$this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$results = $newResults;
|
$results = $newResults;
|
||||||
@ -516,7 +521,7 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
$alias = $column;
|
$alias = $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
$row->$alias = $this->repository->retrieveColumn($this->target, $alias, $row->$alias);
|
$row->$alias = $this->repository->retrieveColumn($this->target, $alias, $row->$alias, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (($this->getOrder() ?: array()) as $rule) {
|
foreach (($this->getOrder() ?: array()) as $rule) {
|
||||||
@ -591,7 +596,7 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
$alias = $column;
|
$alias = $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
$row->$alias = $this->repository->retrieveColumn($this->target, $alias, $row->$alias);
|
$row->$alias = $this->repository->retrieveColumn($this->target, $alias, $row->$alias, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user