Passed
Branch main (a6702e)
by Thierry
04:09 queued 02:04
created

Database::alterTable()   F

Complexity

Conditions 26
Paths 8784

Size

Total Lines 57
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 26
eloc 39
c 1
b 0
f 0
nc 8784
nop 9
dl 0
loc 57
rs 0

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Lagdo\DbAdmin\Driver\PgSql\Db;
4
5
use Lagdo\DbAdmin\Driver\Entity\TableFieldEntity;
6
use Lagdo\DbAdmin\Driver\Entity\TableEntity;
7
use Lagdo\DbAdmin\Driver\Entity\IndexEntity;
8
use Lagdo\DbAdmin\Driver\Entity\ForeignKeyEntity;
9
use Lagdo\DbAdmin\Driver\Entity\TriggerEntity;
10
11
use Lagdo\DbAdmin\Driver\Db\ConnectionInterface;
12
13
use Lagdo\DbAdmin\Driver\Db\Database as AbstractDatabase;
14
15
class Database extends AbstractDatabase
16
{
17
    /**
18
     * @inheritDoc
19
     */
20
    public function alterTable(string $table, string $name, array $fields, array $foreign,
21
        string $comment, string $engine, string $collation, int $autoIncrement, string $partitioning)
22
    {
23
        $alter = [];
24
        $queries = [];
25
        if ($table != "" && $table != $name) {
26
            $queries[] = "ALTER TABLE " . $this->driver->table($table) . " RENAME TO " . $this->driver->table($name);
27
        }
28
        foreach ($fields as $field) {
29
            $column = $this->driver->escapeId($field[0]);
30
            $val = $field[1];
31
            if (!$val) {
32
                $alter[] = "DROP $column";
33
            } else {
34
                $val5 = $val[5];
35
                unset($val[5]);
36
                if ($field[0] == "") {
37
                    if (isset($val[6])) { // auto increment
38
                        $val[1] = ($val[1] == " bigint" ? " big" : ($val[1] == " smallint" ? " small" : " ")) . "serial";
39
                    }
40
                    $alter[] = ($table != "" ? "ADD " : "  ") . implode($val);
41
                    if (isset($val[6])) {
42
                        $alter[] = ($table != "" ? "ADD" : " ") . " PRIMARY KEY ($val[0])";
43
                    }
44
                } else {
45
                    if ($column != $val[0]) {
46
                        $queries[] = "ALTER TABLE " . $this->driver->table($name) . " RENAME $column TO $val[0]";
47
                    }
48
                    $alter[] = "ALTER $column TYPE$val[1]";
49
                    if (!$val[6]) {
50
                        $alter[] = "ALTER $column " . ($val[3] ? "SET$val[3]" : "DROP DEFAULT");
51
                        $alter[] = "ALTER $column " . ($val[2] == " NULL" ? "DROP NOT" : "SET") . $val[2];
52
                    }
53
                }
54
                if ($field[0] != "" || $val5 != "") {
55
                    $queries[] = "COMMENT ON COLUMN " . $this->driver->table($name) . ".$val[0] IS " . ($val5 != "" ? substr($val5, 9) : "''");
56
                }
57
            }
58
        }
59
        $alter = array_merge($alter, $foreign);
60
        if ($table == "") {
61
            array_unshift($queries, "CREATE TABLE " . $this->driver->table($name) . " (\n" . implode(",\n", $alter) . "\n)");
62
        } elseif (!empty($alter)) {
63
            array_unshift($queries, "ALTER TABLE " . $this->driver->table($table) . "\n" . implode(",\n", $alter));
64
        }
65
        if ($table != "" || $comment != "") {
66
            $queries[] = "COMMENT ON TABLE " . $this->driver->table($name) . " IS " . $this->driver->quote($comment);
67
        }
68
        if ($autoIncrement != "") {
69
            //! $queries[] = "SELECT setval(pg_get_serial_sequence(" . $this->driver->quote($name) . ", ), $autoIncrement)";
70
        }
71
        foreach ($queries as $query) {
72
            if (!$this->driver->execute($query)) {
73
                return false;
74
            }
75
        }
76
        return true;
77
    }
78
79
    /**
80
     * @inheritDoc
81
     */
82
    public function alterIndexes(string $table, array $alter)
83
    {
84
        $create = [];
85
        $drop = [];
86
        $queries = [];
87
        foreach ($alter as $val) {
88
            if ($val[0] != "INDEX") {
89
                //! descending UNIQUE indexes results in syntax error
90
                $create[] = (
91
                    $val[2] == "DROP" ? "\nDROP CONSTRAINT " . $this->driver->escapeId($val[1]) :
92
                    "\nADD" . ($val[1] != "" ? " CONSTRAINT " . $this->driver->escapeId($val[1]) : "") .
93
                    " $val[0] " . ($val[0] == "PRIMARY" ? "KEY " : "") . "(" . implode(", ", $val[2]) . ")"
94
                );
95
            } elseif ($val[2] == "DROP") {
96
                $drop[] = $this->driver->escapeId($val[1]);
97
            } else {
98
                $queries[] = "CREATE INDEX " . $this->driver->escapeId($val[1] != "" ? $val[1] : uniqid($table . "_")) .
99
                    " ON " . $this->driver->table($table) . " (" . implode(", ", $val[2]) . ")";
100
            }
101
        }
102
        if ($create) {
103
            array_unshift($queries, "ALTER TABLE " . $this->driver->table($table) . implode(",", $create));
104
        }
105
        if ($drop) {
106
            array_unshift($queries, "DROP INDEX " . implode(", ", $drop));
107
        }
108
        foreach ($queries as $query) {
109
            if (!$this->driver->execute($query)) {
110
                return false;
111
            }
112
        }
113
        return true;
114
    }
115
116
    /**
117
     * @inheritDoc
118
     */
119
    public function tables()
120
    {
121
        $query = "SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = current_schema()";
122
        if ($this->driver->support('materializedview')) {
123
            $query .= " UNION ALL SELECT matviewname, 'MATERIALIZED VIEW' FROM pg_matviews WHERE schemaname = current_schema()";
124
        }
125
        $query .= " ORDER BY 1";
126
        return $this->driver->keyValues($query);
127
    }
128
129
    /**
130
     * @inheritDoc
131
     */
132
    public function sequences()
133
    {
134
        // From db.inc.php
135
        $query = 'SELECT sequence_name FROM information_schema.sequences ' .
136
            'WHERE sequence_schema = selectedSchema() ORDER BY sequence_name';
137
        return $this->driver->values($query);
138
    }
139
140
    /**
141
     * @inheritDoc
142
     */
143
    public function countTables(array $databases)
144
    {
145
        $connection = $this->driver->createConnection(); // New connection
146
        $counts = [];
147
        $systemSchemas = ['information_schema', 'pg_catalog', 'pg_temp_1', 'pg_toast', 'pg_toast_temp_1'];
148
        $query = "SELECT count(*) FROM information_schema.tables WHERE table_schema NOT IN ('" .
149
            implode("','", $systemSchemas) . "')";
150
        foreach ($databases as $database) {
151
            $counts[$database] = 0;
152
            if (!$connection->open($database)) {
153
                continue;
154
            }
155
            $statement = $connection->query($query);
156
            if (is_object($statement) && ($row = $statement->fetchRow())) {
157
                $counts[$database] = intval($row[0]);
158
            }
159
        }
160
        return $counts;
161
    }
162
163
    /**
164
     * @inheritDoc
165
     */
166
    public function dropViews(array $views)
167
    {
168
        return $this->dropTables($views);
169
    }
170
171
    /**
172
     * @inheritDoc
173
     */
174
    public function dropTables(array $tables)
175
    {
176
        foreach ($tables as $table) {
177
            $status = $this->driver->tableStatus($table);
178
            if (!$this->driver->execute("DROP " . strtoupper($status->engine) . " " . $this->driver->table($table))) {
179
                return false;
180
            }
181
        }
182
        return true;
183
    }
184
185
    /**
186
     * @inheritDoc
187
     */
188
    public function moveTables(array $tables, array $views, string $target)
189
    {
190
        foreach (array_merge($tables, $views) as $table) {
191
            $status = $this->driver->tableStatus($table);
192
            if (!$this->driver->execute("ALTER " . strtoupper($status->engine) . " " .
193
                $this->driver->table($table) . " SET SCHEMA " . $this->driver->escapeId($target))) {
194
                return false;
195
            }
196
        }
197
        return true;
198
    }
199
200
    /**
201
     * @inheritDoc
202
     */
203
    public function truncateTables(array $tables)
204
    {
205
        $this->driver->execute("TRUNCATE " . implode(", ", array_map(function ($table) {
206
            return $this->driver->table($table);
207
        }, $tables)));
208
        return true;
209
    }
210
211
    /**
212
     * @inheritDoc
213
     */
214
    public function userTypes()
215
    {
216
        $query = "SELECT typname FROM pg_type WHERE typnamespace = " .
217
            "(SELECT oid FROM pg_namespace WHERE nspname = current_schema()) " .
218
            "AND typtype IN ('b','d','e') AND typelem = 0";
219
        return $this->driver->values($query);
220
    }
221
222
    /**
223
     * @inheritDoc
224
     */
225
    public function schemas()
226
    {
227
        return $this->driver->values("SELECT nspname FROM pg_namespace ORDER BY nspname");
228
    }
229
230
    /**
231
     * @inheritDoc
232
     */
233
    public function routine(string $name, string $type)
234
    {
235
        $query = 'SELECT routine_definition AS definition, LOWER(external_language) AS language, * ' .
236
            'FROM information_schema.routines WHERE routine_schema = current_schema() ' .
237
            'AND specific_name = ' . $this->driver->quote($name);
238
        $rows = $this->driver->rows($query);
239
        $routines = $rows[0];
240
        $routines["returns"] = ["type" => $routines["type_udt_name"]];
241
        $query = 'SELECT parameter_name AS field, data_type AS type, character_maximum_length AS length, ' .
242
            'parameter_mode AS inout FROM information_schema.parameters WHERE specific_schema = current_schema() ' .
243
            'AND specific_name = ' . $this->driver->quote($name) . ' ORDER BY ordinal_position';
244
        $routines["fields"] = $this->driver->rows($query);
245
        return $routines;
246
    }
247
248
    /**
249
     * @inheritDoc
250
     */
251
    public function routines()
252
    {
253
        $query = 'SELECT specific_name AS "SPECIFIC_NAME", routine_type AS "ROUTINE_TYPE", ' .
254
            'routine_name AS "ROUTINE_NAME", type_udt_name AS "DTD_IDENTIFIER" ' .
255
            'FROM information_schema.routines WHERE routine_schema = current_schema() ORDER BY SPECIFIC_NAME';
256
        $rows = $this->driver->rows($query);
257
        return array_map(function($row) {
258
            return new RoutineEntity($row['ROUTINE_NAME'], $row['SPECIFIC_NAME'], $row['ROUTINE_TYPE'], $row['DTD_IDENTIFIER']);
0 ignored issues
show
Bug introduced by
The type Lagdo\DbAdmin\Driver\PgSql\Db\RoutineEntity was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
259
        }, $rows);
260
    }
261
262
    /**
263
     * @inheritDoc
264
     */
265
    public function routineId(string $name, array $row)
266
    {
267
        $routine = [];
268
        foreach ($row["fields"] as $field) {
269
            $routine[] = $field->type;
270
        }
271
        return $this->driver->escapeId($name) . "(" . implode(", ", $routine) . ")";
272
    }
273
}
274