Commit 2b087e85 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Extraction d'un nouveau helper TableHelper. Refactorisations.

parent 161de3f3
Loading
Loading
Loading
Loading
+17 −87
Changes for src/UnicaenDbImport/CodeGenerator/CodeGenerator.php: 17 added lines, 87 removed lines.
Original line number Diff line number Diff line
@@ -5,15 +5,13 @@ namespace UnicaenDbImport\CodeGenerator;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use UnicaenApp\Exception\RuntimeException;
use UnicaenApp\Util;
use UnicaenDbImport\CodeGenerator\Helper\DiffViewHelper;
use UnicaenDbImport\CodeGenerator\Helper\SynchroLogHelper;
use UnicaenDbImport\CodeGenerator\Helper\TableHelper;
use UnicaenDbImport\CodeGenerator\Helper\TableValidationHelper;
use UnicaenDbImport\Domain\DestinationInterface;
use UnicaenDbImport\Domain\Operation;
use UnicaenDbImport\Domain\ResultInterface;
use UnicaenDbImport\Domain\SourceInterface;
use UnicaenDbImport\Domain\Synchro;

/**
 * Classe mère des générateurs de code SQL, quelque soit la plateforme de base de données.
@@ -27,6 +25,11 @@ abstract class CodeGenerator implements CodeGeneratorInterface
     */
    protected $platform;

    /**
     * @var TableHelper
     */
    protected $tableHelper;

    /**
     * @var TableValidationHelper
     */
