Skip to content

Commit

Permalink
Refactor normalizeDefaultValue() (#289)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov authored Nov 16, 2024
1 parent 402c726 commit f6c1d7e
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- Enh #283: Refactor `Dsn` class (@Tigrov)
- Enh #286: Use constructor to create columns and initialize properties (@Tigrov)
- Enh #288: Refactor `Schema::findColumns()` method (@Tigrov)
- Enh #289: Refactor `Schema::normalizeDefaultValue()` method and move it to `ColumnFactory` class (@Tigrov)

## 1.3.0 March 21, 2024

Expand Down
7 changes: 7 additions & 0 deletions src/Column/ColumnFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Schema\Column\AbstractColumnFactory;
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;

use function preg_replace;
use function rtrim;
use function strtolower;

final class ColumnFactory extends AbstractColumnFactory
Expand Down Expand Up @@ -74,4 +76,9 @@ protected function getColumnClass(string $type, array $info = []): string

return parent::getColumnClass($type, $info);
}

protected function normalizeNotNullDefaultValue(string $defaultValue, ColumnSchemaInterface $column): mixed
{
return parent::normalizeNotNullDefaultValue(rtrim($defaultValue), $column);
}
}
41 changes: 2 additions & 39 deletions src/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Throwable;
use Yiisoft\Db\Cache\SchemaCache;
use Yiisoft\Db\Connection\ConnectionInterface;
use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Constraint\CheckConstraint;
use Yiisoft\Db\Constraint\Constraint;
use Yiisoft\Db\Constraint\ForeignKeyConstraint;
Expand All @@ -16,7 +15,6 @@
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidConfigException;
use Yiisoft\Db\Exception\NotSupportedException;
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Helper\DbArrayHelper;
use Yiisoft\Db\Oracle\Column\ColumnFactory;
use Yiisoft\Db\Schema\Builder\ColumnInterface;
Expand All @@ -30,10 +28,7 @@
use function implode;
use function is_array;
use function md5;
use function preg_match;
use function serialize;
use function str_replace;
use function trim;

/**
* Implements the Oracle Server specific schema, supporting Oracle Server 11C and above.
Expand Down Expand Up @@ -449,9 +444,10 @@ protected function getTableSequenceName(string $tableName): string|null
*/
private function loadColumnSchema(array $info): ColumnSchemaInterface
{
$column = $this->getColumnFactory()->fromDbType($info['data_type'], [
return $this->getColumnFactory()->fromDbType($info['data_type'], [
'autoIncrement' => $info['identity_column'] === 'YES',
'comment' => $info['column_comment'],
'defaultValueRaw' => $info['data_default'],
'name' => $info['column_name'],
'notNull' => $info['nullable'] !== 'Y',
'primaryKey' => $info['constraint_type'] === 'P',
Expand All @@ -461,39 +457,6 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface
'table' => $info['table'],
'unique' => $info['constraint_type'] === 'U',
]);

return $column->defaultValue($this->normalizeDefaultValue($info['data_default'], $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 ($defaultValue === null || $column->isPrimaryKey()) {
return null;
}

$defaultValue = trim($defaultValue);

if ($defaultValue === 'NULL') {
return null;
}

if ($column->getType() === ColumnType::TIMESTAMP && $defaultValue === 'CURRENT_TIMESTAMP') {
return new Expression($defaultValue);
}

if (preg_match("/^'(.*)'$/s", $defaultValue, $matches) === 1) {
$defaultValue = str_replace("''", "'", $matches[1]);
}

return $column->phpTypecast($defaultValue);
}

/**
Expand Down
16 changes: 12 additions & 4 deletions tests/ColumnFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Yiisoft\Db\Oracle\Tests;

use PHPUnit\Framework\Attributes\DataProviderExternal;
use Yiisoft\Db\Oracle\Tests\Provider\ColumnFactoryProvider;
use Yiisoft\Db\Oracle\Tests\Support\TestTrait;
use Yiisoft\Db\Tests\AbstractColumnFactoryTest;

Expand All @@ -14,13 +16,13 @@ final class ColumnFactoryTest extends AbstractColumnFactoryTest
{
use TestTrait;

/** @dataProvider \Yiisoft\Db\Oracle\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\Oracle\Tests\Provider\ColumnFactoryProvider::definitions */
#[DataProviderExternal(ColumnFactoryProvider::class, 'definitions')]
public function testFromDefinition(
string $definition,
string $expectedType,
Expand All @@ -30,7 +32,7 @@ public function testFromDefinition(
parent::testFromDefinition($definition, $expectedType, $expectedInstanceOf, $expectedMethodResults);
}

/** @dataProvider \Yiisoft\Db\Oracle\Tests\Provider\ColumnFactoryProvider::pseudoTypes */
#[DataProviderExternal(ColumnFactoryProvider::class, 'pseudoTypes')]
public function testFromPseudoType(
string $pseudoType,
string $expectedType,
Expand All @@ -40,9 +42,15 @@ public function testFromPseudoType(
parent::testFromPseudoType($pseudoType, $expectedType, $expectedInstanceOf, $expectedMethodResults);
}

/** @dataProvider \Yiisoft\Db\Oracle\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);
}
}
13 changes: 13 additions & 0 deletions tests/Provider/ColumnFactoryProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Db\Oracle\Tests\Provider;

use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Oracle\Column\BinaryColumnSchema;
use Yiisoft\Db\Schema\Column\DoubleColumnSchema;
use Yiisoft\Db\Schema\Column\StringColumnSchema;
Expand Down Expand Up @@ -53,4 +54,16 @@ public static function definitions(): array

return $definitions;
}

public static function defaultValueRaw(): array
{
$defaultValueRaw = parent::defaultValueRaw();

$defaultValueRaw[] = [ColumnType::STRING, 'NULL ', null];
$defaultValueRaw[] = [ColumnType::STRING, "'str''ing' ", "str'ing"];
$defaultValueRaw[] = [ColumnType::INTEGER, '-1 ', -1];
$defaultValueRaw[] = [ColumnType::TIMESTAMP, 'now() ', new Expression('now()')];

return $defaultValueRaw;
}
}
6 changes: 3 additions & 3 deletions tests/Provider/SchemaProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public static function columns(): array
'enumValues' => null,
'size' => null,
'scale' => 6,
'defaultValue' => "to_timestamp('2002-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')",
'defaultValue' => new Expression("to_timestamp('2002-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')"),
],
'time_col' => [
'type' => 'time',
Expand All @@ -181,7 +181,7 @@ public static function columns(): array
'enumValues' => null,
'size' => 0,
'scale' => 0,
'defaultValue' => "INTERVAL '0 10:33:21' DAY(0) TO SECOND(0)",
'defaultValue' => new Expression("INTERVAL '0 10:33:21' DAY(0) TO SECOND(0)"),
],
'interval_day_col' => [
'type' => 'string',
Expand All @@ -193,7 +193,7 @@ public static function columns(): array
'enumValues' => null,
'size' => 1,
'scale' => 0,
'defaultValue' => "INTERVAL '2 04:56:12' DAY(1) TO SECOND(0)",
'defaultValue' => new Expression("INTERVAL '2 04:56:12' DAY(1) TO SECOND(0)"),
],
'bool_col' => [
'type' => 'char',
Expand Down

0 comments on commit f6c1d7e

Please sign in to comment.