diff --git a/lib/Migration/Version1000Date20260309120000.php b/lib/Migration/Version1000Date20260309120000.php index cb32ee9..b0c6b04 100644 --- a/lib/Migration/Version1000Date20260309120000.php +++ b/lib/Migration/Version1000Date20260309120000.php @@ -64,7 +64,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt $table->addColumn('created_at', Types::DATETIME, []); $table->addColumn('updated_at', Types::DATETIME, []); - $table->setPrimaryKey(['id']); + $table->setPrimaryKey(['id'], 'pf_definitions_pk'); $table->addUniqueIndex(['field_key'], 'profile_fields_def_key_uk'); $table->addIndex(['active', 'sort_order'], 'pf_def_active_sort_idx'); } @@ -91,8 +91,8 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt ]); $table->addColumn('updated_at', Types::DATETIME, []); - $table->setPrimaryKey(['id']); - $table->addUniqueIndex(['field_definition_id', 'user_uid'], 'profile_fields_val_field_user_uk'); + $table->setPrimaryKey(['id'], 'pf_values_pk'); + $table->addUniqueIndex(['field_definition_id', 'user_uid'], 'pf_val_def_user_uk'); $table->addIndex(['user_uid'], 'profile_fields_val_user_idx'); $table->addIndex(['field_definition_id'], 'profile_fields_val_field_idx'); $table->addForeignKeyConstraint( diff --git a/tests/php/Unit/Migration/Version1000Date20260309120000Test.php b/tests/php/Unit/Migration/Version1000Date20260309120000Test.php new file mode 100644 index 0000000..982a3ca --- /dev/null +++ b/tests/php/Unit/Migration/Version1000Date20260309120000Test.php @@ -0,0 +1,159 @@ +schema = new Schema(); + } + + private function buildSchemaWrapper(Schema $schema, string $prefix): ISchemaWrapper { + return new class($schema, $prefix) implements ISchemaWrapper { + public function __construct( + private Schema $schema, + private string $prefix, + ) { + } + + public function hasTable($tableName): bool { + return $this->schema->hasTable($this->prefix . $tableName); + } + + public function createTable($tableName): Table { + return $this->schema->createTable($this->prefix . $tableName); + } + + public function getTable($tableName): Table { + return $this->schema->getTable($this->prefix . $tableName); + } + + public function dropTable($tableName): Schema { + return $this->schema->dropTable($this->prefix . $tableName); + } + + public function getTables(): array { + return $this->schema->getTables(); + } + + public function getTableNames(): array { + return $this->schema->getTableNames(); + } + + public function getTableNamesWithoutPrefix(): array { + return array_map( + fn (string $n) => substr($n, strlen($this->prefix)), + $this->schema->getTableNames(), + ); + } + + public function getDatabasePlatform(): AbstractPlatform { + throw new \RuntimeException('not implemented in test'); + } + + public function dropAutoincrementColumn(string $table, string $column): void { + throw new \RuntimeException('not implemented in test'); + } + }; + } + + public function testAllNamesPassOracleConstraints(): void { + $wrapper = $this->buildSchemaWrapper($this->schema, self::PREFIX); + $output = $this->createMock(IOutput::class); + $migration = new Version1000Date20260309120000(); + + $migration->changeSchema($output, fn () => $wrapper, ['tablePrefix' => self::PREFIX]); + + $prefixLen = strlen(self::PREFIX); + + foreach ($this->schema->getTables() as $table) { + $tableNameWithoutPrefix = substr($table->getName(), $prefixLen); + + $this->assertLessThanOrEqual( + self::ORACLE_MAX_TABLE, + strlen($tableNameWithoutPrefix), + "Table '{$table->getName()}' name without prefix exceeds Oracle max of " . self::ORACLE_MAX_TABLE . ' chars', + ); + + foreach ($table->getColumns() as $column) { + $this->assertLessThanOrEqual( + self::ORACLE_MAX_NAME, + strlen($column->getName()), + "Column '{$column->getName()}' on '{$table->getName()}' exceeds Oracle max of " . self::ORACLE_MAX_NAME . ' chars', + ); + } + + foreach ($table->getIndexes() as $index) { + $this->assertLessThanOrEqual( + self::ORACLE_MAX_NAME, + strlen($index->getName()), + "Index '{$index->getName()}' on '{$table->getName()}' exceeds Oracle max of " . self::ORACLE_MAX_NAME . ' chars', + ); + } + + foreach ($table->getForeignKeys() as $fk) { + $this->assertLessThanOrEqual( + self::ORACLE_MAX_NAME, + strlen($fk->getName()), + "FK '{$fk->getName()}' on '{$table->getName()}' exceeds Oracle max of " . self::ORACLE_MAX_NAME . ' chars', + ); + } + + $primaryKey = $table->getPrimaryKey(); + if ($primaryKey !== null) { + $pkName = strtolower($primaryKey->getName()); + if ($pkName === 'primary') { + // Default PK name: table name without prefix must be strictly < 23 chars + $this->assertLessThan( + self::ORACLE_MAX_TABLE_FOR_DEFAULT_PK, + strlen($tableNameWithoutPrefix), + "Table '{$tableNameWithoutPrefix}' uses default primary key name but its length " + . strlen($tableNameWithoutPrefix) + . ' >= ' . self::ORACLE_MAX_TABLE_FOR_DEFAULT_PK + . '; set an explicit primary key name <= 30 chars', + ); + } else { + $this->assertLessThanOrEqual( + self::ORACLE_MAX_NAME, + strlen($pkName), + "Primary key name '$pkName' on '{$table->getName()}' exceeds Oracle max of " . self::ORACLE_MAX_NAME . ' chars', + ); + } + } + } + } +}