@@ -131,9 +134,8 @@ abstract class CodeGenerator implements CodeGeneratorInterface
        }

        $sourceTable = $source->getTable();
        $sql = "SELECT * FROM " . $sourceTable;

        return $sql;
        return $this->tableHelper->generateSQLForSelectFromTable($sourceTable);
    }

    /**
@@ -148,36 +150,17 @@ abstract class CodeGenerator implements CodeGeneratorInterface
        $sourceCodeColumn = $source->getSourceCodeColumn();
        $columns = $source->getColumns();

        $commaSeparatedColumnNames = implode(', ', array_merge([$sourceCodeColumn], $columns));

        $sqlTemplate = <<<'EOT'
create table {intermediateTable} as select {commaSeparatedColumnNames} from {destinationTable};
delete from {intermediateTable};
EOT;
        $sql = Util::tokenReplacedString($sqlTemplate, compact('intermediateTable', 'destinationTable', 'commaSeparatedColumnNames'));

        return $sql;
        return $this->tableHelper->generateSQLForIntermediateTableCreation($destinationTable, $sourceCodeColumn, $columns, $intermediateTable);
    }

    /**
     * @param string $tableName
     * @param array  $columnsValues
     * @return string
     */
    public function generateSQLForInsertIntoTable($tableName, array $columnsValues)
    {
        $platform = $this->platform;

        $commaSeparatedColumnNames = implode(', ', array_keys($columnsValues));
        $commaSeparatedColumnValues = implode(', ', array_map(function ($value) use ($platform) {
            if ($value === null) {
                return 'NULL';
            }

            return $platform->quoteStringLiteral($value);
        }, $columnsValues));

        $sqlTemplate = <<<'EOT'
insert into {tableName} ({commaSeparatedColumnNames}) values ({commaSeparatedColumnValues});
EOT;
        $sql = Util::tokenReplacedString($sqlTemplate, compact('tableName', 'commaSeparatedColumnNames', 'commaSeparatedColumnValues'));

        return $sql;
        return $this->tableHelper->generateSQLForInsertIntoTable($tableName, $columnsValues);
    }

    /**
@@ -193,10 +176,11 @@ EOT;

    /**
     * @return string
     * @codeCoverageIgnore
     */
    public function generateSQLForSynchroLogTableCreation()
    {
        throw CodeGeneratorException::methodToImplement(__METHOD__, get_called_class(), $this->platform);
        return $this->synchroLogHelper->generateSQLForSynchroLogTableCreation();
    }

    /**
@@ -226,24 +210,6 @@ EOT;
        return $this->diffViewHelper->generateSQLForCreation($diffSourceTableName, $destinationTable, $sourceCodeColumn, $columns);
    }

    /**
     * @param string $hash
     * @return string
     * @codeCoverageIgnore
     */
    public function generateSQLForFetchingSynchroLogTable($hash)
    {
        $tableName = Synchro::SYNCHRO_LOG_TABLE_NAME;

        $sql = '';
        $sql .= 'SELECT operation, source_code, table_name, field_name, from_value, to_value, created_on ';
        $sql .= "FROM $tableName ";
        $sql .= "WHERE import_hash = '$hash' ";
        $sql .= 'ORDER BY operation, table_name, field_name ;';

        return $sql;
    }

    /**
     * @param SourceInterface      $source
     * @param DestinationInterface $destination
@@ -273,43 +239,7 @@ EOT;
        $sourceCodeColumn = $source->getSourceCodeColumn();
        $columns = $source->getColumns();

        // réorganisation par type d'opération
        $data = [];
        foreach ($rows as $row) {
            $operation = $row['operation'];
            if (!isset($data[$operation])) {
                $data[$operation] = [];
            }
            $data[$operation][] = $row;
        };

        $sqls = [];

        // une instruction SQL (update ou insert) par type d'opération suffira à mettre à jour la table destination
        $operations = array_keys($data);
        foreach ($operations as $operation) {
            switch ($operation) {
                case Operation::OPERATION_INSERT:
                    $sqls[] = $this->diffViewHelper->generateSQLForInsertOperationInDestinationTable($destinationTable, $sourceCodeColumn, $columns) . ';' . PHP_EOL;
                    break;
                case Operation::OPERATION_UPDATE:
                    $sqls[] = $this->diffViewHelper->generateSQLForUpdateOperationInDestinationTable($destinationTable, $sourceCodeColumn, $columns) . ';' . PHP_EOL;
                    break;
                case Operation::OPERATION_UNDELETE:
                    $sqls[] = $this->diffViewHelper->generateSQLForUndeleteOperationInDestinationTable($destinationTable, $sourceCodeColumn, $columns) . ';' . PHP_EOL;
                    break;
                case Operation::OPERATION_DELETE:
                    $sqls[] = $this->diffViewHelper->generateSQLForDeleteOperationInDestinationTable($destinationTable, $sourceCodeColumn, $columns) . ';' . PHP_EOL;
                    break;
                default:
                    throw new RuntimeException("Opération inconnue rencontrée : " . $operation);
                    break;
            }
        }

        $sql = empty($sqls) ? '' : implode(PHP_EOL, $sqls);

        return $sql;
        return $this->diffViewHelper->generateSQLForOperationInDestinationTableFromDiffViewRequestResult($rows, $destinationTable, $sourceCodeColumn, $columns);
    }

    /**
+6 −6
Changes for src/UnicaenDbImport/CodeGenerator/CodeGeneratorInterface.php: 6 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ namespace UnicaenDbImport\CodeGenerator;
use Doctrine\DBAL\DBALException;
use UnicaenApp\Exception\RuntimeException;
use UnicaenDbImport\Domain\DestinationInterface;
use UnicaenDbImport\Domain\ResultInterface;
use UnicaenDbImport\Domain\SourceInterface;

/**
@@ -88,12 +89,6 @@ interface CodeGeneratorInterface
     */
    public function generateSQLForIntermmediateTableDrop($tableName);

    /**
     * @param string $hash
     * @return string
     */
    public function generateSQLForFetchingSynchroLogTable($hash);

    /**
     * @param string $tableName
     * @return string
@@ -127,4 +122,9 @@ interface CodeGeneratorInterface
        SourceInterface $source,
        DestinationInterface $destination);

    /**
     * @param ResultInterface $result
     * @return string
     */
    public function generateSQLForInsertResultIntoSynchroLog(ResultInterface $result);
}
 No newline at end of file
+51 −4
Changes for src/UnicaenDbImport/CodeGenerator/Helper/DiffViewHelper.php: 51 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
namespace UnicaenDbImport\CodeGenerator\Helper;

use Doctrine\DBAL\DBALException;
use UnicaenApp\Exception\RuntimeException;
use UnicaenDbImport\CodeGenerator\Helper;
use UnicaenDbImport\Domain\Operation;

