diff --git a/CHANGELOG.md b/CHANGELOG.md index a851c58b..a43ba890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - New #322: Add `ColumnDefinitionBuilder` class (@Tigrov) - Enh #323: Refactor `Dsn` class (@Tigrov) - Enh #324: Set more specific result type in `Connection` methods `createCommand()` and `createTransaction()` (@vjik) +- Enh #326: Refactor `Schema::normalizeDefaultValue()` method and move it to `ColumnFactory` class (@Tigrov) ## 1.2.0 March 21, 2024 diff --git a/src/Column/ColumnFactory.php b/src/Column/ColumnFactory.php index 4e19ace6..22a748b3 100644 --- a/src/Column/ColumnFactory.php +++ b/src/Column/ColumnFactory.php @@ -6,6 +6,10 @@ use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Schema\Column\AbstractColumnFactory; +use Yiisoft\Db\Schema\Column\ColumnSchemaInterface; + +use function str_replace; +use function substr; final class ColumnFactory extends AbstractColumnFactory { @@ -55,4 +59,16 @@ protected function getType(string $dbType, array $info = []): string default => parent::getType($dbType, $info), }; } + + protected function normalizeNotNullDefaultValue(string $defaultValue, ColumnSchemaInterface $column): mixed + { + if ($defaultValue[0] === '"' && $defaultValue[-1] === '"') { + $value = substr($defaultValue, 1, -1); + $value = str_replace('""', '"', $value); + + return $column->phpTypecast($value); + } + + return parent::normalizeNotNullDefaultValue($defaultValue, $column); + } } diff --git a/src/Schema.php b/src/Schema.php index 08ea64fe..327c4f91 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -15,7 +15,6 @@ use Yiisoft\Db\Exception\InvalidArgumentException; use Yiisoft\Db\Exception\InvalidConfigException; use Yiisoft\Db\Exception\NotSupportedException; -use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Helper\DbArrayHelper; use Yiisoft\Db\Schema\Builder\ColumnInterface; use Yiisoft\Db\Schema\Column\ColumnFactoryInterface; @@ -29,7 +28,6 @@ use function array_map; use function count; use function md5; -use function preg_replace; use function serialize; use function strncasecmp; @@ -450,38 +448,14 @@ public function getSchemaDefaultValues(string $schema = '', bool $refresh = fals */ private function loadColumnSchema(array $info): ColumnSchemaInterface { - $column = $this->getColumnFactory()->fromDefinition($info['type'], [ + return $this->getColumnFactory()->fromDefinition($info['type'], [ + 'defaultValueRaw' => $info['dflt_value'], 'name' => $info['name'], 'notNull' => (bool) $info['notnull'], 'primaryKey' => (bool) $info['pk'], 'schema' => $info['schema'], 'table' => $info['table'], ]); - - return $column->defaultValue($this->normalizeDefaultValue($info['dflt_value'], $column)); - } - - /** - * Converts column's default value according to {@see ColumnSchema::phpType} after retrieval from the database. - * - * @param string|null $defaultValue The default value retrieved from the database. - * @param ColumnSchemaInterface $column The column schema object. - * - * @return mixed The normalized default value. - */ - private function normalizeDefaultValue(string|null $defaultValue, ColumnSchemaInterface $column): mixed - { - if ($column->isPrimaryKey() || in_array($defaultValue, [null, '', 'null', 'NULL'], true)) { - return null; - } - - if (in_array($defaultValue, ['CURRENT_TIMESTAMP', 'CURRENT_DATE', 'CURRENT_TIME'], true)) { - return new Expression($defaultValue); - } - - $value = preg_replace('/^([\'"])(.*)\1$/s', '$2', $defaultValue); - - return $column->phpTypecast($value); } /** diff --git a/tests/ColumnFactoryTest.php b/tests/ColumnFactoryTest.php index 6c6dfd83..b7d2a0a3 100644 --- a/tests/ColumnFactoryTest.php +++ b/tests/ColumnFactoryTest.php @@ -4,6 +4,8 @@ namespace Yiisoft\Db\Sqlite\Tests; +use PHPUnit\Framework\Attributes\DataProviderExternal; +use Yiisoft\Db\Sqlite\Tests\Provider\ColumnFactoryProvider; use Yiisoft\Db\Sqlite\Tests\Support\TestTrait; use Yiisoft\Db\Tests\AbstractColumnFactoryTest; @@ -14,13 +16,13 @@ final class ColumnFactoryTest extends AbstractColumnFactoryTest { use TestTrait; - /** @dataProvider \Yiisoft\Db\Sqlite\Tests\Provider\ColumnFactoryProvider::dbTypes */ + #[DataProviderExternal(ColumnFactoryProvider::class, 'dbTypes')] public function testFromDbType(string $dbType, string $expectedType, string $expectedInstanceOf): void { parent::testFromDbType($dbType, $expectedType, $expectedInstanceOf); } - /** @dataProvider \Yiisoft\Db\Sqlite\Tests\Provider\ColumnFactoryProvider::definitions */ + #[DataProviderExternal(ColumnFactoryProvider::class, 'definitions')] public function testFromDefinition( string $definition, string $expectedType, @@ -30,7 +32,7 @@ public function testFromDefinition( parent::testFromDefinition($definition, $expectedType, $expectedInstanceOf, $expectedMethodResults); } - /** @dataProvider \Yiisoft\Db\Sqlite\Tests\Provider\ColumnFactoryProvider::pseudoTypes */ + #[DataProviderExternal(ColumnFactoryProvider::class, 'pseudoTypes')] public function testFromPseudoType( string $pseudoType, string $expectedType, @@ -40,9 +42,15 @@ public function testFromPseudoType( parent::testFromPseudoType($pseudoType, $expectedType, $expectedInstanceOf, $expectedMethodResults); } - /** @dataProvider \Yiisoft\Db\Sqlite\Tests\Provider\ColumnFactoryProvider::types */ + #[DataProviderExternal(ColumnFactoryProvider::class, 'types')] public function testFromType(string $type, string $expectedType, string $expectedInstanceOf): void { parent::testFromType($type, $expectedType, $expectedInstanceOf); } + + #[DataProviderExternal(ColumnFactoryProvider::class, 'defaultValueRaw')] + public function testFromTypeDefaultValueRaw(string $type, string|null $defaultValueRaw, mixed $expected): void + { + parent::testFromTypeDefaultValueRaw($type, $defaultValueRaw, $expected); + } } diff --git a/tests/Provider/ColumnFactoryProvider.php b/tests/Provider/ColumnFactoryProvider.php index 9904e2d1..4fd412a0 100644 --- a/tests/Provider/ColumnFactoryProvider.php +++ b/tests/Provider/ColumnFactoryProvider.php @@ -60,4 +60,13 @@ public static function definitions(): array return $definitions; } + + public static function defaultValueRaw(): array + { + $defaultValueRaw = parent::defaultValueRaw(); + + $defaultValueRaw[] = [ColumnType::STRING, '"str""ing"', 'str"ing']; + + return $defaultValueRaw; + } }