Commit cbe3d78a authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Déport des procédures de mises à jour dans un paquet spécifique autogénéré.

Appel indirect aux nouvelles procédures de mise à jour
parent 5ca90fec
Loading
Loading
Loading
Loading
+31 −126
Original line number Diff line number Diff line
@@ -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';
@@ -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);
@@ -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) {
@@ -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);

@@ -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
     *
@@ -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
     *
@@ -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;
    }


@@ -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;";
    }


@@ -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;
@@ -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(
@@ -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(
@@ -630,7 +535,7 @@ WHERE
    END LOOP;
    CLOSE diff_cur;

  END MAJ_$tableName;";
  END $tableName;";

        return $sql;
    }