Skip to content

Commit b59bcd2

Browse files
committed
fix default value CURRENT_TIMESTAMP
1 parent 574d04f commit b59bcd2

8 files changed

+33
-40
lines changed

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
}
1515
],
1616
"require": {
17-
"yiisoft/yii2": "^2.0.14.1"
17+
"yiisoft/yii2": "^2.0.29"
1818
},
1919
"require-dev": {
2020
"phpunit/phpunit": "4.8.34"

src/Schema.php

+17-9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class Schema extends \yii\db\pgsql\Schema
2020
const TYPE_BIT = 'bit';
2121
const TYPE_COMPOSITE = 'composite';
2222

23+
const DATE_TYPES = [self::TYPE_TIMESTAMP, self::TYPE_DATETIME, self::TYPE_DATE, self::TYPE_TIME];
24+
const CURRENT_TIME_DEFAULTS = ['now()', 'CURRENT_TIMESTAMP', 'CURRENT_DATE', 'CURRENT_TIME'];
25+
2326
/**
2427
* @var array mapping from composite column types (keys) to PHP types (classes in configuration style).
2528
* `array` by default, `object` also available as PHP type then a result will be converted to \stdClass.
@@ -62,6 +65,12 @@ protected function findColumns($table)
6265
{
6366
$tableName = $this->db->quoteValue($table->name);
6467
$schemaName = $this->db->quoteValue($table->schemaName);
68+
69+
$orIdentity = '';
70+
if (version_compare($this->db->serverVersion, '12.0', '>=')) {
71+
$orIdentity = 'OR a.attidentity != \'\'';
72+
}
73+
6574
$sql = <<<SQL
6675
SELECT
6776
d.nspname AS table_schema,
@@ -74,7 +83,8 @@ protected function findColumns($table)
7483
COALESCE(NULLIF(a.atttypmod, -1), t.typtypmod) AS modifier,
7584
NOT (a.attnotnull OR t.typnotnull) AS is_nullable,
7685
COALESCE(t.typdefault, pg_get_expr(ad.adbin, ad.adrelid)::varchar) AS column_default,
77-
COALESCE(pg_get_expr(ad.adbin, ad.adrelid) ~ 'nextval', false) AS is_autoinc,
86+
COALESCE(pg_get_expr(ad.adbin, ad.adrelid) ~ 'nextval', false) {$orIdentity} AS is_autoinc,
87+
pg_get_serial_sequence(quote_ident(d.nspname) || '.' || quote_ident(c.relname), a.attname) AS sequence_name,
7888
CASE WHEN COALESCE(td.typtype, tb.typtype, t.typtype) = 'e'::char
7989
THEN array_to_string((SELECT array_agg(enumlabel) FROM pg_enum WHERE enumtypid = COALESCE(td.oid, tb.oid, a.atttypid))::varchar[], ',')
8090
ELSE NULL
@@ -95,7 +105,7 @@ protected function findColumns($table)
95105
LEFT JOIN pg_namespace d ON d.oid = c.relnamespace
96106
LEFT JOIN pg_constraint ct ON ct.conrelid = c.oid AND ct.contype = 'p'
97107
WHERE
98-
a.attnum > 0 AND t.typname != ''
108+
a.attnum > 0 AND t.typname != '' AND NOT a.attisdropped
99109
AND c.relname = {$tableName}
100110
AND d.nspname = {$schemaName}
101111
ORDER BY
@@ -114,16 +124,14 @@ protected function findColumns($table)
114124
$table->columns[$column->name] = $column;
115125
if ($column->isPrimaryKey) {
116126
$table->primaryKey[] = $column->name;
117-
if ($table->sequenceName === null && preg_match("/nextval\\('\"?\\w+\"?\.?\"?\\w+\"?'(::regclass)?\\)/", $column->defaultValue) === 1) {
118-
$table->sequenceName = preg_replace(['/nextval/', '/::/', '/regclass/', '/\'\)/', '/\(\'/'], '', $column->defaultValue);
127+
if ($table->sequenceName === null) {
128+
$table->sequenceName = $column->sequenceName;
119129
}
120130
$column->defaultValue = null;
121131
} elseif ($column->defaultValue) {
122-
if (in_array($column->type, [static::TYPE_TIMESTAMP, static::TYPE_DATETIME, static::TYPE_DATE, static::TYPE_TIME]) && $column->defaultValue === 'now()') {
123-
$column->defaultValue = new \DateTime;
124-
} elseif ($column->type === static::TYPE_BIT && !$column->dimension) {
125-
$column->defaultValue = $column->phpTypecast(trim($column->defaultValue, 'B\''));
126-
} elseif (preg_match("/^'(.*?)'::/", $column->defaultValue, $matches)) {
132+
if (in_array($column->type, static::DATE_TYPES) && in_array($column->defaultValue, static::CURRENT_TIME_DEFAULTS)) {
133+
$column->defaultValue = new \DateTime();
134+
} elseif (preg_match("/^B?'(.*?)'::/", $column->defaultValue, $matches)) {
127135
$column->defaultValue = $column->phpTypecast($matches[1]);
128136
} elseif (preg_match('/^(\()?(.*?)(?(1)\))(?:::.+)?$/', $column->defaultValue, $matches)) {
129137
if ($matches[2] === 'NULL') {

tests/ActiveRecordCompositeTest.php

-8
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ protected function setUp()
1616
if (file_exists(__DIR__ . '/data/config.local.php')) {
1717
$config = ArrayHelper::merge($config, require(__DIR__ . '/data/config.local.php'));
1818
}
19-
if (is_array($config['components']['db']['schemaMap']['pgsql'])) {
20-
$config['components']['db']['schemaMap']['pgsql']['compositeMap']['money'] = '\tigrov\tests\unit\pgsql\data\Money';
21-
} else {
22-
$config['components']['db']['schemaMap']['pgsql'] = [
23-
'class' => $config['components']['db']['schemaMap']['pgsql'],
24-
'compositeMap' => ['money' => '\tigrov\tests\unit\pgsql\data\Money'],
25-
];
26-
}
2719

2820
$this->mockApplication($config);
2921
$this->createDatatypesTable();

tests/ActiveRecordTest.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace tigrov\tests\unit\pgsql;
44

55
use tigrov\tests\unit\pgsql\data\Datatypes;
6+
use tigrov\tests\unit\pgsql\data\Money;
67
use yii\helpers\ArrayHelper;
78

89
class ActiveRecordTest extends TestCase
@@ -106,6 +107,7 @@ public function testDefaults()
106107
// For default values see TestCase::createDatatypesTable()
107108
$now = new \DateTime;
108109
$this->assertLessThanOrEqual(1, static::convertIntervalToSeconds($now->diff($model->datetime)));
110+
$this->assertLessThanOrEqual(1, static::convertIntervalToSeconds($now->diff($model->datetime2)));
109111
foreach ($model->datetimes as $datetime) {
110112
$this->assertLessThanOrEqual(1, static::convertIntervalToSeconds($now->diff($datetime)));
111113
}
@@ -121,8 +123,8 @@ public function testDefaults()
121123
$this->assertSame(true, $model->boolean);
122124
$this->assertSame(1, $model->smallint);
123125
$this->assertNull($model->timestamp);
124-
$this->assertSame(['value' => '1.0000', 'currency_code' => 'USD'], $model->price);
125-
$this->assertSame([['value' => '1.0000', 'currency_code' => 'USD']], $model->prices);
126+
$this->assertEquals(new Money(['value' => '1.0000', 'currency_code' => 'USD']), $model->price);
127+
$this->assertEquals([new Money(['value' => '1.0000', 'currency_code' => 'USD'])], $model->prices);
126128
$this->assertSame('USD', $model->currency_code);
127129
$this->assertSame('test', $model->binary);
128130
$this->assertSame(['test'], $model->binaries);
@@ -199,9 +201,9 @@ public function valuesProvider()
199201
['json', ['key' => 'value']],
200202
['json', ['key1' => 'value1', 'key2' => true, 'key3' => false, 'key4' => '', 'key5' => null]],
201203
['json', ['key' => ['key' => ['key' => 'value']]]],
202-
['price', ['value' => null, 'currency_code' => 'EUR']],
203-
['price', ['value' => '10.0000', 'currency_code' => 'USD']],
204-
['prices', [['value' => '10.0000', 'currency_code' => 'USD'], ['value' => '99.9999', 'currency_code' => 'EUR']]],
204+
['price', new Money(['value' => null, 'currency_code' => 'EUR']), false],
205+
['price', new Money(['value' => '10.0000', 'currency_code' => 'USD']), false],
206+
['prices', [new Money(['value' => '10.0000', 'currency_code' => 'USD']), new Money(['value' => '99.9999', 'currency_code' => 'EUR'])], false],
205207
['binary', 'string'],
206208
['binaries', ['string']],
207209
];

tests/SchemaTest.php

-8
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@ protected function setUp()
1515
if (file_exists(__DIR__ . '/data/config.local.php')) {
1616
$config = ArrayHelper::merge($config, require(__DIR__ . '/data/config.local.php'));
1717
}
18-
if (is_array($config['components']['db']['schemaMap']['pgsql'])) {
19-
$config['components']['db']['schemaMap']['pgsql']['compositeMap']['money'] = '\tigrov\tests\unit\pgsql\data\Money';
20-
} else {
21-
$config['components']['db']['schemaMap']['pgsql'] = [
22-
'class' => $config['components']['db']['schemaMap']['pgsql'],
23-
'compositeMap' => ['money' => '\tigrov\tests\unit\pgsql\data\Money'],
24-
];
25-
}
2618

2719
$this->mockApplication($config);
2820
$this->createDatatypesTable();

tests/SchemaViewTest.php

-8
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,6 @@ protected function setUp()
1717
if (file_exists(__DIR__ . '/data/config.local.php')) {
1818
$config = ArrayHelper::merge($config, require(__DIR__ . '/data/config.local.php'));
1919
}
20-
if (is_array($config['components']['db']['schemaMap']['pgsql'])) {
21-
$config['components']['db']['schemaMap']['pgsql']['compositeMap']['money'] = '\tigrov\tests\unit\pgsql\data\Money';
22-
} else {
23-
$config['components']['db']['schemaMap']['pgsql'] = [
24-
'class' => $config['components']['db']['schemaMap']['pgsql'],
25-
'compositeMap' => ['money' => '\tigrov\tests\unit\pgsql\data\Money'],
26-
];
27-
}
2820

2921
$this->mockApplication($config);
3022
$this->createDatatypesTable();

tests/TestCase.php

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ protected function createDatatypesTable()
8383
'varbit' => 'varbit DEFAULT \'B101\'',
8484
'bits' => 'varbit[] DEFAULT \'{101}\'',
8585
'datetime' => 'timestamp DEFAULT now()',
86+
'datetime2' => 'timestamp DEFAULT CURRENT_TIMESTAMP',
8687
'datetimes' => 'timestamp[] DEFAULT \'{now(),now()}\'',
8788
'json' => 'jsonb DEFAULT \'[]\'',
8889
'boolean' => 'boolean DEFAULT true',
@@ -115,5 +116,6 @@ protected function dropDatatypesTable()
115116
$db->createCommand('DROP TABLE IF EXISTS ' . static::TABLENAME . ' CASCADE')->execute();
116117
$db->createCommand('DROP TYPE IF EXISTS ' . $moneyType . ' CASCADE')->execute();
117118
$db->createCommand('DROP DOMAIN IF EXISTS ' . $currencyType . ' CASCADE')->execute();
119+
$db->close();
118120
}
119121
}

tests/data/config.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
'password' => '',
1010
'charset' => 'utf8',
1111
'schemaMap' => [
12-
'pgsql'=> 'tigrov\pgsql\Schema',
12+
'pgsql'=> [
13+
'class' => 'tigrov\pgsql\Schema',
14+
'compositeMap' => [
15+
'money' => '\tigrov\tests\unit\pgsql\data\Money'
16+
],
17+
],
1318
],
1419
],
1520
],

0 commit comments

Comments
 (0)