SchemaTest.php 12.4 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
    public function testHasTableForQuotedAsset(): void
224 225 226 227 228 229
    {
        $schema = new Schema();

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

230
        self::assertTrue($schema->hasTable('`foo`'));
231
    }
Marco Pivetta's avatar
Marco Pivetta committed
232

233
    public function testHasNamespace(): void
Marco Pivetta's avatar
Marco Pivetta committed
234 235 236
    {
        $schema = new Schema();

237
        self::assertFalse($schema->hasNamespace('foo'));
Marco Pivetta's avatar
Marco Pivetta committed
238 239 240

        $schema->createTable('foo');

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

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

245 246 247
        self::assertFalse($schema->hasNamespace('baz'));
        self::assertTrue($schema->hasNamespace('bar'));
        self::assertFalse($schema->hasNamespace('tab'));
Marco Pivetta's avatar
Marco Pivetta committed
248 249 250

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

251
        self::assertTrue($schema->hasNamespace('tab'));
Marco Pivetta's avatar
Marco Pivetta committed
252
    }
253

254
    public function testCreatesNamespace(): void
255 256 257
    {
        $schema = new Schema();

258
        self::assertFalse($schema->hasNamespace('foo'));
259 260 261

        $schema->createNamespace('foo');

262 263 264 265
        self::assertTrue($schema->hasNamespace('foo'));
        self::assertTrue($schema->hasNamespace('FOO'));
        self::assertTrue($schema->hasNamespace('`foo`'));
        self::assertTrue($schema->hasNamespace('`FOO`'));
266 267 268

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

269 270 271 272
        self::assertTrue($schema->hasNamespace('bar'));
        self::assertTrue($schema->hasNamespace('BAR'));
        self::assertTrue($schema->hasNamespace('`bar`'));
        self::assertTrue($schema->hasNamespace('`BAR`'));
273

Sergei Morozov's avatar
Sergei Morozov committed
274
        self::assertSame(['foo' => 'foo', 'bar' => '`bar`'], $schema->getNamespaces());
275 276
    }

277
    public function testThrowsExceptionOnCreatingNamespaceTwice(): void
278 279 280 281
    {
        $schema = new Schema();

        $schema->createNamespace('foo');
282 283 284

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

285 286 287
        $schema->createNamespace('foo');
    }

288
    public function testCreatesNamespaceThroughAddingTableImplicitly(): void
289 290 291
    {
        $schema = new Schema();

292
        self::assertFalse($schema->hasNamespace('foo'));
293 294 295

        $schema->createTable('baz');

296 297
        self::assertFalse($schema->hasNamespace('foo'));
        self::assertFalse($schema->hasNamespace('baz'));
298 299 300

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

301 302
        self::assertTrue($schema->hasNamespace('foo'));
        self::assertFalse($schema->hasNamespace('bar'));
303 304 305

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

306 307
        self::assertTrue($schema->hasNamespace('baz'));
        self::assertFalse($schema->hasNamespace('bloo'));
308 309 310

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

311 312
        self::assertTrue($schema->hasNamespace('baz'));
        self::assertFalse($schema->hasNamespace('moo'));
313 314
    }

315
    public function testCreatesNamespaceThroughAddingSequenceImplicitly(): void
316 317 318
    {
        $schema = new Schema();

319
        self::assertFalse($schema->hasNamespace('foo'));
320 321 322

        $schema->createSequence('baz');

323 324
        self::assertFalse($schema->hasNamespace('foo'));
        self::assertFalse($schema->hasNamespace('baz'));
325 326 327

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

328 329
        self::assertTrue($schema->hasNamespace('foo'));
        self::assertFalse($schema->hasNamespace('bar'));
330 331 332

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

333 334
        self::assertTrue($schema->hasNamespace('baz'));
        self::assertFalse($schema->hasNamespace('bloo'));
335 336 337

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

338 339
        self::assertTrue($schema->hasNamespace('baz'));
        self::assertFalse($schema->hasNamespace('moo'));
340
    }
341

342
    public function testVisitsVisitor(): void
343
    {
Sergei Morozov's avatar
Sergei Morozov committed
344
        $schema  = new Schema();
Sergei Morozov's avatar
Sergei Morozov committed
345
        $visitor = $this->createMock(Visitor::class);
346 347 348 349 350 351 352 353 354 355

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

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

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

356
        $visitor->expects(self::once())
357 358 359
            ->method('acceptSchema')
            ->with($schema);

360
        $visitor->expects(self::exactly(2))
361
            ->method('acceptTable')
362 363 364 365
            ->withConsecutive(
                [$schema->getTable('baz')],
                [$schema->getTable('bla.bloo')]
            );
366

367
        $visitor->expects(self::exactly(2))
368
            ->method('acceptSequence')
369 370 371 372
            ->withConsecutive(
                [$schema->getSequence('moo')],
                [$schema->getSequence('war')]
            );
373

374
        self::assertNull($schema->visit($visitor));
375 376
    }

377
    public function testVisitsNamespaceVisitor(): void
378
    {
Sergei Morozov's avatar
Sergei Morozov committed
379
        $schema  = new Schema();
Sergei Morozov's avatar
Sergei Morozov committed
380
        $visitor = $this->createMock(AbstractVisitor::class);
381 382 383 384 385 386 387 388 389 390

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

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

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

391
        $visitor->expects(self::once())
392 393 394
            ->method('acceptSchema')
            ->with($schema);

395
        $visitor->expects(self::at(1))
396 397 398
            ->method('acceptNamespace')
            ->with('foo');

399
        $visitor->expects(self::at(2))
400 401 402
            ->method('acceptNamespace')
            ->with('bar');

403
        $visitor->expects(self::at(3))
404 405 406 407 408 409 410
            ->method('acceptNamespace')
            ->with('bla');

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

411
        $visitor->expects(self::at(5))
412 413 414 415 416 417 418
            ->method('acceptTable')
            ->with($schema->getTable('bla.bloo'));

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

419
        $visitor->expects(self::at(7))
420 421 422
            ->method('acceptSequence')
            ->with($schema->getSequence('war'));

423
        self::assertNull($schema->visit($visitor));
424
    }
425
}