Passed
Push — master ( 2856b4...cf0423 )
by Felipe
10:02 queued 05:52
created

Postgres74::hasTablespaces()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.33
5
 */
6
7
namespace PHPPgAdmin\Database;
8
9
/**
10
 * @file
11
 * A class that implements the DB interface for Postgres
12
 * Note: This class uses ADODB and returns RecordSets.
13
 *
14
 * Id: Postgres74.php,v 1.72 2008/02/20 21:06:18 ioguix Exp $
15
 * @package PHPPgAdmin
16
 */
17
class Postgres74 extends Postgres80
18
{
19
    public $major_version = 7.4;
20
    // List of all legal privileges that can be applied to different types
21
    // of objects.
22
    public $privlist = [
23
        'table'    => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'RULE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'],
24
        'view'     => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'RULE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'],
25
        'sequence' => ['SELECT', 'UPDATE', 'ALL PRIVILEGES'],
26
        'database' => ['CREATE', 'TEMPORARY', 'ALL PRIVILEGES'],
27
        'function' => ['EXECUTE', 'ALL PRIVILEGES'],
28
        'language' => ['USAGE', 'ALL PRIVILEGES'],
29
        'schema'   => ['CREATE', 'USAGE', 'ALL PRIVILEGES'],
30
    ];
31
32
    // Database functions
33
34
    /**
35
     * Alters a database
36
     * the multiple return vals are for postgres 8+ which support more functionality in alter database.
37
     *
38
     * @param string $dbName   The name of the database
39
     * @param string $newName  new name for the database
40
     * @param string $newOwner The new owner for the database
41
     * @param string $comment
42
     *
43
     * @return bool|int 0 success
44
     */
45
    public function alterDatabase($dbName, $newName, $newOwner = '', $comment = '')
46
    {
47
        //ignore $newowner, not supported pre 8.0
48
        //ignore $comment, not supported pre 8.2
49
        $this->clean($dbName);
50
        $this->clean($newName);
51
52
        $status = $this->alterDatabaseRename($dbName, $newName);
53
        if ($status != 0) {
54
            return -3;
55
        }
56
57
        return 0;
58
    }
59
60
    /**
61
     * Return all database available on the server.
62
     *
63
     * @param null|string $currentdatabase
64
     *
65
     * @return \ADORecordSet A list of databases, sorted alphabetically
66
     */
67
    public function getDatabases($currentdatabase = null)
68
    {
69
        $conf        = $this->conf;
70
        $server_info = $this->server_info;
0 ignored issues
show
Bug Best Practice introduced by
The property server_info does not exist on PHPPgAdmin\Database\Postgres74. Did you maybe forget to declare it?
Loading history...
71
72
        if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser()) {
73
            $username = $server_info['username'];
74
            $this->clean($username);
75
            $clause = " AND pu.usename='{$username}'";
76
        } else {
77
            $clause = '';
78
        }
79
80
        if ($currentdatabase != null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $currentdatabase of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
81
            $this->clean($currentdatabase);
82
            $orderby = "ORDER BY pdb.datname = '{$currentdatabase}' DESC, pdb.datname";
83
        } else {
84
            $orderby = 'ORDER BY pdb.datname';
85
        }
86
87
        if (!$conf['show_system']) {
88
            $where = ' AND NOT pdb.datistemplate';
89
        } else {
90
            $where = ' AND pdb.datallowconn';
91
        }
92
93
        $sql = "SELECT pdb.datname AS datname,
94
                pu.usename AS datowner,
95
                pg_encoding_to_char(encoding) AS datencoding,
96
                (SELECT description FROM pg_description pd WHERE pdb.oid=pd.objoid) AS datcomment
97
                FROM pg_database pdb, pg_user pu
98
    			WHERE pdb.datdba = pu.usesysid
99
    			{$where}
100
    			{$clause}
101
    			{$orderby}";
102
103
        return $this->selectSet($sql);
104
    }
105
106
    /**
107
     * Searches all system catalogs to find objects that match a certain name.
108
     *
109
     * @param $term   The search term
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\Database\The 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...
110
     * @param $filter The object type to restrict to ('' means no restriction)
111
     *
112
     * @return \ADORecordSet A recordset
113
     */
114
    public function findObject($term, $filter)
