Test Failed
Branch master (c7fd68)
by Gaetano
06:34
created

getListCollationsSqlAction()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 63
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 63
rs 8.5226
c 0
b 0
f 0
cc 7
nc 6
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace Db3v4l\Core;
4
5
use Db3v4l\API\Interfaces\SqlAction\CommandAction;
6
use Db3v4l\API\Interfaces\SqlExecutor\Executor;
7
use Db3v4l\Core\SqlAction\Command;
8
9
use OutOfBoundsException;
10
11
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
12
 * @see \Doctrine\DBAL\Platforms for more comprehensive abstractions of per-platform sql
13
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
14
class DatabaseSchemaManager
15
{
16
    protected $databaseConfiguration;
17
18
    public function __construct(array $databaseConfiguration)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
19
    {
20
        $this->databaseConfiguration = $databaseConfiguration;
21
    }
22
23
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
24
     * @return string[]
25
     */
26
    public function getDatabaseConfiguration()
27
    {
28
        return $this->databaseConfiguration;
29
    }
30
31
    /**
32
     * Returns the sql 'action' used to create a new db and accompanying user
33
     * @param string $dbName Max 63 chars for Postgres
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
34
     * @param string $userName Max 16 chars for MySQL 5.5
0 ignored issues
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
35
     * @param string $password
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
36
     * @param string $charset charset/collation name
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
37
     * @return CommandAction
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
38
     * @throws OutOfBoundsException for unsupported database types
0 ignored issues
show
Coding Style introduced by
Tag @throws cannot be grouped with parameter tags in a doc comment
Loading history...
39
     * @todo prevent sql injection!
0 ignored issues
show
Coding Style introduced by
Tag @todo cannot be grouped with parameter tags in a doc comment
Loading history...
Coding Style introduced by
Tag value for @todo tag indented incorrectly; expected 3 spaces but found 1
Loading history...
40
     */
41
    public function getCreateDatabaseSqlAction($dbName, $userName, $password, $charset = null)
42
    {
43
        $collation = $this->getCollationName($charset);
44
45
        switch ($this->databaseConfiguration['vendor']) {
46
47
            case 'mariadb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
48
            case 'mysql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
49
                $statements = [
50
                    "CREATE DATABASE `$dbName`" . ($collation !== null ? " CHARACTER SET $collation" : '') . ';'
51
                ];
52
                if ($userName != '') {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
53
                    $statements[] = "CREATE USER '$userName'@'%' IDENTIFIED BY '$password';";
54
                    $statements[] = "GRANT ALL PRIVILEGES ON `$dbName`.* TO '$userName'@'%';";
55
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
56
                return new Command($statements);
57
58
            case 'mssql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
59
                $statements = [
60
                    /// @see https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility
61
                    // When using sqlcmd, we are told _not_ to use GO as query terminator.
62
                    // Also, by default connections are in autocommit mode...
63
                    // And yet, we need a GO to commit the db creation...
64
                    "SET QUOTED_IDENTIFIER ON;",
65
                    "CREATE DATABASE \"$dbName\"" . ($collation !== null ? " COLLATE $collation" : '') . ';'
66
                ];
67
                if ($userName != '') {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
68
                    $statements[] = "CREATE LOGIN \"$userName\" WITH PASSWORD = '$password', DEFAULT_DATABASE = \"$dbName\", CHECK_POLICY = OFF, CHECK_EXPIRATION = OFF;";
69
                    $statements[] = "GO";
70
                    $statements[] = "USE \"$dbName\";";
71
                    $statements[] = "CREATE USER \"$userName\" FOR LOGIN \"$userName\";";
72
                    $statements[] = "ALTER ROLE db_owner ADD MEMBER \"$userName\";";
73
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
74
                return new Command($statements);
75
76
            //case 'oracle':
77
78
            case 'postgresql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
79
                $statements = [
80
                    // q: do we need to add 'TEMPLATE template0' ?
81
                    //    see f.e. https://www.vertabelo.com/blog/collations-in-postgresql/
82
                    "CREATE DATABASE \"$dbName\"" . ($collation !== null ? " ENCODING $collation" : '') . ';',
83
                ];
84
                if ($userName != '') {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
85
                    $statements[] = "COMMIT;";
86
                    $statements[] = "CREATE USER \"$userName\" WITH PASSWORD '$password'" . ';';
87
                    $statements[] = "GRANT ALL ON DATABASE \"$dbName\" TO \"$userName\""; // q: should we avoid granting CREATE?
88
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
89
                return new Command($statements);
90
91
            case 'sqlite':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
92
                /// @todo this does not support creation of the new db with a different character encoding...
93
                ///       see https://stackoverflow.com/questions/21348459/set-pragma-encoding-utf-16-for-main-database-in-sqlite
94
                $filename = dirname($this->databaseConfiguration['path']) . '/' . $dbName . '.sqlite';
95
                return new Command(
96
                    "ATTACH '$filename' AS \"$dbName\";"
97
                );
98
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
99
                throw new OutOfBoundsException("Unsupported database type '{$this->databaseConfiguration['vendor']}'");
100
        }
101
    }
102
103
    /**
104
     * Returns the sql 'action' used to drop a db and associated user account
105
     * @param string $dbName
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
106
     * @param string $userName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
107
     * @return CommandAction
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
108
     * @param bool $ifExists
0 ignored issues
show
Coding Style introduced by
Tags must be grouped together in a doc comment
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
109
     * @throws OutOfBoundsException for unsupported database types
0 ignored issues
show
Coding Style introduced by
Tag @throws cannot be grouped with parameter tags in a doc comment
Loading history...
110
     * @bug currently some DBs report failures for non-existing user, even when $ifExists = true
0 ignored issues
show
Coding Style introduced by
Tag @bug cannot be grouped with parameter tags in a doc comment
Loading history...
Coding Style introduced by
Tag value for @bug tag indented incorrectly; expected 4 spaces but found 1
Loading history...
111
     * @todo prevent sql injection!
0 ignored issues
show
Coding Style introduced by
Tag @todo cannot be grouped with parameter tags in a doc comment
Loading history...
Coding Style introduced by
Tag value for @todo tag indented incorrectly; expected 3 spaces but found 1
Loading history...
112
     */
113
    public function getDropDatabaseSqlAction($dbName, $userName, $ifExists = false)
114
    {
115
        $ifClause = '';
116
        if ($ifExists) {
117
            $ifClause = 'IF EXISTS';
118
        }
119
120
        switch ($this->databaseConfiguration['vendor']) {
121
122
            case 'mariadb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
123
            case 'mysql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
124
                $statements = [
125
                    "DROP DATABASE {$ifClause} `$dbName`;"
126
                ];
127
                if ($userName != '') {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
128
                    /// @todo since mysql 5.7, 'DROP USER IF EXISTS' is supported. We could use it...
129
                    $statements[] = "DROP USER '$userName'@'%';";
130
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
131
                return new Command($statements);
132
133
            case 'mssql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
134
                $statements = [
135
                    "SET QUOTED_IDENTIFIER ON;"
136
                ];
137
                if ($userName != '') {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
138
                    // we assume users are 'local' to each db, as we create them by default
139
                    $statements[] = "USE \"$dbName\";";
140
                    $statements[] = "DROP LOGIN \"$userName\";";
141
                    $statements[] = "DROP USER {$ifClause} \"$userName\";";
142
                    $statements[] = "USE \"master\";";
143
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
144
                $statements[] = "DROP DATABASE {$ifClause} \"$dbName\";";
145
146
                return new Command($statements);
147
148
            //case 'oracle':
149
150
            case 'postgresql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
151
                $statements = [
152
                    "DROP DATABASE {$ifClause} \"$dbName\";",
153
                ];
154
                if ($userName != '') {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
155
                    $statements[] = "DROP USER {$ifClause} \"$userName\";";
156
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
157
                return new Command($statements);
158
159
            case 'sqlite':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
160
                $filename = dirname($this->databaseConfiguration['path']) . '/' . $dbName . '.sqlite';
161
                return new Command(
162
                    null,
163
                    function() use($filename, $dbName, $ifExists) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
Coding Style introduced by
Expected 1 space after USE keyword; found 0
Loading history...
164
                        if (is_file($filename)) {
165
                            unlink($filename);
166
                        } else {
167
                            if (!$ifExists) {
168
                                throw new \Exception("Can not drop database '$dbName': file not found");
169
                            }
170
                        }
171
                    }
172
                );
173
174
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
175
                throw new OutOfBoundsException("Unsupported database type '{$this->databaseConfiguration['vendor']}'");
176
        }
177
    }
178
179
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
180
     * @param string $userName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
181
     * @param bool $ifExists
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
182
     * @return Command
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
183
     * @throws OutOfBoundsException for unsupported database types
0 ignored issues
show
Coding Style introduced by
Tag @throws cannot be grouped with parameter tags in a doc comment
Loading history...
184
     * @bug currently some DBs report failures for non-existing user, even when $ifExists = true
0 ignored issues
show
Coding Style introduced by
Tag @bug cannot be grouped with parameter tags in a doc comment
Loading history...
Coding Style introduced by
Tag value for @bug tag indented incorrectly; expected 4 spaces but found 1
Loading history...
185
     * @todo prevent sql injection!
0 ignored issues
show
Coding Style introduced by
Tag @todo cannot be grouped with parameter tags in a doc comment
Loading history...
Coding Style introduced by
Tag value for @todo tag indented incorrectly; expected 3 spaces but found 1
Loading history...
186
     */
187
    public function getDropUserSqlAction($userName, $ifExists = false)
188
    {
189
        $ifClause = '';
190
        if ($ifExists) {
191
            $ifClause = 'IF EXISTS';
192
        }
193
194
        switch ($this->databaseConfiguration['vendor']) {
195
196
            case 'mariadb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
197
            case 'mysql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
198
                /// @todo since mysql 5.7, 'DROP USER IF EXISTS' is supported. We could use it...
199
                return new Command([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
200
                    "DROP USER '$userName'@'%';"
201
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
202
203
            case 'mssql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
204
                /// @todo if the user is created inside a specific db, this will fail. We need to add a USE DB cmd 1st...
205
                ///       to find out if a user exists in the current db: SELECT DATABASE_PRINCIPAL_ID('$user');
206
                return new Command([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
207
                    "SET QUOTED_IDENTIFIER ON;",
208
                    "DROP LOGIN \"$userName\";",
209
                    "DROP USER {$ifClause} \"$userName\";"
210
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
211
212
            //case 'oracle':
213
214
            case 'postgresql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
215
                return new Command([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
216
                    "DROP USER {$ifClause} \"$userName\";"
217
                ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
218
219
            case 'sqlite':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
220
                return new Command(
221
                    null,
222
                    function() {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
223
                        /// @todo should we return something ?
224
                    }
225
                );
226
227
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
228
                throw new OutOfBoundsException("Unsupported database type '{$this->databaseConfiguration['vendor']}'");
229
        }
230
    }
231
232
    /**
233
     * Returns the sql 'action' used to list all available collations
234
     * @return CommandAction
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
235
     * @throws OutOfBoundsException for unsupported database types
236
     */
237
    public function getListCollationsSqlAction()
238
    {
239
        switch ($this->databaseConfiguration['vendor']) {
240
241
            case 'mariadb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
242
            case 'mysql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
243
                return new Command(
244
                    'SHOW COLLATION;',
245
                    function ($output, $executor) {
246
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
247
                        $lines = $executor->resultSetToArray($output);
248
                        $out = [];
249
                        foreach($lines as $line) {
0 ignored issues
show
Coding Style introduced by
Expected "foreach (...) {\n"; found "foreach(...) {\n"
Loading history...
250
                            $parts = explode("|", $line, 3);
251
                            $out[] = trim($parts[0]) . ' (' . trim($parts[1]) .')';
252
                        }
253
                        return $out;
254
                    }
255
                );
256
257
            //case 'oracle':
258
259
            case 'postgresql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
260
                return new Command(
261
                    'SELECT collname AS Collation FROM pg_collation ORDER BY collname',
262
                    function ($output, $executor) {
263
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
264
                        return $executor->resultSetToArray($output);
265
                    }
266
                );
267
268
            case 'sqlite':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
269
                return new Command(
270
                    null,
271
                    /// @todo list the supported utf16 variants as soon as allow using them
272
                    function () {
273
                        return [];
274
                    }
275
                );
276
                /*return [
277
                    // q: are these comparable to other databases ? we probably should instead list the values for https://www.sqlite.org/pragma.html#pragma_encoding
278
                    'PRAGMA collation_list;',
279
                    function ($output, $executor) {
280
                        $out = [];
281
                        foreach(explode("\n", $output) as $line) {
282
                            $out[] = explode("|", $line, 2)[1];
283
                        }
284
                        sort($out);
285
                        return implode("\n", $out);
286
                    }
287
                ];*/
288
289
            case 'mssql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
290
                return new Command(
291
                    'SELECT name AS Collation FROM fn_helpcollations();',
292
                    function ($output, $executor) {
293
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
294
                        return $executor->resultSetToArray($output);
295
                    }
296
                );
297
298
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
299
                throw new OutOfBoundsException("Unsupported database type '{$this->databaseConfiguration['vendor']}'");
300
        }
301
    }
302
303
    /**
304
     * Returns the sql 'action' used to list all available databases
305
     * @return CommandAction
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
306
     * @throws OutOfBoundsException for unsupported database types
307
     * @todo for each database, retrieve the charset/collation
0 ignored issues
show
Coding Style introduced by
Tag value for @todo tag indented incorrectly; expected 3 spaces but found 1
Loading history...
308
     */
309
    public function getListDatabasesSqlAction()
310
    {
311
        switch ($this->databaseConfiguration['vendor']) {
312
313
            case 'mariadb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
314
            case 'mysql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
315
                return new Command(
316
                    /// @todo use 'SHOW DATABASES' for versions < 5
317
                    "SELECT SCHEMA_NAME AS 'Database' FROM information_schema.SCHEMATA ORDER BY SCHEMA_NAME;",
318
                    function ($output, $executor) {
319
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
320
                        return $executor->resultSetToArray($output);
321
                    }
322
                );
323
324
            case 'mssql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
325
                return new Command(
326
                    // the way we create it, the user account is contained in the db
327
                    // @todo add "WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb')" ?
328
                    "SELECT name AS 'Database' FROM sys.databases ORDER BY name;",
329
                    function ($output, $executor) {
330
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
331
                        return $executor->resultSetToArray($output);
332
                    }
333
                );
334
335
            //case 'oracle':
336
337
            case 'postgresql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
338
                return new Command(
339
                    'SELECT datname AS "Database" FROM pg_database ORDER BY datname;',
340
                    function ($output, $executor) {
341
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
342
                        return $executor->resultSetToArray($output);
343
                    }
344
                );
345
346
            case 'sqlite':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
347
                $fileGlob = dirname($this->databaseConfiguration['path']) . '/*.sqlite';
348
                return new Command(
349
                    null,
350
                    function() use ($fileGlob) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
351
                        $out = [];
352
                        foreach (glob($fileGlob) as $filename) {
353
                            $out[] =  basename($filename);
354
                        }
355
                        return $out;
356
                    }
357
                );
358
359
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
360
                throw new OutOfBoundsException("Unsupported database type '{$this->databaseConfiguration['vendor']}'");
361
        }
362
    }
363
364
    /**
365
     * Returns the sql 'action' used to list all existing db users
366
     * @return CommandAction
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
367
     * @throws OutOfBoundsException for unsupported database types
368
     */
369
    public function getListUsersSqlAction()
370
    {
371
        switch ($this->databaseConfiguration['vendor']) {
372
373
            case 'mariadb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
374
            case 'mysql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
375
                return new Command(
376
                    'SELECT DISTINCT User FROM mysql.user ORDER BY User;',
377
                    function ($output, $executor) {
378
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
379
                        return $executor->resultSetToArray($output);
380
                    }
381
                );
382
383
            case 'mssql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
384
                return new Command(
385
                    "SELECT name AS 'User' FROM sys.sql_logins ORDER BY name",
386
                    function ($output, $executor) {
387
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
388
                        return $executor->resultSetToArray($output);
389
                    }
390
                );
391
392
            //case 'oracle':
393
394
            case 'postgresql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
395
                return new Command(
396
                    'SELECT usename AS "User" FROM pg_catalog.pg_user ORDER BY usename;',
397
                    function ($output, $executor) {
398
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
399
                        return $executor->resultSetToArray($output);
400
                    }
401
                );
402
403
            case 'sqlite':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
404
                return new Command(
405
                    null,
406
                    function () {
407
                        // since sqlite does not support users, null seems more appropriate than an empty array...
408
                        return null;
409
                    }
410
                );
411
412
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
413
                throw new OutOfBoundsException("Unsupported database type '{$this->databaseConfiguration['vendor']}'");
414
        }
415
    }
416
417
    /**
418
     * Returns the sql 'action' used to retrieve the db instance version info
419
     * @return Command
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
420
     */
421
    public function getRetrieveVersionInfoSqlAction()
422
    {
423
        switch ($this->databaseConfiguration['vendor']) {
424
425
            case 'mariadb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
426
            case 'mysql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
427
                return new Command(
428
                    'SHOW VARIABLES LIKE "version";',
429
                    function ($output, $executor) {
430
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
431
                        $line = $executor->resultSetToArray($output)[0];
432
                        $parts = explode('|', $line);
433
                        return trim($parts[1]);
434
                    }
435
                );
436
437
            //case 'oracle':
438
439
            case 'postgresql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
440
                return new Command(
441
                    'SHOW server_version;',
442
                    function ($output, $executor) {
443
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
444
                        return $executor->resultSetToArray($output)[0];
445
                    }
446
                );
447
448
            case 'sqlite':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
449
                return new Command(
450
                    "select sqlite_version();",
451
                    function ($output, $executor) {
452
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
453
                        return $executor->resultSetToArray($output)[0];
454
                    }
455
                );
456
457
            case 'mssql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
458
                return new Command(
459
                    "SELECT @@version",
460
                    function ($output, $executor) {
461
                        /** @var Executor $executor */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
462
                        $output = $executor->resultSetToArray($output);
463
                        $line = $output[0];
464
                        preg_match('/Microsoft SQL Server +([^ ]+) +([^ ]+) +/', $line, $matches);
465
                        return $matches[1] . ' ' . $matches[2];
466
                    }
467
                );
468
469
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
470
                throw new OutOfBoundsException("Unsupported database type '{$this->databaseConfiguration['vendor']}'");
471
        }
472
    }
473
474
    /**
475
     * Transform collation name into a supported one
476
     * @param null|string $charset so far only 'utf8' is supported...
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
477
     * @return null|string
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
478
     * @throws OutOfBoundsException for unsupported database types
0 ignored issues
show
Coding Style introduced by
Tag @throws cannot be grouped with parameter tags in a doc comment
Loading history...
479
     * @todo what shall we accept as valid input, ie. 'generic' charset names ? maybe do 2 passes: known-db-charset => generic => specific for each db ?
0 ignored issues
show
Coding Style introduced by
Tag @todo cannot be grouped with parameter tags in a doc comment
Loading history...
Coding Style introduced by
Tag value for @todo tag indented incorrectly; expected 3 spaces but found 1
Loading history...
480
     *       see: https://www.iana.org/assignments/character-sets/character-sets.xhtml for IANA names
481
     */
482
    protected function getCollationName($charset)
483
    {
484
        if ($charset == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $charset of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
485
            return null;
486
        }
487
488
        $charset = trim(strtolower($charset));
489
490
        // accept official iana charset name, but most dbs prefer 'utf8'...
491
        if ($charset == 'utf-8') {
492
            $charset = 'utf8';
493
        }
494
495
        switch ($this->databaseConfiguration['vendor']) {
496
            case 'mariadb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
497
                break;
498
499
            case 'mysql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
500
                break;
501
502
            case 'mssql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
503
                if ($charset == 'utf8') {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
504
                    if (version_compare(
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
505
                        str_replace(array('.ga', '.cu'), array('.0', '.'), $this->databaseConfiguration['version']),
506
                        '2019',
507
                        '>=')
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 20 spaces, but found 24.
Loading history...
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
508
                    ) {
509
                        /// @todo allow to set this via configuration
510
                        // default collation for sql server on Linux is SQL_Latin1_General_CP1_CI_AS; we use the UTF8 variant
511
                        $charset = 'Latin1_General_100_CI_AI_SC_UTF8';
512
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
513
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
514
                break;
515
516
            //case 'oracle':
517
            //    break;
518
519
            case 'postgresql':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
520
                break;
521
522
            case 'sqlite':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
523
                break;
524
525
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
526
                throw new OutOfBoundsException("Unsupported database type '{$this->databaseConfiguration['vendor']}'");
527
        }
528
529
        return $charset;
530
    }
531
}
532