Commit 90d4ae4d authored by Laurent Lécluse's avatar Laurent Lécluse
Browse files

Possibilité de définir plusieurs champs autres que SOURCE_CODE et ANNEE_ID...

Possibilité de définir plusieurs champs autres que SOURCE_CODE et ANNEE_ID pour définir la clé de correspondance entre vues sources et tables.
Possibilité de fournir les ID directement dans la vue source et de ne plus utiliser SOURCE_CODE dans certains cas avancés
parent 3ec9a878
CHANGELOG
=========
3.1.0 (29/01/2020)
------------------
Possibilité de définir plusieurs champs autres que SOURCE_CODE et ANNEE_ID pour définir la clé de correspondance entre vues sources et tables.
Possibilité de fournir les ID directement dans la vue source et de ne plus utiliser SOURCE_CODE dans certains cas avancés
3.0.2 (16/06/2020)
------------------
Prise en compte des associations (clés étrangères) pour pouvoir retrouver le nom de la colonne
......@@ -80,7 +80,6 @@ FROM
LEFT JOIN user_tab_cols stc ON stc.table_name = 'SRC_' || tc.table_name AND stc.column_name = tc.column_name
WHERE
tc.column_name not like 'HISTO_%'
AND tc.column_name <> 'ID'
AND tc.table_name <> 'SYNC_LOG'
ORDER BY
it.ordre, tc.table_name, tc.column_id;
......
......@@ -61,6 +61,12 @@ class Table
*/
protected $syncHookAfter = null;
/**
* @var bool
* @ORM\Column(name="SYNC_NON_IMPORTABLES", type="boolean", nullable=false)
*/
protected $syncNonImportables = false;
/**
......@@ -255,4 +261,28 @@ class Table
return $this;
}
/**
* @return bool
*/
public function getSyncNonImportables(): bool
{
return $this->syncNonImportables;
}
/**
* @param bool $syncNonImportables
*
* @return Table
*/
public function setSyncNonImportables(bool $syncNonImportables): Table
{
$this->syncNonImportables = $syncNonImportables;
return $this;
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ namespace UnicaenImport\Service\Factory;
use UnicaenImport\Options\ModuleOptions;
use UnicaenImport\Service\QueryGeneratorService;
use UnicaenImport\Service\SchemaService;
use UnicaenImport\Service\TableService;
use Interop\Container\ContainerInterface;
......@@ -27,6 +28,7 @@ class QueryGeneratorServiceFactory
{
$service = new QueryGeneratorService();
$service->setServiceSchema( $container->get(SchemaService::class));
$service->setServiceTable( $container->get(TableService::class));
$service->setOptionsModule($container->get(ModuleOptions::class));
return $service;
......
......@@ -9,6 +9,7 @@ use UnicaenImport\Exception\Exception;
use UnicaenImport\Entity\Differentiel\Query;
use UnicaenImport\Options\Traits\ModuleOptionsAwareTrait;
use UnicaenImport\Service\Traits\SchemaServiceAwareTrait;
use UnicaenImport\Service\Traits\TableServiceAwareTrait;
/**
*
......@@ -18,6 +19,7 @@ use UnicaenImport\Service\Traits\SchemaServiceAwareTrait;
class QueryGeneratorService extends AbstractService
{
use SchemaServiceAwareTrait;
use TableServiceAwareTrait;
use ModuleOptionsAwareTrait;
const AUTOGEN_PACKAGE_NAME = 'UNICAEN_IMPORT_AUTOGEN_PROCS__';
......@@ -429,17 +431,25 @@ class QueryGeneratorService extends AbstractService
{
// Pour l'annualisation :
$schema = $this->getServiceSchema()->getSchema($tableName);
$joinCond = 'S.source_code = D.source_code';
$table = $this->getServiceTable()->get($tableName);
$sourceCodeCol = 'SOURCE_CODE';
if ($this->getServiceSchema()->hasColumn('SRC_'.$tableName, 'ID')){
$sourceCodeCol = 'ID';
}
$joinCond = "S.$sourceCodeCol = D.$sourceCodeCol";
$delCond = '';
$depJoin = '';
foreach ($schema as $columnName => $column) {
if ($column->isKey){
$joinCond .= ' AND S.' . $columnName . ' = d.' . $columnName;
if ('ID' != $sourceCodeCol) {
foreach ($schema as $columnName => $column) {
if ($column->isKey) {
$joinCond .= ' AND S.' . $columnName . ' = d.' . $columnName;
}
}
}
if (array_key_exists(self::ANNEE_COLUMN_NAME, $schema)) {
// Si la table courante est annualisée ...
if ($this->getServiceSchema()->hasColumn('V_DIFF_' . $tableName, self::ANNEE_COLUMN_NAME)) {
if ('ID' != $sourceCodeCol && $this->getServiceSchema()->hasColumn('V_DIFF_' . $tableName, self::ANNEE_COLUMN_NAME)) {
// ... et que la source est également annualisée alors concordance nécessaire
$joinCond .= ' AND S.' . self::ANNEE_COLUMN_NAME . ' = d.' . self::ANNEE_COLUMN_NAME;
}
......@@ -476,42 +486,44 @@ class QueryGeneratorService extends AbstractService
$sql = "CREATE OR REPLACE FORCE VIEW V_DIFF_$tableName AS
select diff.* from (SELECT
D.id id,
COALESCE( S.source_id, D.source_id ) source_id,
COALESCE( S.source_code, D.source_code ) source_code,
CASE
CASE
WHEN S.source_code IS NOT NULL AND D.source_code IS NULL THEN 'insert'
WHEN S.source_code IS NOT NULL AND D.source_code IS NOT NULL AND (D.histo_destruction IS NULL OR D.histo_destruction > SYSDATE) THEN 'update'
WHEN S.source_code IS NULL AND D.source_code IS NOT NULL AND (D.histo_destruction IS NULL OR D.histo_destruction > SYSDATE)$delCond THEN 'delete'
WHEN S.source_code IS NOT NULL AND D.source_code IS NOT NULL AND D.histo_destruction IS NOT NULL AND D.histo_destruction <= SYSDATE THEN 'undelete' END import_action,
" . $this->formatColQuery($cols, function (Column $col) {
if ($col->dataType == 'CLOB') {
return ' CASE WHEN S.source_code IS NULL AND D.source_code IS NOT NULL THEN D.:column ELSE to_clob(S.:column) END :column';
return 'CASE WHEN S.source_code IS NULL AND D.source_code IS NOT NULL THEN D.:column ELSE to_clob(S.:column) END :column';
} else {
return ' CASE WHEN S.source_code IS NULL AND D.source_code IS NOT NULL THEN D.:column ELSE S.:column END :column';
return 'CASE WHEN S.source_code IS NULL AND D.source_code IS NOT NULL THEN D.:column ELSE S.:column END :column';
}
}, ",\n ") . ",
" . $this->formatColQuery($cols, function (Column $col) {
if ($col->dataType == 'CLOB') {
return ' CASE WHEN dbms_lob.compare(D.:column,S.:column) <> 0 OR (D.:column IS NULL AND S.:column IS NOT NULL) OR (D.:column IS NOT NULL AND S.:column IS NULL) THEN 1 ELSE 0 END U_:column';
return 'CASE WHEN dbms_lob.compare(D.:column,S.:column) <> 0 OR (D.:column IS NULL AND S.:column IS NOT NULL) OR (D.:column IS NOT NULL AND S.:column IS NULL) THEN 1 ELSE 0 END U_:column';
} else {
return ' CASE WHEN D.:column <> S.:column OR (D.:column IS NULL AND S.:column IS NOT NULL) OR (D.:column IS NOT NULL AND S.:column IS NULL) THEN 1 ELSE 0 END U_:column';
return 'CASE WHEN D.:column <> S.:column OR (D.:column IS NULL AND S.:column IS NOT NULL) OR (D.:column IS NOT NULL AND S.:column IS NULL) THEN 1 ELSE 0 END U_:column';
}
}, ",\n ") . "
FROM
$tableName D$depJoin
FULL JOIN SRC_$tableName S ON S.source_id = D.source_id AND $joinCond
FULL JOIN SRC_$tableName S ON $joinCond
WHERE
(S.source_code IS NOT NULL AND D.source_code IS NOT NULL AND D.histo_destruction IS NOT NULL AND D.histo_destruction <= SYSDATE)
OR (S.source_code IS NULL AND D.source_code IS NOT NULL AND (D.histo_destruction IS NULL OR D.histo_destruction > SYSDATE))
OR (S.source_code IS NOT NULL AND D.source_code IS NULL)
OR " . $this->formatColQuery($cols, function (Column $col) {
(S.source_code IS NOT NULL AND D.source_code IS NOT NULL AND D.histo_destruction IS NOT NULL AND D.histo_destruction <= SYSDATE)
OR (S.source_code IS NULL AND D.source_code IS NOT NULL AND (D.histo_destruction IS NULL OR D.histo_destruction > SYSDATE))
OR (S.source_code IS NOT NULL AND D.source_code IS NULL)
OR " . $this->formatColQuery($cols, function (Column $col) {
if ($col->dataType == 'CLOB') {
return 'dbms_lob.compare(D.:column,S.:column) <> 0 OR (D.:column IS NULL AND S.:column IS NOT NULL) OR (D.:column IS NOT NULL AND S.:column IS NULL)';
} else {
return 'D.:column <> S.:column OR (D.:column IS NULL AND S.:column IS NOT NULL) OR (D.:column IS NOT NULL AND S.:column IS NULL)';
}
}, "\n OR ") . "
) diff JOIN source on source.id = diff.source_id WHERE import_action IS NOT NULL AND source.importable = 1";
) diff JOIN source on source.id = diff.source_id WHERE import_action IS NOT NULL";
if (!$table->getSyncNonImportables()) {
$sql .= " AND source.importable = 1";
}
return $sql;
}
......@@ -567,9 +579,9 @@ WHERE
CASE diff_row.import_action
WHEN 'insert' THEN
INSERT INTO $tableName
( id, " . $this->formatColQuery($cols) . ", source_id, source_code, histo_createur_id, histo_modificateur_id )
( id, " . $this->formatColQuery($cols) . ", source_code, histo_createur_id, histo_modificateur_id )
VALUES
( COALESCE(diff_row.id,$tableName" . "_ID_SEQ.NEXTVAL), " . $this->formatColQuery($cols, 'diff_row.:column') . ", diff_row.source_id, diff_row.source_code, unicaen_import.get_current_user, unicaen_import.get_current_user );
( COALESCE(diff_row.id,$tableName" . "_ID_SEQ.NEXTVAL), " . $this->formatColQuery($cols, 'diff_row.:column') . ", diff_row.source_code, unicaen_import.get_current_user, unicaen_import.get_current_user );
WHEN 'update' THEN
" . $this->formatColQuery(
......
......@@ -50,7 +50,7 @@ class SchemaService extends AbstractService
/**
* @return Column[][]
*/
public function makeSchema()
private function makeSchema()
{
$sql = 'SELECT * FROM V_IMPORT_TAB_COLS';
$d = $this->query($sql, []);
......@@ -200,7 +200,7 @@ class SchemaService extends AbstractService
WHERE
utc.COLUMN_NAME NOT IN ('ID')
AND utc.COLUMN_NAME NOT LIKE 'HISTO_%'
AND utc.COLUMN_NAME NOT LIKE 'SOURCE_%'
AND utc.COLUMN_NAME <> 'SOURCE_CODE'
AND utc.table_name = :tableName
ORDER BY
utc.COLUMN_NAME";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment