Provide `DbMigration` hook & register when bootstrapping

This commit is contained in:
Yonas Habteab 2023-08-02 18:27:55 +02:00 committed by Johannes Meyer
parent bc3c444cf5
commit 15792fb59a
6 changed files with 93 additions and 4 deletions

View File

@ -6,6 +6,7 @@ namespace Icinga\Application;
use DirectoryIterator;
use ErrorException;
use Exception;
use Icinga\Application\ProvidedHook\DbMigration;
use ipl\I18n\GettextTranslator;
use ipl\I18n\StaticTranslator;
use LogicException;
@ -731,4 +732,16 @@ abstract class ApplicationBootstrap
$localedir = $this->getLocaleDir();
return $localedir !== false && file_exists($localedir) && is_dir($localedir);
}
/**
* Register all hooks provided by the main application
*
* @return $this
*/
protected function registerApplicationHooks(): self
{
Hook::register('migration', DbMigration::class, DbMigration::class);
return $this;
}
}

View File

@ -48,7 +48,8 @@ class Cli extends ApplicationBootstrap
->setupModuleManager()
->setupUserBackendFactory()
->loadSetupModuleIfNecessary()
->setupFakeAuthentication();
->setupFakeAuthentication()
->registerApplicationHooks();
}
/**

View File

@ -75,7 +75,8 @@ class EmbeddedWeb extends ApplicationBootstrap
->setupTimezone()
->prepareFakeInternationalization()
->setupModuleManager()
->loadEnabledModules();
->loadEnabledModules()
->registerApplicationHooks();
}
/**

View File

@ -0,0 +1,73 @@
<?php
/* Icinga Web 2 | (c) 2023 Icinga GmbH | GPLv2+ */
namespace Icinga\Application\ProvidedHook;
use Icinga\Application\Hook\MigrationHook;
use Icinga\Common\Database;
use Icinga\Model\Schema;
use ipl\Orm\Query;
use ipl\Stdlib\Filter;
class DbMigration extends MigrationHook
{
use Database;
public function getName(): string
{
return $this->translate('Icinga Web 2');
}
public function providedDescriptions(): array
{
return [];
}
public function getVersion(): string
{
if ($this->version === null) {
$conn = $this->getDb();
$schemaQuery = Schema::on($conn)
->orderBy('id', SORT_DESC)
->limit(2);
if (static::getColumnType($conn, $schemaQuery->getModel()->getTableName(), 'success')) {
/** @var Schema $schema */
foreach ($schemaQuery as $schema) {
if ($schema->success) {
$this->version = $schema->version;
}
}
if (! $this->version) {
$this->version = '2.12.0';
}
} elseif (static::tableExists($conn, $schemaQuery->getModel()->getTableName())) {
$this->version = '2.11.0';
} elseif (static::tableExists($conn, 'icingaweb_rememberme')) {
$randomIvType = static::getColumnType($conn, 'icingaweb_rememberme', 'random_iv');
if ($randomIvType === 'varchar(32)') {
$this->version = '2.9.1';
} else {
$this->version = '2.9.0';
}
} else {
$usernameType = static::getColumnType($conn, 'icingaweb_group_membership', 'username');
if ($usernameType === 'varchar(254)') {
$this->version = '2.5.0';
} else {
$this->version = '2.0.0';
}
}
}
return $this->version;
}
protected function getSchemaQueryFor(string $version): Query
{
return Schema::on($this->getDb())
->filter(Filter::equal('version', $version));
}
}

View File

@ -104,7 +104,8 @@ class Web extends EmbeddedWeb
->setupUser()
->setupTimezone()
->setupInternationalization()
->setupFatalErrorHandling();
->setupFatalErrorHandling()
->registerApplicationHooks();
}
/**

View File

@ -22,7 +22,7 @@ trait Database
*
* @throws \Icinga\Exception\ConfigurationError
*/
protected function getDb()
protected function getDb(): Connection
{
if (! $this->hasDb()) {
throw new LogicException('Please check if a db instance exists at all');