diff --git a/app/src/Lib/Util/SchemaManager.php b/app/src/Lib/Util/SchemaManager.php index cb802c1ed..77f1245f1 100644 --- a/app/src/Lib/Util/SchemaManager.php +++ b/app/src/Lib/Util/SchemaManager.php @@ -31,6 +31,8 @@ use Cake\Console\ConsoleIo; +use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\SchemaDiff; @@ -346,8 +348,11 @@ protected function processSchema( // schema file). $comparator = new Comparator(); $schemaDiff = $comparator->compareSchemas($curSchema, $schema); - - $diffSql = $schemaDiff->toSaveSql($this->conn->getDatabasePlatform()); + + $diffSql = $this->getAlterSchemaSqlSaveMode( + $this->conn->getDatabasePlatform(), + $schemaDiff + ); // We don't start a transaction since in general we always want to move to // the desired state, and if we fail in flight it's probably a bug that @@ -375,7 +380,7 @@ protected function processSchema( if($qualifiedTable !== null) { // We will skip this index if it's bound to a constraint - if($this->io) $this->io->out('Skipping index drop since it is bound to a constraint'); + if($this->io) $this->io->out('Skipping index:' . $m[1] . ' drop since it is bound to a constraint'); continue; } } @@ -451,4 +456,54 @@ protected function resolvePgConstraintTable(string $constraintName): ?string { return null; } } -} + + + /** + * Generate non-destructive (save-mode) schema SQL. + * + * Equivalent to SchemaDiff::_toSql($platform, true). + * + * - Does NOT drop tables + * - Does NOT drop sequences + * - Does NOT drop orphaned FKs + * + * @param AbstractPlatform $platform Database platform abstraction + * @param SchemaDiff $diff Schema differences to generate SQL for + * @return array Array of SQL statements to execute + * @throws Exception + * @since COmanage Registry v5.2.0 + */ + protected function getAlterSchemaSqlSaveMode( + AbstractPlatform $platform, + SchemaDiff $diff + ): array { + $sql = []; + + // 1) Schemas to create + if ($platform->supportsSchemas()) { + foreach ($diff->getCreatedSchemas() as $schema) { + $sql[] = $platform->getCreateSchemaSQL($schema); + } + } + + // 2) Sequences (alter + create; no drops in save mode) + if ($platform->supportsSequences()) { + foreach ($diff->getAlteredSequences() as $sequence) { + $sql[] = $platform->getAlterSequenceSQL($sequence); + } + foreach ($diff->getCreatedSequences() as $sequence) { + $sql[] = $platform->getCreateSequenceSQL($sequence); + } + } + + // 3) Tables (create only; no drops in save mode) + $sql = array_merge($sql, $platform->getCreateTablesSQL($diff->getCreatedTables())); + + // 4) Alter existing tables (may emit FK drops/adds as required for alterations) + foreach ($diff->getAlteredTables() as $tableDiff) { + $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff)); + } + + return $sql; + } +} \ No newline at end of file