Commit dbf67d72 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Import : le SOURCE_ID peut être fourni dans les données à importer ou en dur...

Import : le SOURCE_ID peut être fourni dans les données à importer ou en dur dans la config via l'attribut 'code' de la 'source' ; les insertions sont désormais réalisées 1 enregistrement à la fois
parent 64ad6e7b
Loading
Loading
Loading
Loading
+6 −13
Original line number Diff line number Diff line
@@ -257,24 +257,17 @@ abstract class CodeGenerator implements CodeGeneratorInterface

    /**
     * @param string $tableName
     * @param array $columnsValues
     * @param string $sourceCode
     * @param array $row
     * @param string|null $sourceCode
     * @param string|null|false $idColumnSequence
     * @return string
     */
    public function generateSQLForInsertIntoTable(
        string $tableName,
        array $columnsValues,
        string $sourceCode,
    public function generateSQLForInsertOneRowIntoTable(string $tableName,
                                                  array  $row,
                                                  string $sourceCode = null,
                                                         $idColumnSequence = null): string
    {
        $insertsSQL = '';
        foreach ($columnsValues as $row) {
            $sql = $this->tableHelper->generateSQLForInsertIntoTable($tableName, $row, $sourceCode, $idColumnSequence);
            $insertsSQL .= $sql . PHP_EOL;
        }

        return $insertsSQL;
        return $this->tableHelper->generateSQLForInsertOneRowIntoTable($tableName, $row, $sourceCode, $idColumnSequence);
    }

    /**
+5 −6
Original line number Diff line number Diff line
@@ -78,15 +78,14 @@ interface CodeGeneratorInterface

    /**
     * @param string $tableName
     * @param array $columnsValues
     * @param string $sourceCode
     * @param array $row
     * @param string|null $sourceCode
     * @param string|null|false $idColumnSequence
     * @return string
     */
    public function generateSQLForInsertIntoTable(
        string $tableName,
        array $columnsValues,
        string $sourceCode,
    public function generateSQLForInsertOneRowIntoTable(string $tableName,
                                                        array  $row,
                                                        string $sourceCode = null,
                                                               $idColumnSequence = null): string;

    /**
+0 −24
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@
namespace UnicaenDbImport\CodeGenerator;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use UnicaenApp\Exception\RuntimeException;
use UnicaenDbImport\Config\ConfigAwareTrait;

/**
@@ -39,29 +38,6 @@ abstract class Helper
        throw CodeGeneratorException::methodToImplement(__METHOD__, get_called_class(), $this->platform);
    }

    /**
     * @param $value
     * @return string
     */
    protected function formatValueForInsert($value): string
    {
        if ($value === null) {
            return 'NULL';
        }

        if ($value instanceof \stdClass) {
            if (isset($value->date)) {
                $tz = isset($value->timezone) ? new \DateTimeZone($value->timezone) : NULL;
                $d = date_create($value->date, $tz);
                $value = $d->format('c');
            } else {
                throw new RuntimeException("Type de valeur inattendu!");
            }
        }

        return $this->platform->quoteStringLiteral($value);
    }

    /**
     * @param int $length
     * @param string $string
+73 −24
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

namespace UnicaenDbImport\CodeGenerator\Helper;

use UnicaenApp\Exception\RuntimeException;
use UnicaenDbImport\CodeGenerator\Helper;
use UnicaenDbImport\Domain\Operation;
use UnicaenDbImport\Domain\Synchro;
@@ -245,20 +246,20 @@ EOT;

    /**
     * @param string $destinationTable
     * @param array $columnsValues
     * @param string $sourceCode
     * @param array $row ['COLONNE_EN_MAJUSCULE' => value, ...]
     * @param string|null $sourceCode
     * @param string|null|false $idColumnSequence
     * @return string
     */
    public function generateSQLForInsertIntoTable(
    public function generateSQLForInsertOneRowIntoTable(
        string $destinationTable,
        array $columnsValues,
        string $sourceCode,
        array  $row,
        string $sourceCode = null,
               $idColumnSequence = null): string
    {
        $now = $this->platform->getNowExpression();

        $columnsValues = array_map([$this, 'formatValueForInsert'], $columnsValues);
        $row = array_map([$this, 'formatValueForInsert'], $row);

        $useSequenceForId = true;
        if ($idColumnSequence === false) {
@@ -266,38 +267,51 @@ EOT;
            // auto-incrémentable pour que l'INSERT fonctionne.
            $useSequenceForId = false;
            // les éventuels ids sources sont écartés
            unset($columnsValues['id']);
            unset($columnsValues['ID']);
            unset($row['id']);
            unset($row['ID']);
        } elseif ($idColumnSequence === null) {
            // si aucun nom de séquence n'a été fourni, on tente celui par défaut.
            $idColumnSequence = $this->generateSQLForIdSequenceDefaultName($destinationTable);
        }

        if ($useSequenceForId) {
            // les éventuels id d'origine sont écrasés
            unset($columnsValues['id']);
            unset($columnsValues['ID']);
            unset($row['id']);
            unset($row['ID']);
            $idExpr = $this->generateSQLForSequenceNextVal($idColumnSequence);
            $columnsValues['id'] = $idExpr;
            $row['id'] = $idExpr;
        }

        $createdOnCol = $this->config->getHistoColumnAliasForCreatedOn();
        $createdByCol = $this->config->getHistoColumnAliasForCreatedBy();
        $createdByValue = $this->config->getHistoColumnValueForCreatedBy();

        // génération des noms de colonnes de la table destination pour l'INSERT.
        $destinationColumns = array_keys($columnsValues);
        array_unshift($destinationColumns,
        $destinationColumns = array_keys($row);

        $columnsToAdd = [
            $createdOnCol,
            $createdByCol,
            'source_id',
        );
        // génération de la liste des valeurs à INSERTer.
        $selectExpressions = $columnsValues;
        array_unshift($selectExpressions,
        ];
        $valuesToAdd = [
            $now,
            $createdByValue !== null ? $createdByValue : 'NULL',
            's.id',
        );
        ];
        if ($sourceCode !== null) {
            // si le code de la Source est fourni dans la config, on l'utilise
            $sourceCode = $this->platform->quoteStringLiteral($sourceCode);
            $columnsToAdd[] = 'source_id';
            $valuesToAdd[] = 's.id';
        } else {
            // si la Source n'est pas fournie (par son 'code'), elle est présente dans les données (colonne 'SOURCE_ID')
            $sourceCode = $row['SOURCE_ID'];
            $row['SOURCE_ID'] = 's.id';
        }

        // génération des noms de colonnes de la table destination pour l'INSERT.
        array_unshift($destinationColumns, ...$columnsToAdd);
        // génération de la liste des valeurs à INSERTer.
        $selectExpressions = $row;
        array_unshift($selectExpressions, ...$valuesToAdd);

        $commaSeparatedColumnNames = implode(', ', $destinationColumns);
        $commaSeparatedColumnValues = implode(', ', $selectExpressions);
@@ -306,7 +320,7 @@ EOT;
INSERT INTO $destinationTable ($commaSeparatedColumnNames)
SELECT $commaSeparatedColumnValues
FROM source s
WHERE s.code = '$sourceCode';
WHERE s.code = $sourceCode;
EOT;
    }

@@ -348,7 +362,6 @@ EOT;
            $createdOnCol,
            $createdByCol,
            $sourceCodeColumn,
            'source_id',
        );
        if ($useSequenceForId) {
            array_unshift($destinationColumns,
@@ -364,7 +377,6 @@ EOT;
            $now,
            $createdByValue !== null ? $createdByValue : 'NULL',
            $sourceCodeColumn,
            'source_id'
        );
        if ($useSequenceForId) {
            $idExpr = $this->generateSQLForSequenceNextVal($idColumnSequence);
@@ -443,6 +455,43 @@ EOT;
        return $setters;
    }

    /**
     * @param $value
     * @return string
     */
    protected function formatValueForInsert($value): string
    {
        if ($value === null) {
            return 'NULL';
        }

        if ($value instanceof \stdClass) {
            if (isset($value->date)) {
                $tz = isset($value->timezone) ? new \DateTimeZone($value->timezone) : NULL;
                $d = date_create($value->date, $tz);

                return $this->formatDateTimeForInsert($d);
            } else {
                throw new RuntimeException("Type de valeur inattendu!");
            }
        }

        return $this->platform->quoteStringLiteral($value);
    }

    /**
     * Formate un DateTime pour pouvoir l'utiliser dans un INSERT.
     *
     * @param \DateTime $value
     * @return string
     */
    protected function formatDateTimeForInsert(\DateTime $value): string
    {
        $value = $value->format('c');

        return $this->platform->quoteStringLiteral($value);
    }

    /**
     * @param string $tableName
     * @return string
+0 −16
Original line number Diff line number Diff line
@@ -24,22 +24,6 @@ class CodeGenerator extends \UnicaenDbImport\CodeGenerator\CodeGenerator
        $this->platform = new OraclePlatform();
    }

    /**
     * @inheritDoc
     */
    public function generateSQLForInsertIntoTable(
        string $tableName,
        array $columnsValues,
        string $sourceCode,
        $idColumnSequence = null): string
    {
        // les ; séparant les INSERTs perturbent le driver Oracle donc on met tout dans un bloc BEGIN END et miracle...
        return
            'BEGIN ' . PHP_EOL .
            parent::generateSQLForInsertIntoTable($tableName, $columnsValues, $sourceCode, $idColumnSequence) .
            'END;';
    }

    /**
     * @inheritDoc
     */
Loading