Completed
Pull Request — master (#3759)
by Benjamin
131:22 queued 67:31
created

WriteTest::testExecuteUpdateWithTypes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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

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