Passed
Push — master ( 9dff63...ec8207 )
by Darío
02:00
created

MySQLTest::testCannotEstablishConnection()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 0
dl 0
loc 15
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * DronePHP (http://www.dronephp.com)
4
 *
5
 * @link      http://github.com/Pleets/DronePHP
6
 * @copyright Copyright (c) 2016-2018 Pleets. (http://www.pleets.org)
7
 * @license   http://www.dronephp.com/license
8
 * @author    Darío Rivera <[email protected]>
9
 */
10
11
namespace DroneTest\Util;
12
13
use Drone\Db\Driver\MySQL;
14
use Drone\Db\Driver\Exception\InvalidQueryException;
15
use PHPUnit\Framework\TestCase;
16
17
class MySQLTest extends TestCase
18
{
19
    /**
20
     * Database parameters
21
     */
22
    private $options = [
23
        "dbhost"       => "localhost",
24
        "dbuser"       => "root",
25
        "dbpass"       => "",
26
        "dbname"       => "test",
27
        "dbchar"       => "utf8",
28
        "dbport"       => "3306",
29
        "auto_connect" => false
30
    ];
31
32
    /*
33
    |--------------------------------------------------------------------------
34
    | Establishing connections
35
    |--------------------------------------------------------------------------
36
    |
37
    | The following tests are related to the connection methods and its
38
    | exceptions and returned values.
39
    |
40
    */
41
42
    /**
43
     * Tests if we can connect to the database server
44
     *
45
     * @return null
46
     */
47
    public function testCanEstablishConnection()
48
    {
49
        $conn = new MySQL($this->options);
50
51
        $mysqliObject = $conn->connect();
52
53
        $this->assertInstanceOf('\mysqli', $mysqliObject);
54
        $this->assertTrue($conn->isConnected());
55
    }
56
57
    /**
58
     * Tests if we can disconnect from the database server
59
     *
60
     * @return null
61
     */
62
    public function testCanDownConnection()
63
    {
64
        $conn = new MySQL($this->options);
65
66
        $conn->connect();
67
        $result = $conn->disconnect();
68
69
        $this->assertNotTrue($conn->isConnected());
70
        $this->assertTrue($result);
71
    }
72
73
    /**
74
     * Tests if we can disconnect from server when there is not a connection established
75
     *
76
     * @expectedException LogicException
77
     */
78
    public function testCannotDisconnectWhenNotConnected()
79
    {
80
        $conn = new MySQL($this->options);
81
82
        try {
83
            $conn->disconnect();
84
        }
85
        catch (\Exception $e)
86
        {
87
            $this->assertNotTrue($conn->isConnected());
88
            throw $e;
89
        }
90
    }
91
92
    /**
93
     * Tests if we can reconnect to the database server
94
     *
95
     * @return null
96
     */
97
    public function testCanEstablishConnectionAgain()
98
    {
99
        $conn = new MySQL($this->options);
100
101
        $conn->connect();
102
        $mysqliObject = $conn->reconnect();
103
104
        $this->assertInstanceOf('\mysqli', $mysqliObject);
105
        $this->assertTrue($conn->isConnected());
106
    }
107
108
    /**
109
     * Tests if we can reconnect to the database server when there is not a connection established
110
     *
111
     * @expectedException LogicException
112
     */
113
    public function testCannotEstablishReconnection()
114
    {
115
        $conn = new MySQL($this->options);
116
117
        try {
118
            $conn->reconnect();
119
        }
120
        catch (\Exception $e)
121
        {
122
            $this->assertNotTrue($conn->isConnected());
123
            throw $e;
124
        }
125
    }
126
127
    /**
128
     * Tests if a failed connection throws a ConnectionException
129
     *
130
     * @expectedException Drone\Db\Driver\Exception\ConnectionException
131
     */
132
    public function testCannotEstablishConnection()
133
    {
134
        $options = $this->options;
135
        $options["dbhost"] = 'myserver';   // this server does not exists
136
137
        $conn = new MySQL($options);
138
139
        try
140
        {
141
            $conn->connect();
142
        }
143
        catch (\Exception $e)
144
        {
145
            $this->assertNotTrue($conn->isConnected());
146
            throw $e;
147
        }
148
    }
149
150
    /*
151
    |--------------------------------------------------------------------------
152
    | Querying and Transactions
153
    |--------------------------------------------------------------------------
154
    |
155
    | The following tests are related to query and transaction operations and its
156
    | exceptions and returned values.
157
    |
158
    */
159
160
    /**
161
     * Tests if we can execute DDL statements
162
     *
163
     * @return null
164
     */
165
    public function testCanExecuteDLLStatement()
166
    {
167
        $options = $this->options;
168
        $options["auto_connect"] = true;
169
170
        $conn = new MySQL($options);
171
        $sql = "CREATE TABLE MYTABLE (ID INTEGER(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, DESCRIPTION VARCHAR(100))";
172
        $result = $conn->execute($sql);
173
174
        # mysqli
175
        $this->assertTrue(is_object($result));
176
177
        # properties modified by execute() method
178
        $this->assertEquals(0, $conn->getNumRows());
179
        $this->assertEquals(0, $conn->getNumFields());
180
        $this->assertEquals(0, $conn->getRowsAffected());
181
    }
182
183
    /**
184
     * Tests if we can execute DML statements
185
     *
186
     * @return null
187
     */
188
    public function testCanExecuteDMLStatement()
189
    {
190
        $options = $this->options;
191
        $options["auto_connect"] = true;
192
193
        $conn = new MySQL($options);
194
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('Hello world!')";
195
        $result = $conn->execute($sql);
196
197
        $this->assertTrue(is_object($result));
198
199
        # properties modified by execute() method
200
        $this->assertEquals(0, $conn->getNumRows());
201
        $this->assertEquals(0, $conn->getNumFields());
202
        $this->assertEquals(1, $conn->getRowsAffected());
203
    }
204
205
    /**
206
     * Tests if we can execute a prepared DML statement
207
     *
208
     * @return null
209
     */
210
    public function testCanExecutePreparedDMLStatement()
211
    {
212
        $options = $this->options;
213
        $options["auto_connect"] = true;
214
215
        $conn = new MySQL($options);
216
        $sql = "UPDATE MYTABLE SET DESCRIPTION = ? WHERE ID = ?";
217
        $result = $conn->execute($sql, ["Bonjour le monde!", 1]);
218
219
        $this->assertTrue(is_object($result));
220
221
        # properties modified by execute() method
222
        $this->assertEquals(0, $conn->getNumRows());
223
        $this->assertEquals(0, $conn->getNumFields());
224
        $this->assertEquals(1, $conn->getRowsAffected());
225
    }
226
227
    /**
228
     * Tests if a wrong query execution throws an InvalidQueryException
229
     *
230
     * @expectedException Drone\Db\Driver\Exception\InvalidQueryException
231
     */
232
    public function testGettingInvalidQueryException()
233
    {
234
        $options = $this->options;
235
        $options["auto_connect"] = true;
236
237
        $conn = new MySQL($options);
238
239
        $sql = "INSERT INTO MYTABLE (DESCRIPTION, WRONG) VALUES ('Hello world!')";
240
        $conn->execute($sql);
241
    }
242
243
    /**
244
     * Tests getting results
245
     *
246
     * @return null
247
     */
248
    public function testGettingResults()
249
    {
250
        $options = $this->options;
251
        $options["auto_connect"] = true;
252
253
        $conn = new MySQL($options);
254
        $sql = "SELECT * FROM MYTABLE LIMIT 2";
255
        $conn->execute($sql);
256
257
        # properties modified by execute() method
258
        $this->assertEquals(1, $conn->getNumRows());
259
        $this->assertEquals(2, $conn->getNumFields());
260
        $this->assertEquals(0, $conn->getRowsAffected());
261
262
        $rowset = $conn->getArrayResult();    # array with results
263
        $row = array_shift($rowset);
264
265
        $this->assertArrayHasKey("ID", $row);
266
        $this->assertArrayHasKey("DESCRIPTION", $row);
267
    }
268
269
    /**
270
     * Tests if we can commit transactions
271
     *
272
     * @return null
273
     */
274
    public function testCommitBehavior()
275
    {
276
        $options = $this->options;
277
        $options["auto_connect"] = true;
278
279
        $conn = new MySQL($options);
280
        $conn->autocommit(false);
281
282
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('COMMIT_ROW_1')";
283
        $conn->execute($sql);
284
285
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION = 'COMMIT_ROW_1'";
286
        $conn->execute($sql);
287
        $rowcount = count($conn->getArrayResult());
288
289
        $this->assertTrue(($rowcount === 1));    # the row is available for now
290
291
        # properties modified by execute() method
292
        $this->assertEquals(1, $conn->getNumRows());
293
        $this->assertEquals(2, $conn->getNumFields());
294
        $this->assertEquals(0, $conn->getRowsAffected());    # nothing affected (autocommit = false)
295
296
        $this->assertTrue($conn->commit());
297
298
        # now let's to verify if the record exists after commit
299
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION = 'COMMIT_ROW_1'";
300
        $conn->execute($sql);
301
        $rowcount = count($conn->getArrayResult());
302
303
        $this->assertTrue(($rowcount === 1));    # the row is available
304
    }
305
306
    /**
307
     * Tests if we can rollback transactions
308
     *
309
     * @return null
310
     */
311
    public function testRollbackBehavior()
312
    {
313
        $options = $this->options;
314
        $options["auto_connect"] = true;
315
316
        $conn = new MySQL($options);
317
        $conn->autocommit(false);
318
319
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('ROLLBACK_ROW_1')";
320
        $conn->execute($sql);
321
322
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION = 'ROLLBACK_ROW_1'";
323
        $conn->execute($sql);
324
        $rowcount = count($conn->getArrayResult());
325
326
        $this->assertTrue(($rowcount === 1));    # the row is available for now
327
328
        # properties modified by execute() method
329
        $this->assertEquals(1, $conn->getNumRows());
330
        $this->assertEquals(2, $conn->getNumFields());
331
        $this->assertEquals(0, $conn->getRowsAffected());    # nothing affected (autocommit = false)
332
333
        $this->assertTrue($conn->rollback());
334
335
        # now let's to verify if the record exists after commit
336
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION = 'ROLLBACK_ROW_1'";
337
        $conn->execute($sql);
338
        $rowcount = count($conn->getArrayResult());
339
340
        $this->assertNotTrue(($rowcount === 1));    # the row is not available
341
    }
342
343
    /**
344
     * Tests if we can do a transaction with commiting changes
345
     *
346
     * @return null
347
     */
348
    public function testTransactionConfirmation()
349
    {
350
        $options = $this->options;
351
        $options["auto_connect"] = true;
352
353
        $conn = new MySQL($options);
354
        $conn->autocommit(false);
355
356
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('COMMIT_ROW_TRANSACTION_1')";
357
        $conn->execute($sql);
358
359
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('COMMIT_ROW_TRANSACTION_2')";
360
        $conn->execute($sql);
361
362
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('COMMIT_ROW_TRANSACTION_3')";
363
        $conn->execute($sql);
364
365
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('COMMIT_ROW_TRANSACTION_4')";
366
        $conn->execute($sql);
367
368
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION LIKE 'COMMIT_ROW_TRANSACTION_%'";
369
        $conn->execute($sql);
370
        $rowcount = count($conn->getArrayResult());
371
372
        $this->assertTrue(($rowcount === 4));    # the rows are available for now
373
374
        # properties modified by execute() method
375
        $this->assertEquals(4, $conn->getNumRows());
376
        $this->assertEquals(2, $conn->getNumFields());
377
        $this->assertEquals(0, $conn->getRowsAffected());    # nothing affected (autocommit = false)
378
379
        $this->assertTrue($conn->commit());
380
381
        # now let's to verify if the record exists after commit
382
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION LIKE 'COMMIT_ROW_TRANSACTION_%'";
383
        $conn->execute($sql);
384
        $rowcount = count($conn->getArrayResult());
385
386
        $this->assertTrue(($rowcount === 4));    # the rows are available
387
    }
388
389
    /**
390
     * Tests if we can do a transaction with reverting changes
391
     *
392
     * @return null
393
     */
394
    public function testTransactionReversion()
395
    {
396
        $options = $this->options;
397
        $options["auto_connect"] = true;
398
399
        $conn = new MySQL($options);
400
        $conn->autocommit(false);
401
402
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('ROLLBACK_ROW_TRANSACTION_1')";
403
        $conn->execute($sql);
404
405
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('ROLLBACK_ROW_TRANSACTION_2')";
406
        $conn->execute($sql);
407
408
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('ROLLBACK_ROW_TRANSACTION_3')";
409
        $conn->execute($sql);
410
411
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('ROLLBACK_ROW_TRANSACTION_4')";
412
        $conn->execute($sql);
413
414
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION LIKE 'ROLLBACK_ROW_TRANSACTION_%'";
415
        $conn->execute($sql);
416
        $rowcount = count($conn->getArrayResult());
417
418
        $this->assertTrue(($rowcount === 4));    # the rows are available for now
419
420
        # properties modified by execute() method
421
        $this->assertEquals(4, $conn->getNumRows());
422
        $this->assertEquals(2, $conn->getNumFields());
423
        $this->assertEquals(0, $conn->getRowsAffected());    # nothing affected (autocommit = false)
424
425
        $this->assertTrue($conn->rollback());
426
427
        # now let's to verify if the record exists after commit
428
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION LIKE 'ROLLBACK_ROW_TRANSACTION_%'";
429
        $conn->execute($sql);
430
        $rowcount = count($conn->getArrayResult());
431
432
        $this->assertNotTrue(($rowcount === 4));    # the rows are not available
433
        $this->assertTrue(($rowcount === 0));
434
    }
435
436
    /**
437
     * Tests if we can do a transaction with the shortcut method
438
     *
439
     * @return null
440
     */
441
    public function testTransactionConfirmationShortcut()
442
    {
443
        $options = $this->options;
444
        $options["auto_connect"] = true;
445
446
        $conn = new MySQL($options);
447
448
        # not necessary!
449
        # $conn->autocommit(false);
450
451
        # starts the transaction
452
        $conn->beginTransaction();
453
454
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('TRANSACTION_SHORTCUT_1')";
455
        $conn->execute($sql);
456
457
        $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('TRANSACTION_SHORTCUT_1')";
458
        $conn->execute($sql);
459
460
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION LIKE 'TRANSACTION_SHORTCUT_%'";
461
        $conn->execute($sql);
462
        $rowcount = count($conn->getArrayResult());
463
464
        $this->assertTrue(($rowcount === 2));    # the rows are available for now
465
466
        # properties modified by execute() method
467
        $this->assertEquals(2, $conn->getNumRows());
468
        $this->assertEquals(2, $conn->getNumFields());
469
        $this->assertEquals(0, $conn->getRowsAffected());    # nothing affected (autocommit = false)
470
471
        # ends the transaction
472
        $conn->endTransaction();
473
474
        # now let's to verify if the record exists after endTransaction()
475
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION LIKE 'TRANSACTION_SHORTCUT_%'";
476
        $conn->execute($sql);
477
        $rowcount = count($conn->getArrayResult());
478
479
        $this->assertTrue(($rowcount === 2));    # the row is available
480
    }
481
482
    /**
483
     * Tests if we can do a transaction with reverting changes
484
     *
485
     * @return null
486
     */
487
    public function testTransactionReversionShortcut()
488
    {
489
        $options = $this->options;
490
        $options["auto_connect"] = true;
491
492
        $conn = new MySQL($options);
493
494
        # not necessary!
495
        # $conn->autocommit(false);
496
497
        # starts the transaction
498
        $conn->beginTransaction();
499
500
        try
501
        {
502
            $sql = "INSERT INTO MYTABLE (DESCRIPTION) VALUES ('TRANS_SHORTCUT_1')";
503
            $conn->execute($sql);
504
505
            $sql = "INSERT INTO MYTABLE (DESCRIPTION, WRONG) VALUES ('TRANS_SHORTCUT_2')";
506
            $conn->execute($sql);    # this throws the exception
507
        }
508
        catch (InvalidQueryException $e)
509
        {
510
            #·not necessary!
511
            # $this->assertTrue($conn->rollback());
512
        }
513
514
        # ends the transaction
515
        $conn->endTransaction();
516
517
        # now let's to verify if the record exists after endTransaction()
518
        $sql = "SELECT * FROM MYTABLE WHERE DESCRIPTION LIKE 'TRANS_SHORTCUT_%'";
519
        $conn->execute($sql);
520
        $rowcount = count($conn->getArrayResult());
521
522
        $this->assertNotTrue(($rowcount === 0));    # the rows are not available
523
524
        # remove all work
525
        $conn->execute("DROP TABLE MYTABLE");
526
    }
527
}