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

Postgres74::alterColumn()   C

Complexity

Conditions 10
Paths 36

Size

Total Lines 66
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 28
nc 36
nop 12
dl 0
loc 66
rs 6.2025
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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