Loading src/UnicaenImport/Service/QueryGeneratorService.php +31 −126 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ class QueryGeneratorService extends AbstractService use SchemaServiceAwareTrait; use ModuleOptionsAwareTrait; const AUTOGEN_PACKAGE_NAME = 'UNICAEN_IMPORT_AUTOGEN_PROCS__'; const AG_BEGIN = '-- AUTOMATIC GENERATION --'; const AG_END = '-- END OF AUTOMATIC GENERATION --'; const ANNEE_COLUMN_NAME = 'ANNEE_ID'; Loading Loading @@ -100,7 +101,7 @@ class QueryGeneratorService extends AbstractService throw new Exception('Vous devez être authentifié pour réaliser cette action'); } $userId = $this->escape($currentUser->getId()); $procName = $this->escapeKW('MAJ_' . $query->getTableName()); $tableName = $this->escape($query->getTableName()); $conditions = $query->toSql(Query::SQL_PARTIAL); if (!empty($conditions)) { $conditions = $this->escape($conditions); Loading @@ -114,7 +115,7 @@ class QueryGeneratorService extends AbstractService $ignoreFields = $this->escape(implode(',', $ignoreFields)); } $sql = "BEGIN " . $this->getPackage() . ".SET_CURRENT_USER($userId);" . $this->getPackage() . ".$procName($conditions,$ignoreFields); END;"; $sql = "BEGIN " . $this->getPackage() . ".SET_CURRENT_USER($userId);" . $this->getPackage() . ".SYNCHRONISATION($tableName,$conditions,$ignoreFields); END;"; try { $this->getEntityManager()->getConnection()->exec($sql); } catch (DBALException $e) { Loading @@ -133,34 +134,15 @@ class QueryGeneratorService extends AbstractService * * @return string[] */ public function syncTable($query) public function syncTable(Query $query) { $currentUser = $this->getDbUser(); if (empty($currentUser)) { throw new Exception('Vous devez être authentifié pour réaliser cette action'); } $userId = $this->escape($currentUser->getId()); $errors = []; $lastLogId = $this->getLastLogId(); $partial = $query->toSql($query::SQL_PARTIAL); if ($partial) { $partial = $this::escape($partial); } else { $partial = ''; } $sql = "BEGIN " . $this->getPackage() . ".SET_CURRENT_USER($userId);" . $this->getPackage() . "." . $this::escapeKW('MAJ_' . $query->getTableName()) . "(" . $partial . ");" . " END;"; try { $this->getEntityManager()->getConnection()->exec($sql); $this->execMaj($query); } catch (DBALException $e) { $errors[] = Exception::duringMajException($e, $query->getTableName())->getMessage(); $errors[] = $e->getMessage(); } $errors = $errors + $this->getLogMessages($lastLogId); Loading Loading @@ -230,39 +212,6 @@ class QueryGeneratorService extends AbstractService /** * Retourne les identifiants des données concernés * * @param string $tableName * @param string|string[]|null $sourceCode * @param integer|null $anneeId * * @return integer[]|null */ public function getIdFromSourceCode($tableName, $sourceCode, $anneeId = null) { if (empty($sourceCode)) return null; $sql = 'SELECT ID FROM ' . $this->escapeKW($tableName) . ' WHERE SOURCE_CODE IN (:sourceCode)'; if ($anneeId) { $sql .= ' AND ANNEE_ID = ' . (string)(int)$anneeId; } $stmt = $this->getEntityManager()->getConnection()->executeQuery( $sql, ['sourceCode' => (array)$sourceCode], ['sourceCode' => \Doctrine\DBAL\Connection::PARAM_INT_ARRAY] ); if ($r = $stmt->fetch()) { ; return (int)$r['ID']; } else { return null; } } /** * Mettre à jour toutes les infos dans la BDD * Loading Loading @@ -294,36 +243,6 @@ class QueryGeneratorService extends AbstractService /** * Retourne le code source du package d'import * * @return string */ protected function getPackageDeclaration() { $sql = "SELECT TEXT FROM USER_SOURCE WHERE NAME = '" . $this->getPackage() . "' AND type = 'PACKAGE'"; $result = $this->query($sql, [], 'TEXT'); return implode("", $result); } /** * Retourne le code source du package d'import * * @return string */ protected function getPackageBody() { $sql = "SELECT TEXT FROM USER_SOURCE WHERE NAME = '" . $this->getPackage() . "' AND type = 'PACKAGE BODY'"; $result = $this->query($sql, [], 'TEXT'); return implode("", $result); } /** * Construit toutes les vues différentielles * Loading Loading @@ -413,54 +332,40 @@ class QueryGeneratorService extends AbstractService */ protected function makePackageDeclaration() { $src = $this->getPackageDeclaration(); $decl = implode("\n", $this->makeProcDeclarations()); $pname = self::AUTOGEN_PACKAGE_NAME; $decls = implode("\n", $this->makeProcDeclarations()); return $this->updatePackageContent($src, $decl); } $head = " SQL_CRITERION CLOB DEFAULT ''; IGNORE_UPD_COLS CLOB DEFAULT '';"; $psql = "CREATE OR REPLACE PACKAGE $pname IS\n$head\n\n$decls\n\nEND $pname;"; /** * Constuit la nouvelle déclaration du package IMPORT * * @return string */ protected function makePackageBody() { $src = $this->getPackageBody(); $decl = implode("\n\n\n\n", $this->makeProcBodies()); return $this->updatePackageContent($src, $decl); return $psql; } /** * Mise à jour du contenu d'un package (déclaration ou corps) * * @param string $packageSource * @param string $newContent * Constuit la nouvelle déclaration du package IMPORT * * @return string */ protected function updatePackageContent($packageSource, $newContent) protected function makePackageBody() { $src = $packageSource; if (null === $begin = strpos($packageSource, self::AG_BEGIN)) { throw new Exception('Le tag indiquant le début de la zone automatique du package n\'a pas été trouvée'); } $pname = self::AUTOGEN_PACKAGE_NAME; $procs = implode("\n\n\n\n", $this->makeProcBodies()); if (null === $end = strpos($packageSource, self::AG_END)) { throw new Exception('Le tag indiquant la fin de la zone automatique du package n\'a pas été trouvée'); } $funcs = " FUNCTION IN_COLUMN_LIST( VALEUR VARCHAR2, CHAMPS CLOB ) RETURN NUMERIC IS BEGIN IF REGEXP_LIKE(CHAMPS, '(^|,)[ \\t\\r\\n\\v\\f]*' || VALEUR || '[ \\t\\r\\n\\v\\f]*(,|$)') THEN RETURN 1; END IF; RETURN 0; END;"; $src = 'CREATE OR REPLACE ' . substr($packageSource, 0, $begin + strlen(self::AG_BEGIN)) . "\n\n" . $newContent . "\n\n " . substr($packageSource, $end); $psql = "CREATE OR REPLACE PACKAGE BODY $pname IS\n$funcs\n\n\n$procs\n\nEND $pname;"; return $src; return $psql; } Loading Loading @@ -569,7 +474,7 @@ WHERE */ protected function makeProcDeclaration($tableName) { return " PROCEDURE MAJ_$tableName(SQL_CRITERION CLOB DEFAULT '', IGNORE_UPD_COLS CLOB DEFAULT '');"; return " PROCEDURE $tableName;"; } Loading @@ -585,13 +490,13 @@ WHERE { $cols = $this->getCols($tableName); $sql = " PROCEDURE MAJ_$tableName(SQL_CRITERION CLOB DEFAULT '', IGNORE_UPD_COLS CLOB DEFAULT '') IS $sql = " PROCEDURE $tableName IS TYPE r_cursor IS REF CURSOR; sql_query CLOB; diff_cur r_cursor; diff_row V_DIFF_$tableName%ROWTYPE; BEGIN sql_query := 'SELECT V_DIFF_$tableName.* FROM V_DIFF_$tableName ' || get_sql_criterion('$tableName',SQL_CRITERION); sql_query := 'SELECT V_DIFF_$tableName.* FROM V_DIFF_$tableName ' || unicaen_import.get_sql_criterion('$tableName',SQL_CRITERION); OPEN diff_cur FOR sql_query; LOOP FETCH diff_cur INTO diff_row; EXIT WHEN diff_cur%NOTFOUND; Loading @@ -602,7 +507,7 @@ WHERE INSERT INTO $tableName ( id, " . $this->formatColQuery($cols) . ", source_id, 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, get_current_user, get_current_user ); ( 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 ); WHEN 'update' THEN " . $this->formatColQuery( Loading @@ -612,7 +517,7 @@ WHERE ) . " WHEN 'delete' THEN UPDATE $tableName SET histo_destruction = SYSDATE, histo_destructeur_id = get_current_user WHERE ID = diff_row.id; UPDATE $tableName SET histo_destruction = SYSDATE, histo_destructeur_id = unicaen_import.get_current_user WHERE ID = diff_row.id; WHEN 'undelete' THEN " . $this->formatColQuery( Loading @@ -630,7 +535,7 @@ WHERE END LOOP; CLOSE diff_cur; END MAJ_$tableName;"; END $tableName;"; return $sql; } Loading Loading
src/UnicaenImport/Service/QueryGeneratorService.php +31 −126 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ class QueryGeneratorService extends AbstractService use SchemaServiceAwareTrait; use ModuleOptionsAwareTrait; const AUTOGEN_PACKAGE_NAME = 'UNICAEN_IMPORT_AUTOGEN_PROCS__'; const AG_BEGIN = '-- AUTOMATIC GENERATION --'; const AG_END = '-- END OF AUTOMATIC GENERATION --'; const ANNEE_COLUMN_NAME = 'ANNEE_ID'; Loading Loading @@ -100,7 +101,7 @@ class QueryGeneratorService extends AbstractService throw new Exception('Vous devez être authentifié pour réaliser cette action'); } $userId = $this->escape($currentUser->getId()); $procName = $this->escapeKW('MAJ_' . $query->getTableName()); $tableName = $this->escape($query->getTableName()); $conditions = $query->toSql(Query::SQL_PARTIAL); if (!empty($conditions)) { $conditions = $this->escape($conditions); Loading @@ -114,7 +115,7 @@ class QueryGeneratorService extends AbstractService $ignoreFields = $this->escape(implode(',', $ignoreFields)); } $sql = "BEGIN " . $this->getPackage() . ".SET_CURRENT_USER($userId);" . $this->getPackage() . ".$procName($conditions,$ignoreFields); END;"; $sql = "BEGIN " . $this->getPackage() . ".SET_CURRENT_USER($userId);" . $this->getPackage() . ".SYNCHRONISATION($tableName,$conditions,$ignoreFields); END;"; try { $this->getEntityManager()->getConnection()->exec($sql); } catch (DBALException $e) { Loading @@ -133,34 +134,15 @@ class QueryGeneratorService extends AbstractService * * @return string[] */ public function syncTable($query) public function syncTable(Query $query) { $currentUser = $this->getDbUser(); if (empty($currentUser)) { throw new Exception('Vous devez être authentifié pour réaliser cette action'); } $userId = $this->escape($currentUser->getId()); $errors = []; $lastLogId = $this->getLastLogId(); $partial = $query->toSql($query::SQL_PARTIAL); if ($partial) { $partial = $this::escape($partial); } else { $partial = ''; } $sql = "BEGIN " . $this->getPackage() . ".SET_CURRENT_USER($userId);" . $this->getPackage() . "." . $this::escapeKW('MAJ_' . $query->getTableName()) . "(" . $partial . ");" . " END;"; try { $this->getEntityManager()->getConnection()->exec($sql); $this->execMaj($query); } catch (DBALException $e) { $errors[] = Exception::duringMajException($e, $query->getTableName())->getMessage(); $errors[] = $e->getMessage(); } $errors = $errors + $this->getLogMessages($lastLogId); Loading Loading @@ -230,39 +212,6 @@ class QueryGeneratorService extends AbstractService /** * Retourne les identifiants des données concernés * * @param string $tableName * @param string|string[]|null $sourceCode * @param integer|null $anneeId * * @return integer[]|null */ public function getIdFromSourceCode($tableName, $sourceCode, $anneeId = null) { if (empty($sourceCode)) return null; $sql = 'SELECT ID FROM ' . $this->escapeKW($tableName) . ' WHERE SOURCE_CODE IN (:sourceCode)'; if ($anneeId) { $sql .= ' AND ANNEE_ID = ' . (string)(int)$anneeId; } $stmt = $this->getEntityManager()->getConnection()->executeQuery( $sql, ['sourceCode' => (array)$sourceCode], ['sourceCode' => \Doctrine\DBAL\Connection::PARAM_INT_ARRAY] ); if ($r = $stmt->fetch()) { ; return (int)$r['ID']; } else { return null; } } /** * Mettre à jour toutes les infos dans la BDD * Loading Loading @@ -294,36 +243,6 @@ class QueryGeneratorService extends AbstractService /** * Retourne le code source du package d'import * * @return string */ protected function getPackageDeclaration() { $sql = "SELECT TEXT FROM USER_SOURCE WHERE NAME = '" . $this->getPackage() . "' AND type = 'PACKAGE'"; $result = $this->query($sql, [], 'TEXT'); return implode("", $result); } /** * Retourne le code source du package d'import * * @return string */ protected function getPackageBody() { $sql = "SELECT TEXT FROM USER_SOURCE WHERE NAME = '" . $this->getPackage() . "' AND type = 'PACKAGE BODY'"; $result = $this->query($sql, [], 'TEXT'); return implode("", $result); } /** * Construit toutes les vues différentielles * Loading Loading @@ -413,54 +332,40 @@ class QueryGeneratorService extends AbstractService */ protected function makePackageDeclaration() { $src = $this->getPackageDeclaration(); $decl = implode("\n", $this->makeProcDeclarations()); $pname = self::AUTOGEN_PACKAGE_NAME; $decls = implode("\n", $this->makeProcDeclarations()); return $this->updatePackageContent($src, $decl); } $head = " SQL_CRITERION CLOB DEFAULT ''; IGNORE_UPD_COLS CLOB DEFAULT '';"; $psql = "CREATE OR REPLACE PACKAGE $pname IS\n$head\n\n$decls\n\nEND $pname;"; /** * Constuit la nouvelle déclaration du package IMPORT * * @return string */ protected function makePackageBody() { $src = $this->getPackageBody(); $decl = implode("\n\n\n\n", $this->makeProcBodies()); return $this->updatePackageContent($src, $decl); return $psql; } /** * Mise à jour du contenu d'un package (déclaration ou corps) * * @param string $packageSource * @param string $newContent * Constuit la nouvelle déclaration du package IMPORT * * @return string */ protected function updatePackageContent($packageSource, $newContent) protected function makePackageBody() { $src = $packageSource; if (null === $begin = strpos($packageSource, self::AG_BEGIN)) { throw new Exception('Le tag indiquant le début de la zone automatique du package n\'a pas été trouvée'); } $pname = self::AUTOGEN_PACKAGE_NAME; $procs = implode("\n\n\n\n", $this->makeProcBodies()); if (null === $end = strpos($packageSource, self::AG_END)) { throw new Exception('Le tag indiquant la fin de la zone automatique du package n\'a pas été trouvée'); } $funcs = " FUNCTION IN_COLUMN_LIST( VALEUR VARCHAR2, CHAMPS CLOB ) RETURN NUMERIC IS BEGIN IF REGEXP_LIKE(CHAMPS, '(^|,)[ \\t\\r\\n\\v\\f]*' || VALEUR || '[ \\t\\r\\n\\v\\f]*(,|$)') THEN RETURN 1; END IF; RETURN 0; END;"; $src = 'CREATE OR REPLACE ' . substr($packageSource, 0, $begin + strlen(self::AG_BEGIN)) . "\n\n" . $newContent . "\n\n " . substr($packageSource, $end); $psql = "CREATE OR REPLACE PACKAGE BODY $pname IS\n$funcs\n\n\n$procs\n\nEND $pname;"; return $src; return $psql; } Loading Loading @@ -569,7 +474,7 @@ WHERE */ protected function makeProcDeclaration($tableName) { return " PROCEDURE MAJ_$tableName(SQL_CRITERION CLOB DEFAULT '', IGNORE_UPD_COLS CLOB DEFAULT '');"; return " PROCEDURE $tableName;"; } Loading @@ -585,13 +490,13 @@ WHERE { $cols = $this->getCols($tableName); $sql = " PROCEDURE MAJ_$tableName(SQL_CRITERION CLOB DEFAULT '', IGNORE_UPD_COLS CLOB DEFAULT '') IS $sql = " PROCEDURE $tableName IS TYPE r_cursor IS REF CURSOR; sql_query CLOB; diff_cur r_cursor; diff_row V_DIFF_$tableName%ROWTYPE; BEGIN sql_query := 'SELECT V_DIFF_$tableName.* FROM V_DIFF_$tableName ' || get_sql_criterion('$tableName',SQL_CRITERION); sql_query := 'SELECT V_DIFF_$tableName.* FROM V_DIFF_$tableName ' || unicaen_import.get_sql_criterion('$tableName',SQL_CRITERION); OPEN diff_cur FOR sql_query; LOOP FETCH diff_cur INTO diff_row; EXIT WHEN diff_cur%NOTFOUND; Loading @@ -602,7 +507,7 @@ WHERE INSERT INTO $tableName ( id, " . $this->formatColQuery($cols) . ", source_id, 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, get_current_user, get_current_user ); ( 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 ); WHEN 'update' THEN " . $this->formatColQuery( Loading @@ -612,7 +517,7 @@ WHERE ) . " WHEN 'delete' THEN UPDATE $tableName SET histo_destruction = SYSDATE, histo_destructeur_id = get_current_user WHERE ID = diff_row.id; UPDATE $tableName SET histo_destruction = SYSDATE, histo_destructeur_id = unicaen_import.get_current_user WHERE ID = diff_row.id; WHEN 'undelete' THEN " . $this->formatColQuery( Loading @@ -630,7 +535,7 @@ WHERE END LOOP; CLOSE diff_cur; END MAJ_$tableName;"; END $tableName;"; return $sql; } Loading