1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Doctrine\Tests\DBAL\Schema; |
4
|
|
|
|
5
|
|
|
use Doctrine\DBAL\Schema\Schema; |
6
|
|
|
use Doctrine\DBAL\Schema\SchemaConfig; |
7
|
|
|
use Doctrine\DBAL\Schema\SchemaException; |
8
|
|
|
use Doctrine\DBAL\Schema\Sequence; |
9
|
|
|
use Doctrine\DBAL\Schema\Table; |
10
|
|
|
use Doctrine\DBAL\Schema\Visitor\AbstractVisitor; |
11
|
|
|
use Doctrine\DBAL\Schema\Visitor\Visitor; |
12
|
|
|
use PHPUnit\Framework\TestCase; |
13
|
|
|
use ReflectionProperty; |
14
|
|
|
use function current; |
15
|
|
|
use function strlen; |
16
|
|
|
|
17
|
|
|
class SchemaTest extends TestCase |
18
|
|
|
{ |
19
|
|
|
public function testAddTable() : void |
20
|
|
|
{ |
21
|
|
|
$tableName = 'public.foo'; |
22
|
|
|
$table = new Table($tableName); |
23
|
|
|
|
24
|
|
|
$schema = new Schema([$table]); |
25
|
|
|
|
26
|
|
|
self::assertTrue($schema->hasTable($tableName)); |
27
|
|
|
|
28
|
|
|
$tables = $schema->getTables(); |
29
|
|
|
self::assertArrayHasKey($tableName, $tables); |
30
|
|
|
self::assertSame($table, $tables[$tableName]); |
31
|
|
|
self::assertSame($table, $schema->getTable($tableName)); |
32
|
|
|
self::assertTrue($schema->hasTable($tableName)); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
View Code Duplication |
public function testTableMatchingCaseInsensitive() : void |
|
|
|
|
36
|
|
|
{ |
37
|
|
|
$table = new Table('Foo'); |
38
|
|
|
|
39
|
|
|
$schema = new Schema([$table]); |
40
|
|
|
self::assertTrue($schema->hasTable('foo')); |
41
|
|
|
self::assertTrue($schema->hasTable('FOO')); |
42
|
|
|
|
43
|
|
|
self::assertSame($table, $schema->getTable('FOO')); |
44
|
|
|
self::assertSame($table, $schema->getTable('foo')); |
45
|
|
|
self::assertSame($table, $schema->getTable('Foo')); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
public function testGetUnknownTableThrowsException() : void |
49
|
|
|
{ |
50
|
|
|
$this->expectException(SchemaException::class); |
51
|
|
|
|
52
|
|
|
$schema = new Schema(); |
53
|
|
|
$schema->getTable('unknown'); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
public function testCreateTableTwiceThrowsException() : void |
57
|
|
|
{ |
58
|
|
|
$this->expectException(SchemaException::class); |
59
|
|
|
|
60
|
|
|
$tableName = 'foo'; |
61
|
|
|
$table = new Table($tableName); |
62
|
|
|
$tables = [$table, $table]; |
63
|
|
|
|
64
|
|
|
$schema = new Schema($tables); |
|
|
|
|
65
|
|
|
} |
66
|
|
|
|
67
|
|
View Code Duplication |
public function testRenameTable() : void |
|
|
|
|
68
|
|
|
{ |
69
|
|
|
$tableName = 'foo'; |
70
|
|
|
$table = new Table($tableName); |
71
|
|
|
$schema = new Schema([$table]); |
72
|
|
|
|
73
|
|
|
self::assertTrue($schema->hasTable('foo')); |
74
|
|
|
$schema->renameTable('foo', 'bar'); |
75
|
|
|
self::assertFalse($schema->hasTable('foo')); |
76
|
|
|
self::assertTrue($schema->hasTable('bar')); |
77
|
|
|
self::assertSame($table, $schema->getTable('bar')); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
public function testDropTable() : void |
81
|
|
|
{ |
82
|
|
|
$tableName = 'foo'; |
83
|
|
|
$table = new Table($tableName); |
84
|
|
|
$schema = new Schema([$table]); |
85
|
|
|
|
86
|
|
|
self::assertTrue($schema->hasTable('foo')); |
87
|
|
|
|
88
|
|
|
$schema->dropTable('foo'); |
89
|
|
|
|
90
|
|
|
self::assertFalse($schema->hasTable('foo')); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
public function testCreateTable() : void |
94
|
|
|
{ |
95
|
|
|
$schema = new Schema(); |
96
|
|
|
|
97
|
|
|
self::assertFalse($schema->hasTable('foo')); |
98
|
|
|
|
99
|
|
|
$table = $schema->createTable('foo'); |
100
|
|
|
|
101
|
|
|
self::assertInstanceOf(Table::class, $table); |
102
|
|
|
self::assertEquals('foo', $table->getName()); |
103
|
|
|
self::assertTrue($schema->hasTable('foo')); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
public function testAddSequences() : void |
107
|
|
|
{ |
108
|
|
|
$sequence = new Sequence('a_seq', 1, 1); |
109
|
|
|
|
110
|
|
|
$schema = new Schema([], [$sequence]); |
111
|
|
|
|
112
|
|
|
self::assertTrue($schema->hasSequence('a_seq')); |
113
|
|
|
self::assertInstanceOf(Sequence::class, $schema->getSequence('a_seq')); |
114
|
|
|
|
115
|
|
|
$sequences = $schema->getSequences(); |
116
|
|
|
self::assertArrayHasKey('public.a_seq', $sequences); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
View Code Duplication |
public function testSequenceAccessCaseInsensitive() : void |
|
|
|
|
120
|
|
|
{ |
121
|
|
|
$sequence = new Sequence('a_Seq'); |
122
|
|
|
|
123
|
|
|
$schema = new Schema([], [$sequence]); |
124
|
|
|
self::assertTrue($schema->hasSequence('a_seq')); |
125
|
|
|
self::assertTrue($schema->hasSequence('a_Seq')); |
126
|
|
|
self::assertTrue($schema->hasSequence('A_SEQ')); |
127
|
|
|
|
128
|
|
|
self::assertEquals($sequence, $schema->getSequence('a_seq')); |
129
|
|
|
self::assertEquals($sequence, $schema->getSequence('a_Seq')); |
130
|
|
|
self::assertEquals($sequence, $schema->getSequence('A_SEQ')); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
public function testGetUnknownSequenceThrowsException() : void |
134
|
|
|
{ |
135
|
|
|
$this->expectException(SchemaException::class); |
136
|
|
|
|
137
|
|
|
$schema = new Schema(); |
138
|
|
|
$schema->getSequence('unknown'); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
public function testCreateSequence() : void |
142
|
|
|
{ |
143
|
|
|
$schema = new Schema(); |
144
|
|
|
$sequence = $schema->createSequence('a_seq', 10, 20); |
145
|
|
|
|
146
|
|
|
self::assertEquals('a_seq', $sequence->getName()); |
147
|
|
|
self::assertEquals(10, $sequence->getAllocationSize()); |
148
|
|
|
self::assertEquals(20, $sequence->getInitialValue()); |
149
|
|
|
|
150
|
|
|
self::assertTrue($schema->hasSequence('a_seq')); |
151
|
|
|
self::assertInstanceOf(Sequence::class, $schema->getSequence('a_seq')); |
152
|
|
|
|
153
|
|
|
$sequences = $schema->getSequences(); |
154
|
|
|
self::assertArrayHasKey('public.a_seq', $sequences); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
public function testDropSequence() : void |
158
|
|
|
{ |
159
|
|
|
$sequence = new Sequence('a_seq', 1, 1); |
160
|
|
|
|
161
|
|
|
$schema = new Schema([], [$sequence]); |
162
|
|
|
|
163
|
|
|
$schema->dropSequence('a_seq'); |
164
|
|
|
self::assertFalse($schema->hasSequence('a_seq')); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
public function testAddSequenceTwiceThrowsException() : void |
168
|
|
|
{ |
169
|
|
|
$this->expectException(SchemaException::class); |
170
|
|
|
|
171
|
|
|
$sequence = new Sequence('a_seq', 1, 1); |
172
|
|
|
|
173
|
|
|
$schema = new Schema([], [$sequence, $sequence]); |
|
|
|
|
174
|
|
|
} |
175
|
|
|
|
176
|
|
View Code Duplication |
public function testConfigMaxIdentifierLength() : void |
|
|
|
|
177
|
|
|
{ |
178
|
|
|
$schemaConfig = new SchemaConfig(); |
179
|
|
|
$schemaConfig->setMaxIdentifierLength(5); |
180
|
|
|
|
181
|
|
|
$schema = new Schema([], [], $schemaConfig); |
182
|
|
|
$table = $schema->createTable('smalltable'); |
183
|
|
|
$table->addColumn('long_id', 'integer'); |
184
|
|
|
$table->addIndex(['long_id']); |
185
|
|
|
|
186
|
|
|
$index = current($table->getIndexes()); |
187
|
|
|
self::assertEquals(5, strlen($index->getName())); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
public function testDeepClone() : void |
191
|
|
|
{ |
192
|
|
|
$schema = new Schema(); |
193
|
|
|
$sequence = $schema->createSequence('baz'); |
194
|
|
|
|
195
|
|
|
$tableA = $schema->createTable('foo'); |
196
|
|
|
$tableA->addColumn('id', 'integer'); |
197
|
|
|
|
198
|
|
|
$tableB = $schema->createTable('bar'); |
199
|
|
|
$tableB->addColumn('id', 'integer'); |
200
|
|
|
$tableB->addColumn('foo_id', 'integer'); |
201
|
|
|
$tableB->addForeignKeyConstraint($tableA, ['foo_id'], ['id']); |
202
|
|
|
|
203
|
|
|
$schemaNew = clone $schema; |
204
|
|
|
|
205
|
|
|
self::assertNotSame($sequence, $schemaNew->getSequence('baz')); |
206
|
|
|
|
207
|
|
|
self::assertNotSame($tableA, $schemaNew->getTable('foo')); |
208
|
|
|
self::assertNotSame($tableA->getColumn('id'), $schemaNew->getTable('foo')->getColumn('id')); |
209
|
|
|
|
210
|
|
|
self::assertNotSame($tableB, $schemaNew->getTable('bar')); |
211
|
|
|
self::assertNotSame($tableB->getColumn('id'), $schemaNew->getTable('bar')->getColumn('id')); |
212
|
|
|
|
213
|
|
|
$fk = $schemaNew->getTable('bar')->getForeignKeys(); |
214
|
|
|
$fk = current($fk); |
215
|
|
|
|
216
|
|
|
$re = new ReflectionProperty($fk, '_localTable'); |
217
|
|
|
$re->setAccessible(true); |
218
|
|
|
|
219
|
|
|
self::assertSame($schemaNew->getTable('bar'), $re->getValue($fk)); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* @group DBAL-219 |
224
|
|
|
*/ |
225
|
|
|
public function testHasTableForQuotedAsset() : void |
226
|
|
|
{ |
227
|
|
|
$schema = new Schema(); |
228
|
|
|
|
229
|
|
|
$tableA = $schema->createTable('foo'); |
230
|
|
|
$tableA->addColumn('id', 'integer'); |
231
|
|
|
|
232
|
|
|
self::assertTrue($schema->hasTable('`foo`')); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* @group DBAL-669 |
237
|
|
|
*/ |
238
|
|
|
public function testHasNamespace() : void |
239
|
|
|
{ |
240
|
|
|
$schema = new Schema(); |
241
|
|
|
|
242
|
|
|
self::assertFalse($schema->hasNamespace('foo')); |
243
|
|
|
|
244
|
|
|
$schema->createTable('foo'); |
245
|
|
|
|
246
|
|
|
self::assertFalse($schema->hasNamespace('foo')); |
247
|
|
|
|
248
|
|
|
$schema->createTable('bar.baz'); |
249
|
|
|
|
250
|
|
|
self::assertFalse($schema->hasNamespace('baz')); |
251
|
|
|
self::assertTrue($schema->hasNamespace('bar')); |
252
|
|
|
self::assertFalse($schema->hasNamespace('tab')); |
253
|
|
|
|
254
|
|
|
$schema->createTable('tab.taz'); |
255
|
|
|
|
256
|
|
|
self::assertTrue($schema->hasNamespace('tab')); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @group DBAL-669 |
261
|
|
|
*/ |
262
|
|
|
public function testCreatesNamespace() : void |
263
|
|
|
{ |
264
|
|
|
$schema = new Schema(); |
265
|
|
|
|
266
|
|
|
self::assertFalse($schema->hasNamespace('foo')); |
267
|
|
|
|
268
|
|
|
$schema->createNamespace('foo'); |
269
|
|
|
|
270
|
|
|
self::assertTrue($schema->hasNamespace('foo')); |
271
|
|
|
self::assertTrue($schema->hasNamespace('FOO')); |
272
|
|
|
self::assertTrue($schema->hasNamespace('`foo`')); |
273
|
|
|
self::assertTrue($schema->hasNamespace('`FOO`')); |
274
|
|
|
|
275
|
|
|
$schema->createNamespace('`bar`'); |
276
|
|
|
|
277
|
|
|
self::assertTrue($schema->hasNamespace('bar')); |
278
|
|
|
self::assertTrue($schema->hasNamespace('BAR')); |
279
|
|
|
self::assertTrue($schema->hasNamespace('`bar`')); |
280
|
|
|
self::assertTrue($schema->hasNamespace('`BAR`')); |
281
|
|
|
|
282
|
|
|
self::assertSame(['foo' => 'foo', 'bar' => '`bar`'], $schema->getNamespaces()); |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* @group DBAL-669 |
287
|
|
|
*/ |
288
|
|
|
public function testThrowsExceptionOnCreatingNamespaceTwice() : void |
289
|
|
|
{ |
290
|
|
|
$schema = new Schema(); |
291
|
|
|
|
292
|
|
|
$schema->createNamespace('foo'); |
293
|
|
|
|
294
|
|
|
$this->expectException(SchemaException::class); |
295
|
|
|
|
296
|
|
|
$schema->createNamespace('foo'); |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* @group DBAL-669 |
301
|
|
|
*/ |
302
|
|
View Code Duplication |
public function testCreatesNamespaceThroughAddingTableImplicitly() : void |
|
|
|
|
303
|
|
|
{ |
304
|
|
|
$schema = new Schema(); |
305
|
|
|
|
306
|
|
|
self::assertFalse($schema->hasNamespace('foo')); |
307
|
|
|
|
308
|
|
|
$schema->createTable('baz'); |
309
|
|
|
|
310
|
|
|
self::assertFalse($schema->hasNamespace('foo')); |
311
|
|
|
self::assertFalse($schema->hasNamespace('baz')); |
312
|
|
|
|
313
|
|
|
$schema->createTable('foo.bar'); |
314
|
|
|
|
315
|
|
|
self::assertTrue($schema->hasNamespace('foo')); |
316
|
|
|
self::assertFalse($schema->hasNamespace('bar')); |
317
|
|
|
|
318
|
|
|
$schema->createTable('`baz`.bloo'); |
319
|
|
|
|
320
|
|
|
self::assertTrue($schema->hasNamespace('baz')); |
321
|
|
|
self::assertFalse($schema->hasNamespace('bloo')); |
322
|
|
|
|
323
|
|
|
$schema->createTable('`baz`.moo'); |
324
|
|
|
|
325
|
|
|
self::assertTrue($schema->hasNamespace('baz')); |
326
|
|
|
self::assertFalse($schema->hasNamespace('moo')); |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
/** |
330
|
|
|
* @group DBAL-669 |
331
|
|
|
*/ |
332
|
|
View Code Duplication |
public function testCreatesNamespaceThroughAddingSequenceImplicitly() : void |
|
|
|
|
333
|
|
|
{ |
334
|
|
|
$schema = new Schema(); |
335
|
|
|
|
336
|
|
|
self::assertFalse($schema->hasNamespace('foo')); |
337
|
|
|
|
338
|
|
|
$schema->createSequence('baz'); |
339
|
|
|
|
340
|
|
|
self::assertFalse($schema->hasNamespace('foo')); |
341
|
|
|
self::assertFalse($schema->hasNamespace('baz')); |
342
|
|
|
|
343
|
|
|
$schema->createSequence('foo.bar'); |
344
|
|
|
|
345
|
|
|
self::assertTrue($schema->hasNamespace('foo')); |
346
|
|
|
self::assertFalse($schema->hasNamespace('bar')); |
347
|
|
|
|
348
|
|
|
$schema->createSequence('`baz`.bloo'); |
349
|
|
|
|
350
|
|
|
self::assertTrue($schema->hasNamespace('baz')); |
351
|
|
|
self::assertFalse($schema->hasNamespace('bloo')); |
352
|
|
|
|
353
|
|
|
$schema->createSequence('`baz`.moo'); |
354
|
|
|
|
355
|
|
|
self::assertTrue($schema->hasNamespace('baz')); |
356
|
|
|
self::assertFalse($schema->hasNamespace('moo')); |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* @group DBAL-669 |
361
|
|
|
*/ |
362
|
|
|
public function testVisitsVisitor() : void |
363
|
|
|
{ |
364
|
|
|
$schema = new Schema(); |
365
|
|
|
$visitor = $this->createMock(Visitor::class); |
366
|
|
|
|
367
|
|
|
$schema->createNamespace('foo'); |
368
|
|
|
$schema->createNamespace('bar'); |
369
|
|
|
|
370
|
|
|
$schema->createTable('baz'); |
371
|
|
|
$schema->createTable('bla.bloo'); |
372
|
|
|
|
373
|
|
|
$schema->createSequence('moo'); |
374
|
|
|
$schema->createSequence('war'); |
375
|
|
|
|
376
|
|
|
$visitor->expects($this->once()) |
377
|
|
|
->method('acceptSchema') |
378
|
|
|
->with($schema); |
379
|
|
|
|
380
|
|
|
$visitor->expects($this->at(1)) |
381
|
|
|
->method('acceptTable') |
382
|
|
|
->with($schema->getTable('baz')); |
383
|
|
|
|
384
|
|
|
$visitor->expects($this->at(2)) |
385
|
|
|
->method('acceptTable') |
386
|
|
|
->with($schema->getTable('bla.bloo')); |
387
|
|
|
|
388
|
|
|
$visitor->expects($this->exactly(2)) |
389
|
|
|
->method('acceptTable'); |
390
|
|
|
|
391
|
|
|
$visitor->expects($this->at(3)) |
392
|
|
|
->method('acceptSequence') |
393
|
|
|
->with($schema->getSequence('moo')); |
394
|
|
|
|
395
|
|
|
$visitor->expects($this->at(4)) |
396
|
|
|
->method('acceptSequence') |
397
|
|
|
->with($schema->getSequence('war')); |
398
|
|
|
|
399
|
|
|
$visitor->expects($this->exactly(2)) |
400
|
|
|
->method('acceptSequence'); |
401
|
|
|
|
402
|
|
|
self::assertNull($schema->visit($visitor)); |
|
|
|
|
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* @group DBAL-669 |
407
|
|
|
*/ |
408
|
|
|
public function testVisitsNamespaceVisitor() : void |
409
|
|
|
{ |
410
|
|
|
$schema = new Schema(); |
411
|
|
|
$visitor = $this->createMock(AbstractVisitor::class); |
412
|
|
|
|
413
|
|
|
$schema->createNamespace('foo'); |
414
|
|
|
$schema->createNamespace('bar'); |
415
|
|
|
|
416
|
|
|
$schema->createTable('baz'); |
417
|
|
|
$schema->createTable('bla.bloo'); |
418
|
|
|
|
419
|
|
|
$schema->createSequence('moo'); |
420
|
|
|
$schema->createSequence('war'); |
421
|
|
|
|
422
|
|
|
$visitor->expects($this->once()) |
423
|
|
|
->method('acceptSchema') |
424
|
|
|
->with($schema); |
425
|
|
|
|
426
|
|
|
$visitor->expects($this->at(1)) |
427
|
|
|
->method('acceptNamespace') |
428
|
|
|
->with('foo'); |
429
|
|
|
|
430
|
|
|
$visitor->expects($this->at(2)) |
431
|
|
|
->method('acceptNamespace') |
432
|
|
|
->with('bar'); |
433
|
|
|
|
434
|
|
|
$visitor->expects($this->at(3)) |
435
|
|
|
->method('acceptNamespace') |
436
|
|
|
->with('bla'); |
437
|
|
|
|
438
|
|
|
$visitor->expects($this->exactly(3)) |
439
|
|
|
->method('acceptNamespace'); |
440
|
|
|
|
441
|
|
|
$visitor->expects($this->at(4)) |
442
|
|
|
->method('acceptTable') |
443
|
|
|
->with($schema->getTable('baz')); |
444
|
|
|
|
445
|
|
|
$visitor->expects($this->at(5)) |
446
|
|
|
->method('acceptTable') |
447
|
|
|
->with($schema->getTable('bla.bloo')); |
448
|
|
|
|
449
|
|
|
$visitor->expects($this->exactly(2)) |
450
|
|
|
->method('acceptTable'); |
451
|
|
|
|
452
|
|
|
$visitor->expects($this->at(6)) |
453
|
|
|
->method('acceptSequence') |
454
|
|
|
->with($schema->getSequence('moo')); |
455
|
|
|
|
456
|
|
|
$visitor->expects($this->at(7)) |
457
|
|
|
->method('acceptSequence') |
458
|
|
|
->with($schema->getSequence('war')); |
459
|
|
|
|
460
|
|
|
$visitor->expects($this->exactly(2)) |
461
|
|
|
->method('acceptSequence'); |
462
|
|
|
|
463
|
|
|
self::assertNull($schema->visit($visitor)); |
|
|
|
|
464
|
|
|
} |
465
|
|
|
} |
466
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.