Skip to content

Commit

Permalink
Add capability to dump SQL Views
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremynikolic committed Jan 18, 2023
1 parent e387c38 commit 9dbdd08
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 22 deletions.
40 changes: 36 additions & 4 deletions src/DumpProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception as DbalException;
use Doctrine\DBAL\Schema\View;
use Safe\Exceptions\JsonException;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -31,8 +32,12 @@ class DumpProcess
*
* @throws JsonException|DbalException
*/
public function __construct($dsn, string $config, OutputInterface $dumpOutput, ConsoleOutput $consoleOutput = null)
{
public function __construct(
$dsn,
string $config,
OutputInterface $dumpOutput,
ConsoleOutput $consoleOutput = null,
) {
$this->dumpOutput = $dumpOutput;
$this->config = new Settings(json_decode(file_get_contents($config)));

Expand Down Expand Up @@ -62,6 +67,14 @@ public function run(): void
);
$dumper->dumpConfiguration();

$this->dumpTables($dumper);
$this->dumpViews($dumper);

$dumper->dumpResetConfiguration();
}

private function dumpTables(Dumper $dumper): void
{
$db = $this->db;

$platform = $db->getDatabasePlatform();
Expand All @@ -77,14 +90,33 @@ public function run(): void
}

// Dump the schema of the table.
$dumper->dumpSchema($tableName, $db);
$dumper->dumpTableSchema($tableName, $db);

// Dump data for the table if allowed
if ($table->withData()) {
$dumper->dumpData($tableName, $table, $db);
}
}
}

