BuilderTest::testItCreateMySQLTable()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 1
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 11
rs 9.9666
c 3
b 1
f 1
1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of FlexPHP.
4
 *
5
 * (c) Freddie Gar <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace FlexPHP\Database\Tests\Unit;
11
12
use FlexPHP\Database\Builder;
13
use FlexPHP\Database\Exception\DatabaseValidationException;
14
use FlexPHP\Database\Tests\TestCase;
15
use FlexPHP\Schema\Schema;
16
use FlexPHP\Schema\SchemaAttribute;
17
use FlexPHP\Schema\SchemaInterface;
18
19
class BuilderTest extends TestCase
20
{
21
    public function testItPlatformErrorThrowException(): void
22
    {
23
        $this->expectException(DatabaseValidationException::class);
24
        $this->expectExceptionMessage('try: MySQL, SQLSrv');
25
26
        new Builder('Unknow');
27
    }
28
29
    public function testItDatabaseNameErrorThrowException(): void
30
    {
31
        $this->expectException(DatabaseValidationException::class);
32
        $this->expectExceptionMessage('Database name [_db] invalid');
33
34
        $builder = new Builder('MySQL');
35
        $builder->createDatabase('_db');
36
    }
37
38
    public function testItCreateMySQLDatabase(): void
39
    {
40
        $name = 'db';
41
42
        $builder = new Builder('MySQL');
43
        $builder->createDatabase($name);
44
        $this->assertEquals(<<<T
45
CREATE DATABASE $name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
46
47
T
48
, $builder->toSql());
49
    }
50
51
    public function testItCreateSQLSrvDatabase(): void
52
    {
53
        $name = 'db';
54
55
        $builder = new Builder('SQLSrv');
56
        $builder->createDatabase($name);
57
        $this->assertEquals(<<<T
58
CREATE DATABASE $name COLLATE latin1_general_100_ci_ai_sc;
59
60
T
61
, $builder->toSql());
62
    }
63
64
    public function testItCreateSQLiteDatabase(): void
65
    {
66
        $name = 'db';
67
68
        $builder = new Builder('SQLite');
69
        $builder->createDatabase($name);
70
        $this->assertEquals(<<<T
71
72
T
73
, $builder->toSql());
74
    }
75
76
    public function testItCreateMySQLDatabaseWithUse(): void
77
    {
78
        $name = 'db';
79
80
        $builder = new Builder('MySQL');
81
        $builder->createDatabaseWithUse($name);
82
        $this->assertEquals(<<<T
83
CREATE DATABASE $name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
84
85
USE $name;
86
87
T
88
, $builder->toSql());
89
    }
90
91
    public function testItCreateSQLSrvDatabaseWithUse(): void
92
    {
93
        $name = 'db';
94
95
        $builder = new Builder('SQLSrv');
96
        $builder->createDatabaseWithUse($name);
97
        $this->assertEquals(<<<T
98
CREATE DATABASE $name COLLATE latin1_general_100_ci_ai_sc;
99
100
T
101
, $builder->toSql());
102
    }
103
104
    public function testItCreateSQLiteDatabaseWithUse(): void
105
    {
106
        $name = 'db';
107
108
        $builder = new Builder('SQLite');
109
        $builder->createDatabaseWithUse($name);
110
        $this->assertEquals(<<<T
111
T
112
, $builder->toSql());
113
    }
114
115
    public function testItCreateMySQLUser(): void
116
    {
117
        $name = 'mysql';
118
        $password = 'p4sw00rd';
119
120
        $builder = new Builder('MySQL');
121
        $builder->createUser($name, $password);
122
        $this->assertEquals(<<<T
123
CREATE USER '$name'@'%' IDENTIFIED BY '$password';
124
125
T
126
, $builder->toSql());
127
    }
128
129
    public function testItCreateSQLSrvUser(): void
130
    {
131
        $name = 'sqlsrv';
132
        $password = 'p4sw00rd';
133
134
        $builder = new Builder('SQLSrv');
135
        $builder->createUser($name, $password);
136
        $this->assertEquals(<<<T
137
CREATE LOGIN $name WITH PASSWORD = '$password';
138
GO
139
CREATE USER $name FOR LOGIN $name;
140
GO
141
142
T
143
, $builder->toSql());
144
    }
145
146
    public function testItCreateSQLiteUser(): void
147
    {
148
        $name = 'sqlite';
149
        $password = 'p4sw00rd';
150
151
        $builder = new Builder('SQLite');
152
        $builder->createUser($name, $password);
153
        $this->assertEquals(<<<T
154
T
155
, $builder->toSql());
156
    }
157
158
    public function testItCreateMySQLUserWithGrants(): void
159
    {
160
        $name = 'mysql';
161
        $password = 'p4sw00rd';
162
163
        $builder = new Builder('MySQL');
164
        $builder->createUser($name, $password, 'host', ['ALL PRIVILEGES']);
165
        $this->assertEquals(<<<T
166
CREATE USER '$name'@'host' IDENTIFIED BY '$password';
167
168
GRANT ALL PRIVILEGES ON *.* TO '$name'@'host';
169
170
T
171
, $builder->toSql());
172
    }
173
174
    public function testItCreateSQLSrvUserWithGrants(): void
175
    {
176
        $name = 'sqlsrv';
177
        $password = 'p4sw00rd';
178
179
        $builder = new Builder('SQLSrv');
180
        $builder->createUser($name, $password, 'host', ['ALL PRIVILEGES']);
181
        $this->assertEquals(<<<T
182
CREATE LOGIN $name WITH PASSWORD = '$password';
183
GO
184
CREATE USER $name FOR LOGIN $name;
185
GO
186
187
GRANT ALL TO $name;
188
GO
189
190
T
191
, $builder->toSql());
192
    }
193
194
    public function testItCreateSQLiteUserWithGrants(): void
195
    {
196
        $name = 'sqlite';
197
        $password = 'p4sw00rd';
198
199
        $builder = new Builder('SQLite');
200
        $builder->createUser($name, $password, 'host', ['ALL PRIVILEGES']);
201
        $this->assertEquals(<<<T
202
T
203
, $builder->toSql());
204
    }
205
206
    public function testItCreateMySQLTable(): void
207
    {
208
        $builder = new Builder('MySQL');
209
        $builder->createTable($this->getSchema());
210
        $this->assertEquals(<<<T
211
CREATE TABLE bar (
212
    foo INT DEFAULT NULL COMMENT 'foo'
213
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;
214
215
T
216
, $builder->toSql());
217
    }
218
219
    public function testItCreateSQLSrvTable(): void
220
    {
221
        $builder = new Builder('SQLSrv');
222
        $builder->createTable($this->getSchema());
223
        $this->assertEquals(<<<T
224
CREATE TABLE bar (
225
    foo INT
226
);
227
228
EXEC sp_addextendedproperty N'MS_Description', N'foo', N'SCHEMA', 'dbo', N'TABLE', 'bar', N'COLUMN', foo;
229
230
T
231
, $builder->toSql());
232
    }
233
234
    public function testItCreateSQLiteTable(): void
235
    {
236
        $builder = new Builder('SQLite');
237
        $builder->createTable($this->getSchema());
238
        $this->assertEquals(<<<T
239
CREATE TABLE bar (
240
    foo INTEGER DEFAULT NULL
241
);
242
243
T
244
, $builder->toSql());
245
    }
246
247
    public function testItCreateMySQLComplete(): void
248
    {
249
        $dbname = 'complete';
250
        $username = 'username';
251
        $password = 'password';
252
        $host = 'host';
253
        $schema = new Schema('bar', 'title', [
254
            new SchemaAttribute('Pk', 'string', 'pk|required'),
255
            new SchemaAttribute('foo', 'string', 'minlength:10|maxlength:100'),
256
            new SchemaAttribute('bar', 'integer', 'min:10|max:50'),
257
        ]);
258
259
        $schemaFk = new Schema('fuz', 'title', [
260
            new SchemaAttribute('Pk', 'integer', 'pk|ai|required'),
261
            new SchemaAttribute('barId', 'integer', 'fk:bar'),
262
        ]);
263
264
        $builder = new Builder('MySQL');
265
        $builder->createDatabaseWithUse($dbname);
266
        $builder->createUser($username, $password, $host, ['ALL PRIVILEGES'], $dbname);
267
        $builder->createTable($schema);
268
        $builder->createTable($schemaFk);
269
270
        $this->assertEquals(<<<T
271
CREATE DATABASE $dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
272
273
USE $dbname;
274
275
CREATE USER '$username'@'$host' IDENTIFIED BY '$password';
276
277
GRANT ALL PRIVILEGES ON $dbname.* TO '$username'@'$host';
278
279
CREATE TABLE bar (
280
    Pk VARCHAR(255) NOT NULL COMMENT 'Pk',
281
    foo VARCHAR(100) DEFAULT NULL COMMENT 'foo',
282
    bar INT DEFAULT NULL COMMENT 'bar',
283
    PRIMARY KEY(Pk)
284
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;
285
286
CREATE TABLE fuz (
287
    Pk INT AUTO_INCREMENT NOT NULL COMMENT 'Pk',
288
    barId INT DEFAULT NULL COMMENT 'barId',
289
    INDEX IDX_51837B119A5BAE65 (barId),
290
    PRIMARY KEY(Pk)
291
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;
292
293
ALTER TABLE fuz ADD CONSTRAINT FK_51837B119A5BAE65 FOREIGN KEY (barId) REFERENCES bar (id);
294
295
T
296
, $builder->toSql());
297
    }
298
299
    public function testItConstraints(): void
300
    {
301
        $dbname = 'complete';
302
        $username = 'username';
303
        $password = 'password';
304
        $host = 'host';
305
        $schema = new Schema('bar', 'title', [
306
            new SchemaAttribute('Pk', 'string', 'pk|required'),
307
            new SchemaAttribute('foo', 'string', 'minlength:10|maxlength:100'),
308
            new SchemaAttribute('bar', 'integer', 'min:10|max:50|default:20'),
309
        ]);
310
311
        $schemaFk = new Schema('fuz', 'title', [
312
            new SchemaAttribute('Pk', 'integer', 'pk|ai|required'),
313
            new SchemaAttribute('barId', 'integer', 'fk:bar'),
314
        ]);
315
316
        $schemaFk2 = new Schema('baz', 'title', [
317
            new SchemaAttribute('Pk', 'integer', 'pk|ai|required'),
318
            new SchemaAttribute('fuzId', 'integer', 'fk:fuz'),
319
            new SchemaAttribute('barId', 'integer', 'fk:bar'),
320
            new SchemaAttribute('string', 'string', 'default:DEFAULT'),
321
        ]);
322
323
        $builder = new Builder('MySQL');
324
        $builder->createDatabase($dbname);
325
        $builder->createUser($username, $password, $host);
326
        $builder->createTable($schema);
327
        $builder->createTable($schemaFk);
328
        $builder->createTable($schemaFk2);
329
330
        $this->assertEquals(<<<T
331
CREATE DATABASE $dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
332
333
CREATE USER '$username'@'$host' IDENTIFIED BY '$password';
334
335
CREATE TABLE bar (
336
    Pk VARCHAR(255) NOT NULL COMMENT 'Pk',
337
    foo VARCHAR(100) DEFAULT NULL COMMENT 'foo',
338
    bar INT DEFAULT 20 COMMENT 'bar',
339
    PRIMARY KEY(Pk)
340
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;
341
342
CREATE TABLE fuz (
343
    Pk INT AUTO_INCREMENT NOT NULL COMMENT 'Pk',
344
    barId INT DEFAULT NULL COMMENT 'barId',
345
    INDEX IDX_51837B119A5BAE65 (barId),
346
    PRIMARY KEY(Pk)
347
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;
348
349
CREATE TABLE baz (
350
    Pk INT AUTO_INCREMENT NOT NULL COMMENT 'Pk',
351
    fuzId INT DEFAULT NULL COMMENT 'fuzId',
352
    barId INT DEFAULT NULL COMMENT 'barId',
353
    string VARCHAR(255) DEFAULT 'DEFAULT' COMMENT 'string',
354
    INDEX IDX_78240498BEB399D5 (fuzId),
355
    INDEX IDX_782404989A5BAE65 (barId),
356
    PRIMARY KEY(Pk)
357
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;
358
359
ALTER TABLE fuz ADD CONSTRAINT FK_51837B119A5BAE65 FOREIGN KEY (barId) REFERENCES bar (id);
360
361
ALTER TABLE baz ADD CONSTRAINT FK_78240498BEB399D5 FOREIGN KEY (fuzId) REFERENCES fuz (id);
362
363
ALTER TABLE baz ADD CONSTRAINT FK_782404989A5BAE65 FOREIGN KEY (barId) REFERENCES bar (id);
364
365
T
366
, $builder->toSql());
367
    }
368
369
    public function testItConstraintsFkErrorThrowException(): void
370
    {
371
        $this->expectException(DatabaseValidationException::class);
372
        $this->expectExceptionMessage('Tables in foreign');
373
374
        $schema = new Schema('bar', 'title', [
375
            new SchemaAttribute('Pk', 'string', 'pk|required'),
376
            new SchemaAttribute('foo', 'string', 'minlength:10|maxlength:100'),
377
            new SchemaAttribute('bar', 'integer', 'min:10|max:50'),
378
        ]);
379
380
        $schemaFk = new Schema('fuz', 'title', [
381
            new SchemaAttribute('Pk', 'integer', 'pk|ai|required'),
382
            new SchemaAttribute('barId', 'integer', 'fk:notexist'),
383
        ]);
384
385
        $builder = new Builder('MySQL');
386
        $builder->createTable($schema);
387
        $builder->createTable($schemaFk);
388
389
        $builder->toSql();
390
    }
391
392
    public function getSchema(): SchemaInterface
393
    {
394
        return new Schema('bar', 'title', [
395
            new SchemaAttribute('foo', 'integer', [
396
                'min' => 10,
397
                'max' => 100,
398
            ]),
399
        ]);
400
    }
401
}
402