115
    {
116
        $conf = $this->conf;
117
118
        /*about escaping:
119
         * SET standard_conforming_string is not available before 8.2
120
         * So we must use PostgreSQL specific notation :/
121
         * E'' notation is not available before 8.1
122
         * $$ is available since 8.0
123
         * Nothing specific from 7.4
124
         */
125
126
        // Escape search term for ILIKE match
127
        $term = str_replace('_', '\\_', $term);
128
        $term = str_replace('%', '\\%', $term);
129
        $this->clean($term);
130
        $this->clean($filter);
131
132
        // Exclude system relations if necessary
133
        if (!$conf['show_system']) {
134
            // XXX: The mention of information_schema here is in the wrong place, but
135
            // it's the quickest fix to exclude the info schema from 7.4
136
            $where     = " AND pn.nspname NOT LIKE 'pg\\\\_%' AND pn.nspname != 'information_schema'";
137
            $lan_where = 'AND pl.lanispl';
138
        } else {
139
            $where     = '';
140
            $lan_where = '';
141
        }
142
143
        // Apply outer filter
144
        $sql = '';
145
        if ($filter != '') {
146
            $sql = 'SELECT * FROM (';
147
        }
148
149
        $sql .= "
150
			SELECT 'SCHEMA' AS type, oid, NULL AS schemaname, NULL AS relname, nspname AS name
151
				FROM pg_catalog.pg_namespace pn WHERE nspname ILIKE '%{$term}%' {$where}
152
			UNION ALL
153
			SELECT CASE WHEN relkind='r' THEN 'TABLE' WHEN relkind='v' THEN 'VIEW' WHEN relkind='S' THEN 'SEQUENCE' END, pc.oid,
154
				pn.nspname, NULL, pc.relname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn
155
				WHERE pc.relnamespace=pn.oid AND relkind IN ('r', 'v', 'S') AND relname ILIKE '%{$term}%' {$where}
156
			UNION ALL
157
			SELECT CASE WHEN pc.relkind='r' THEN 'COLUMNTABLE' ELSE 'COLUMNVIEW' END, NULL, pn.nspname, pc.relname, pa.attname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn,
158
				pg_catalog.pg_attribute pa WHERE pc.relnamespace=pn.oid AND pc.oid=pa.attrelid
159
				AND pa.attname ILIKE '%{$term}%' AND pa.attnum > 0 AND NOT pa.attisdropped AND pc.relkind IN ('r', 'v') {$where}
160
			UNION ALL
161
			SELECT 'FUNCTION', pp.oid, pn.nspname, NULL, pp.proname || '(' || pg_catalog.oidvectortypes(pp.proargtypes) || ')' FROM pg_catalog.pg_proc pp, pg_catalog.pg_namespace pn
162
				WHERE pp.pronamespace=pn.oid AND NOT pp.proisagg AND pp.proname ILIKE '%{$term}%' {$where}
163
			UNION ALL
164
			SELECT 'INDEX', NULL, pn.nspname, pc.relname, pc2.relname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn,
165
				pg_catalog.pg_index pi, pg_catalog.pg_class pc2 WHERE pc.relnamespace=pn.oid AND pc.oid=pi.indrelid
166
				AND pi.indexrelid=pc2.oid
167
				AND NOT EXISTS (
168
					SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c
169
					ON (d.refclassid = c.tableoid AND d.refobjid = c.oid)
170
					WHERE d.classid = pc2.tableoid AND d.objid = pc2.oid AND d.deptype = 'i' AND c.contype IN ('u', 'p')
171
				)
172
				AND pc2.relname ILIKE '%{$term}%' {$where}
173
			UNION ALL
174
			SELECT 'CONSTRAINTTABLE', NULL, pn.nspname, pc.relname, pc2.conname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn,
175
				pg_catalog.pg_constraint pc2 WHERE pc.relnamespace=pn.oid AND pc.oid=pc2.conrelid AND pc2.conrelid != 0
176
				AND CASE WHEN pc2.contype IN ('f', 'c') THEN TRUE ELSE NOT EXISTS (
177
					SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c
178
					ON (d.refclassid = c.tableoid AND d.refobjid = c.oid)
179
					WHERE d.classid = pc2.tableoid AND d.objid = pc2.oid AND d.deptype = 'i' AND c.contype IN ('u', 'p')
180
				) END
181
				AND pc2.conname ILIKE '%{$term}%' {$where}
182
			UNION ALL
183
			SELECT 'CONSTRAINTDOMAIN', pt.oid, pn.nspname, pt.typname, pc.conname FROM pg_catalog.pg_type pt, pg_catalog.pg_namespace pn,
184
				pg_catalog.pg_constraint pc WHERE pt.typnamespace=pn.oid AND pt.oid=pc.contypid AND pc.contypid != 0
185
				AND pc.conname ILIKE '%{$term}%' {$where}
186
			UNION ALL
187
			SELECT 'TRIGGER', NULL, pn.nspname, pc.relname, pt.tgname FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pn,
188
				pg_catalog.pg_trigger pt WHERE pc.relnamespace=pn.oid AND pc.oid=pt.tgrelid
189
					AND ( pt.tgisconstraint = 'f' OR NOT EXISTS
190
					(SELECT 1 FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_constraint c
191
					ON (d.refclassid = c.tableoid AND d.refobjid = c.oid)
192
					WHERE d.classid = pt.tableoid AND d.objid = pt.oid AND d.deptype = 'i' AND c.contype = 'f'))
193
				AND pt.tgname ILIKE '%{$term}%' {$where}
194
			UNION ALL
195
			SELECT 'RULETABLE', NULL, pn.nspname AS schemaname, c.relname AS tablename, r.rulename FROM pg_catalog.pg_rewrite r
196
				JOIN pg_catalog.pg_class c ON c.oid = r.ev_class
197
				LEFT JOIN pg_catalog.pg_namespace pn ON pn.oid = c.relnamespace
198
				WHERE c.relkind='r' AND r.rulename != '_RETURN' AND r.rulename ILIKE '%{$term}%' {$where}
199
			UNION ALL
200
			SELECT 'RULEVIEW', NULL, pn.nspname AS schemaname, c.relname AS tablename, r.rulename FROM pg_catalog.pg_rewrite r
201
				JOIN pg_catalog.pg_class c ON c.oid = r.ev_class
202
				LEFT JOIN pg_catalog.pg_namespace pn ON pn.oid = c.relnamespace
203
				WHERE c.relkind='v' AND r.rulename != '_RETURN' AND r.rulename ILIKE '%{$term}%' {$where}
204
		";
205
206
        // Add advanced objects if show_advanced is set
207
        if ($conf['show_advanced']) {
208
            $sql .= "
209
				UNION ALL
210
				SELECT CASE WHEN pt.typtype='d' THEN 'DOMAIN' ELSE 'TYPE' END, pt.oid, pn.nspname, NULL,
211
					pt.typname FROM pg_catalog.pg_type pt, pg_catalog.pg_namespace pn
212
					WHERE pt.typnamespace=pn.oid AND typname ILIKE '%{$term}%'
213
					AND (pt.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = pt.typrelid))
214
					{$where}
215
				UNION ALL
216
				SELECT 'OPERATOR', po.oid, pn.nspname, NULL, po.oprname FROM pg_catalog.pg_operator po, pg_catalog.pg_namespace pn
217
					WHERE po.oprnamespace=pn.oid AND oprname ILIKE '%{$term}%' {$where}
218
				UNION ALL
219
				SELECT 'CONVERSION', pc.oid, pn.nspname, NULL, pc.conname FROM pg_catalog.pg_conversion pc,
220
					pg_catalog.pg_namespace pn WHERE pc.connamespace=pn.oid AND conname ILIKE '%{$term}%' {$where}
221
				UNION ALL
222
				SELECT 'LANGUAGE', pl.oid, NULL, NULL, pl.lanname FROM pg_catalog.pg_language pl
223
					WHERE lanname ILIKE '%{$term}%' {$lan_where}
224
				UNION ALL
225
				SELECT DISTINCT ON (p.proname) 'AGGREGATE', p.oid, pn.nspname, NULL, p.proname FROM pg_catalog.pg_proc p
226
					LEFT JOIN pg_catalog.pg_namespace pn ON p.pronamespace=pn.oid
227
					WHERE p.proisagg AND p.proname ILIKE '%{$term}%' {$where}
228
				UNION ALL
229
				SELECT DISTINCT ON (po.opcname) 'OPCLASS', po.oid, pn.nspname, NULL, po.opcname FROM pg_catalog.pg_opclass po,
230
					pg_catalog.pg_namespace pn WHERE po.opcnamespace=pn.oid
231
					AND po.opcname ILIKE '%{$term}%' {$where}
232
			";
233
        } // Otherwise just add domains
