diff --git a/library/Icinga/Repository/DbRepository.php b/library/Icinga/Repository/DbRepository.php index 8ba43efaf..2b9901c21 100644 --- a/library/Icinga/Repository/DbRepository.php +++ b/library/Icinga/Repository/DbRepository.php @@ -3,6 +3,10 @@ namespace Icinga\Repository; +use Icinga\Data\Extensible; +use Icinga\Data\Filter\Filter; +use Icinga\Data\Reducible; +use Icinga\Data\Updatable; use Icinga\Exception\IcingaException; use Icinga\Exception\ProgrammingError; @@ -12,10 +16,45 @@ use Icinga\Exception\ProgrammingError; * Additionally provided features: * */ -abstract class DbRepository extends Repository +abstract class DbRepository extends Repository implements Extensible, Updatable, Reducible { + /** + * The statement columns being provided + * + * This may be initialized by repositories which are going to make use of table aliases. It allows to provide + * alias-less column names to be used for a statement. The array needs to be in the following format: + *

+     *  array(
+     *      'table_name' => array(
+     *          'column1',
+     *          'alias1' => 'column2',
+     *          'alias2' => 'column3'
+     *      )
+     *  )
+     * 

+     *
+     * @var array
+     */
+    protected $statementColumns;
+
+    /**
+     * An array to map table names to statement columns/aliases
+     *
+     * @var array
+     */
+    protected $statementTableMap;
+
+    /**
+     * A flattened array to map statement columns to aliases
+     *
+     * @var array
+     */
+    protected $statementColumnMap;
+
     /**
      * Return the base table name this repository is responsible for
      *
@@ -61,4 +100,154 @@ abstract class DbRepository extends Repository
 
         return $table;
     }
+
+    /**
+     * Insert a table row with the given data
+     *
+     * @param   string  $table
+     * @param   array   $bind
+     */
+    public function insert($table, array $bind)
+    {
+        $this->ds->insert($this->prependTablePrefix($table), $this->requireStatementColumns($bind));
+    }
+
+    /**
+     * Update table rows with the given data, optionally limited by using a filter
+     *
+     * @param   string  $table
+     * @param   array   $bind
+     * @param   Filter  $filter
+     */
+    public function update($table, array $bind, Filter $filter = null)
+    {
+        if ($filter) {
+            $this->requireFilter($filter);
+        }
+
+        $this->ds->update($this->prependTablePrefix($table), $this->requireStatementColumns($bind), $filter);
+    }
+
+    /**
+     * Delete table rows, optionally limited by using a filter
+     *
+     * @param   string  $table
+     * @param   Filter  $filter
+     */
+    public function delete($table, Filter $filter = null)
+    {
+        if ($filter) {
+            $this->requireFilter($filter);
+        }
+
+        $this->ds->delete($this->prependTablePrefix($table), $filter);
+    }
+
+    /**
+     * Return the statement columns being provided
+     *
+     * Calls $this->initializeStatementColumns() in case $this->statementColumns is null.
+     *
+     * @return  array
+     */
+    public function getStatementColumns()
+    {
+        if ($this->statementColumns === null) {
+            $this->statementColumns = $this->initializeStatementColumns();
+        }
+
+        return $this->statementColumns;
+    }
+
+    /**
+     * Overwrite this in your repository implementation in case you need to initialize the statement columns lazily
+     *
+     * @return  array
+     */
+    protected function initializeStatementColumns()
+    {
+        return array();
+    }
+
+    /**
+     * Return an array to map table names to statement columns/aliases
+     *
+     * @return  array
+     */
+    protected function getStatementTableMap()
+    {
+        if ($this->statementTableMap === null) {
+            $this->initializeStatementMaps();
+        }
+
+        return $this->statementTableMap;
+    }
+
+    /**
+     * Return a flattened array to map statement columns to aliases
+     *
+     * @return  array
+     */
+    protected function getStatementColumnMap()
+    {
+        if ($this->statementColumnMap === null) {
+            $this->initializeStatementMaps();
+        }
+
+        return $this->statementColumnMap;
+    }
+
+    /**
+     * Initialize $this->statementTableMap and $this->statementColumnMap
+     */
+    protected function initializeStatementMaps()
+    {
+        foreach ($this->getStatementColumns() as $table => $columns) {
+            foreach ($columns as $alias => $column) {
+                if (! is_string($alias)) {
+                    $this->statementTableMap[$column] = $table;
+                    $this->statementColumnMap[$column] = $column;
+                } else {
+                    $this->statementTableMap[$alias] = $table;
+                    $this->statementColumnMap[$alias] = $column;
+                }
+            }
+        }
+    }
+
+    /**
+     * Return whether the given column name or alias is a valid statement column
+     *
+     * @param   string  $name   The column name or alias to check
+     *
+     * @return  bool
+     */
+    public function hasStatementColumn($name)
+    {
+        $statementColumnMap = $this->getStatementColumnMap();
+        if (! array_key_exists($name, $statementColumnMap)) {
+            return parent::hasStatementColumn($name);
+        }
+
+        return true;
+    }
+
+    /**
+     * Validate that the given column is a valid statement column and return it or the actual name if it's an alias
+     *
+     * @param   string  $name       The name or alias of the column to validate
+     *
+     * @return  string              The given column's name
+     *
+     * @throws  QueryException      In case the given column is not a statement column
+     */
+    public function requireStatementColumn($name)
+    {
+        $statementColumnMap = $this->getStatementColumnMap();
+        if (! array_key_exists($name, $statementColumnMap)) {
+            return parent::requireStatementColumn($name);
+        }
+
+        return $statementColumnMap[$name];
+    }
 }