$dumper->dumpResetConfiguration();
private function dumpViews(Dumper $dumper): void
{
$db = $this->db;
$schemaManager = $db->createSchemaManager();

$views = $schemaManager->listViews();

foreach ($views as $viewName => $view) {
/**
* @var View $view
*/
$viewSettings = $this->config->findView($viewName);

if ($viewSettings === null) {
continue;
}

$dumper->dumpViewSchema($view);
}
}
}
48 changes: 38 additions & 10 deletions src/Dumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\PDO\Connection as PdoConnection;
use Doctrine\DBAL\Exception as DbalException;
use Doctrine\DBAL\Schema\View;
use PDO;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;
Expand Down Expand Up @@ -96,8 +97,10 @@ public function dumpResetConfiguration(): void
*
* @throws DbalException
*/
public function dumpSchema(string $table, Connection $db): void
{
public function dumpTableSchema(
string $table,
Connection $db,
): void {
$this->dumpNewLine("-- BEGIN STRUCTURE `$table`");
$this->dumpNewLine("DROP TABLE IF EXISTS `$table`;");
$this->dumpNewLine('/*!40101 SET @saved_cs_client = @@character_set_client */;');
Expand All @@ -108,15 +111,33 @@ public function dumpSchema(string $table, Connection $db): void
$this->dumpNewLine($tableCreationCommand . ';');
$this->dumpNewLine();

$this->showDumpingSchemaProgress($table);
}

public function dumpViewSchema(View $view): void
{
$this->dumpNewLine("-- BEGIN STRUCTURE `{$view->getName()}`");
$this->dumpNewLine("DROP VIEW IF EXISTS `{$view->getName()}`;");
$this->dumpNewLine('/*!40101 SET @saved_cs_client = @@character_set_client */;');
$this->dumpNewLine('SET character_set_client = utf8mb4;');

$this->dumpNewLine("CREATE VIEW `{$view->getName()}` AS {$view->getSql()}" . ';');
$this->dumpNewLine();
$this->showDumpingSchemaProgress($view->getName());
}

private function showDumpingSchemaProgress(string $schema): void
{
$progress = $this->createProgressBar(1);
$progress->setFormat("Dumping schema <fg=cyan>$table</>: <fg=yellow>%percent:3s%%</>");
$progress->setFormat("Dumping schema <fg=cyan>$schema</>: <fg=yellow>%percent:3s%%</>");
$progress->setOverwrite(true);
$progress->setRedrawFrequency(1);
$progress->start();
$progress->setFormat("Dumping schema <fg=green>$table</>: <fg=green>%percent:3s%%</> Took: %elapsed%");
$progress->setFormat("Dumping schema <fg=green>$schema</>: <fg=green>%percent:3s%%</> Took: %elapsed%");
$progress->finish();
if ($this->consoleOutput instanceof ConsoleOutput) {
$this->consoleOutput->getErrorOutput()->writeln(''); // write a newline after the progressbar.
$this->consoleOutput->getErrorOutput()
->writeln(''); // write a newline after the progressbar.
}
}

Expand All @@ -125,8 +146,11 @@ public function dumpSchema(string $table, Connection $db): void
*
* @throws DbalException
*/
public function dumpData(string $table, Table $tableSettings, Connection $db): void
{
public function dumpData(
string $table,
Table $tableSettings,
Connection $db,
): void {
$cols = $this->getColumnsForTable($table, $db);

$selectQuery = 'SELECT ';
Expand Down Expand Up @@ -155,7 +179,9 @@ public function dumpData(string $table, Table $tableSettings, Connection $db): v
}

$progress = $this->createProgressBar($numRows);
$progress->setFormat("Dumping data <fg=cyan>$table</>: <fg=yellow>%percent:3s%%</> %remaining% / %estimated%");
$progress->setFormat(
"Dumping data <fg=cyan>$table</>: <fg=yellow>%percent:3s%%</> %remaining% / %estimated%"
);
$progress->setRedrawFrequency(max($numRows / 100, 1));
$progress->start();

Expand Down Expand Up @@ -215,8 +241,10 @@ public function dumpData(string $table, Table $tableSettings, Connection $db): v
*
* @throws DbalException
*/
protected function getColumnsForTable(string $table, Connection $db): array
{
protected function getColumnsForTable(
string $table,
Connection $db,
): array {
$columns = [];
foreach ($db->fetchAllAssociative("SHOW COLUMNS FROM `$table`") as $row) {
$columns[$row['Field']] = $row['Type'];
Expand Down
28 changes: 22 additions & 6 deletions src/Settings/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,31 @@ public function __construct(stdClass $settings)
*/
public function getTable(string $table): Table
{
$configTables = $this->settings;
try {
return new Table($this->findInSettings($table));
} catch (InvalidArgumentException) {
throw new InvalidArgumentException("The table [$table] does not exist in config.");
}
}

foreach ($configTables as $name => $config) {
$pattern = str_replace(['*', '?'], ['(.*)', '.'], $name);
if (preg_match("/^$pattern$/i", $table)) {
return new Table($config);
public function getView(string $view): View
{
try {
return new View($this->findInSettings($view));
} catch (InvalidArgumentException) {
throw new InvalidArgumentException("The view [$view] does not exist in config.");
}
}

private function findInSettings(string $search): stdClass
{
foreach ($this->settings as $name => $config) {
$pattern = str_replace([ '*', '?' ], [ '(.*)', '.' ], $name);
if (preg_match("/^$pattern$/i", $search)) {
return $config;
}
}

throw new InvalidArgumentException("The table [$table] does not exist in config.");
throw new InvalidArgumentException("[$search] does not exist in config.");
}
}
15 changes: 13 additions & 2 deletions src/Settings/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,21 @@ public function getDatabase(): Database
return new Database($this->settings->database);
}

public function findTable(string $table): ?Table
public function findTable(string $table): Table|null
{
try {
return $this->getDatabase()->getTable($table);
return $this->getDatabase()
->getTable($table);
} catch (InvalidArgumentException $exception) {
return null;
}
}

public function findView(string $view): View|null
{
try {
return $this->getDatabase()
->getView(($view));
} catch (InvalidArgumentException $exception) {
return null;
}
Expand Down
19 changes: 19 additions & 0 deletions src/Settings/View.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Worksome\Foggy\Settings;

use stdClass;

/**
* The container for all of the settings for a view.
* None at the moment
*/
class View
{
protected stdClass $settings;

public function __construct(stdClass $settings)
{
$this->settings = $settings;
}
}

0 comments on commit 9dbdd08

Please sign in to comment.