234
        else {
0 ignored issues
show
Coding Style introduced by
Expected "} else \n"; found " // Otherwise just add domains\n else {\n"
Loading history...
235
            $sql .= "
236
				UNION ALL
237
				SELECT 'DOMAIN', pt.oid, pn.nspname, NULL,
238
					pt.typname FROM pg_catalog.pg_type pt, pg_catalog.pg_namespace pn
239
					WHERE pt.typnamespace=pn.oid AND pt.typtype='d' AND typname ILIKE '%{$term}%'
240
					AND (pt.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = pt.typrelid))
241
					{$where}
242
			";
243
        }
244
245
        if ($filter != '') {
246
            // We use like to make RULE, CONSTRAINT and COLUMN searches work
247
            $sql .= ") AS sub WHERE type LIKE '{$filter}%' ";
248
        }
249
250
        $sql .= 'ORDER BY type, schemaname, relname, name';
251
252
        return $this->selectSet($sql);
253
    }
254
255
    /**
256
     * Returns table locks information in the current database.
257
     *
258
     * @return \ADORecordSet A recordset
259
     */
260
    public function getLocks()
261
    {
262
        $conf = $this->conf;
263
264
        if (!$conf['show_system']) {
265
            $where = "AND pn.nspname NOT LIKE 'pg\\\\_%'";
266
        } else {
267
            $where = "AND nspname !~ '^pg_t(emp_[0-9]+|oast)$'";
268
        }
269
270
        $sql = "SELECT pn.nspname, pc.relname AS tablename, pl.transaction, pl.pid, pl.mode, pl.granted
271
		FROM pg_catalog.pg_locks pl, pg_catalog.pg_class pc, pg_catalog.pg_namespace pn
272
		WHERE pl.relation = pc.oid AND pc.relnamespace=pn.oid {$where}
273
		ORDER BY nspname,tablename";
274
275
        return $this->selectSet($sql);
276
    }
277
278
    /**
279
     * Returns the current database encoding.
280
     *
281
     * @return The encoding.  eg. SQL_ASCII, UTF-8, etc.
282
     */
283
    public function getDatabaseEncoding()
284
    {
285
        $sql = 'SELECT getdatabaseencoding() AS encoding';
286
287
        return $this->selectField($sql, 'encoding');
288
    }
289
290
    // Table functions
291
292
    /**
293
     * Alters a column in a table OR view.
294
     *
295
     * @param $table      The table in which the column resides
296
     * @param $column     The column to alter
297
     * @param $name       The new name for the column
298
     * @param $notnull    (boolean) True if not null, false otherwise
299
     * @param $oldnotnull (boolean) True if column is already not null, false otherwise
300
     * @param $default    The new default for the column
301
     * @param $olddefault The old default for the column
302
     * @param $type       The new type for the column
303
     * @param $length     The optional size of the column (ie. 30 for varchar(30))
304
     * @param $array      True if array type, false otherwise
305
     * @param $oldtype    The old type for the column
306
     * @param $comment    Comment for the column
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\Database\Comment 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...
307
     *
308
     * @return array|bool|int 0 success
309
     */
310
    public function alterColumn(
311
        $table,
312
        $column,
313
        $name,
314
        $notnull,
315
        $oldnotnull,
316
        $default,
317
        $olddefault,
318
        $type,
319
        $length,
320
        $array,
321
        $oldtype,
322
        $comment
323
    ) {
324
        $status = $this->beginTransaction();
325
        if ($status != 0) {
326
            return -1;
327
        }
328
329
        // @@ NEED TO HANDLE "NESTED" TRANSACTION HERE
330
        if ($notnull != $oldnotnull) {
331
            $status = $this->setColumnNull($table, $column, !$notnull);
332
            if ($status != 0) {
333
                $this->rollbackTransaction();
334
335
                return -2;
336
            }
337
        }
338
339
        // Set default, if it has changed
340
        if ($default != $olddefault) {
341
            if ($default == '') {
342
                $status = $this->dropColumnDefault($table, $column);
343
            } else {
344
                $status = $this->setColumnDefault($table, $column, $default);
345
            }
346
347
            if ($status != 0) {
348
                $this->rollbackTransaction();
349
350
                return -3;
351
            }
352
        }
353
354
        // Rename the column, if it has been changed
355
        if ($column != $name) {
356
            $status = $this->renameColumn($table, $column, $name);
357
            if ($status != 0) {
358
                $this->rollbackTransaction();
359
360
                return -4;
361
            }
362
        }
363
364
        // The $name and $table parameters must be cleaned for the setComment function.
365
        // It's ok to do that here since this is the last time these variables are used.
366
        $this->fieldClean($name);
367
        $this->fieldClean($table);
368
        $status = $this->setComment('COLUMN', $name, $table, $comment);
369
        if ($status != 0) {
370
            $this->rollbackTransaction();
371
372
            return -5;
373
        }
374
375
        return $this->endTransaction();
376
    }