@@ -186,13 +187,59 @@ EOT;
        return $sql;
    }

    /**
     * @param array    $rows
     * @param string   $destinationTable
     * @param string   $sourceCodeColumn
     * @param string[] $columns
     * @return string
     */
    public function generateSQLForOperationInDestinationTableFromDiffViewRequestResult(array $rows, $destinationTable, $sourceCodeColumn, $columns)
    {
        // réorganisation par type d'opération
        $data = [];
        foreach ($rows as $row) {
            $operation = $row['operation'];
            if (!isset($data[$operation])) {
                $data[$operation] = [];
            }
            $data[$operation][] = $row;
        };

        $sqls = [];

        // une instruction SQL (update ou insert) par type d'opération suffira à mettre à jour la table destination
        $operations = array_keys($data);
        foreach ($operations as $operation) {
            switch ($operation) {
                case Operation::OPERATION_INSERT:
                    $sqls[] = $this->generateSQLForInsertOperationInDestinationTable($destinationTable, $sourceCodeColumn, $columns) . ';' . PHP_EOL;
                    break;
                case Operation::OPERATION_UPDATE:
                    $sqls[] = $this->generateSQLForUpdateOperationInDestinationTable($destinationTable, $sourceCodeColumn, $columns) . ';' . PHP_EOL;
                    break;
                case Operation::OPERATION_UNDELETE:
                    $sqls[] = $this->generateSQLForUndeleteOperationInDestinationTable($destinationTable, $sourceCodeColumn, $columns) . ';' . PHP_EOL;
                    break;
                case Operation::OPERATION_DELETE:
                    $sqls[] = $this->generateSQLForDeleteOperationInDestinationTable($destinationTable, $sourceCodeColumn, $columns) . ';' . PHP_EOL;
                    break;
                default:
                    throw new RuntimeException("Opération inconnue rencontrée : " . $operation);
                    break;
            }
        }

        return empty($sqls) ? '' : implode(PHP_EOL, $sqls);
    }

    /**
     * @param string $destinationTable
     * @param string $sourceCodeColumn
     * @param array  $columns
     * @return string
     */
    public function generateSQLForInsertOperationInDestinationTable($destinationTable, $sourceCodeColumn, array $columns)
    protected function generateSQLForInsertOperationInDestinationTable($destinationTable, $sourceCodeColumn, array $columns)
    {
        $diffViewName = $this->generateViewName($destinationTable);

@@ -220,7 +267,7 @@ EOT;
     * @param array $columns
     * @return string
     */
    abstract public function generateSQLForUpdateOperationInDestinationTable($destinationTable, $sourceCodeColumn, array $columns);
    abstract protected function generateSQLForUpdateOperationInDestinationTable($destinationTable, $sourceCodeColumn, array $columns);

    /**
     * @param string $destinationTable
@@ -228,7 +275,7 @@ EOT;
     * @param array $columns
     * @return string
     */
    abstract public function generateSQLForUndeleteOperationInDestinationTable($destinationTable, $sourceCodeColumn, array $columns);
    abstract protected function generateSQLForUndeleteOperationInDestinationTable($destinationTable, $sourceCodeColumn, array $columns);

    /**
     * @param string $destinationTable
@@ -236,5 +283,5 @@ EOT;
     * @param array $columns
     * @return string
     */
    abstract public function generateSQLForDeleteOperationInDestinationTable($destinationTable, $sourceCodeColumn, array $columns);
    abstract protected function generateSQLForDeleteOperationInDestinationTable($destinationTable, $sourceCodeColumn, array $columns);
}
 No newline at end of file
+74 −0
Changes for src/UnicaenDbImport/CodeGenerator/Helper/TableHelper.php: 74 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace UnicaenDbImport\CodeGenerator\Helper;

use UnicaenApp\Util;
use UnicaenDbImport\CodeGenerator\Helper;

/**
 * Génération de code SQL autour des tables.
 *
 * Version commune à toutes les plateformes de bases de données.
 *
 * @author Unicaen
 */
abstract class TableHelper extends Helper
{
    /**
     * @param string $tableName
     * @return string
     */
    public function generateSQLForSelectFromTable($tableName)
    {
        return "SELECT * FROM " . $tableName;
    }

