Skip to content

Commit

Permalink
Migration: Views unterstützen (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
gharlan authored Mar 20, 2022
1 parent 96710b7 commit 32d7f3c
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 9 deletions.
46 changes: 40 additions & 6 deletions lib/command/diff.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
*/
private function handleSchema(array $tables, rex_ydeploy_diff_file $diff): void
{
$charsets = rex_sql::factory()->getArray('
$sql = rex_sql::factory();

$charsets = $sql->getArray('
SELECT T.TABLE_NAME table_name, CCSA.CHARACTER_SET_NAME charset, CCSA.COLLATION_NAME collation
FROM INFORMATION_SCHEMA.TABLES T
INNER JOIN INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY AS CCSA ON CCSA.COLLATION_NAME = T.TABLE_COLLATION
Expand All @@ -74,14 +76,22 @@ private function handleSchema(array $tables, rex_ydeploy_diff_file $diff): void

$charsets = array_column($charsets, null, 'table_name');

$this->addSchemaDiff($diff, $tables, $charsets);
$this->createSchema($tables, $charsets);
$views = [];
foreach ($sql->getViews(rex::getTablePrefix()) as $view) {
$sql->setQuery('SHOW CREATE VIEW '.$sql->escapeIdentifier($view));
$query = (string) $sql->getValue('Create View');
$query = substr($query, strpos($query, ' AS ') + 4);
$views[$view] = $query;
}

$this->addSchemaDiff($diff, $tables, $charsets, $views);
$this->createSchema($tables, $charsets, $views);
}

/**
* @param rex_sql_table[] $tables
*/
private function createSchema(array $tables, array $charsets): void
private function createSchema(array $tables, array $charsets, array $views): void
{
$schema = [];

Expand Down Expand Up @@ -119,20 +129,32 @@ private function createSchema(array $tables, array $charsets): void
}
}

rex_file::putConfig($this->addon->getDataPath('schema.yml'), $schema);
$schema = ['tables' => $schema];

if ($views) {
$schema['views'] = $views;
}

rex_file::putConfig($this->addon->getDataPath('schema.yml'), $schema, 4);
}

/**
* @param rex_sql_table[] $tables
*/
private function addSchemaDiff(rex_ydeploy_diff_file $diff, array $tables, array $charsets): void
private function addSchemaDiff(rex_ydeploy_diff_file $diff, array $tables, array $charsets, array $views): void
{
$schema = rex_file::getConfig($this->addon->getDataPath('schema.yml'));

if (!$schema) {
return;
}

$schemaViews = [];
if (isset($schema['tables'])) {
$schemaViews = $schema['views'] ?? [];
$schema = $schema['tables'];
}

foreach ($tables as $table) {
$tableName = $table->getName();

Expand Down Expand Up @@ -263,6 +285,18 @@ private function addSchemaDiff(rex_ydeploy_diff_file $diff, array $tables, array
foreach ($schema as $tableName => $table) {
$diff->dropTable($tableName);
}

foreach ($views as $viewName => $query) {
if (!isset($schemaViews[$viewName]) || $schemaViews[$viewName] !== $query) {
$diff->ensureView($viewName, $query);
}

unset($schemaViews[$viewName]);
}

foreach ($schemaViews as $viewName => $_) {
$diff->dropView($viewName);
}
}

private function columnEqualsSchema(rex_sql_column $column, array $schema): bool
Expand Down
49 changes: 46 additions & 3 deletions lib/diff_file.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ final class rex_ydeploy_diff_file
/** @var list<string> */
private $drop = [];

/** @var array<string, string> */
private $views = [];

/** @var list<string> */
private $dropViews = [];

/** @var array<string, array{ensure?: list<array<?scalar>>, remove?: list<array<string, int|string>>}> */
private $fixtures = [];

Expand Down Expand Up @@ -85,6 +91,16 @@ public function removeForeignKey(string $tableName, string $foreignKeyName): voi
$this->alter[$tableName]['removeForeignKey'][] = $foreignKeyName;
}

public function ensureView(string $viewName, string $query): void
{
$this->views[$viewName] = $query;
}

public function dropView(string $viewName): void
{
$this->dropViews[] = $viewName;
}

/** @param array<?scalar> $data */
public function ensureFixture(string $tableName, array $data): void
{
Expand All @@ -99,14 +115,16 @@ public function removeFixture(string $tableName, array $key): void

public function isEmpty(): bool
{
return !$this->create && !$this->alter && !$this->drop && !$this->fixtures;
return !$this->create && !$this->alter && !$this->drop && !$this->views && !$this->dropViews && !$this->fixtures;
}

public function getContent(): string
{
$changes = $this->addCreateTables();
$changes = $this->addDropViews();
$changes .= $this->addCreateTables();
$changes .= $this->addAlterTables();
$changes .= $this->addDropTables();
$changes .= $this->addEnsureViews();
$changes .= $this->addFixtures();
$changes = ltrim($changes);

Expand Down Expand Up @@ -326,10 +344,35 @@ private function addDropTables(): string
return $content;
}

private function addFixtures(): string
private function addEnsureViews(): string
{
$content = '';
$sql = rex_sql::factory();

foreach ($this->views as $viewName => $query) {
$statement = 'CREATE OR REPLACE VIEW '.$sql->escapeIdentifier($viewName)." AS\n".$query;
$content .= "\n\n \$sql->setQuery(".$this->nowdoc($statement).');';
}

return $content;
}

private function addDropViews(): string
{
$content = '';
$sql = rex_sql::factory();

foreach ($this->dropViews as $viewName) {
$statement = 'DROP VIEW IF EXISTS '.$sql->escapeIdentifier($viewName);
$content .= "\n\n \$sql->setQuery(".$this->nowdoc($statement).');';
}

return $content;
}

private function addFixtures(): string
{
$content = '';
$sql = rex_sql::factory();

foreach ($this->fixtures as $tableName => $changes) {
Expand Down

0 comments on commit 32d7f3c

Please sign in to comment.