Failed Conditions
Pull Request — master (#3759)
by Benjamin
65:18
created

WriteTest::insertRows()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL\Functional;
6
7
use DateTime;
8
use Doctrine\DBAL\Driver\AbstractOracleDriver;
9
use Doctrine\DBAL\Driver\DriverException;
10
use Doctrine\DBAL\Driver\PDOConnection;
11
use Doctrine\DBAL\ParameterType;
12
use Doctrine\DBAL\Platforms\OraclePlatform;
13
use Doctrine\DBAL\Schema\Sequence;
14
use Doctrine\DBAL\Schema\Table;
15
use Doctrine\Tests\DbalFunctionalTestCase;
16
use Doctrine\Tests\TestUtil;
17
use Throwable;
18
use function array_filter;
19
use function strtolower;
20
21
class WriteTest extends DbalFunctionalTestCase
22
{
23
    protected function setUp() : void
24
    {
25
        parent::setUp();
26
27
        $table = new Table('write_table');
28
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
29
        $table->addColumn('test_int', 'integer');
30
        $table->addColumn('test_string', 'string', [
31
            'length' => 32,
32
            'notnull' => false,
33
        ]);
34
        $table->setPrimaryKey(['id']);
35
36
        $this->connection->getSchemaManager()->dropAndCreateTable($table);
37
38
        $this->connection->executeUpdate('DELETE FROM write_table');
39
    }
40
41
    public function testExecuteUpdate() : void
42
    {
43
        $sql      = 'INSERT INTO write_table (test_int) VALUES (1)';
44
        $affected = $this->connection->executeUpdate($sql);
45
46
        self::assertEquals(1, $affected, 'executeUpdate() should return the number of affected rows!');
47
    }
48
49
    public function testExecuteUpdateWithTypes() : void
50
    {
51
        $sql      = 'INSERT INTO write_table (test_int, test_string) VALUES (?, ?)';
52
        $affected = $this->connection->executeUpdate(
53
            $sql,
54
            [1, 'foo'],
55
            [ParameterType::INTEGER, ParameterType::STRING]
56
        );
57
58
        self::assertEquals(1, $affected, 'executeUpdate() should return the number of affected rows!');
59
    }
60
61
    public function testPrepareRowCountReturnsAffectedRows() : void
62
    {
63
        $sql  = 'INSERT INTO write_table (test_int, test_string) VALUES (?, ?)';
64
        $stmt = $this->connection->prepare($sql);
65
66
        $stmt->bindValue(1, 1);
67
        $stmt->bindValue(2, 'foo');
68
        $stmt->execute();
69
70
        self::assertEquals(1, $stmt->rowCount());
71
    }
72
73
    public function testPrepareWithPdoTypes() : void
74
    {
75
        $sql  = 'INSERT INTO write_table (test_int, test_string) VALUES (?, ?)';
76
        $stmt = $this->connection->prepare($sql);
77
78
        $stmt->bindValue(1, 1, ParameterType::INTEGER);
79
        $stmt->bindValue(2, 'foo', ParameterType::STRING);
80
        $stmt->execute();
81
82
        self::assertEquals(1, $stmt->rowCount());
83
    }
84
85
    public function testPrepareWithDbalTypes() : void
86
    {
87
        $sql  = 'INSERT INTO write_table (test_int, test_string) VALUES (?, ?)';
88
        $stmt = $this->connection->prepare($sql);
89
90
        $stmt->bindValue(1, 1, ParameterType::INTEGER);
91
        $stmt->bindValue(2, 'foo', ParameterType::STRING);
92
        $stmt->execute();
93
94
        self::assertEquals(1, $stmt->rowCount());
95
    }
96
97
    public function testPrepareWithDbalTypeNames() : void
98
    {
99
        $sql  = 'INSERT INTO write_table (test_int, test_string) VALUES (?, ?)';
100
        $stmt = $this->connection->prepare($sql);
101
102
        $stmt->bindValue(1, 1, ParameterType::INTEGER);
103
        $stmt->bindValue(2, 'foo', ParameterType::STRING);
104
        $stmt->execute();
105
106
        self::assertEquals(1, $stmt->rowCount());
107
    }
108
109
    public function insertRows() : void
110
    {
111
        self::assertEquals(1, $this->connection->insert('write_table', ['test_int' => 1, 'test_string' => 'foo']));
112
        self::assertEquals(1, $this->connection->insert('write_table', ['test_int' => 2, 'test_string' => 'bar']));
113
    }
114
115
    public function testInsert() : void
116
    {
117
        $this->insertRows();
118
    }
119
120
    public function testDelete() : void
121
    {
122
        $this->insertRows();
123
124
        self::assertEquals(1, $this->connection->delete('write_table', ['test_int' => 2]));
125
        self::assertCount(1, $this->connection->fetchAll('SELECT * FROM write_table'));
126
127
        self::assertEquals(1, $this->connection->delete('write_table', ['test_int' => 1]));
128
        self::assertCount(0, $this->connection->fetchAll('SELECT * FROM write_table'));
129
    }
130
131
    public function testUpdate() : void
132
    {
133
        $this->insertRows();
134
135
        self::assertEquals(1, $this->connection->update('write_table', ['test_string' => 'bar'], ['test_string' => 'foo']));
136
        self::assertEquals(2, $this->connection->update('write_table', ['test_string' => 'baz'], ['test_string' => 'bar']));
137
        self::assertEquals(0, $this->connection->update('write_table', ['test_string' => 'baz'], ['test_string' => 'bar']));
138
    }
139
140
    public function testLastInsertId() : void
141
    {
142
        if (! $this->connection->getDatabasePlatform()->supportsIdentityColumns()) {
143
            $this->markTestSkipped('This test targets platforms that support identity columns.');
144
        }
145
146
        self::assertEquals(1, $this->connection->insert('write_table', ['test_int' => 2, 'test_string' => 'bar']));
147
        $num = $this->connection->lastInsertId();
148
149
        self::assertGreaterThan(0, $num, 'LastInsertId() should be non-negative number.');
150
    }
151
152
    public function testLastInsertIdNotSupported() : void
153
    {
154
        if ($this->connection->getDatabasePlatform()->supportsIdentityColumns()) {
155
            $this->markTestSkipped('This test targets platforms that don\'t support identity columns.');
156
        }
157
158
        self::assertEquals(1, $this->connection->insert('write_table', ['test_int' => 2, 'test_string' => 'bar']));
159
160
        self::expectException(DriverException::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

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

160
        self::/** @scrutinizer ignore-call */ 
161
              expectException(DriverException::class);
Loading history...
161
        $this->connection->lastInsertId();
162
    }
163
164
    public function testLastInsertIdNewConnection() : void
165
    {
166
        $connection = TestUtil::getConnection();
167
168
        $this->expectException(DriverException::class);
169
        $connection->lastInsertId();
170
    }
171
172
    public function testGetSequenceNumber() : void
173
    {
174
        $platform = $this->connection->getDatabasePlatform();
175
176
        if (! $platform->supportsSequences()) {
177
            $this->markTestSkipped('This test targets platforms that support sequences.');
178
        }
179
180
        if ($platform instanceof OraclePlatform && $this->connection->getWrappedConnection() instanceof PDOConnection) {
181
            $this->markTestSkipped('Oracle supports sequences, but PDO OCI driver does not support lastInsertId()');
182
        }
183
184
        $sequence = new Sequence('write_table_id_seq');
185
        try {
186
            $this->connection->getSchemaManager()->createSequence($sequence);
187
        } catch (Throwable $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
188
        }
189
190
        $sequences = $this->connection->getSchemaManager()->listSequences();
191
        self::assertCount(1, array_filter($sequences, static function ($sequence) {
192
            return strtolower($sequence->getName()) === 'write_table_id_seq';
193
        }));
194
195
        $stmt            = $this->connection->query($this->connection->getDatabasePlatform()->getSequenceNextValSQL('write_table_id_seq'));
196
        $nextSequenceVal = $stmt->fetchColumn();
197
198
        $sequenceNumber = $this->connection->getSequenceNumber('write_table_id_seq');
199
200
        self::assertGreaterThan(0, $sequenceNumber);
201
        self::assertEquals($nextSequenceVal, $sequenceNumber);
202
    }
203
204
    public function testGetSequenceNumberNotSupportedOrSequenceDoesNotExist() : void
205
    {
206
        $this->expectException(DriverException::class);
207
        $this->connection->getSequenceNumber('unknown-sequence');
208
    }
209
210
    /**
211
     * @group DBAL-445
212
     */
213
    public function testInsertWithKeyValueTypes() : void
214
    {
215
        $testString = new DateTime('2013-04-14 10:10:10');
216
217
        $this->connection->insert(
218
            'write_table',
219
            ['test_int' => '30', 'test_string' => $testString],
220
            ['test_string' => 'datetime', 'test_int' => 'integer']
221
        );
222
223
        $data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
224
225
        self::assertEquals($testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()), $data);
226
    }
227
228
    /**
229
     * @group DBAL-445
230
     */
231
    public function testUpdateWithKeyValueTypes() : void
232
    {
233
        $testString = new DateTime('2013-04-14 10:10:10');
234
235
        $this->connection->insert(
236
            'write_table',
237
            ['test_int' => '30', 'test_string' => $testString],
238
            ['test_string' => 'datetime', 'test_int' => 'integer']
239
        );
240
241
        $testString = new DateTime('2013-04-15 10:10:10');
242
243
        $this->connection->update(
244
            'write_table',
245
            ['test_string' => $testString],
246
            ['test_int' => '30'],
247
            ['test_string' => 'datetime', 'test_int' => 'integer']
248
        );
249
250
        $data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
251
252
        self::assertEquals($testString->format($this->connection->getDatabasePlatform()->getDateTimeFormatString()), $data);
253
    }
254
255
    /**
256
     * @group DBAL-445
257
     */
258
    public function testDeleteWithKeyValueTypes() : void
259
    {
260
        $val = new DateTime('2013-04-14 10:10:10');
261
        $this->connection->insert(
262
            'write_table',
263
            ['test_int' => '30', 'test_string' => $val],
264
            ['test_string' => 'datetime', 'test_int' => 'integer']
265
        );
266
267
        $this->connection->delete('write_table', ['test_int' => 30, 'test_string' => $val], ['test_string' => 'datetime', 'test_int' => 'integer']);
268
269
        $data = $this->connection->fetchColumn('SELECT test_string FROM write_table WHERE test_int = 30');
270
271
        self::assertFalse($data);
272
    }
273
274
    public function testEmptyIdentityInsert() : void
275
    {
276
        $platform = $this->connection->getDatabasePlatform();
277
278
        if (! $platform->supportsIdentityColumns() || $platform->usesSequenceEmulatedIdentityColumns()) {
279
            $this->markTestSkipped(
280
                'Test only works on platforms with native support for identity columns.'
281
            );
282
        }
283
284
        $table = new Table('test_empty_identity');
285
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
286
        $table->setPrimaryKey(['id']);
287
288
        try {
289
            $this->connection->getSchemaManager()->dropTable($table->getQuotedName($platform));
290
        } catch (Throwable $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
291
        }
292
293
        foreach ($platform->getCreateTableSQL($table) as $sql) {
294
            $this->connection->exec($sql);
295
        }
296
297
        $sql = $platform->getEmptyIdentityInsertSQL('test_empty_identity', 'id');
298
299
        $this->connection->exec($sql);
300
        $firstId = $this->connection->lastInsertId();
301
302
        $this->connection->exec($sql);
303
        $secondId = $this->connection->lastInsertId();
304
305
        self::assertGreaterThan($firstId, $secondId);
306
    }
307
308
    public function testEmptyIdentityInsertEmulated() : void
309
    {
310
        $platform = $this->connection->getDatabasePlatform();
311
312
        if (! $platform->usesSequenceEmulatedIdentityColumns()) {
313
            $this->markTestSkipped(
314
                'Test only works on platforms with emulated identity columns.'
315
            );
316
        }
317
318
        if ($this->connection->getDriver() instanceof AbstractOracleDriver) {
319
            $this->markTestSkipped('The driver does not support lastInsertId()');
320
        }
321
322
        $table = new Table('test_empty_identity');
323
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
324
        $table->setPrimaryKey(['id']);
325
326
        try {
327
            $this->connection->getSchemaManager()->dropTable($table->getQuotedName($platform));
328
        } catch (Throwable $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
329
        }
330
331
        foreach ($platform->getCreateTableSQL($table) as $sql) {
332
            $this->connection->exec($sql);
333
        }
334
335
        $seqName = $platform->getIdentitySequenceName('test_empty_identity', 'id');
336
337
        $sql = $platform->getEmptyIdentityInsertSQL('test_empty_identity', 'id');
338
339
        $this->connection->exec($sql);
340
        $firstId = $this->connection->getSequenceNumber($seqName);
341
342
        $this->connection->exec($sql);
343
        $secondId = $this->connection->getSequenceNumber($seqName);
344
345
        self::assertGreaterThan($firstId, $secondId);
346
    }
347
348
    /**
349
     * @group DBAL-2688
350
     */
351
    public function testUpdateWhereIsNull() : void
352
    {
353
        $this->connection->insert(
354
            'write_table',
355
            ['test_int' => '30', 'test_string' => null],
356
            ['test_string' => 'string', 'test_int' => 'integer']
357
        );
358
359
        $data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30');
360
361
        self::assertCount(1, $data);
362
363
        $this->connection->update('write_table', ['test_int' => 10], ['test_string' => null], ['test_string' => 'string', 'test_int' => 'integer']);
364
365
        $data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30');
366
367
        self::assertCount(0, $data);
368
    }
369
370
    public function testDeleteWhereIsNull() : void
371
    {
372
        $this->connection->insert(
373
            'write_table',
374
            ['test_int' => '30', 'test_string' => null],
375
            ['test_string' => 'string', 'test_int' => 'integer']
376
        );
377
378
        $data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30');
379
380
        self::assertCount(1, $data);
381
382
        $this->connection->delete('write_table', ['test_string' => null], ['test_string' => 'string']);
383
384
        $data = $this->connection->fetchAll('SELECT * FROM write_table WHERE test_int = 30');
385
386
        self::assertCount(0, $data);
387
    }
388
}
389