SchemaTrait::updateSchema()   B
last analyzed

Complexity

Conditions 7
Paths 9

Size

Total Lines 48
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 25
c 0
b 0
f 0
nc 9
nop 4
dl 0
loc 48
rs 8.5866
1
<?php
2
3
/**
4
 * PHPPgAdmin 6.1.3
5
 */
6
7
namespace PHPPgAdmin\Database\Traits;
8
9
/**
10
 * Common trait for tables manipulation.
11
 */
12
trait SchemaTrait
13
{
14
    // Schema functons
15
16
    /**
17
     * Return all schemas in the current database.
18
     *
19
     * @return int|\PHPPgAdmin\ADORecordSet
20
     */
21
    public function getSchemas()
22
    {
23
        $conf = $this->conf;
24
25
        if (!$conf['show_system']) {
26
            $where = "WHERE nspname NOT LIKE 'pg@_%' ESCAPE '@' AND nspname != 'information_schema'";
27
        } else {
28
            $where = "WHERE nspname !~ '^pg_t(emp_[0-9]+|oast)$'";
29
        }
30
31
        $sql = "
32
            SELECT pn.nspname,
33
                   pu.rolname AS nspowner,
34
                   pg_catalog.obj_description(pn.oid, 'pg_namespace') AS nspcomment, ";
35
36
        /*
37
         * Either display_sizes is true for tables and schemas,
38
         * or we must check if said config is an associative array
39
         */
40
        if ($this->conf['display_sizes']['tables']) {
41
            $sql .= ' pg_size_pretty(SUM(pg_total_relation_size(pg_class.oid))) as schema_size ';
42
        } else {
43
            $sql .= " 'N/A' as schema_size ";
44
        }
45
46
        $sql .= " FROM pg_catalog.pg_namespace pn
47
            LEFT JOIN pg_catalog.pg_class  ON relnamespace = pn.oid
48
            LEFT JOIN pg_catalog.pg_roles pu ON (pn.nspowner = pu.oid)
49
            {$where}
50
            GROUP BY pn.nspname, pu.rolname, pg_catalog.obj_description(pn.oid, 'pg_namespace')
51
            ORDER BY nspname";
52
53
        return $this->selectSet($sql);
54
    }
55
56
    /**
57
     * Sets the current working schema.  Will also set Class variable.
58
     *
59
     * @param string $schema The the name of the schema to work in
60
     *
61
     * @return int 0 if operation was successful
62
     */
63
    public function setSchema($schema)
64
    {
65
        // Get the current schema search path, including 'pg_catalog'.
66
        $search_path = $this->getSearchPath();
67
        // Prepend $schema to search path
68
        \array_unshift($search_path, $schema);
69
        $status = $this->setSearchPath($search_path);
70
71
        if (0 === $status) {
72
            $this->_schema = $schema;
73
74
            return 0;
75
        }
76
77
        return $status;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $status also could return the type PHPPgAdmin\ADORecordSet which is incompatible with the documented return type integer.
Loading history...
78
    }
79
80
    /**
81
     * Return the current schema search path.
82
     *
83
     * @return array array of schema names
84
     */
85
    public function getSearchPath()
86
    {
87
        $sql = 'SELECT current_schemas(false) AS search_path';
88
89
        $fetchMode = $this->conn->fetchMode;
90
        $this->conn->setFetchMode(\ADODB_FETCH_ASSOC);
91
        $search_path = $this->selectField($sql, 'search_path');
92
        $this->conn->setFetchMode($fetchMode);
93
94
        return $this->phpArray($search_path);
95
    }
96
97
    /**
98
     * Sets the current schema search path.
99
     *
100
     * @param mixed $paths An array of schemas in required search order
101
     *
102
     * @return int|\PHPPgAdmin\ADORecordSet
103
     */
104
    public function setSearchPath($paths)
105
    {
106
        if (!\is_array($paths)) {
107
            return -1;
108
        }
109
110
        if (0 === \count($paths)) {
111
            return -2;
112
        }
113
114
        if (1 === \count($paths) && '' === $paths[0]) {
115
            // Need to handle empty paths in some cases
116
            $paths[0] = 'pg_catalog';
117
        }
118
119
        // Loop over all the paths to check that none are empty
120
        $temp = [];
121
122
        foreach ($paths as $schema) {
123
            if ('' !== $schema) {
124
                $temp[] = $schema;
125
            }
126
        }
127
        $this->fieldArrayClean($temp);
128
129
        $sql = 'SET SEARCH_PATH TO "' . \implode('","', $temp) . '"';
130
131
        return $this->execute($sql);
132
    }
133
134
    /**
135
     * Creates a new schema.
136
     *
137
     * @param string $schemaname    The name of the schema to create
138
     * @param string $authorization (optional) The username to create the schema for
139
     * @param string $comment       (optional) If omitted, defaults to nothing
140
     *
141
     * @return bool|int 0 success
142
     */
143
    public function createSchema($schemaname, $authorization = '', $comment = '')
144
    {
145
        $this->fieldClean($schemaname);
146
        $this->fieldClean($authorization);
147
148
        $sql = "CREATE SCHEMA \"{$schemaname}\"";
149
150
        if ('' !== $authorization) {
151
            $sql .= " AUTHORIZATION \"{$authorization}\"";
152
        }
153
154
        if ('' !== $comment) {
155
            $status = $this->beginTransaction();
156
157
            if (0 !== $status) {
158
                return -1;
159
            }
160
        }
161
162
        // Create the new schema
163
        $status = $this->execute($sql);
164
165
        if (0 !== $status) {
166
            $this->rollbackTransaction();
167
168
            return -1;
169
        }
170
171
        // Set the comment
172
        if ('' !== $comment) {
173
            $status = $this->setComment('SCHEMA', $schemaname, '', $comment);
174
175
            if (0 !== $status) {
176
                $this->rollbackTransaction();
177
178
                return -1;
179
            }
180
181
            return $this->endTransaction();
182
        }
183
184
        return 0;
185
    }
186
187
    /**
188
     * Updates a schema.
189
     *
190
     * @param string $schemaname The name of the schema to drop
191
     * @param string $comment    The new comment for this schema
192
     * @param string $name       new name for this schema
193
     * @param string $owner      The new owner for this schema
194
     *
195
     * @return bool|int 0 success
196
     */
197
    public function updateSchema($schemaname, $comment, $name, $owner)
198
    {
199
        $this->fieldClean($schemaname);
200
        $this->fieldClean($name);
201
        $this->fieldClean($owner);
202
203
        $status = $this->beginTransaction();
204
205
        if (0 !== $status) {
206
            $this->rollbackTransaction();
207
208
            return -1;
209
        }
210
211
        $status = $this->setComment('SCHEMA', $schemaname, '', $comment);
212
213
        if (0 !== $status) {
214
            $this->rollbackTransaction();
215
216
            return -1;
217
        }
218
219
        $schema_rs = $this->getSchemaByName($schemaname);
220
        /* Only if the owner change */
221
        if ($schema_rs->fields['ownername'] !== $owner) {
222
            $sql = "ALTER SCHEMA \"{$schemaname}\" OWNER TO \"{$owner}\"";
223
            $status = $this->execute($sql);
224
225
            if (0 !== $status) {
226
                $this->rollbackTransaction();
227
228
                return -1;
229
            }
230
        }
231
232
        // Only if the name has changed
233
        if ($name !== $schemaname) {
234
            $sql = "ALTER SCHEMA \"{$schemaname}\" RENAME TO \"{$name}\"";
235
            $status = $this->execute($sql);
236
237
            if (0 !== $status) {
238
                $this->rollbackTransaction();
239
240
                return -1;
241
            }
242
        }
243
244
        return $this->endTransaction();
245
    }
246
247
    /**
248
     * Return all information relating to a schema.
249
     *
250
     * @param string $schema The name of the schema
251
     *
252
     * @return int|\PHPPgAdmin\ADORecordSet
253
     */
254
    public function getSchemaByName($schema)
255
    {
256
        $this->clean($schema);
257
        $sql = "
258
            SELECT nspname, nspowner, r.rolname AS ownername, nspacl,
259
                pg_catalog.obj_description(pn.oid, 'pg_namespace') as nspcomment
260
            FROM pg_catalog.pg_namespace pn
261
                LEFT JOIN pg_roles as r ON pn.nspowner = r.oid
262
            WHERE nspname='{$schema}'";
263
264
        return $this->selectSet($sql);
265
    }
266
267
    // Table functions
268
269
    /**
270
     * Drops a schema.
271
     *
272
     * @param string $schemaname The name of the schema to drop
273
     * @param bool   $cascade    True to cascade drop, false to restrict
274
     *
275
     * @return int|\PHPPgAdmin\ADORecordSet
276
     */
277
    public function dropSchema($schemaname, $cascade)
278
    {
279
        $this->fieldClean($schemaname);
280
281
        $sql = "DROP SCHEMA \"{$schemaname}\"";
282
283
        if ($cascade) {
284
            $sql .= ' CASCADE';
285
        }
286
287
        return $this->execute($sql);
288
    }
289
290
    abstract public function fieldClean(&$str);
291
292
    abstract public function beginTransaction();
293
294
    abstract public function rollbackTransaction();
295
296
    abstract public function endTransaction();
297
298
    abstract public function execute($sql);
299
300
    abstract public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null);
301
302
    abstract public function selectSet($sql);
303
304
    abstract public function clean(&$str);
305
306
    abstract public function phpBool($parameter);
307
308
    abstract public function hasCreateTableLikeWithConstraints();
309
310
    abstract public function hasCreateTableLikeWithIndexes();
311
312
    abstract public function hasTablespaces();
313
314
    abstract public function delete($table, $conditions, $schema = '');
315
316
    abstract public function fieldArrayClean(&$arr);
317
318
    abstract public function hasCreateFieldWithConstraints();
319
320
    abstract public function getAttributeNames($table, $atts);
321
322
    abstract public function selectField($sql, $field);
323
324
    abstract public function phpArray($dbarr);
325
}
326