Passed
Push — main ( b2ddc1...a529c9 )
by Thierry
01:51
created

Database::tables()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
namespace Lagdo\DbAdmin\Driver\PgSql\Db;
4
5
use Lagdo\DbAdmin\Driver\Entity\TableEntity;
6
use Lagdo\DbAdmin\Driver\Entity\RoutineEntity;
7
8
use Lagdo\DbAdmin\Driver\Db\Database as AbstractDatabase;
9
10
class Database extends AbstractDatabase
11
{
12
    use DatabaseTrait;
0 ignored issues
show
introduced by
The trait Lagdo\DbAdmin\Driver\PgSql\Db\DatabaseTrait requires some properties which are not provided by Lagdo\DbAdmin\Driver\PgSql\Db\Database: $name, $dropped, $fields, $comment, $edited, $engine
Loading history...
13
14
    /**
15
     * @inheritDoc
16
     */
17
    public function createTable(TableEntity $tableAttrs)
18
    {
19
        $queries = $this->getQueries($tableAttrs);
20
        $columns = $this->getNewColumns($tableAttrs);
21
        $columns = array_merge($columns, $tableAttrs->foreign);
22
        array_unshift($queries, 'CREATE TABLE ' . $this->driver->table($tableAttrs->name) .
23
            '(' . implode(', ', $columns) . ')');
24
        foreach ($queries as $query) {
25
            $this->driver->execute($query);
26
        }
27
        return true;
28
    }
29
30
    /**
31
     * @inheritDoc
32
     */
33
    public function alterTable(string $table, TableEntity $tableAttrs)
34
    {
35
        $queries = $this->getQueries($tableAttrs);
36
        $columns = $this->getColumnChanges($tableAttrs);
37
        if ($tableAttrs->name !== '' && $table !== $tableAttrs->name) {
38
            array_unshift($queries, 'ALTER TABLE ' . $this->driver->table($table) .
39
                ' RENAME TO ' . $this->driver->table($tableAttrs->name));
40
        }
41
        $columns = array_merge($columns, $tableAttrs->foreign);
42
        if (!empty($columns)) {
43
            array_unshift($queries, 'ALTER TABLE ' . $this->driver->table($table) . ' ' . implode(', ', $columns));
44
        }
45
        // if ($tableAttrs->autoIncrement != '') {
46
        //     //! $queries[] = 'SELECT setval(pg_get_serial_sequence(' . $this->driver->quote($tableAttrs->name) . ', ), $tableAttrs->autoIncrement)';
47
        // }
48
        foreach ($queries as $query) {
49
            $this->driver->execute($query);
50
        }
51
        return true;
52
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57
    public function alterIndexes(string $table, array $alter, array $drop)
58
    {
59
        $queries = [];
60
        $columns = [];
61
        foreach (array_reverse($drop) as $index) {
62
            if ($index->type === 'INDEX') {
63
                $queries[] = 'DROP INDEX ' . $this->driver->escapeId($index);
64
            } else {
65
                $columns[] = 'DROP CONSTRAINT ' . $this->driver->escapeId($index->name);
66
            }
67
        }
68
        foreach ($alter as $index) {
69
            if ($index->type === 'INDEX') {
70
                $queries[] = 'CREATE INDEX ' .
71
                    $this->driver->escapeId($index->name != '' ? $index->name : uniqid($table . '_')) .
72
                    ' ON ' . $this->driver->table($table) . ' (' . implode(', ', $index->columns) . ')';
73
            } else {
74
                //! descending UNIQUE indexes results in syntax error
75
                $constraint = ($index->name != '' ? ' CONSTRAINT ' . $this->driver->escapeId($index->name) : '');
76
                $columns[] = "ADD$constraint " . ($index->type == 'PRIMARY' ? 'PRIMARY KEY' : $index->type) .
77
                    ' (' . implode(', ', $index->columns) . ')';
78
            }
79
        }
80
        if (!empty($columns)) {
81
            array_unshift($queries, 'ALTER TABLE ' . $this->driver->table($table) . implode(', ', $columns));
82
        }
83
        foreach ($queries as $query) {
84
            $this->driver->execute($query);
85
        }
86
        return true;
87
    }
88
89
    /**
90
     * @inheritDoc
91
     */
92
    public function tables()
93
    {
94
        $query = 'SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = current_schema()';
95
        if ($this->driver->support('materializedview')) {
96
            $query .= " UNION ALL SELECT matviewname, 'MATERIALIZED VIEW' FROM pg_matviews WHERE schemaname = current_schema()";
97
        }
98
        $query .= ' ORDER BY 1';
99
        return $this->driver->keyValues($query);
100
    }
101
102
    /**
103
     * @inheritDoc
104
     */
105
    public function sequences()
106
    {
107
        // From db.inc.php
108
        $query = 'SELECT sequence_name FROM information_schema.sequences ' .
109
            'WHERE sequence_schema = selectedSchema() ORDER BY sequence_name';
110
        return $this->driver->values($query);
111
    }
112
113
    /**
114
     * @inheritDoc
115
     */
116
    public function countTables(array $databases)
117
    {
118
        $connection = $this->driver->createConnection(); // New connection
119
        $counts = [];
120
        $systemSchemas = ['information_schema', 'pg_catalog', 'pg_temp_1', 'pg_toast', 'pg_toast_temp_1'];
121
        $query = "SELECT count(*) FROM information_schema.tables WHERE table_schema NOT IN ('" .
122
            implode("','", $systemSchemas) . "')";
123
        foreach ($databases as $database) {
124
            $counts[$database] = 0;
125
            if (!$connection->open($database)) {
126
                continue;
127
            }
128
            $statement = $connection->query($query);
129
            if (is_object($statement) && ($row = $statement->fetchRow())) {
130
                $counts[$database] = intval($row[0]);
131
            }
132
        }
133
        return $counts;
134
    }
135
136
    /**
137
     * @inheritDoc
138
     */
139
    public function dropViews(array $views)
140
    {
141
        return $this->dropTables($views);
142
    }
143
144
    /**
145
     * @inheritDoc
146
     */
147
    public function dropTables(array $tables)
148
    {
149
        foreach ($tables as $table) {
150
            $status = $this->driver->tableStatus($table);
151
            if (!$this->driver->execute('DROP ' . strtoupper($status->engine) . ' ' . $this->driver->table($table))) {
152
                return false;
153
            }
154
        }
155
        return true;
156
    }
157
158
    /**
159
     * @inheritDoc
160
     */
161
    public function schemas()
162
    {
163
        return $this->driver->values('SELECT nspname FROM pg_namespace ORDER BY nspname');
164
    }
165
166
    /**
167
     * @inheritDoc
168
     */
169
    public function routine(string $name, string $type)
170
    {
171
        $query = 'SELECT routine_definition AS definition, LOWER(external_language) AS language, * ' .
172
            'FROM information_schema.routines WHERE routine_schema = current_schema() ' .
173
            'AND specific_name = ' . $this->driver->quote($name);
0 ignored issues
show
Bug introduced by
The method quote() does not exist on Lagdo\DbAdmin\Driver\DriverInterface. Did you maybe mean quoteBinary()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

173
            'AND specific_name = ' . $this->driver->/** @scrutinizer ignore-call */ quote($name);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
174
        $rows = $this->driver->rows($query);
175
        $routines = $rows[0];
176
        $routines['returns'] = ['type' => $routines['type_udt_name']];
177
        $query = 'SELECT parameter_name AS field, data_type AS type, character_maximum_length AS length, ' .
178
            'parameter_mode AS inout FROM information_schema.parameters WHERE specific_schema = current_schema() ' .
179
            'AND specific_name = ' . $this->driver->quote($name) . ' ORDER BY ordinal_position';
180
        $routines['fields'] = $this->driver->rows($query);
181
        return $routines;
182
    }
183
184
    /**
185
     * @inheritDoc
186
     */
187
    public function routines()
188
    {
189
        $query = 'SELECT specific_name AS "SPECIFIC_NAME", routine_type AS "ROUTINE_TYPE", ' .
190
            'routine_name AS "ROUTINE_NAME", type_udt_name AS "DTD_IDENTIFIER" ' .
191
            'FROM information_schema.routines WHERE routine_schema = current_schema() ORDER BY SPECIFIC_NAME';
192
        $rows = $this->driver->rows($query);
193
        return array_map(function($row) {
194
            return new RoutineEntity($row['ROUTINE_NAME'], $row['SPECIFIC_NAME'], $row['ROUTINE_TYPE'], $row['DTD_IDENTIFIER']);
195
        }, $rows);
196
    }
197
198
    /**
199
     * @inheritDoc
200
     */
201
    public function routineId(string $name, array $row)
202
    {
203
        $routine = [];
204
        foreach ($row['fields'] as $field) {
205
            $routine[] = $field->type;
206
        }
207
        return $this->driver->escapeId($name) . '(' . implode(', ', $routine) . ')';
208
    }
209
}
210