Passed
Push — master ( bff06a...77db42 )
by Alexander
01:45
created

SchemaTest   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 313
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 221
dl 0
loc 313
rs 10
c 0
b 0
f 0
wmc 17

12 Methods

Rating   Name   Duplication   Size   Complexity  
A constraintsProvider() 0 9 1
A testSequenceName() 0 19 1
A testBooleanDefaultValues() 0 7 1
A testTimestampNullDefaultValue() 0 15 2
A testPartitionedTable() 0 11 2
A testCompositeFk() 0 11 1
A testFindSchemaNames() 0 5 1
A testGetPDOType() 0 20 2
A bigintValueProvider() 0 10 1
B getExpectedColumns() 0 134 1
A testParenthesisDefaultValue() 0 20 2
A testGeneratedValues() 0 15 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql\Tests;
6
7
use Yiisoft\Db\Conditions\ExistsConditionBuilder;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Conditions\ExistsConditionBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Yiisoft\Db\Expressions\Expression;
9
use Yiisoft\Db\Tests\SchemaTest as AbstractSchemaTest;
10
11
class SchemaTest extends AbstractSchemaTest
12
{
13
    public ?string $driverName = 'pgsql';
14
15
    protected array $expectedSchemas = [
16
        'public',
17
    ];
18
19
    public function getExpectedColumns()
20
    {
21
        $columns = parent::getExpectedColumns();
22
        unset($columns['enum_col']);
23
        $columns['int_col']['dbType'] = 'int4';
24
        $columns['int_col']['size'] = null;
25
        $columns['int_col']['precision'] = 32;
26
        $columns['int_col']['scale'] = 0;
27
        $columns['int_col2']['dbType'] = 'int4';
28
        $columns['int_col2']['size'] = null;
29
        $columns['int_col2']['precision'] = 32;
30
        $columns['int_col2']['scale'] = 0;
31
        $columns['tinyint_col']['type'] = 'smallint';
32
        $columns['tinyint_col']['dbType'] = 'int2';
33
        $columns['tinyint_col']['size'] = null;
34
        $columns['tinyint_col']['precision'] = 16;
35
        $columns['tinyint_col']['scale'] = 0;
36
        $columns['smallint_col']['dbType'] = 'int2';
37
        $columns['smallint_col']['size'] = null;
38
        $columns['smallint_col']['precision'] = 16;
39
        $columns['smallint_col']['scale'] = 0;
40
        $columns['char_col']['dbType'] = 'bpchar';
41
        $columns['char_col']['precision'] = null;
42
        $columns['char_col2']['dbType'] = 'varchar';
43
        $columns['char_col2']['precision'] = null;
44
        $columns['float_col']['dbType'] = 'float8';
45
        $columns['float_col']['precision'] = 53;
46
        $columns['float_col']['scale'] = null;
47
        $columns['float_col']['size'] = null;
48
        $columns['float_col2']['dbType'] = 'float8';
49
        $columns['float_col2']['precision'] = 53;
50
        $columns['float_col2']['scale'] = null;
51
        $columns['float_col2']['size'] = null;
52
        $columns['blob_col']['dbType'] = 'bytea';
53
        $columns['blob_col']['phpType'] = 'resource';
54
        $columns['blob_col']['type'] = 'binary';
55
        $columns['numeric_col']['dbType'] = 'numeric';
56
        $columns['numeric_col']['size'] = null;
57
        $columns['bool_col']['type'] = 'boolean';
58
        $columns['bool_col']['phpType'] = 'boolean';
59
        $columns['bool_col']['dbType'] = 'bool';
60
        $columns['bool_col']['size'] = null;
61
        $columns['bool_col']['precision'] = null;
62
        $columns['bool_col']['scale'] = null;
63
        $columns['bool_col2']['type'] = 'boolean';
64
        $columns['bool_col2']['phpType'] = 'boolean';
65
        $columns['bool_col2']['dbType'] = 'bool';
66
        $columns['bool_col2']['size'] = null;
67
        $columns['bool_col2']['precision'] = null;
68
        $columns['bool_col2']['scale'] = null;
69
        $columns['bool_col2']['defaultValue'] = true;
70
        $columns['ts_default']['defaultValue'] = new Expression('now()');
71
        $columns['bit_col']['dbType'] = 'bit';
72
        $columns['bit_col']['size'] = 8;
73
        $columns['bit_col']['precision'] = null;
74
        $columns['bigint_col'] = [
75
            'type' => 'bigint',
76
            'dbType' => 'int8',
77
            'phpType' => 'integer',
78
            'allowNull' => true,
79
            'autoIncrement' => false,
80
            'enumValues' => null,
81
            'size' => null,
82
            'precision' => 64,
83
            'scale' => 0,
84
            'defaultValue' => null,
85
        ];
86
        $columns['intarray_col'] = [
87
            'type' => 'integer',
88
            'dbType' => 'int4',
89
            'phpType' => 'integer',
90
            'allowNull' => true,
91
            'autoIncrement' => false,
92
            'enumValues' => null,
93
            'size' => null,
94
            'precision' => null,
95
            'scale' => null,
96
            'defaultValue' => null,
97
            'dimension' => 1
98
        ];
99
        $columns['textarray2_col'] = [
100
            'type' => 'text',
101
            'dbType' => 'text',
102
            'phpType' => 'string',
103
            'allowNull' => true,
104
            'autoIncrement' => false,
105
            'enumValues' => null,
106
            'size' => null,
107
            'precision' => null,
108
            'scale' => null,
109
            'defaultValue' => null,
110
            'dimension' => 2
111
        ];
112
        $columns['json_col'] = [
113
            'type' => 'json',
114
            'dbType' => 'json',
115
            'phpType' => 'array',
116
            'allowNull' => true,
117
            'autoIncrement' => false,
118
            'enumValues' => null,
119
            'size' => null,
120
            'precision' => null,
121
            'scale' => null,
122
            'defaultValue' => ["a" => 1],
123
            'dimension' => 0
124
        ];
125
        $columns['jsonb_col'] = [
126
            'type' => 'json',
127
            'dbType' => 'jsonb',
128
            'phpType' => 'array',
129
            'allowNull' => true,
130
            'autoIncrement' => false,
131
            'enumValues' => null,
132
            'size' => null,
133
            'precision' => null,
134
            'scale' => null,
135
            'defaultValue' => null,
136
            'dimension' => 0
137
        ];
138
        $columns['jsonarray_col'] = [
139
            'type' => 'json',
140
            'dbType' => 'json',
141
            'phpType' => 'array',
142
            'allowNull' => true,
143
            'autoIncrement' => false,
144
            'enumValues' => null,
145
            'size' => null,
146
            'precision' => null,
147
            'scale' => null,
148
            'defaultValue' => null,
149
            'dimension' => 1
150
        ];
151
152
        return $columns;
153
    }
154
155
    public function testCompositeFk()
156
    {
157
        $schema = $this->getConnection()->getSchema();
158
159
        $table = $schema->getTableSchema('composite_fk');
160
161
        $this->assertCount(1, $table->foreignKeys);
162
        $this->assertTrue(isset($table->foreignKeys['fk_composite_fk_order_item']));
163
        $this->assertEquals('order_item', $table->foreignKeys['fk_composite_fk_order_item'][0]);
164
        $this->assertEquals('order_id', $table->foreignKeys['fk_composite_fk_order_item']['order_id']);
165
        $this->assertEquals('item_id', $table->foreignKeys['fk_composite_fk_order_item']['item_id']);
166
    }
167
168
    public function testGetPDOType()
169
    {
170
        $values = [
171
            [null, \PDO::PARAM_NULL],
172
            ['', \PDO::PARAM_STR],
173
            ['hello', \PDO::PARAM_STR],
174
            [0, \PDO::PARAM_INT],
175
            [1, \PDO::PARAM_INT],
176
            [1337, \PDO::PARAM_INT],
177
            [true, \PDO::PARAM_BOOL],
178
            [false, \PDO::PARAM_BOOL],
179
            [$fp = fopen(__FILE__, 'rb'), \PDO::PARAM_LOB],
180
        ];
181
182
        $schema = $this->getConnection()->getSchema();
183
184
        foreach ($values as $value) {
185
            $this->assertEquals($value[1], $schema->getPdoType($value[0]));
186
        }
187
        fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

187
        fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
188
    }
189
190
    public function testBooleanDefaultValues()
191
    {
192
        $schema = $this->getConnection()->getSchema();
193
194
        $table = $schema->getTableSchema('bool_values');
195
        $this->assertTrue($table->getColumn('default_true')->defaultValue);
196
        $this->assertFalse($table->getColumn('default_false')->defaultValue);
197
    }
198
199
    public function testSequenceName()
200
    {
201
        $connection = $this->getConnection();
202
203
        $sequenceName = $connection->getSchema()->getTableSchema('item')->sequenceName;
204
205
        $connection->createCommand(
206
            'ALTER TABLE "item" ALTER COLUMN "id" SET DEFAULT nextval(\'item_id_seq_2\')'
207
        )->execute();
208
209
        $connection->getSchema()->refreshTableSchema('item');
210
        $this->assertEquals('item_id_seq_2', $connection->getSchema()->getTableSchema('item')->sequenceName);
211
212
        $connection->createCommand(
213
            'ALTER TABLE "item" ALTER COLUMN "id" SET DEFAULT nextval(\'' .  $sequenceName . '\')'
214
        )->execute();
215
216
        $connection->getSchema()->refreshTableSchema('item');
217
        $this->assertEquals($sequenceName, $connection->getSchema()->getTableSchema('item')->sequenceName);
218
    }
219
220
    public function testGeneratedValues()
221
    {
222
        if (version_compare($this->getConnection(false)->getServerVersion(), '12.0', '<')) {
223
            $this->markTestSkipped('PostgreSQL < 12.0 does not support GENERATED AS IDENTITY columns.');
224
        }
225
226
        $config = $this->database;
0 ignored issues
show
Bug introduced by
The property database does not exist on Yiisoft\Db\Pgsql\Tests\SchemaTest. Did you mean databases?
Loading history...
227
        unset($config['fixture']);
228
        $this->prepareDatabase($config, realpath(__DIR__ . '/../../../data') . '/postgres12.sql');
0 ignored issues
show
Bug introduced by
realpath(__DIR__ . '/../...a') . '/postgres12.sql' of type string is incompatible with the type boolean expected by parameter $open of Yiisoft\Db\Tests\Databas...Case::prepareDatabase(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

228
        $this->prepareDatabase($config, /** @scrutinizer ignore-type */ realpath(__DIR__ . '/../../../data') . '/postgres12.sql');
Loading history...
229
230
        $table = $this->getConnection(false)->getSchema()->getTableSchema('generated');
231
        $this->assertTrue($table->getColumn('id_always')->autoIncrement);
232
        $this->assertTrue($table->getColumn('id_primary')->autoIncrement);
233
        $this->assertTrue($table->getColumn('id_primary')->isPrimaryKey);
234
        $this->assertTrue($table->getColumn('id_default')->autoIncrement);
235
    }
236
237
    public function testPartitionedTable()
238
    {
239
        if (version_compare($this->getConnection(false)->getServerVersion(), '10.0', '<')) {
240
            $this->markTestSkipped('PostgreSQL < 10.0 does not support PARTITION BY clause.');
241
        }
242
243
        $config = $this->database;
0 ignored issues
show
Bug introduced by
The property database does not exist on Yiisoft\Db\Pgsql\Tests\SchemaTest. Did you mean databases?
Loading history...
244
        unset($config['fixture']);
245
        $this->prepareDatabase($config, realpath(__DIR__ . '/../../../data') . '/postgres10.sql');
0 ignored issues
show
Bug introduced by
realpath(__DIR__ . '/../...a') . '/postgres10.sql' of type string is incompatible with the type boolean expected by parameter $open of Yiisoft\Db\Tests\Databas...Case::prepareDatabase(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

245
        $this->prepareDatabase($config, /** @scrutinizer ignore-type */ realpath(__DIR__ . '/../../../data') . '/postgres10.sql');
Loading history...
246
247
        $this->assertNotNull($this->getConnection(false)->getSchema()->getTableSchema('partitioned'));
248
    }
249
250
    public function testFindSchemaNames()
251
    {
252
        $schema = $this->getConnection()->getSchema();
253
254
        $this->assertCount(3, $schema->getSchemaNames());
255
    }
256
257
    public function bigintValueProvider()
258
    {
259
        return [
260
            [8817806877],
261
            [3797444208],
262
            [3199585540],
263
            [1389831585],
264
            [922337203685477580],
265
            [9223372036854775807],
266
            [-9223372036854775808],
267
        ];
268
    }
269
270
    /**
271
     * @see https://github.com/yiisoft/yii2/issues/12483
272
     */
273
    public function testParenthesisDefaultValue()
274
    {
275
        $db = $this->getConnection(false);
276
        if ($db->getSchema()->getTableSchema('test_default_parenthesis') !== null) {
277
            $db->createCommand()->dropTable('test_default_parenthesis')->execute();
278
        }
279
280
        $db->createCommand()->createTable('test_default_parenthesis', [
281
            'id' => 'pk',
282
            'user_timezone' => 'numeric(5,2) DEFAULT (0)::numeric NOT NULL',
283
        ])->execute();
284
285
        $db->getSchema()->refreshTableSchema('test_default_parenthesis');
286
        $tableSchema = $db->getSchema()->getTableSchema('test_default_parenthesis');
287
        $this->assertNotNull($tableSchema);
288
        $column = $tableSchema->getColumn('user_timezone');
289
        $this->assertNotNull($column);
290
        $this->assertFalse($column->allowNull);
291
        $this->assertEquals('numeric', $column->dbType);
292
        $this->assertEquals(0, $column->defaultValue);
293
    }
294
295
    /**
296
     * @see https://github.com/yiisoft/yii2/issues/14192
297
     */
298
    public function testTimestampNullDefaultValue()
299
    {
300
        $db = $this->getConnection(false);
301
        if ($db->getSchema()->getTableSchema('test_timestamp_default_null') !== null) {
302
            $db->createCommand()->dropTable('test_timestamp_default_null')->execute();
303
        }
304
305
        $db->createCommand()->createTable('test_timestamp_default_null', [
306
            'id' => 'pk',
307
            'timestamp' => 'timestamp DEFAULT NULL',
308
        ])->execute();
309
310
        $db->getSchema()->refreshTableSchema('test_timestamp_default_null');
311
        $tableSchema = $db->getSchema()->getTableSchema('test_timestamp_default_null');
312
        $this->assertNull($tableSchema->getColumn('timestamp')->defaultValue);
313
    }
314
315
    public function constraintsProvider(): array
316
    {
317
        $result = parent::constraintsProvider();
318
319
        $result['1: check'][2][0]->setExpression('CHECK ((("C_check")::text <> \'\'::text))');
320
        //$result['3: foreign key'][2][0]->setForeignSchemaName('public');
321
        $result['3: index'][2] = [];
322
323
        return $result;
324
    }
325
}
326