Test Failed
Push — develop ( b901bb...90b3ce )
by Felipe
04:12
created

SchemaTrait::getSchemas()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 33
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 4
nop 0
dl 0
loc 33
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-RC8
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 \PHPPgAdmin\ADORecordSet All schemas, sorted alphabetically
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 ($status == 0) {
72
            $this->_schema = $schema;
73
74
            return 0;
75
        }
76
77
        return $status;
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 0 if operation was successful
103
     */
104
    public function setSearchPath($paths)
105
    {
106
        if (!is_array($paths)) {
107
            return -1;
108
        }
109
110
        if (sizeof($paths) == 0) {
111
            return -2;
112
        }
113
        if (sizeof($paths) == 1 && $paths[0] == '') {
114
            // Need to handle empty paths in some cases
115
            $paths[0] = 'pg_catalog';
116
        }
117
118
        // Loop over all the paths to check that none are empty
119
        $temp = [];
120
        foreach ($paths as $schema) {
121
            if ($schema != '') {
122
                $temp[] = $schema;
123
            }
124
        }
125
        $this->fieldArrayClean($temp);
126
127
        $sql = 'SET SEARCH_PATH TO "'.implode('","', $temp).'"';
128
129
        return $this->execute($sql);
130
    }
131
132
    /**
133
     * Creates a new schema.
134
     *
135
     * @param string $schemaname    The name of the schema to create
136
     * @param string $authorization (optional) The username to create the schema for
137
     * @param string $comment       (optional) If omitted, defaults to nothing
138
     *
139
     * @return bool|int 0 success
140
     */
141
    public function createSchema($schemaname, $authorization = '', $comment = '')
142
    {
143
        $this->fieldClean($schemaname);
144
        $this->fieldClean($authorization);
145
146
        $sql = "CREATE SCHEMA \"{$schemaname}\"";
147
        if ($authorization != '') {
148
            $sql .= " AUTHORIZATION \"{$authorization}\"";
149
        }
150
151
        if ($comment != '') {
152
            $status = $this->beginTransaction();
153
            if ($status != 0) {
154
                return -1;
155
            }
156
        }
157
158
        // Create the new schema
159
        $status = $this->execute($sql);
160
        if ($status != 0) {
161
            $this->rollbackTransaction();
162
163
            return -1;
164
        }
165
166
        // Set the comment
167
        if ($comment != '') {
168
            $status = $this->setComment('SCHEMA', $schemaname, '', $comment);
169
            if ($status != 0) {
170
                $this->rollbackTransaction();
171
172
                return -1;
173
            }
174
175
            return $this->endTransaction();
176
        }
177
178
        return 0;
179
    }
180
181
    /**
182
     * Updates a schema.
183
     *
184
     * @param string $schemaname The name of the schema to drop
185
     * @param string $comment    The new comment for this schema
186
     * @param string $name       new name for this schema
187
     * @param string $owner      The new owner for this schema
188
     *
189
     * @return bool|int 0 success
190
     */
191
    public function updateSchema($schemaname, $comment, $name, $owner)
192
    {
193
        $this->fieldClean($schemaname);
194
        $this->fieldClean($name);
195
        $this->fieldClean($owner);
196
197
        $status = $this->beginTransaction();
198
        if ($status != 0) {
199
            $this->rollbackTransaction();
200
201
            return -1;
202
        }
203
204
        $status = $this->setComment('SCHEMA', $schemaname, '', $comment);
205
        if ($status != 0) {
206
            $this->rollbackTransaction();
207
208
            return -1;
209
        }
210
211
        $schema_rs = $this->getSchemaByName($schemaname);
212
        /* Only if the owner change */
213
        if ($schema_rs->fields['ownername'] != $owner) {
214
            $sql    = "ALTER SCHEMA \"{$schemaname}\" OWNER TO \"{$owner}\"";
215
            $status = $this->execute($sql);
216
            if ($status != 0) {
217
                $this->rollbackTransaction();
218
219
                return -1;
220
            }
221
        }
222
223
        // Only if the name has changed
224
        if ($name != $schemaname) {
225
            $sql    = "ALTER SCHEMA \"{$schemaname}\" RENAME TO \"{$name}\"";
226
            $status = $this->execute($sql);
227
            if ($status != 0) {
228
                $this->rollbackTransaction();
229
230
                return -1;
231
            }
232
        }
233
234
        return $this->endTransaction();
235
    }
236
237
    /**
238
     * Return all information relating to a schema.
239
     *
240
     * @param string $schema The name of the schema
241
     *
242
     * @return \PHPPgAdmin\ADORecordSet Schema information
243
     */
244
    public function getSchemaByName($schema)
245
    {
246
        $this->clean($schema);
247
        $sql = "
248
            SELECT nspname, nspowner, r.rolname AS ownername, nspacl,
249
                pg_catalog.obj_description(pn.oid, 'pg_namespace') as nspcomment
250
            FROM pg_catalog.pg_namespace pn
251
                LEFT JOIN pg_roles as r ON pn.nspowner = r.oid
252
            WHERE nspname='{$schema}'";
253
254
        return $this->selectSet($sql);
255
    }
256
257
    // Table functions
258
259
    /**
260
     * Drops a schema.
261
     *
262
     * @param string $schemaname The name of the schema to drop
263
     * @param bool   $cascade    True to cascade drop, false to restrict
264
     *
265
     * @return int 0 if operation was successful
266
     */
267
    public function dropSchema($schemaname, $cascade)
268
    {
269
        $this->fieldClean($schemaname);
270
271
        $sql = "DROP SCHEMA \"{$schemaname}\"";
272
        if ($cascade) {
273
            $sql .= ' CASCADE';
274
        }
275
276
        return $this->execute($sql);
277
    }
278
279
    abstract public function fieldClean(&$str);
280
281
    abstract public function beginTransaction();
282
283
    abstract public function rollbackTransaction();
284
285
    abstract public function endTransaction();
286
287
    abstract public function execute($sql);
288
289
    abstract public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null);
290
291
    abstract public function selectSet($sql);
292
293
    abstract public function clean(&$str);
294
295
    abstract public function phpBool($parameter);
296
297
    abstract public function hasCreateTableLikeWithConstraints();
298
299
    abstract public function hasCreateTableLikeWithIndexes();
300
301
    abstract public function hasTablespaces();
302
303
    abstract public function delete($table, $conditions, $schema = '');
304
305
    abstract public function fieldArrayClean(&$arr);
306
307
    abstract public function hasCreateFieldWithConstraints();
308
309
    abstract public function getAttributeNames($table, $atts);
310
311
    abstract public function selectField($sql, $field);
312
313
    abstract public function phpArray($dbarr);
314
}
315