377
378
    /**
379
     * Returns table information.
380
     *
381
     * @param $table The name of the table
382
     *
383
     * @return \ADORecordSet A recordset
384
     */
385
    public function getTable($table)
386
    {
387
        $c_schema = $this->_schema;
388
        $this->clean($c_schema);
389
        $this->clean($table);
390
391
        $sql = "
392
			SELECT
393
			  c.relname, n.nspname, u.usename AS relowner,
394
			  pg_catalog.obj_description(c.oid, 'pg_class') AS relcomment
395
			FROM pg_catalog.pg_class c
396
			     LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner
397
			     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
398
			WHERE c.relkind = 'r'
399
				AND n.nspname = '{$c_schema}'
400
			    AND c.relname = '{$table}'";
401
402
        return $this->selectSet($sql);
403
    }
404
405
    /**
406
     * Returns the current default_with_oids setting.
407
     *
408
     * @return default_with_oids setting
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\Database\default_with_oids 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...
409
     */
410
    public function getDefaultWithOid()
411
    {
412
        // 8.0 is the first release to have this setting
413
        // Prior releases don't have this setting... oids always activated
414
        return 'on';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'on' returns the type string which is incompatible with the documented return type PHPPgAdmin\Database\default_with_oids.
Loading history...
415
    }
416
417
    /**
418
     * Returns a list of all constraints on a table,
419
     * including constraint name, definition, related col and referenced namespace,
420
     * table and col if needed.
421
     *
422
     * @param $table the table where we are looking for fk
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\Database\the 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...
423
     *
424
     * @return \ADORecordSet A recordset
425
     */
426
    public function getConstraintsWithFields($table)
