Skip to content
Snippets Groups Projects
Commit 18dd60ce authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

[FIX] Le générateur SQL de la destination était utilisé aussi pour interroger...

[FIX] Le générateur SQL de la destination était utilisé aussi pour interroger la source, désormais la source a le sien propre.
parent e64c2b24
Branches
Tags
No related merge requests found
Pipeline #34998 passed
......@@ -4,6 +4,7 @@ Changelog
7.2.0
-----
- Suppression de la dépendance avec unicaen/app, et avec laminas/laminas-dependency-plugin.
- [FIX] Le générateur SQL de la destination était utilisé aussi pour interroger la source, désormais la source a le sien propre.
7.1.0
-----
......
......@@ -17,7 +17,8 @@ abstract class AbstractDatabaseService
{
protected CodeGeneratorPluginManager $codeGeneratorPluginManager;
protected array $codeGeneratorsConfig;
protected CodeGenerator $codeGenerator;
protected CodeGenerator $codeGeneratorForSource;
protected CodeGenerator $codeGeneratorForDestination;
/** @var CodeGenerator[] */
protected array $cachedCodeGenerators = [];
......@@ -46,6 +47,8 @@ abstract class AbstractDatabaseService
public function setSource(SourceInterface $source): void
{
$this->source = $source;
$this->initCodeGeneratorFromSource();
}
public function setDestination(DestinationInterface $destination): void
......@@ -55,10 +58,28 @@ abstract class AbstractDatabaseService
$this->initCodeGeneratorFromDestination();
}
/**
* Détermine, selon la plateforme de bdd source, le générateur de code SQL à utiliser.
*
* @throws \UnicaenDbImport\Service\Exception\DatabaseServiceException
*/
public function initCodeGeneratorFromSource(): CodeGenerator
{
try {
$platformClass = get_class($this->source->getConnection()->getDatabasePlatform());
} catch (Exception $e) {
throw DatabaseServiceException::error(
"Impossible de déterminer la plateforme de la base de données source", $e);
}
$this->codeGeneratorForSource = $this->initCodeGeneratorForPlatform($platformClass);
return $this->codeGeneratorForSource;
}
/**
* Détermine, selon la plateforme de bdd destination, le générateur de code SQL à utiliser.
*
* @return CodeGenerator
* @throws \UnicaenDbImport\Service\Exception\DatabaseServiceException
*/
public function initCodeGeneratorFromDestination(): CodeGenerator
......@@ -70,6 +91,13 @@ abstract class AbstractDatabaseService
"Impossible de déterminer la plateforme de la base de données destination", $e);
}
$this->codeGeneratorForDestination = $this->initCodeGeneratorForPlatform($platformClass);
return $this->codeGeneratorForDestination;
}
protected function initCodeGeneratorForPlatform(string $platformClass): CodeGenerator
{
if (! isset($this->cachedCodeGenerators[$platformClass])) {
try {
Assertion::keyExists($this->codeGeneratorsConfig, $platformClass);
......@@ -84,23 +112,21 @@ abstract class AbstractDatabaseService
$this->cachedCodeGenerators[$platformClass] = $codeGenerator;
}
$this->codeGenerator = $this->cachedCodeGenerators[$platformClass];
return $this->codeGenerator;
return $this->cachedCodeGenerators[$platformClass];
}
/**
* @throws \UnicaenDbImport\Service\Exception\DatabaseServiceException
*/
protected function assertTableExists(string $tableName, Connection $connection, ?string $message = null)
protected function assertTableExistsInDestination(string $tableName, ?string $message = null): void
{
$sql = $this->codeGenerator->generateSQLForTableExistenceCheck($tableName);
$sql = $this->codeGeneratorForDestination->generateSQLForTableExistenceCheck($tableName);
try {
$result = $this->queryExecutor->fetchAll($sql, $connection);
$result = $this->queryExecutor->fetchAll($sql, $this->destination->getConnection());
} catch (Exception $e) {
throw DatabaseServiceException::error("Erreur lors du test d'existence de la table '$tableName'", $e);
}
$exists = $this->codeGenerator->convertTableExistenceCheckResultToBoolean($result);
$exists = $this->codeGeneratorForDestination->convertTableExistenceCheckResultToBoolean($result);
if (!$exists) {
throw DatabaseServiceException::error(sprintf(
$message ?: "La table '%s' nécessaire au fonctionnement est introuvable dans la base destination. ",
......
......@@ -28,17 +28,17 @@ class DatabaseService extends AbstractDatabaseService
$sourceCodeColumn = $this->destination->getSourceCodeColumn();
// test if table exists
$this->assertTableExists($table, $connection, "La table destination '%s' est introuvable. ");
$this->assertTableExistsInDestination($table, "La table destination '%s' est introuvable. ");
// id column validation
$columnCount = 0;
$sql = $this->codeGenerator->generateSQLForIdColumnValidationInTable($table, $columnCount);
$sql = $this->codeGeneratorForDestination->generateSQLForIdColumnValidationInTable($table, $columnCount);
try {
$result = $this->queryExecutor->fetchAll($sql, $connection);
} catch (Exception $e) {
throw DatabaseServiceException::error("Erreur lors de la validation de la colonne id dans la table destination '$table'", $e);
}
$exception = $this->codeGenerator->convertIdColumnValidationBadResultToException($table, $result, $columnCount);
$exception = $this->codeGeneratorForDestination->convertIdColumnValidationBadResultToException($table, $result, $columnCount);
if ($exception !== null) {
throw DatabaseServiceException::error("La table '$table' n'est pas une table de destination valide. ", $exception);
}
......@@ -46,13 +46,13 @@ class DatabaseService extends AbstractDatabaseService
if ($this->destination->getIdColumnStrategy() === DestinationInterface::ID_STRATEGY_SEQUENCE) {
// existence de la sequence pour la colonne id
$idColumnSequence = $this->destination->getIdColumnSequence();
$sql = $this->codeGenerator->generateSQLForSequenceExistenceCheck($table, $idColumnSequence);
$sql = $this->codeGeneratorForDestination->generateSQLForSequenceExistenceCheck($table, $idColumnSequence);
try {
$result = $this->queryExecutor->fetchAll($sql, $connection);
} catch (Exception $e) {
throw DatabaseServiceException::error("Erreur lors du test d'existence de la séquence dans la table destination '$table'", $e);
}
$exception = $this->codeGenerator->convertSequenceExistenceCheckResultToException($idColumnSequence, $result);
$exception = $this->codeGeneratorForDestination->convertSequenceExistenceCheckResultToException($idColumnSequence, $result);
if ($exception !== null) {
throw DatabaseServiceException::error("La sequence '$idColumnSequence' est introuvable. ", $exception);
}
......@@ -60,26 +60,26 @@ class DatabaseService extends AbstractDatabaseService
// histo columns validation
$columnCount = 0;
$sql = $this->codeGenerator->generateSQLForHistoColumnsValidationInTable($table, $columnCount);
$sql = $this->codeGeneratorForDestination->generateSQLForHistoColumnsValidationInTable($table, $columnCount);
try {
$result = $this->queryExecutor->fetchAll($sql, $connection);
} catch (Exception $e) {
throw DatabaseServiceException::error("Erreur lors de la validation des colonne d'historique dans la table destination '$table'", $e);
}
$exception = $this->codeGenerator->convertHistoColumnsValidationBadResultToException($table, $result, $columnCount);
$exception = $this->codeGeneratorForDestination->convertHistoColumnsValidationBadResultToException($table, $result, $columnCount);
if ($exception !== null) {
throw DatabaseServiceException::error("La table '$table' n'est pas une table de destination valide. ", $exception);
}
// source columns validation
$columnCount = 0;
$sql = $this->codeGenerator->generateSQLForSourceColumnsValidationInTable($table, $sourceCodeColumn, $columnCount);
$sql = $this->codeGeneratorForDestination->generateSQLForSourceColumnsValidationInTable($table, $sourceCodeColumn, $columnCount);
try {
$result = $this->queryExecutor->fetchAll($sql, $connection);
} catch (Exception $e) {
throw DatabaseServiceException::error("Erreur lors de la validation des colonne de source dans la table destination '$table'", $e);
}
$exception = $this->codeGenerator->convertSourceColumnsValidationBadResultToException($table, $sourceCodeColumn, $result, $columnCount);
$exception = $this->codeGeneratorForDestination->convertSourceColumnsValidationBadResultToException($table, $sourceCodeColumn, $result, $columnCount);
if ($exception !== null) {
throw DatabaseServiceException::error("La table '$table' n'est pas une table de destination valide. ", $exception);
}
......@@ -95,16 +95,18 @@ class DatabaseService extends AbstractDatabaseService
*/
public function validateSourceTable()
{
$connection = $this->destination->getConnection();
$tableName = self::SOURCE_TABLE_NAME;
// test if table exists
$this->assertTableExists($tableName, $connection);
$this->assertTableExistsInDestination($tableName);
}
/**
* Vérifie dans la table SOURCE qu'il existe bien une source ayant le 'code' spécifié.
*
* ATTENTION : on parle bien ici de la table nommée `SOURCE` qui doit exister dans la base de données destination,
* et non pas de la table contenant les données sources de l'import/synchro.
*
* @throws \UnicaenDbImport\Service\Exception\DatabaseServiceException
*/
public function validateCodeExistsInSourceTable(string $code)
......@@ -114,13 +116,13 @@ class DatabaseService extends AbstractDatabaseService
$column = self::SOURCE_TABLE_CODE_COLUMN;
// test if value exists in table
$sql = $this->codeGenerator->generateSQLForValueExistenceCheckInTable($column, $code, $tableName);
$sql = $this->codeGeneratorForDestination->generateSQLForValueExistenceCheckInTable($column, $code, $tableName);
try {
$result = $this->queryExecutor->fetchAll($sql, $connection);
} catch (Exception $e) {
throw DatabaseServiceException::error("Erreur lors du test d'existence de la valeur '$code' dans la table '$tableName'", $e);
}
$exists = $this->codeGenerator->convertValueExistenceCheckInTableResultToBoolean($result);
$exists = $this->codeGeneratorForDestination->convertValueExistenceCheckInTableResultToBoolean($result);
if (!$exists) {
throw DatabaseServiceException::error("Vous devez déclarer une source dans la table '$tableName' dont le $column est '$code'.");
}
......@@ -132,7 +134,7 @@ class DatabaseService extends AbstractDatabaseService
public function checkIntermediateTableNotExists(string $intermediateTable)
{
try {
$this->assertTableExists($intermediateTable, $this->destination->getConnection());
$this->assertTableExistsInDestination($intermediateTable);
} catch (DatabaseServiceException $e) {
// :-) la table n'existe pas
return;
......@@ -149,7 +151,7 @@ class DatabaseService extends AbstractDatabaseService
*/
public function createIntermediateTable($intermediateTable)
{
$sql = $this->codeGenerator->generateSQLForIntermediateTableCreation($this->source, $this->destination, $intermediateTable);
$sql = $this->codeGeneratorForDestination->generateSQLForIntermediateTableCreation($this->source, $this->destination, $intermediateTable);
try {
$this->queryExecutor->exec($sql, $this->destination->getConnection());
} catch (Exception $e) {
......@@ -162,7 +164,7 @@ class DatabaseService extends AbstractDatabaseService
*/
public function dropIntermediateTable($intermediateTable)
{
$sql = $this->codeGenerator->generateSQLForIntermmediateTableDrop($intermediateTable);
$sql = $this->codeGeneratorForDestination->generateSQLForIntermmediateTableDrop($intermediateTable);
try {
$this->queryExecutor->exec($sql, $this->destination->getConnection());
} catch (Exception $e) {
......@@ -192,7 +194,7 @@ class DatabaseService extends AbstractDatabaseService
);
}
$sql = $this->codeGenerator->generateSQLForClearTable($table);
$sql = $this->codeGeneratorForDestination->generateSQLForClearTable($table);
$sql .= " WHERE source_id = (SELECT id FROM source WHERE code = '$sourceId')";
try {
$this->queryExecutor->exec($sql, $this->destination->getConnection());
......@@ -250,7 +252,7 @@ class DatabaseService extends AbstractDatabaseService
$preparedRow = $this->prepareSourceDataRow($row);
$columnsValues = $this->prepareDestinationData($preparedRow);
$insertsSQL = $this->codeGenerator->generateSQLForInsertOneRowIntoTable($tableName, $columnsValues, $sourceCode, $idColumnStrategy, $idColumnSequence);
$insertsSQL = $this->codeGeneratorForDestination->generateSQLForInsertOneRowIntoTable($tableName, $columnsValues, $sourceCode, $idColumnStrategy, $idColumnSequence);
try {
$n = $this->queryExecutor->exec($insertsSQL, $this->destination->getConnection());
} catch (Exception $e) {
......@@ -372,10 +374,10 @@ class DatabaseService extends AbstractDatabaseService
public function recreateDiffView(?string $intermediateTable = null): void
{
$destinationTable = $this->destination->getTable();
$diffViewName = $this->codeGenerator->generateDiffViewName($destinationTable);
$diffViewName = $this->codeGeneratorForDestination->generateDiffViewName($destinationTable);
try {
$sql = $this->codeGenerator->generateSQLForDiffViewCreation($this->source, $this->destination, $diffViewName, $intermediateTable);
$sql = $this->codeGeneratorForDestination->generateSQLForDiffViewCreation($this->source, $this->destination, $diffViewName, $intermediateTable);
} catch (Exception $e) {
throw DatabaseServiceException::error("Erreur lors de la génération du SQL de création de la vue différentielle '$diffViewName'", $e);
}
......@@ -392,7 +394,7 @@ class DatabaseService extends AbstractDatabaseService
*/
public function fetchDiffView(): array
{
$sql = $this->codeGenerator->generateSQLForDiffViewSelect($this->source, $this->destination);
$sql = $this->codeGeneratorForDestination->generateSQLForDiffViewSelect($this->source, $this->destination);
try {
return $this->queryExecutor->fetchAll($sql, $this->destination->getConnection());
......@@ -406,7 +408,7 @@ class DatabaseService extends AbstractDatabaseService
*/
public function fetchDiffViewFound(): bool
{
$sql = $this->codeGenerator->generateSQLForDiffViewSelect($this->source, $this->destination);
$sql = $this->codeGeneratorForDestination->generateSQLForDiffViewSelect($this->source, $this->destination);
$sql = 'select count(*) as found from (' . $sql . ' limit 1) tmp';
try {
......@@ -424,7 +426,7 @@ class DatabaseService extends AbstractDatabaseService
*/
public function fetchDiffViewCount(): int
{
$sql = $this->codeGenerator->generateSQLForDiffViewSelect($this->source, $this->destination);
$sql = $this->codeGeneratorForDestination->generateSQLForDiffViewSelect($this->source, $this->destination);
$sql = 'select count(*) as nb from (' . $sql . ') tmp';
try {
......@@ -453,7 +455,7 @@ class DatabaseService extends AbstractDatabaseService
// ->andWhere("io.enabled = 1")
// ->addOrderBy('io.operation, io.tableName, io.columnName');
// $importObservRows = $qb->getQuery()->getResult(Query::HYDRATE_ARRAY);
$sql = $this->codeGenerator->generateSQLForSelectingInImportObservTable($this->destination->getTable());
$sql = $this->codeGeneratorForDestination->generateSQLForSelectingInImportObservTable($this->destination->getTable());
try {
$importObservRows = $this->queryExecutor->fetchAll($sql, $this->destination->getConnection());
} catch (Exception $e) {
......@@ -461,7 +463,7 @@ class DatabaseService extends AbstractDatabaseService
}
if (!empty($importObservRows)) {
$sql = $this->codeGenerator->generateSQLForInsertionIntoImportObservResult($this->destination, $importObservRows);
$sql = $this->codeGeneratorForDestination->generateSQLForInsertionIntoImportObservResult($this->destination, $importObservRows);
try {
$this->queryExecutor->exec($sql, $this->destination->getConnection());
} catch (Exception $e) {
......@@ -505,7 +507,7 @@ class DatabaseService extends AbstractDatabaseService
$sqls = [];
foreach (Operation::OPERATIONS as $operation) {
$sqls[$operation] =
$this->codeGenerator->generateSQLForDestinationUpdate($operation, $this->source, $this->destination);
$this->codeGeneratorForDestination->generateSQLForDestinationUpdate($operation, $this->source, $this->destination);
}
return $sqls;
......@@ -519,7 +521,7 @@ class DatabaseService extends AbstractDatabaseService
*/
public function fetchSource(): array
{
$selectSql = $this->codeGenerator->generateSQLForSelectFromSource($this->source);
$selectSql = $this->codeGeneratorForSource->generateSQLForSelectFromSource($this->source);
try {
return $this->queryExecutor->fetchAll($selectSql, $this->source->getConnection());
......@@ -536,7 +538,7 @@ class DatabaseService extends AbstractDatabaseService
*/
public function fetchSourceFirstRow(): ?array
{
$selectSql = $this->codeGenerator->generateSQLForSelectFromSource($this->source);
$selectSql = $this->codeGeneratorForSource->generateSQLForSelectFromSource($this->source);
try {
return $this->queryExecutor->fetch($selectSql, $this->source->getConnection());
......@@ -551,7 +553,7 @@ class DatabaseService extends AbstractDatabaseService
public function fetchSourceTableColumnNames(): array
{
$sourceTableName = $this->source->getTable();
$selectSql = $this->codeGenerator->generateSQLForSelectSourceTableColumnsInformation($sourceTableName);
$selectSql = $this->codeGeneratorForSource->generateSQLForSelectSourceTableColumnsInformation($sourceTableName);
try {
$result = $this->queryExecutor->fetchAll($selectSql, $this->source->getConnection());
......
......@@ -17,14 +17,14 @@ class ImportLogDatabaseService extends AbstractDatabaseService
$importLogTable = $this->destination->getLogTable();
try {
$this->assertTableExists($importLogTable, $connection);
$this->assertTableExistsInDestination($importLogTable);
return;
} catch (DatabaseServiceException $e) {
// la table n'existe pas
}
// create table
$sql = $this->codeGenerator->generateSQLForImportLogTableCreation($this->destination->getLogTable());
$sql = $this->codeGeneratorForDestination->generateSQLForImportLogTableCreation($this->destination->getLogTable());
try {
$this->queryExecutor->exec($sql, $connection);
} catch (Exception $e) {
......@@ -40,7 +40,7 @@ class ImportLogDatabaseService extends AbstractDatabaseService
{
$importLogTable = $this->destination->getLogTable();
$sql = $this->codeGenerator->generateSQLForInsertResultIntoLogTable($result, $importLogTable);
$sql = $this->codeGeneratorForDestination->generateSQLForInsertResultIntoLogTable($result, $importLogTable);
try {
$this->queryExecutor->exec($sql, $this->destination->getConnection());
} catch (Exception $e) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment