SchemaTest.php 12.7 KB
Newer Older
1 2
<?php

3
namespace Doctrine\DBAL\Tests\Schema;
4 5

use Doctrine\DBAL\Schema\Schema;
Sergei Morozov's avatar
Sergei Morozov committed
6
use Doctrine\DBAL\Schema\SchemaConfig;
Sergei Morozov's avatar
Sergei Morozov committed
7
use Doctrine\DBAL\Schema\SchemaException;
8
use Doctrine\DBAL\Schema\Sequence;
jeroendedauw's avatar
jeroendedauw committed
9
use Doctrine\DBAL\Schema\Table;
Sergei Morozov's avatar
Sergei Morozov committed
10 11
use Doctrine\DBAL\Schema\Visitor\AbstractVisitor;
use Doctrine\DBAL\Schema\Visitor\Visitor;
Sergei Morozov's avatar
Sergei Morozov committed
12
use PHPUnit\Framework\TestCase;
13
use ReflectionProperty;
14

15 16
use function current;
use function strlen;
17

Sergei Morozov's avatar
Sergei Morozov committed
18
class SchemaTest extends TestCase
19
{
20
    public function testAddTable(): void
21
    {
Sergei Morozov's avatar
Sergei Morozov committed
22 23
        $tableName = 'public.foo';
        $table     = new Table($tableName);
24

Sergei Morozov's avatar
Sergei Morozov committed
25
        $schema = new Schema([$table]);
26

27
        self::assertTrue($schema->hasTable($tableName));
28 29

        $tables = $schema->getTables();
Gabriel Caruso's avatar
Gabriel Caruso committed
30
        self::assertArrayHasKey($tableName, $tables);
31 32 33
        self::assertSame($table, $tables[$tableName]);
        self::assertSame($table, $schema->getTable($tableName));
        self::assertTrue($schema->hasTable($tableName));
34 35
    }

36
    public function testTableMatchingCaseInsensitive(): void
37
    {
Sergei Morozov's avatar
Sergei Morozov committed
38
        $table = new Table('Foo');
39

Sergei Morozov's avatar
Sergei Morozov committed
40 41 42
        $schema = new Schema([$table]);
        self::assertTrue($schema->hasTable('foo'));
        self::assertTrue($schema->hasTable('FOO'));
43

44 45 46
        self::assertSame($table, $schema->getTable('FOO'));
        self::assertSame($table, $schema->getTable('foo'));
        self::assertSame($table, $schema->getTable('Foo'));
47 48
    }

49
    public function testGetUnknownTableThrowsException(): void
50
    {
Sergei Morozov's avatar
Sergei Morozov committed
51
        $this->expectException(SchemaException::class);
52 53

        $schema = new Schema();
Sergei Morozov's avatar
Sergei Morozov committed
54
        $schema->getTable('unknown');
55 56
    }

57
    public function testCreateTableTwiceThrowsException(): void
58
    {
Sergei Morozov's avatar
Sergei Morozov committed
59
        $this->expectException(SchemaException::class);
60

Sergei Morozov's avatar
Sergei Morozov committed
61 62 63
        $tableName = 'foo';
        $table     = new Table($tableName);
        $tables    = [$table, $table];
64 65 66 67

        $schema = new Schema($tables);
    }

68
    public function testRenameTable(): void
69
    {
Sergei Morozov's avatar
Sergei Morozov committed
70 71 72 73 74 75 76 77 78
        $tableName = 'foo';
        $table     = new Table($tableName);
        $schema    = new Schema([$table]);

        self::assertTrue($schema->hasTable('foo'));
        $schema->renameTable('foo', 'bar');
        self::assertFalse($schema->hasTable('foo'));
        self::assertTrue($schema->hasTable('bar'));
        self::assertSame($table, $schema->getTable('bar'));
79 80
    }

81
    public function testDropTable(): void
82
    {
Sergei Morozov's avatar
Sergei Morozov committed
83 84 85
        $tableName = 'foo';
        $table     = new Table($tableName);
        $schema    = new Schema([$table]);
86

Sergei Morozov's avatar
Sergei Morozov committed
87
        self::assertTrue($schema->hasTable('foo'));
88

Sergei Morozov's avatar
Sergei Morozov committed
89
        $schema->dropTable('foo');
90

Sergei Morozov's avatar
Sergei Morozov committed
91
        self::assertFalse($schema->hasTable('foo'));
92 93
    }

94
    public function testCreateTable(): void
95 96 97
    {
        $schema = new Schema();

Sergei Morozov's avatar
Sergei Morozov committed
98
        self::assertFalse($schema->hasTable('foo'));
99

Sergei Morozov's avatar
Sergei Morozov committed
100
        $table = $schema->createTable('foo');
101

Sergei Morozov's avatar
Sergei Morozov committed
102
        self::assertInstanceOf(Table::class, $table);
Sergei Morozov's avatar
Sergei Morozov committed
103 104
        self::assertEquals('foo', $table->getName());
        self::assertTrue($schema->hasTable('foo'));
105 106
    }

107
    public function testAddSequences(): void
108
    {
Sergei Morozov's avatar
Sergei Morozov committed
109
        $sequence = new Sequence('a_seq', 1, 1);
110

Sergei Morozov's avatar
Sergei Morozov committed
111
        $schema = new Schema([], [$sequence]);
112

Sergei Morozov's avatar
Sergei Morozov committed
113
        self::assertTrue($schema->hasSequence('a_seq'));
Sergei Morozov's avatar
Sergei Morozov committed
114
        self::assertInstanceOf(Sequence::class, $schema->getSequence('a_seq'));
115 116

        $sequences = $schema->getSequences();
117
        self::assertArrayHasKey('public.a_seq', $sequences);
118 119
    }

120
    public function testSequenceAccessCaseInsensitive(): void
121
    {
Sergei Morozov's avatar
Sergei Morozov committed
122
        $sequence = new Sequence('a_Seq');
123

Sergei Morozov's avatar
Sergei Morozov committed
124
        $schema = new Schema([], [$sequence]);
125 126 127
        self::assertTrue($schema->hasSequence('a_seq'));
        self::assertTrue($schema->hasSequence('a_Seq'));
        self::assertTrue($schema->hasSequence('A_SEQ'));
128

129 130 131
        self::assertEquals($sequence, $schema->getSequence('a_seq'));
        self::assertEquals($sequence, $schema->getSequence('a_Seq'));
        self::assertEquals($sequence, $schema->getSequence('A_SEQ'));
132 133
    }

134
    public function testGetUnknownSequenceThrowsException(): void
135
    {
Sergei Morozov's avatar
Sergei Morozov committed
136
        $this->expectException(SchemaException::class);
137 138

        $schema = new Schema();
Sergei Morozov's avatar
Sergei Morozov committed
139
        $schema->getSequence('unknown');
140 141
    }

142
    public function testCreateSequence(): void
143
    {
Sergei Morozov's avatar
Sergei Morozov committed
144
        $schema   = new Schema();
145 146
        $sequence = $schema->createSequence('a_seq', 10, 20);

147 148 149
        self::assertEquals('a_seq', $sequence->getName());
        self::assertEquals(10, $sequence->getAllocationSize());
        self::assertEquals(20, $sequence->getInitialValue());
150

Sergei Morozov's avatar
Sergei Morozov committed
151
        self::assertTrue($schema->hasSequence('a_seq'));
Sergei Morozov's avatar
Sergei Morozov committed
152
        self::assertInstanceOf(Sequence::class, $schema->getSequence('a_seq'));
153 154

        $sequences = $schema->getSequences();
155
        self::assertArrayHasKey('public.a_seq', $sequences);
156 157
    }

158
    public function testDropSequence(): void
159
    {
Sergei Morozov's avatar
Sergei Morozov committed
160
        $sequence = new Sequence('a_seq', 1, 1);
161

Sergei Morozov's avatar
Sergei Morozov committed
162
        $schema = new Schema([], [$sequence]);
163

Sergei Morozov's avatar
Sergei Morozov committed
164 165
        $schema->dropSequence('a_seq');
        self::assertFalse($schema->hasSequence('a_seq'));
166 167
    }

168
    public function testAddSequenceTwiceThrowsException(): void
169
    {
Sergei Morozov's avatar
Sergei Morozov committed
170
        $this->expectException(SchemaException::class);
171

Sergei Morozov's avatar
Sergei Morozov committed
172
        $sequence = new Sequence('a_seq', 1, 1);
173

Sergei Morozov's avatar
Sergei Morozov committed
174
        $schema = new Schema([], [$sequence, $sequence]);
175
    }
176

177
    public function testConfigMaxIdentifierLength(): void
178
    {
Sergei Morozov's avatar
Sergei Morozov committed
179
        $schemaConfig = new SchemaConfig();
180
        $schemaConfig->setMaxIdentifierLength(5);
181

Sergei Morozov's avatar
Sergei Morozov committed
182 183
        $schema = new Schema([], [], $schemaConfig);
        $table  = $schema->createTable('smalltable');
184
        $table->addColumn('long_id', 'integer');
Sergei Morozov's avatar
Sergei Morozov committed
185
        $table->addIndex(['long_id']);
186

187
        $index = current($table->getIndexes());
188
        self::assertEquals(5, strlen($index->getName()));
189
    }
190

191
    public function testDeepClone(): void
192
    {
Sergei Morozov's avatar
Sergei Morozov committed
193
        $schema   = new Schema();
194 195 196
        $sequence = $schema->createSequence('baz');

        $tableA = $schema->createTable('foo');
197
        $tableA->addColumn('id', 'integer');
198 199

        $tableB = $schema->createTable('bar');
200 201
        $tableB->addColumn('id', 'integer');
        $tableB->addColumn('foo_id', 'integer');
Sergei Morozov's avatar
Sergei Morozov committed
202
        $tableB->addForeignKeyConstraint($tableA, ['foo_id'], ['id']);
203 204 205

        $schemaNew = clone $schema;

206
        self::assertNotSame($sequence, $schemaNew->getSequence('baz'));
207

208 209
        self::assertNotSame($tableA, $schemaNew->getTable('foo'));
        self::assertNotSame($tableA->getColumn('id'), $schemaNew->getTable('foo')->getColumn('id'));
210

211 212
        self::assertNotSame($tableB, $schemaNew->getTable('bar'));
        self::assertNotSame($tableB->getColumn('id'), $schemaNew->getTable('bar')->getColumn('id'));
213

jwage's avatar
jwage committed
214 215
        $fk = $schemaNew->getTable('bar')->getForeignKeys();
        $fk = current($fk);
216 217 218 219 220

        $re = new ReflectionProperty($fk, '_localTable');
        $re->setAccessible(true);

        self::assertSame($schemaNew->getTable('bar'), $re->getValue($fk));
221
    }
222 223 224 225

    /**
     * @group DBAL-219
     */
226
    public function testHasTableForQuotedAsset(): void
227 228 229 230 231 232
    {
        $schema = new Schema();

        $tableA = $schema->createTable('foo');
        $tableA->addColumn('id', 'integer');

233
        self::assertTrue($schema->hasTable('`foo`'));
234
    }
Marco Pivetta's avatar
Marco Pivetta committed
235 236 237 238

    /**
     * @group DBAL-669
     */
239
    public function testHasNamespace(): void
Marco Pivetta's avatar
Marco Pivetta committed
240 241 242
    {
        $schema = new Schema();

243
        self::assertFalse($schema->hasNamespace('foo'));
Marco Pivetta's avatar
Marco Pivetta committed
244 245 246

        $schema->createTable('foo');

247
        self::assertFalse($schema->hasNamespace('foo'));
Marco Pivetta's avatar
Marco Pivetta committed
248 249 250

        $schema->createTable('bar.baz');

251 252 253
        self::assertFalse($schema->hasNamespace('baz'));
        self::assertTrue($schema->hasNamespace('bar'));
        self::assertFalse($schema->hasNamespace('tab'));
Marco Pivetta's avatar
Marco Pivetta committed
254 255 256

        $schema->createTable('tab.taz');

257
        self::assertTrue($schema->hasNamespace('tab'));
Marco Pivetta's avatar
Marco Pivetta committed
258
    }
259 260 261 262

    /**
     * @group DBAL-669
     */
263
    public function testCreatesNamespace(): void
264 265 266
    {
        $schema = new Schema();

267
        self::assertFalse($schema->hasNamespace('foo'));
268 269 270

        $schema->createNamespace('foo');

271 272 273 274
        self::assertTrue($schema->hasNamespace('foo'));
        self::assertTrue($schema->hasNamespace('FOO'));
        self::assertTrue($schema->hasNamespace('`foo`'));
        self::assertTrue($schema->hasNamespace('`FOO`'));
275 276 277

        $schema->createNamespace('`bar`');

278 279 280 281
        self::assertTrue($schema->hasNamespace('bar'));
        self::assertTrue($schema->hasNamespace('BAR'));
        self::assertTrue($schema->hasNamespace('`bar`'));
        self::assertTrue($schema->hasNamespace('`BAR`'));
282

Sergei Morozov's avatar
Sergei Morozov committed
283
        self::assertSame(['foo' => 'foo', 'bar' => '`bar`'], $schema->getNamespaces());
284 285 286 287 288
    }

    /**
     * @group DBAL-669
     */
289
    public function testThrowsExceptionOnCreatingNamespaceTwice(): void
290 291 292 293
    {
        $schema = new Schema();

        $schema->createNamespace('foo');
294 295 296

        $this->expectException(SchemaException::class);

297 298 299 300 301 302
        $schema->createNamespace('foo');
    }

    /**
     * @group DBAL-669
     */
303
    public function testCreatesNamespaceThroughAddingTableImplicitly(): void
304 305 306
    {
        $schema = new Schema();

307
        self::assertFalse($schema->hasNamespace('foo'));
308 309 310

        $schema->createTable('baz');

311 312
        self::assertFalse($schema->hasNamespace('foo'));
        self::assertFalse($schema->hasNamespace('baz'));
313 314 315

        $schema->createTable('foo.bar');

316 317
        self::assertTrue($schema->hasNamespace('foo'));
        self::assertFalse($schema->hasNamespace('bar'));
318 319 320

        $schema->createTable('`baz`.bloo');

321 322
        self::assertTrue($schema->hasNamespace('baz'));
        self::assertFalse($schema->hasNamespace('bloo'));
323 324 325

        $schema->createTable('`baz`.moo');

326 327
        self::assertTrue($schema->hasNamespace('baz'));
        self::assertFalse($schema->hasNamespace('moo'));
328 329 330 331 332
    }

    /**
     * @group DBAL-669
     */
333
    public function testCreatesNamespaceThroughAddingSequenceImplicitly(): void
334 335 336
    {
        $schema = new Schema();

337
        self::assertFalse($schema->hasNamespace('foo'));
338 339 340

        $schema->createSequence('baz');

341 342
        self::assertFalse($schema->hasNamespace('foo'));
        self::assertFalse($schema->hasNamespace('baz'));
343 344 345

        $schema->createSequence('foo.bar');

346 347
        self::assertTrue($schema->hasNamespace('foo'));
        self::assertFalse($schema->hasNamespace('bar'));
348 349 350

        $schema->createSequence('`baz`.bloo');

351 352
        self::assertTrue($schema->hasNamespace('baz'));
        self::assertFalse($schema->hasNamespace('bloo'));
353 354 355

        $schema->createSequence('`baz`.moo');

356 357
        self::assertTrue($schema->hasNamespace('baz'));
        self::assertFalse($schema->hasNamespace('moo'));
358
    }
359 360 361 362

    /**
     * @group DBAL-669
     */
363
    public function testVisitsVisitor(): void
364
    {
Sergei Morozov's avatar
Sergei Morozov committed
365
        $schema  = new Schema();
Sergei Morozov's avatar
Sergei Morozov committed
366
        $visitor = $this->createMock(Visitor::class);
367 368 369 370 371 372 373 374 375 376

        $schema->createNamespace('foo');
        $schema->createNamespace('bar');

        $schema->createTable('baz');
        $schema->createTable('bla.bloo');

        $schema->createSequence('moo');
        $schema->createSequence('war');

377
        $visitor->expects(self::once())
378 379 380
            ->method('acceptSchema')
            ->with($schema);

381
        $visitor->expects(self::exactly(2))
382
            ->method('acceptTable')
383 384 385 386
            ->withConsecutive(
                [$schema->getTable('baz')],
                [$schema->getTable('bla.bloo')]
            );
387

388
        $visitor->expects(self::exactly(2))
389
            ->method('acceptSequence')
390 391 392 393
            ->withConsecutive(
                [$schema->getSequence('moo')],
                [$schema->getSequence('war')]
            );
394

395
        self::assertNull($schema->visit($visitor));
396 397 398 399 400
    }

    /**
     * @group DBAL-669
     */
401
    public function testVisitsNamespaceVisitor(): void
402
    {
Sergei Morozov's avatar
Sergei Morozov committed
403
        $schema  = new Schema();
Sergei Morozov's avatar
Sergei Morozov committed
404
        $visitor = $this->createMock(AbstractVisitor::class);
405 406 407 408 409 410 411 412 413 414

        $schema->createNamespace('foo');
        $schema->createNamespace('bar');

        $schema->createTable('baz');
        $schema->createTable('bla.bloo');

        $schema->createSequence('moo');
        $schema->createSequence('war');

415
        $visitor->expects(self::once())
416 417 418
            ->method('acceptSchema')
            ->with($schema);

419
        $visitor->expects(self::at(1))
420 421 422
            ->method('acceptNamespace')
            ->with('foo');

423
        $visitor->expects(self::at(2))
424 425 426
            ->method('acceptNamespace')
            ->with('bar');

427
        $visitor->expects(self::at(3))
428 429 430 431 432 433 434
            ->method('acceptNamespace')
            ->with('bla');

        $visitor->expects($this->at(4))
            ->method('acceptTable')
            ->with($schema->getTable('baz'));

435
        $visitor->expects(self::at(5))
436 437 438 439 440 441 442
            ->method('acceptTable')
            ->with($schema->getTable('bla.bloo'));

        $visitor->expects($this->at(6))
            ->method('acceptSequence')
            ->with($schema->getSequence('moo'));

443
        $visitor->expects(self::at(7))
444 445 446
            ->method('acceptSequence')
            ->with($schema->getSequence('war'));

447
        self::assertNull($schema->visit($visitor));
448
    }
449
}