427
    {
428
        $c_schema = $this->_schema;
429
        $this->clean($c_schema);
430
        $this->clean($table);
431
432
        // get the max number of col used in a constraint for the table
433
        $sql = "SELECT DISTINCT
434
			max(SUBSTRING(array_dims(c.conkey) FROM '^\\\\[.*:(.*)\\\\]$')) as nb
435
		FROM pg_catalog.pg_constraint AS c
436
			JOIN pg_catalog.pg_class AS r ON (c.conrelid=r.oid)
437
		    JOIN pg_catalog.pg_namespace AS ns ON (r.relnamespace=ns.oid)
438
		WHERE
439
			r.relname = '{$table}' AND ns.nspname='{$c_schema}'";
440
441
        $rs = $this->selectSet($sql);
442
443
        if ($rs->EOF) {
444
            $max_col = 0;
1 ignored issue
show
Unused Code introduced by
The assignment to $max_col is dead and can be removed.
Loading history...
445
        } else {
446
            $max_col = $rs->fields['nb'];
447
        }
448
449
        $sql = '
450
			SELECT
451
				c.oid AS conid, c.contype, c.conname, pg_catalog.pg_get_constraintdef(c.oid, true) AS consrc,
452
				ns1.nspname as p_schema, r1.relname as p_table, ns2.nspname as f_schema,
453
				r2.relname as f_table, f1.attname as p_field, f1.attnum AS p_attnum, f2.attname as f_field,
454
				f2.attnum AS f_attnum, pg_catalog.obj_description(c.oid, \'pg_constraint\') AS constcomment,
455
				c.conrelid, c.confrelid
456
			FROM
457
				pg_catalog.pg_constraint AS c
458
				JOIN pg_catalog.pg_class AS r1 ON (c.conrelid=r1.oid)
459
				JOIN pg_catalog.pg_attribute AS f1 ON (f1.attrelid=r1.oid AND (f1.attnum=c.conkey[1]';
460
        for ($i = 2; $i <= $rs->fields['nb']; ++$i) {
461
            $sql .= " OR f1.attnum=c.conkey[${i}]";
462
        }
463
        $sql .= '))
464
				JOIN pg_catalog.pg_namespace AS ns1 ON r1.relnamespace=ns1.oid
465
				LEFT JOIN (
466
					pg_catalog.pg_class AS r2 JOIN pg_catalog.pg_namespace AS ns2 ON (r2.relnamespace=ns2.oid)
467
				) ON (c.confrelid=r2.oid)
468
				LEFT JOIN pg_catalog.pg_attribute AS f2 ON
469
					(f2.attrelid=r2.oid AND ((c.confkey[1]=f2.attnum AND c.conkey[1]=f1.attnum)';
470
        for ($i = 2; $i <= $rs->fields['nb']; ++$i) {
471
            $sql .= " OR (c.confkey[${i}]=f2.attnum AND c.conkey[${i}]=f1.attnum)";
472
        }
473
474
        $sql .= sprintf("))
1 ignored issue
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
475
			WHERE
476
				r1.relname = '%s' AND ns1.nspname='%s'
477
			ORDER BY 1", $table, $c_schema);
1 ignored issue
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
478
479
        return $this->selectSet($sql);
480
    }
481
482
    // Constraint functions
483
484
    /**
485
     * Returns all sequences in the current database.
486
     *
487
     * @param bool $all
488
     *
489
     * @return \ADORecordSet A recordset
490
     */
491
    public function getSequences($all = false)
492
    {
493
        $c_schema = $this->_schema;
494
        $this->clean($c_schema);
495
        if ($all) {
496
            // Exclude pg_catalog and information_schema tables
497
            $sql = "SELECT n.nspname, c.relname AS seqname, u.usename AS seqowner
498
				FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n
499
				WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid
500
				AND c.relkind = 'S'
501
				AND n.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
502
				ORDER BY nspname, seqname";
503
        } else {
504
            $sql = "SELECT c.relname AS seqname, u.usename AS seqowner, pg_catalog.obj_description(c.oid, 'pg_class') AS seqcomment
505
				FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n
506
				WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid
507
				AND c.relkind = 'S' AND n.nspname='{$c_schema}' ORDER BY seqname";
508
        }
509
510
        return $this->selectSet($sql);
511
    }
512
513
    // Sequence functions
514
515
    /**
516
     * Returns all details for a particular function.
517
     *
518
     * @param $function_oid
519
     *
520
     * @return \ADORecordSet Function info
521
     *
522
     * @internal param string The $func name of the function to retrieve
523
     */
524
    public function getFunction($function_oid)
525
    {
526
        $this->clean($function_oid);
527
528
        $sql = "
529
		SELECT
530
			pc.oid AS prooid,
531
			proname,
532
			pg_catalog.pg_get_userbyid(proowner) AS proowner,
533
			nspname as proschema,
534
			lanname as prolanguage,
535
			pg_catalog.format_type(prorettype, NULL) as proresult,
536
			prosrc,
537
			probin,
538
			proretset,
539
			proisstrict,
540
			provolatile,
541
			prosecdef,
542
			pg_catalog.oidvectortypes(pc.proargtypes) AS proarguments,
543
			pg_catalog.obj_description(pc.oid, 'pg_proc') AS procomment
544
		FROM
545
			pg_catalog.pg_proc pc, pg_catalog.pg_language pl, pg_catalog.pg_namespace n
546
		WHERE
547
			pc.oid = '${function_oid}'::oid
548
			AND pc.prolang = pl.oid
549
			AND n.oid = pc.pronamespace
550
		";
551
552
        return $this->selectSet($sql);
553
    }
554
555
    // Function functions
556
557
    /**
558
     * Returns a list of all casts in the database.
559
     *
560
     * @return All casts
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\Database\All 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...
561
     */
562
    public function getCasts()
563
    {
564
        $conf = $this->conf;
565
566
        if ($conf['show_system']) {
567
            $where = '';
568
        } else {
569
            $where = "
570
				AND n1.nspname NOT LIKE 'pg\\\\_%'
571
				AND n2.nspname NOT LIKE 'pg\\\\_%'
572
				AND n3.nspname NOT LIKE 'pg\\\\_%'
573
			";
574
        }
575
576
        $sql = "
577
			SELECT
578
				c.castsource::pg_catalog.regtype AS castsource,
579
				c.casttarget::pg_catalog.regtype AS casttarget,
580
				CASE WHEN c.castfunc=0 THEN NULL
581
				ELSE c.castfunc::pg_catalog.regprocedure END AS castfunc,
582
				c.castcontext,
583
				obj_description(c.oid, 'pg_cast') as castcomment
584
			FROM
585
				(pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p ON c.castfunc=p.oid JOIN pg_catalog.pg_namespace n3 ON p.pronamespace=n3.oid),
586
				pg_catalog.pg_type t1,
587
				pg_catalog.pg_type t2,
588
				pg_catalog.pg_namespace n1,
589
				pg_catalog.pg_namespace n2
590
			WHERE
591
				c.castsource=t1.oid
592
				AND c.casttarget=t2.oid
593
				AND t1.typnamespace=n1.oid
594
				AND t2.typnamespace=n2.oid
595
				{$where}
596
			ORDER BY 1, 2
597
		";
598
599
        return $this->selectSet($sql);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->selectSet($sql) returns the type ADORecordSet which is incompatible with the documented return type PHPPgAdmin\Database\All.
Loading history...
600
    }
601
602
    public function hasAlterColumnType()
603
    {
604
        return false;
605
    }
606
607
    // Capabilities
608
609
    public function hasCreateFieldWithConstraints()
1 ignored issue
show
Coding Style introduced by
You must use "/**" style comments for a function comment
Loading history...
610
    {
611
        return false;
612
    }
613
614
    public function hasAlterDatabaseOwner()
615
    {
616
        return false;
617
    }
618
619
    public function hasAlterSchemaOwner()
620
    {
621
        return false;
622
    }
623
624
    public function hasFunctionAlterOwner()
625
    {
626
        return false;
627
    }
628
629
    public function hasNamedParams()
630
    {
631
        return false;
632
    }
633
634
    public function hasQueryCancel()
635
    {
636
        return false;
637
    }
638
639
    public function hasTablespaces()
640
    {
641
        return false;
642
    }
643
644
    public function hasMagicTypes()
645
    {
646
        return false;
647
    }
648
649
    /**
650
     * Protected method which alter a table
651
     * SHOULDN'T BE CALLED OUTSIDE OF A TRANSACTION.
652
     *
653
     * @param $tblrs      The table recordSet returned by getTable()
654
     * @param $name       The new name for the table
655
     * @param $owner      The new owner for the table
656
     * @param $schema     The new schema for the table
657
     * @param $comment    The comment on the table
658
     * @param $tablespace The new tablespace for the table ('' means leave as is)
659
     *
660
     * @return int 0 success
661
     */
662
    protected function _alterTable($tblrs, $name, $owner, $schema, $comment, $tablespace)
1 ignored issue
show
Coding Style introduced by
Protected method name "Postgres74::_alterTable" must not be prefixed with an underscore
Loading history...
663
    {
664
        /* $schema and tablespace not supported in pg74- */
665
        $this->fieldArrayClean($tblrs->fields);
666
667
        // Comment
668
        $status = $this->setComment('TABLE', '', $tblrs->fields['relname'], $comment);
669
        if ($status != 0) {
670
            return -4;
671
        }
672
673
        // Owner
674
        $this->fieldClean($owner);
675
        $status = $this->alterTableOwner($tblrs, $owner);
676
        if ($status != 0) {
677
            return -5;
678
        }
679
680
        // Rename
681
        $this->fieldClean($name);
682
        $status = $this->alterTableName($tblrs, $name);
683
        if ($status != 0) {
684
            return -3;
685
        }
686
687
        return 0;
688
    }
689
}
690