IniRepository: improve initialization of per-table datasources

refs #13034
This commit is contained in:
Alexander A. Klimov 2016-11-03 18:05:05 +01:00
parent 38602379be
commit bd7851d15c

View File

@ -25,17 +25,22 @@ use Icinga\Exception\StatementException;
abstract class IniRepository extends Repository implements Extensible, Updatable, Reducible abstract class IniRepository extends Repository implements Extensible, Updatable, Reducible
{ {
/** /**
* Per-table datasources * Per-table configs
* *
* Example:
* <code> * <code>
* array( * array(
* $table => $datasource * 'event-type' => array(
* 'module' => 'elasticsearch',
* 'path' => 'event-types',
* 'keyColumn' => 'name'
* )
* ) * )
* </code> * </code>
* *
* @var Config[] * @var array
*/ */
protected $datasources = array(); protected $configs = null;
/** /**
* The tables for which triggers are available when inserting, updating or deleting rows * 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 * 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 * @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(). 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'); 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) 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);
}
} }
/** /**
@ -100,6 +154,15 @@ abstract class IniRepository extends Repository implements Extensible, Updatable
return array(); return array();
} }
/**
* 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 * Run a trigger for the given table and row which is about to be inserted
* *