Passed
Push — develop ( c2019a...2cab77 )
by Felipe
04:50
created

SchemaTrait::getSearchPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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