    /**
     * @param string   $destinationTable
     * @param string   $sourceCodeColumn
     * @param string[] $columns
     * @param string   $intermediateTable
     * @return string
     */
    public function generateSQLForIntermediateTableCreation($destinationTable, $sourceCodeColumn, $columns, $intermediateTable)
    {
        $commaSeparatedColumnNames = implode(', ', array_merge([$sourceCodeColumn], $columns));

        $sqlTemplate = <<<'EOT'
create table {intermediateTable} as select {commaSeparatedColumnNames} from {destinationTable};
delete from {intermediateTable};
EOT;
        return Util::tokenReplacedString($sqlTemplate, compact('intermediateTable', 'destinationTable', 'commaSeparatedColumnNames'));
    }

    /**
     * @param string $tableName
     * @param array  $columnsValues
     * @return string
     */
    public function generateSQLForInsertIntoTable($tableName, array $columnsValues)
    {
        $platform = $this->platform;

        $formatter = function ($value) use ($platform) {
            return $value === null ? 'NULL' : $platform->quoteStringLiteral($value);
        };

        $commaSeparatedColumnNames = implode(', ', array_keys($columnsValues));
        $commaSeparatedColumnValues = implode(', ', array_map($formatter, $columnsValues));

        $sqlTemplate = <<<'EOT'
insert into {tableName} ({commaSeparatedColumnNames}) values ({commaSeparatedColumnValues});
EOT;
        return Util::tokenReplacedString($sqlTemplate, compact('tableName', 'commaSeparatedColumnNames', 'commaSeparatedColumnValues'));
    }

    /**
     * @param string $tableName
     * @return string
     */
    public function generateSQLForTruncateTable($tableName)
    {
        return $this->platform->getTruncateTableSQL($tableName);
    }
}
 No newline at end of file
+23 −10
Changes for src/UnicaenDbImport/CodeGenerator/PostgreSQL/CodeGenerator.php: 23 added lines, 10 removed lines.
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use UnicaenDbImport\CodeGenerator\PostgreSQL\Helper\DiffViewHelper as PostgreSQLDiffViewHelper;
use UnicaenDbImport\CodeGenerator\PostgreSQL\Helper\SynchroLogHelper as PostgreSQLSynchroLogHelper;
use UnicaenDbImport\CodeGenerator\PostgreSQL\Helper\TableValidationHelper as PostgreSQLTableValidationHelper;
use UnicaenDbImport\CodeGenerator\PostgreSQL\Helper\TableHelper as PostgreSQLTableHelper;

/**
 * Version PostgreSQL.
@@ -20,6 +21,26 @@ class CodeGenerator extends \UnicaenDbImport\CodeGenerator\CodeGenerator
     */
    protected $platform;

    /**
     * @var PostgreSQLTableHelper
     */
    protected $tableHelper;

    /**
     * @var PostgreSQLTableValidationHelper
     */
    protected $tableValidationHelper;

    /**
     * @var PostgreSQLDiffViewHelper
     */
    protected $diffViewHelper;

    /**
     * @var PostgreSQLSynchroLogHelper
     */
    protected $synchroLogHelper;

    /**
     * CodeGenerator constructor.
     *
@@ -29,20 +50,12 @@ class CodeGenerator extends \UnicaenDbImport\CodeGenerator\CodeGenerator
    {
        parent::__construct($platform);

        $this->tableHelper = new PostgreSQLTableHelper($this->platform);
        $this->tableValidationHelper = new PostgreSQLTableValidationHelper($this->platform);
        $this->diffViewHelper = new PostgreSQLDiffViewHelper($this->platform);
        $this->synchroLogHelper = new PostgreSQLSynchroLogHelper($this->platform);
    }

    /**
     * @return string
     * @codeCoverageIgnore
     */
    public function generateSQLForSynchroLogTableCreation()
    {
        return $this->synchroLogHelper->generateSQLForSynchroLogTableCreation();
    }

    /**
     * @param string $tableName
     * @return string
@@ -50,6 +63,6 @@ class CodeGenerator extends \UnicaenDbImport\CodeGenerator\CodeGenerator
     */
    public function generateSQLForIntermmediateTableDrop($tableName)
    {
        return "DROP TABLE IF EXISTS $tableName CASCADE";
        return "DROP TABLE IF EXISTS $tableName CASCADE ;";
    }
}
 No newline at end of file
Loading