[icinga-checkins] icinga.org: icingaweb2/feature/ inirepository-should-support-multiple-tables-13034: IniRepository: improve initialization of per-table datasources

git at icinga.org git at icinga.org
Thu Nov 3 18:10:42 CET 2016


Module: icingaweb2
Branch: feature/inirepository-should-support-multiple-tables-13034
Commit: bd7851d15c4412eefda411f524969e123cce8c49
URL:    https://git.icinga.org/?p=icingaweb2.git;a=commit;h=bd7851d15c4412eefda411f524969e123cce8c49

Author: Alexander A. Klimov <alexander.klimov at icinga.com>
Date:   Thu Nov  3 18:05:05 2016 +0100

IniRepository: improve initialization of per-table datasources

refs #13034

---

 library/Icinga/Repository/IniRepository.php |   79 ++++++++++++++++++++++++---
 1 file changed, 71 insertions(+), 8 deletions(-)

diff --git a/library/Icinga/Repository/IniRepository.php b/library/Icinga/Repository/IniRepository.php
index ec9b4b1..e17bbaa 100644
--- a/library/Icinga/Repository/IniRepository.php
+++ b/library/Icinga/Repository/IniRepository.php
@@ -25,17 +25,22 @@ use Icinga\Exception\StatementException;
 abstract class IniRepository extends Repository implements Extensible, Updatable, Reducible
 {
     /**
-     * Per-table datasources
+     * Per-table configs
      *
+     * Example:
      * <code>
      * array(
-     *   $table => $datasource
+     *   'event-type' => array(
+     *     'module'    => 'elasticsearch',
+     *     'path'      => 'event-types',
+     *     'keyColumn' => 'name'
+     *   )
      * )
      * </code>
      *
-     * @var Config[]
+     * @var array
      */
-    protected $datasources = array();
+    protected $configs = null;
 
     /**
      * The tables for which triggers are available when inserting, updating or deleting rows
@@ -53,15 +58,15 @@ abstract class IniRepository extends Repository implements Extensible, Updatable
     /**
      * Create a new INI repository object
      *
-     * @param   Config  $ds         The data source to use
+     * @param   Config|null $ds     The data source to use
      *
      * @throws  ProgrammingError    In case the given data source does not provide a valid key column
      */
-    public function __construct(Config $ds)
+    public function __construct(Config $ds = null)
     {
         parent::__construct($ds); // First! Due to init().
 
-        if (! $ds->getConfigObject()->getKeyColumn()) {
+        if (! ($ds === null || $ds->getConfigObject()->getKeyColumn())) {
             throw new ProgrammingError('INI repositories require their data source to provide a valid key column');
         }
     }
@@ -71,7 +76,56 @@ abstract class IniRepository extends Repository implements Extensible, Updatable
      */
     public function getDataSource($table = null)
     {
-        return isset($this->datasources[$table]) ? $this->datasources[$table] : parent::getDataSource($table);
+        if ($this->ds === null) {
+            if ($table === null) {
+                $table = $this->getBaseTable();
+            }
+
+            if ($this->configs === null) {
+                $this->configs = $this->initializeConfigs();
+                if ($this->configs === null) {
+                    throw new ProgrammingError('Per-table configs missing');
+                }
+            }
+
+            if (! isset($this->configs[$table])) {
+                throw new ProgrammingError('Config for table "%s" missing', $table);
+            }
+
+            $config = $this->configs[$table];
+            if ($config instanceof Config) {
+                if (! $config->getConfigObject()->getKeyColumn()) {
+                    throw new ProgrammingError(
+                        'INI repositories require their data source to provide a valid key column'
+                    );
+                }
+            } elseif (is_array($config)) {
+                if (! isset($config['path'])) {
+                    throw new ProgrammingError('Path to config for table "%s" missing', $table);
+                }
+                if (! isset($config['keyColumn'])) {
+                    throw new ProgrammingError(
+                        'INI repositories require their data source to provide a valid key column'
+                    );
+                }
+
+                $newConfig = isset($config['module'])
+                    ? Config::module($config['module'], $config['path'])
+                    : Config::app($config['path']);
+                $newConfig->getConfigObject()->setKeyColumn($config['keyColumn']);
+                $this->configs[$table] = $config = $newConfig;
+            } else {
+                throw new ProgrammingError(
+                    'Config for table "%s" is a %s, expected either Icinga\Application\Config or an associative array',
+                    $table,
+                    is_object($config) ? get_class($config) : gettype($config)
+                );
+            }
+
+            return $config;
+        } else {
+            return parent::getDataSource($table);
+        }
     }
 
     /**
@@ -101,6 +155,15 @@ abstract class IniRepository extends Repository implements Extensible, Updatable
     }
 
     /**
+     * Overwrite this in your INI repository implementation in case you need to initialize the configs lazily
+     *
+     * @return array
+     */
+    protected function initializeConfigs()
+    {
+    }
+
+    /**
      * Run a trigger for the given table and row which is about to be inserted
      *
      * @param   string          $table



More information about the icinga-checkins mailing list