Passed
Pull Request — master (#30)
by David
05:42 queued 02:14
created

TDBMAbstractServiceTest::delete()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 8
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 3
dl 8
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 Copyright (C) 2006-2014 David Négrier - THE CODING MACHINE
5
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
*/
20
21
namespace TheCodingMachine\TDBM;
22
23
use Doctrine\Common\Cache\ArrayCache;
24
use Doctrine\Common\EventManager;
25
use Doctrine\DBAL\Connection;
26
use Doctrine\DBAL\DriverManager;
27
use Doctrine\DBAL\Event\Listeners\OracleSessionInit;
28
use Doctrine\DBAL\Platforms\MySqlPlatform;
29
use Doctrine\DBAL\Platforms\OraclePlatform;
30
use TheCodingMachine\FluidSchema\FluidSchema;
31
use TheCodingMachine\TDBM\Utils\DefaultNamingStrategy;
32
use TheCodingMachine\TDBM\Utils\PathFinder\PathFinder;
33
34
abstract class TDBMAbstractServiceTest extends \PHPUnit_Framework_TestCase
35
{
36
    /**
37
     * @var Connection
38
     */
39
    protected static $dbConnection;
40
41
    /**
42
     * @var TDBMService
43
     */
44
    protected $tdbmService;
45
46
    /**
47
     * @var DummyGeneratorListener
48
     */
49
    private $dummyGeneratorListener;
50
51
    /**
52
     * @var ConfigurationInterface
53
     */
54
    private $configuration;
55
56
    public static function setUpBeforeClass()
57
    {
58
        self::resetConnection();
59
60
        $config = new \Doctrine\DBAL\Configuration();
61
62
        $dbDriver = $GLOBALS['db_driver'];
63
64
        if ($dbDriver === 'pdo_sqlite') {
65
            $dbConnection = self::getConnection();
66
            $dbConnection->exec('PRAGMA foreign_keys = ON;');
67
        } elseif ($dbDriver === 'oci8') {
68
            $connectionParams = array(
69
                'servicename' => 'XE',
70
                'user' => $GLOBALS['db_admin_username'],
71
                // Because of issues in DBAL, admin and normal user password have to be the same.
72
                'password' => $GLOBALS['db_password'],
73
                'host' => $GLOBALS['db_host'],
74
                'port' => $GLOBALS['db_port'],
75
                'driver' => $GLOBALS['db_driver'],
76
                'dbname' => $GLOBALS['db_admin_username'],
77
                'charset' => 'AL32UTF8',
78
            );
79
80
            $adminConn = DriverManager::getConnection($connectionParams, $config);
81
82
            // When dropAndCreateDatabase is run several times, Oracle can have some issues releasing the TDBM user.
83
            // Let's forcefully delete the connection!
84
            $adminConn->exec("select 'alter system kill session ''' || sid || ',' || serial# || ''';' from v\$session where username = '".strtoupper($GLOBALS['db_name'])."'");
85
86
            $adminConn->getSchemaManager()->dropAndCreateDatabase($GLOBALS['db_name']);
87
88
            $dbConnection = self::getConnection();
89
        } else {
90
            $connectionParams = array(
91
                'user' => $GLOBALS['db_username'],
92
                'password' => $GLOBALS['db_password'],
93
                'host' => $GLOBALS['db_host'],
94
                'port' => $GLOBALS['db_port'],
95
                'driver' => $dbDriver,
96
            );
97
98
            $adminConn = DriverManager::getConnection($connectionParams, $config);
99
100
            $adminConn->getSchemaManager()->dropAndCreateDatabase($GLOBALS['db_name']);
101
102
            $connectionParams['dbname'] = $GLOBALS['db_name'];
103
104
            $dbConnection = DriverManager::getConnection($connectionParams, $config);
105
        }
106
107
108
        self::initSchema($dbConnection);
109
    }
110
111
    private static function resetConnection(): void
112
    {
113
        if (self::$dbConnection !== null) {
114
            self::$dbConnection->close();
115
        }
116
        self::$dbConnection = null;
117
    }
118
119
    protected static function getConnection(): Connection
120
    {
121
        if (self::$dbConnection === null) {
122
            $config = new \Doctrine\DBAL\Configuration();
123
124
            $dbDriver = $GLOBALS['db_driver'];
125
126
            if ($dbDriver === 'pdo_sqlite') {
127
                $connectionParams = array(
128
                    'memory' => true,
129
                    'driver' => 'pdo_sqlite',
130
                );
131
                self::$dbConnection = DriverManager::getConnection($connectionParams, $config);
132
            } elseif ($dbDriver === 'oci8') {
133
                $evm = new EventManager();
134
                $evm->addEventSubscriber(new OracleSessionInit(array(
135
                    'NLS_TIME_FORMAT' => 'HH24:MI:SS',
136
                    'NLS_DATE_FORMAT' => 'YYYY-MM-DD HH24:MI:SS',
137
                    'NLS_TIMESTAMP_FORMAT' => 'YYYY-MM-DD HH24:MI:SS',
138
                )));
139
140
                $connectionParams = array(
141
                    'servicename' => 'XE',
142
                    'user' => $GLOBALS['db_username'],
143
                    'password' => $GLOBALS['db_password'],
144
                    'host' => $GLOBALS['db_host'],
145
                    'port' => $GLOBALS['db_port'],
146
                    'driver' => $GLOBALS['db_driver'],
147
                    'dbname' => $GLOBALS['db_name'],
148
                    'charset' => 'AL32UTF8',
149
                );
150
                self::$dbConnection = DriverManager::getConnection($connectionParams, $config, $evm);
151
                self::$dbConnection->setAutoCommit(true);
152
153
            } else {
154
                $connectionParams = array(
155
                    'user' => $GLOBALS['db_username'],
156
                    'password' => $GLOBALS['db_password'],
157
                    'host' => $GLOBALS['db_host'],
158
                    'port' => $GLOBALS['db_port'],
159
                    'driver' => $GLOBALS['db_driver'],
160
                    'dbname' => $GLOBALS['db_name'],
161
                );
162
                self::$dbConnection = DriverManager::getConnection($connectionParams, $config);
163
            }
164
165
        }
166
        return self::$dbConnection;
167
    }
168
169
    protected function onlyMySql()
170
    {
171
        if (!self::getConnection()->getDatabasePlatform() instanceof MySqlPlatform) {
172
            $this->markTestSkipped('MySQL specific test');
173
        }
174
    }
175
176
    protected function setUp()
177
    {
178
        $this->tdbmService = new TDBMService($this->getConfiguration());
179
    }
180
181
    protected function getDummyGeneratorListener() : DummyGeneratorListener
182
    {
183
        if ($this->dummyGeneratorListener === null) {
184
            $this->dummyGeneratorListener = new DummyGeneratorListener();
185
        }
186
        return $this->dummyGeneratorListener;
187
    }
188
189
    protected function getConfiguration() : ConfigurationInterface
190
    {
191
        if ($this->configuration === null) {
192
193
            $this->configuration = new Configuration('TheCodingMachine\\TDBM\\Test\\Dao\\Bean', 'TheCodingMachine\\TDBM\\Test\\Dao', self::getConnection(), $this->getNamingStrategy(), new ArrayCache(), null, null, [$this->getDummyGeneratorListener()]);
194
            $this->configuration->setPathFinder(new PathFinder(null, dirname(__DIR__, 4)));
195
        }
196
        return $this->configuration;
197
    }
198
199
    protected function getNamingStrategy()
200
    {
201
        $strategy = new DefaultNamingStrategy();
202
        $strategy->setBeanPrefix('');
203
        $strategy->setBeanSuffix('Bean');
204
        $strategy->setBaseBeanPrefix('');
205
        $strategy->setBaseBeanSuffix('BaseBean');
206
        $strategy->setDaoPrefix('');
207
        $strategy->setDaoSuffix('Dao');
208
        $strategy->setBaseDaoPrefix('');
209
        $strategy->setBaseDaoSuffix('BaseDao');
210
211
        return $strategy;
212
    }
213
214
    private static function initSchema(Connection $connection): void
215
    {
216
        $fromSchema = $connection->getSchemaManager()->createSchema();
217
        $toSchema = clone $fromSchema;
218
219
        $db = new FluidSchema($toSchema, new \TheCodingMachine\FluidSchema\DefaultNamingStrategy($connection->getDatabasePlatform()));
220
221
        $db->table('country')
222
            ->column('id')->integer()->primaryKey()->autoIncrement()->comment('@Autoincrement')
223
            ->column('label')->string(255);
224
225
        $db->table('person')
226
            ->column('id')->integer()->primaryKey()->autoIncrement()->comment('@Autoincrement')
227
            ->column('name')->string(255);
228
229
        if ($connection->getDatabasePlatform() instanceof OraclePlatform) {
230
            $toSchema->getTable($connection->quoteIdentifier('person'))
231
                ->addColumn(
232
                    $connection->quoteIdentifier('created_at'),
233
                    'datetime',
234
                    ['columnDefinition' => 'TIMESTAMP(0) DEFAULT SYSDATE NOT NULL']
235
                );
236
        } else {
237
            $toSchema->getTable('person')
238
                ->addColumn(
239
                    $connection->quoteIdentifier('created_at'),
240
                    'datetime',
241
                    ['columnDefinition' => 'timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP']
242
                );
243
        }
244
245
        $db->table('person')
246
            ->column('modified_at')->datetime()->null()
247
            ->column('order')->integer()->null();
248
249
250
        $db->table('contact')
251
            ->extends('person')
252
            ->column('email')->string(255)
253
            ->column('manager_id')->references('contact')->null();
254
255
        $db->table('users')
256
            ->extends('contact')
257
            ->column('login')->string(255)
258
            ->column('password')->string(255)->null()
259
            ->column('status')->string(10)->null()->default(null)
260
            ->column('country_id')->references('country');
261
262
        $db->table('rights')
263
            ->column('label')->string(255)->primaryKey()->comment('Non autoincrementable primary key');
264
265
        $db->table('roles')
266
            ->column('id')->integer()->primaryKey()->autoIncrement()->comment('@Autoincrement')
267
            ->column('name')->string(255)
268
            ->column('created_at')->date()->null()
269
            ->column('status')->boolean()->null()->default(1);
270
271
        $db->table('roles_rights')
272
            ->column('role_id')->references('roles')
273
            ->column('right_label')->references('rights')->then()
274
            ->primaryKey(['role_id', 'right_label']);
275
276
        $db->table('users_roles')
277
            ->column('id')->integer()->primaryKey()->autoIncrement()->comment('@Autoincrement')
278
            ->column('user_id')->references('users')
279
            ->column('role_id')->references('roles');
280
281
        $db->table('all_nullable')
282
            ->column('id')->integer()->primaryKey()->autoIncrement()->comment('@Autoincrement')
283
            ->column('label')->string(255)->null()
284
            ->column('country_id')->references('country')->null();
285
286
        $db->table('animal')
287
            ->column('id')->integer()->primaryKey()->autoIncrement()->comment('@Autoincrement')
288
            ->column('name')->string(45)->index()
289
            ->column('order')->integer()->null();
290
291
        $db->table('dog')
292
            ->extends('animal')
293
            ->column('race')->string(45)->null();
294
295
        $db->table('cat')
296
            ->extends('animal')
297
            ->column('cuteness_level')->integer()->null();
298
299
        $db->table('boats')
300
            ->column('id')->integer()->primaryKey()->autoIncrement()->comment('@Autoincrement')
301
            ->column('name')->string(255)
302
            ->column('anchorage_country')->references('country')->notNull();
303
304
        $db->table('sailed_countries')
305
            ->column('boat_id')->references('boats')
306
            ->column('country_id')->references('country')
307
            ->then()->primaryKey(['boat_id', 'country_id']);
308
309
        $db->table('category')
310
            ->column('id')->integer()->primaryKey()->autoIncrement()->comment('@Autoincrement')
311
            ->column('label')->string(255)
312
            ->column('parent_id')->references('category')->null();
313
314
        $db->table('article')
315
            ->column('id')->string(36)->primaryKey()->comment('@UUID')
316
            ->column('content')->string(255);
317
318
        $db->table('article2')
319
            ->column('id')->string(36)->primaryKey()->comment('@UUID v4')
320
            ->column('content')->string(255);
321
322
        $toSchema->getTable('users')
323
            ->addUniqueIndex([$connection->quoteIdentifier('login')], 'users_login_idx')
324
            ->addIndex([$connection->quoteIdentifier('status'), $connection->quoteIdentifier('country_id')], 'users_status_country_idx');
325
326
        // We create the same index twice
327
        // except for Oracle that won't let us create twice the same index.
328
        if (!$connection->getDatabasePlatform() instanceof OraclePlatform) {
329
            $toSchema->getTable('users')
330
                ->addUniqueIndex([$connection->quoteIdentifier('login')], 'users_login_idx_2');
331
        }
332
333
334
        $sqlStmts = $toSchema->getMigrateFromSql($fromSchema, $connection->getDatabasePlatform());
335
336
        foreach ($sqlStmts as $sqlStmt) {
337
            $connection->exec($sqlStmt);
338
        }
339
340
        self::insert($connection, 'country', [
341
            'label' => 'France',
342
        ]);
343
        self::insert($connection, 'country', [
344
            'label' => 'UK',
345
        ]);
346
        self::insert($connection, 'country', [
347
            'label' => 'Jamaica',
348
        ]);
349
350
        self::insert($connection, 'person', [
351
            'name' => 'John Smith',
352
            'created_at' => '2015-10-24 11:57:13',
353
        ]);
354
        self::insert($connection, 'person', [
355
            'name' => 'Jean Dupont',
356
            'created_at' => '2015-10-24 11:57:13',
357
        ]);
358
        self::insert($connection, 'person', [
359
            'name' => 'Robert Marley',
360
            'created_at' => '2015-10-24 11:57:13',
361
        ]);
362
        self::insert($connection, 'person', [
363
            'name' => 'Bill Shakespeare',
364
            'created_at' => '2015-10-24 11:57:13',
365
        ]);
366
367
        self::insert($connection, 'contact', [
368
            'id' => 1,
369
            'email' => '[email protected]',
370
            'manager_id' => null,
371
        ]);
372
        self::insert($connection, 'contact', [
373
            'id' => 2,
374
            'email' => '[email protected]',
375
            'manager_id' => null,
376
        ]);
377
        self::insert($connection, 'contact', [
378
            'id' => 3,
379
            'email' => '[email protected]',
380
            'manager_id' => null,
381
        ]);
382
        self::insert($connection, 'contact', [
383
            'id' => 4,
384
            'email' => '[email protected]',
385
            'manager_id' => 1,
386
        ]);
387
388
        self::insert($connection, 'rights', [
389
            'label' => 'CAN_SING',
390
        ]);
391
        self::insert($connection, 'rights', [
392
            'label' => 'CAN_WRITE',
393
        ]);
394
395
        self::insert($connection, 'roles', [
396
            'name' => 'Admins',
397
            'created_at' => '2015-10-24'
398
        ]);
399
        self::insert($connection, 'roles', [
400
            'name' => 'Writers',
401
            'created_at' => '2015-10-24'
402
        ]);
403
        self::insert($connection, 'roles', [
404
            'name' => 'Singers',
405
            'created_at' => '2015-10-24'
406
        ]);
407
408
        self::insert($connection, 'roles_rights', [
409
            'role_id' => 1,
410
            'right_label' => 'CAN_SING'
411
        ]);
412
        self::insert($connection, 'roles_rights', [
413
            'role_id' => 3,
414
            'right_label' => 'CAN_SING'
415
        ]);
416
        self::insert($connection, 'roles_rights', [
417
            'role_id' => 1,
418
            'right_label' => 'CAN_WRITE'
419
        ]);
420
        self::insert($connection, 'roles_rights', [
421
            'role_id' => 2,
422
            'right_label' => 'CAN_WRITE'
423
        ]);
424
425
        self::insert($connection, 'users', [
426
            'id' => 1,
427
            'login' => 'john.smith',
428
            'password' => null,
429
            'status' => 'on',
430
            'country_id' => 2
431
        ]);
432
        self::insert($connection, 'users', [
433
            'id' => 2,
434
            'login' => 'jean.dupont',
435
            'password' => null,
436
            'status' => 'on',
437
            'country_id' => 1
438
        ]);
439
        self::insert($connection, 'users', [
440
            'id' => 3,
441
            'login' => 'robert.marley',
442
            'password' => null,
443
            'status' => 'off',
444
            'country_id' => 3
445
        ]);
446
        self::insert($connection, 'users', [
447
            'id' => 4,
448
            'login' => 'bill.shakespeare',
449
            'password' => null,
450
            'status' => 'off',
451
            'country_id' => 2
452
        ]);
453
454
        self::insert($connection, 'users_roles', [
455
            'user_id' => 1,
456
            'role_id' => 1,
457
        ]);
458
        self::insert($connection, 'users_roles', [
459
            'user_id' => 2,
460
            'role_id' => 1,
461
        ]);
462
        self::insert($connection, 'users_roles', [
463
            'user_id' => 3,
464
            'role_id' => 3,
465
        ]);
466
        self::insert($connection, 'users_roles', [
467
            'user_id' => 4,
468
            'role_id' => 2,
469
        ]);
470
        self::insert($connection, 'users_roles', [
471
            'user_id' => 3,
472
            'role_id' => 2,
473
        ]);
474
    }
475
476 View Code Duplication
    protected static function insert(Connection $connection, string $tableName, array $data): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
477
    {
478
        $quotedData = [];
479
        foreach ($data as $id => $value) {
480
            $quotedData[$connection->quoteIdentifier($id)] = $value;
481
        }
482
        $connection->insert($connection->quoteIdentifier($tableName), $quotedData);
483
    }
484
485 View Code Duplication
    protected static function delete(Connection $connection, string $tableName, array $data): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
486
    {
487
        $quotedData = [];
488
        foreach ($data as $id => $value) {
489
            $quotedData[$connection->quoteIdentifier($id)] = $value;
490
        }
491
        $connection->delete($connection->quoteIdentifier($tableName), $quotedData);
492
    }
493
}
494