diff --git a/CHANGELOG.md b/CHANGELOG.md index c4e1df0..2963e74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,7 +49,7 @@ - Enh #324: Refactor `Command::insertWithReturningPks()` method (@Tigrov) - Enh #325: Refactor `DMLQueryBuilder::upsert()` method (@Tigrov) - Chg #326: Add alias in `DQLQueryBuilder::selectExists()` method for consistency with other DBMS (@Tigrov) -- Enh #327: Refactor constraints (@Tigrov) +- Enh #327, #343: Refactor constraints (@Tigrov) - Chg #330: Rename `insertWithReturningPks()` to `insertReturningPks()` in `Command` and `DMLQueryBuilder` classes (@Tigrov) - Enh #336: Provide `yiisoft/db-implementation` virtual package (@vjik) - Enh #340: Adapt to `Param` refactoring in `yiisoft/db` package (@vjik) diff --git a/src/DMLQueryBuilder.php b/src/DMLQueryBuilder.php index 02b7114..e4b8c29 100644 --- a/src/DMLQueryBuilder.php +++ b/src/DMLQueryBuilder.php @@ -80,7 +80,7 @@ public function upsert( $quotedTableName = $this->quoter->quoteTableName($table); foreach ($constraints as $constraint) { - $columnNames = $constraint->getColumnNames(); + $columnNames = $constraint->columnNames; $constraintCondition = ['and']; foreach ($columnNames as $name) { diff --git a/src/Schema.php b/src/Schema.php index 490d3bf..755d391 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -8,9 +8,9 @@ use Yiisoft\Db\Connection\ConnectionInterface; use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Constant\ReferentialAction; -use Yiisoft\Db\Constraint\CheckConstraint; -use Yiisoft\Db\Constraint\ForeignKeyConstraint; -use Yiisoft\Db\Constraint\IndexConstraint; +use Yiisoft\Db\Constraint\Check; +use Yiisoft\Db\Constraint\ForeignKey; +use Yiisoft\Db\Constraint\Index; use Yiisoft\Db\Driver\Pdo\AbstractPdoSchema; use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Helper\DbArrayHelper; @@ -230,15 +230,15 @@ protected function loadTableSchema(string $name): TableSchemaInterface|null return null; } - protected function loadTablePrimaryKey(string $tableName): IndexConstraint|null + protected function loadTablePrimaryKey(string $tableName): Index|null { - /** @var IndexConstraint|null */ + /** @var Index|null */ return $this->loadTableConstraints($tableName, self::PRIMARY_KEY); } protected function loadTableForeignKeys(string $tableName): array { - /** @var ForeignKeyConstraint[] */ + /** @var ForeignKey[] */ return $this->loadTableConstraints($tableName, self::FOREIGN_KEYS); } @@ -280,7 +280,7 @@ protected function loadTableIndexes(string $tableName): array } /** @var string[] $columnNames */ - $result[] = new IndexConstraint( + $result[] = new Index( $name, $columnNames, (bool) $index[0]['is_unique'], @@ -293,13 +293,13 @@ protected function loadTableIndexes(string $tableName): array protected function loadTableUniques(string $tableName): array { - /** @var IndexConstraint[] */ + /** @var Index[] */ return $this->loadTableConstraints($tableName, self::UNIQUES); } protected function loadTableChecks(string $tableName): array { - /** @var CheckConstraint[] */ + /** @var Check[] */ return $this->loadTableConstraints($tableName, self::CHECKS); } @@ -598,9 +598,9 @@ public function findUniqueIndexes(TableSchemaInterface $table): array * - uniques * - checks * - * @return CheckConstraint[]|ForeignKeyConstraint[]|IndexConstraint|IndexConstraint[]|null Constraints. + * @return Check[]|ForeignKey[]|Index|Index[]|null Constraints. */ - private function loadTableConstraints(string $tableName, string $returnType): array|IndexConstraint|null + private function loadTableConstraints(string $tableName, string $returnType): array|Index|null { $sql = << $constraint) { switch ($type) { case 'P': - $result[self::PRIMARY_KEY] = new IndexConstraint( + $result[self::PRIMARY_KEY] = new Index( $name, array_column($constraint, 'column_name'), true, @@ -655,24 +655,25 @@ private function loadTableConstraints(string $tableName, string $returnType): ar ); break; case 'R': - $result[self::FOREIGN_KEYS][] = new ForeignKeyConstraint( + $result[self::FOREIGN_KEYS][] = new ForeignKey( $name, array_column($constraint, 'column_name'), - $constraint[0]['foreign_table_schema'] . '.' . $constraint[0]['foreign_table_name'], + $constraint[0]['foreign_table_schema'], + $constraint[0]['foreign_table_name'], array_column($constraint, 'foreign_column_name'), - null, $constraint[0]['on_delete'], + null, ); break; case 'U': - $result[self::UNIQUES][] = new IndexConstraint( + $result[self::UNIQUES][] = new Index( $name, array_column($constraint, 'column_name'), true, ); break; case 'C': - $result[self::CHECKS][] = new CheckConstraint( + $result[self::CHECKS][] = new Check( $name, array_column($constraint, 'column_name'), $constraint[0]['check_expr'], diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 34ba362..d010ddd 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\Attributes\DataProviderExternal; use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Constant\PseudoType; +use Yiisoft\Db\Constraint\Index; use Yiisoft\Db\Exception\Exception; use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Oracle\Column\ColumnBuilder; @@ -16,6 +17,7 @@ use Yiisoft\Db\Query\Query; use Yiisoft\Db\Query\QueryInterface; use Yiisoft\Db\Tests\Common\CommonCommandTest; +use Yiisoft\Db\Tests\Support\Assert; use function is_resource; use function str_pad; @@ -608,18 +610,16 @@ public function testCreateSearchIndex() $command->createTable($tableName, ['col1' => ColumnBuilder::text()])->execute(); $command->createIndex($tableName, $indexName, ['col1'], IndexType::SEARCH)->execute(); - $this->assertCount(2, $schema->getTableIndexes($tableName)); + $indexes = $schema->getTableIndexes($tableName); + Assert::setPropertyValue($indexes[1], 'name', ''); - $index = $schema->getTableIndexes($tableName)[0]; - - $this->assertSame(['col1'], $index->getColumnNames()); - $this->assertFalse($index->isUnique()); - $this->assertFalse($index->isPrimaryKey()); - - $sysIndex = $schema->getTableIndexes($tableName)[1]; - $this->assertSame([], $sysIndex->getColumnNames()); - $this->assertTrue($sysIndex->isUnique()); - $this->assertFalse($sysIndex->isPrimaryKey()); + $this->assertEquals( + [ + new Index($indexName, ['col1']), + new Index('', [], true), + ], + $indexes, + ); $db->close(); } diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index bb39ba7..62ac0f9 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -10,7 +10,7 @@ use Yiisoft\Db\Constant\DataType; use Yiisoft\Db\Constant\PseudoType; use Yiisoft\Db\Constant\ReferentialAction; -use Yiisoft\Db\Constraint\ForeignKeyConstraint; +use Yiisoft\Db\Constraint\ForeignKey; use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Oracle\Column\ColumnBuilder; use Yiisoft\Db\Oracle\Tests\Support\TestTrait; @@ -243,15 +243,19 @@ public static function upsert(): array public static function buildColumnDefinition(): array { - $referenceRestrict = new ForeignKeyConstraint(); - $referenceRestrict->foreignColumnNames(['id']); - $referenceRestrict->foreignTableName('ref_table'); - $referenceRestrict->onDelete(ReferentialAction::RESTRICT); - $referenceRestrict->onUpdate(ReferentialAction::RESTRICT); - - $referenceSetNull = clone $referenceRestrict; - $referenceSetNull->onDelete(ReferentialAction::SET_NULL); - $referenceRestrict->onUpdate(ReferentialAction::SET_NULL); + $referenceRestrict = new ForeignKey( + foreignTableName: 'ref_table', + foreignColumnNames: ['id'], + onDelete: ReferentialAction::RESTRICT, + onUpdate: ReferentialAction::RESTRICT, + ); + + $referenceSetNull = new ForeignKey( + foreignTableName: 'ref_table', + foreignColumnNames:['id'], + onDelete: ReferentialAction::SET_NULL, + onUpdate: ReferentialAction::SET_NULL, + ); $values = parent::buildColumnDefinition(); @@ -343,8 +347,8 @@ public static function buildColumnDefinition(): array $values['unsigned()'][0] = 'number(10)'; $values['scale(2)'][0] = 'number(10,2)'; $values['integer(8)->scale(2)'][0] = 'number(8)'; - $values['reference($reference)'][0] = 'number(10) REFERENCES "ref_table" ("id") ON DELETE CASCADE'; - $values['reference($referenceWithSchema)'][0] = 'number(10) REFERENCES "ref_schema"."ref_table" ("id") ON DELETE CASCADE'; + $values['reference($reference)'][0] = 'number(10) REFERENCES "ref_table" ("id") ON DELETE SET NULL'; + $values['reference($referenceWithSchema)'][0] = 'number(10) REFERENCES "ref_schema"."ref_table" ("id") ON DELETE SET NULL'; $db = self::getDb(); diff --git a/tests/Provider/SchemaProvider.php b/tests/Provider/SchemaProvider.php index 91eb5cf..d444428 100644 --- a/tests/Provider/SchemaProvider.php +++ b/tests/Provider/SchemaProvider.php @@ -7,7 +7,7 @@ use DateTimeImmutable; use DateTimeZone; use Yiisoft\Db\Constant\ColumnType; -use Yiisoft\Db\Constraint\CheckConstraint; +use Yiisoft\Db\Constraint\Check; use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Oracle\Column\BinaryColumn; use Yiisoft\Db\Oracle\Column\BooleanColumn; @@ -17,6 +17,7 @@ use Yiisoft\Db\Schema\Column\DoubleColumn; use Yiisoft\Db\Schema\Column\IntegerColumn; use Yiisoft\Db\Schema\Column\StringColumn; +use Yiisoft\Db\Tests\Support\Assert; final class SchemaProvider extends \Yiisoft\Db\Tests\Provider\SchemaProvider { @@ -175,24 +176,25 @@ public static function constraints(): array { $constraints = parent::constraints(); - $constraints['1: check'][2][0]->expression('"C_check" <> \'\''); - $constraints['1: check'][2][] = new CheckConstraint('', ['C_id'], '"C_id" IS NOT NULL'); - $constraints['1: check'][2][] = new CheckConstraint('', ['C_not_null'], '"C_not_null" IS NOT NULL'); - $constraints['1: check'][2][] = new CheckConstraint('', ['C_unique'], '"C_unique" IS NOT NULL'); - $constraints['1: check'][2][] = new CheckConstraint('', ['C_default'], '"C_default" IS NOT NULL'); + Assert::setPropertyValue($constraints['1: check'][2][0], 'expression', '"C_check" <> \'\''); + $constraints['1: check'][2][] = new Check('', ['C_id'], '"C_id" IS NOT NULL'); + $constraints['1: check'][2][] = new Check('', ['C_not_null'], '"C_not_null" IS NOT NULL'); + $constraints['1: check'][2][] = new Check('', ['C_unique'], '"C_unique" IS NOT NULL'); + $constraints['1: check'][2][] = new Check('', ['C_default'], '"C_default" IS NOT NULL'); - $constraints['2: check'][2][] = new CheckConstraint('', ['C_id_1'], '"C_id_1" IS NOT NULL'); - $constraints['2: check'][2][] = new CheckConstraint('', ['C_id_2'], '"C_id_2" IS NOT NULL'); + $constraints['2: check'][2][] = new Check('', ['C_id_1'], '"C_id_1" IS NOT NULL'); + $constraints['2: check'][2][] = new Check('', ['C_id_2'], '"C_id_2" IS NOT NULL'); - $constraints['3: foreign key'][2][0]->foreignTableName('SYSTEM.T_constraints_2'); - $constraints['3: foreign key'][2][0]->onUpdate(null); + Assert::setPropertyValue($constraints['3: foreign key'][2][0], 'foreignSchemaName', 'SYSTEM'); + Assert::setPropertyValue($constraints['3: foreign key'][2][0], 'foreignTableName', 'T_constraints_2'); + Assert::setPropertyValue($constraints['3: foreign key'][2][0], 'onUpdate', null); $constraints['3: index'][2] = []; - $constraints['3: check'][2][] = new CheckConstraint('', ['C_fk_id_1'], '"C_fk_id_1" IS NOT NULL'); - $constraints['3: check'][2][] = new CheckConstraint('', ['C_fk_id_2'], '"C_fk_id_2" IS NOT NULL'); - $constraints['3: check'][2][] = new CheckConstraint('', ['C_id'], '"C_id" IS NOT NULL'); + $constraints['3: check'][2][] = new Check('', ['C_fk_id_1'], '"C_fk_id_1" IS NOT NULL'); + $constraints['3: check'][2][] = new Check('', ['C_fk_id_2'], '"C_fk_id_2" IS NOT NULL'); + $constraints['3: check'][2][] = new Check('', ['C_id'], '"C_id" IS NOT NULL'); - $constraints['4: check'][2][] = new CheckConstraint('', ['C_id'], '"C_id" IS NOT NULL'); - $constraints['4: check'][2][] = new CheckConstraint('', ['C_col_2'], '"C_col_2" IS NOT NULL'); + $constraints['4: check'][2][] = new Check('', ['C_id'], '"C_id" IS NOT NULL'); + $constraints['4: check'][2][] = new Check('', ['C_col_2'], '"C_col_2" IS NOT NULL'); return $constraints; }