Completed
Pull Request — develop (#209)
by Felipe
26:08 queued 36s
created

Postgres82::hasFunctionCosting()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\Database;
8
9
/**
10
 * @file
11
 * PostgreSQL 8.2 support
12
 *
13
 * Id: Postgres82.php,v 1.10 2007/12/28 16:21:25 ioguix Exp $
14
 *
15
 * @package PHPPgAdmin
16
 */
17
class Postgres82 extends Postgres83
1 ignored issue
show
Coding Style introduced by
The property $major_version is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
18
{
19
    public $major_version = 8.2;
20
21
    // Select operators
22
    public $selectOps = [
23
        '='              => 'i',
24
        '!='             => 'i',
25
        '<'              => 'i',
26
        '>'              => 'i',
27
        '<='             => 'i',
28
        '>='             => 'i',
29
        '<<'             => 'i',
30
        '>>'             => 'i',
31
        '<<='            => 'i',
32
        '>>='            => 'i',
33
        'LIKE'           => 'i',
34
        'NOT LIKE'       => 'i',
35
        'ILIKE'          => 'i',
36
        'NOT ILIKE'      => 'i',
37
        'SIMILAR TO'     => 'i',
38
        'NOT SIMILAR TO' => 'i',
39
        '~'              => 'i',
40
        '!~'             => 'i',
41
        '~*'             => 'i',
42
        '!~*'            => 'i',
43
        'IS NULL'        => 'p',
44
        'IS NOT NULL'    => 'p',
45
        'IN'             => 'x',
46
        'NOT IN'         => 'x',
47
    ];
48
49
    // Database functions
50
51
    /**
52
     * Returns table locks information in the current database.
53
     *
54
     * @return \PHPPgAdmin\ADORecordSet A recordset
55
     */
56 View Code Duplication
    public function getLocks()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
57
    {
58
        $conf = $this->conf;
59
60
        if (!$conf['show_system']) {
61
            $where = 'AND pn.nspname NOT LIKE $$pg\_%$$';
62
        } else {
63
            $where = "AND nspname !~ '^pg_t(emp_[0-9]+|oast)$'";
64
        }
65
66
        $sql = "SELECT pn.nspname, pc.relname AS tablename, pl.transaction, pl.pid, pl.mode, pl.granted
67
		FROM pg_catalog.pg_locks pl, pg_catalog.pg_class pc, pg_catalog.pg_namespace pn
68
		WHERE pl.relation = pc.oid AND pc.relnamespace=pn.oid {$where}
69
		ORDER BY nspname,tablename";
70
71
        return $this->selectSet($sql);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->selectSet($sql); of type integer|PHPPgAdmin\ADORecordSet adds the type integer to the return on line 71 which is incompatible with the return type documented by PHPPgAdmin\Database\Postgres82::getLocks of type PHPPgAdmin\ADORecordSet.
Loading history...
72
    }
73
74
    // Sequence functions
75
76
    /**
77
     * Rename a sequence.
78
     *
79
     * @param \PHPPgAdmin\ADORecordSet $seqrs The sequence RecordSet returned by getSequence()
80
     * @param string                   $name  The new name for the sequence
81
     *
82
     * @return int 0 if operation was successful
0 ignored issues
show
Documentation introduced by
Should the return type not be \PHPPgAdmin\ADORecordSet|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
83
     */
84 View Code Duplication
    public function alterSequenceName($seqrs, $name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
85
    {
86
        /* vars are cleaned in _alterSequence */
87
        if (!empty($name) && ($seqrs->fields['seqname'] != $name)) {
88
            $f_schema = $this->_schema;
89
            $this->fieldClean($f_schema);
90
            $sql    = "ALTER TABLE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" RENAME TO \"{$name}\"";
91
            $status = $this->execute($sql);
92
            if ($status == 0) {
93
                $seqrs->fields['seqname'] = $name;
94
            } else {
95
                return $status;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $status; (PHPPgAdmin\ADORecordSet) is incompatible with the return type of the parent method PHPPgAdmin\Database\Postgres::alterSequenceName of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
96
            }
97
        }
98
99
        return 0;
100
    }
101
102
    // View functions
103
104
    /**
105
     * Rename a view.
106
     *
107
     * @param \PHPPgAdmin\ADORecordSet $vwrs The view recordSet returned by getView()
108
     * @param string                   $name The new view's name
109
     *
110
     * @return int -1 if Failed
0 ignored issues
show
Documentation introduced by
Should the return type not be \PHPPgAdmin\ADORecordSet|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
111
     */
112 View Code Duplication
    public function alterViewName($vwrs, $name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113
    {
114
        // Rename (only if name has changed)
115
        /* $vwrs and $name are cleaned in _alterView */
116
        if (!empty($name) && ($name != $vwrs->fields['relname'])) {
117
            $f_schema = $this->_schema;
118
            $this->fieldClean($f_schema);
119
            $sql    = "ALTER TABLE \"{$f_schema}\".\"{$vwrs->fields['relname']}\" RENAME TO \"{$name}\"";
120
            $status = $this->execute($sql);
121
            if ($status == 0) {
122
                $vwrs->fields['relname'] = $name;
123
            } else {
124
                return $status;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $status; (PHPPgAdmin\ADORecordSet) is incompatible with the return type of the parent method PHPPgAdmin\Database\Postgres::alterViewName of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
125
            }
126
        }
127
128
        return 0;
129
    }
130
131
    // Trigger functions
132
133
    /**
134
     * Grabs a list of triggers on a table.
135
     *
136
     * @param string $table The name of a table whose triggers to retrieve
137
     *
138
     * @return \PHPPgAdmin\ADORecordSet A recordset
139
     */
140
    public function getTriggers($table = '')
141
    {
142
        $c_schema = $this->_schema;
143
        $this->clean($c_schema);
144
        $this->clean($table);
145
146
        $sql = "SELECT
147
				t.tgname, pg_catalog.pg_get_triggerdef(t.oid) AS tgdef, t.tgenabled, p.oid AS prooid,
148
				p.proname || ' (' || pg_catalog.oidvectortypes(p.proargtypes) || ')' AS proproto,
149
				ns.nspname AS pronamespace
150
			FROM pg_catalog.pg_trigger t, pg_catalog.pg_proc p, pg_catalog.pg_namespace ns
151
			WHERE t.tgrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname='{$table}'
152
				AND relnamespace=(SELECT oid FROM pg_catalog.pg_namespace WHERE nspname='{$c_schema}'))
153
				AND (NOT tgisconstraint OR NOT EXISTS
154
						(SELECT 1 FROM pg_catalog.pg_depend d    JOIN pg_catalog.pg_constraint c
155
							ON (d.refclassid = c.tableoid AND d.refobjid = c.oid)
156
						WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))
157
				AND p.oid=t.tgfoid
158
				AND p.pronamespace = ns.oid";
159
160
        return $this->selectSet($sql);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->selectSet($sql); of type integer|PHPPgAdmin\ADORecordSet adds the type integer to the return on line 160 which is incompatible with the return type documented by PHPPgAdmin\Database\Postgres82::getTriggers of type PHPPgAdmin\ADORecordSet.
Loading history...
161
    }
162
163
    // Function functions
164
165
    /**
166
     * Returns all details for a particular function.
167
     *
168
     * @param int $function_oid
169
     *
170
     * @return \PHPPgAdmin\ADORecordSet Function info
171
     *
172
     * @internal param string The $func name of the function to retrieve
173
     */
174
    public function getFunction($function_oid)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $function_oid is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
175
    {
176
        $this->clean($function_oid);
177
178
        $sql = "SELECT
179
					pc.oid AS prooid,
180
					proname,
181
					pg_catalog.pg_get_userbyid(proowner) AS proowner,
182
					nspname as proschema,
183
					lanname as prolanguage,
184
					pg_catalog.format_type(prorettype, NULL) as proresult,
185
					prosrc,
186
					probin,
187
					proretset,
188
					proisstrict,
189
					provolatile,
190
					prosecdef,
191
					pg_catalog.oidvectortypes(pc.proargtypes) AS proarguments,
192
					proargnames AS proargnames,
193
					pg_catalog.obj_description(pc.oid, 'pg_proc') AS procomment
194
				FROM
195
					pg_catalog.pg_proc pc, pg_catalog.pg_language pl, pg_catalog.pg_namespace pn
196
				WHERE
197
					pc.oid = '{$function_oid}'::oid
198
					AND pc.prolang = pl.oid
199
					AND pc.pronamespace = pn.oid
200
				";
201
202
        return $this->selectSet($sql);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->selectSet($sql); of type integer|PHPPgAdmin\ADORecordSet adds the type integer to the return on line 202 which is incompatible with the return type documented by PHPPgAdmin\Database\Postgres82::getFunction of type PHPPgAdmin\ADORecordSet.
Loading history...
203
    }
204
205
    /**
206
     * Creates a new function.
207
     *
208
     * @param string $funcname   The name of the function to create
209
     * @param string $args       A comma separated string of types
210
     * @param string $returns    The return type
211
     * @param string $definition The definition for the new function
212
     * @param string $language   The language the function is written for
213
     * @param array  $flags      An array of optional flags
214
     * @param bool   $setof      True if it returns a set, false otherwise
215
     * @param float  $cost       cost the planner should use in the function execution step
216
     * @param int    $rows       number of rows planner should estimate will be returned
217
     * @param string $comment    The comment on the function
218
     * @param bool   $replace    (optional) True if OR REPLACE, false for normal
219
     *
220
     * @return bool|int 0 success
221
     */
222
    public function createFunction($funcname, $args, $returns, $definition, $language, $flags, $setof, $cost, $rows, $comment, $replace = false)
223
    {
224
        // Begin a transaction
225
        $status = $this->beginTransaction();
226
        if ($status != 0) {
227
            $this->rollbackTransaction();
228
229
            return -1;
230
        }
231
232
        $f_schema = $this->_schema;
233
        $this->fieldClean($f_schema);
234
        $this->fieldClean($funcname);
235
        $this->clean($args);
236
        $this->fieldClean($language);
237
        $this->arrayClean($flags);
238
239
        $sql = 'CREATE';
240
        if ($replace) {
241
            $sql .= ' OR REPLACE';
242
        }
243
244
        $sql .= " FUNCTION \"{$f_schema}\".\"{$funcname}\" (";
245
246
        if ($args != '') {
247
            $sql .= $args;
248
        }
249
250
        // For some reason, the returns field cannot have quotes...
251
        $sql .= ') RETURNS ';
252
        if ($setof) {
253
            $sql .= 'SETOF ';
254
        }
255
256
        $sql .= "{$returns} AS ";
257
258 View Code Duplication
        if (is_array($definition)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
259
            $this->arrayClean($definition);
260
            $sql .= "'".$definition[0]."'";
261
            if ($definition[1]) {
262
                $sql .= ",'".$definition[1]."'";
263
            }
264
        } else {
265
            $this->clean($definition);
266
            $sql .= "'".$definition."'";
267
        }
268
269
        $sql .= " LANGUAGE \"{$language}\"";
270
271
        // Add flags
272
        foreach ($flags as $v) {
273
            // Skip default flags
274
            if ($v == '') {
275
                continue;
276
            }
277
278
            $sql .= "\n{$v}";
279
        }
280
281
        $status = $this->execute($sql);
282
        if ($status != 0) {
283
            $this->rollbackTransaction();
284
285
            return -3;
286
        }
287
288
        /* set the comment */
289
        $status = $this->setComment('FUNCTION', "\"{$funcname}\"({$args})", null, $comment);
290
        if ($status != 0) {
291
            $this->rollbackTransaction();
292
293
            return -4;
294
        }
295
296
        return $this->endTransaction();
297
    }
298
299
    // Index functions
300
301
    /**
302
     * Clusters an index.
303
     *
304
     * @param string $table The table the index is on
305
     * @param string $index The name of the index
306
     *
307
     * @return array 0 if operation was successful
308
     */
309 View Code Duplication
    public function clusterIndex($table = '', $index = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
310
    {
311
        $sql = 'CLUSTER';
312
313
        // We don't bother with a transaction here, as there's no point rolling
314
        // back an expensive cluster if a cheap analyze fails for whatever reason
315
316
        if (!empty($table)) {
317
            $f_schema = $this->_schema;
318
            $this->fieldClean($f_schema);
319
            $this->fieldClean($table);
320
321
            if (!empty($index)) {
322
                $this->fieldClean($index);
323
                $sql .= " \"{$index}\" ON \"{$f_schema}\".\"{$table}\"";
324
            } else {
325
                $sql .= " \"{$f_schema}\".\"{$table}\"";
326
            }
327
        }
328
329
        $status = $this->execute($sql);
330
331
        return [$status, $sql];
332
    }
333
334
    // Operator functions
335
336
    /**
337
     * Returns all details for a particular operator.
338
     *
339
     * @param int $operator_oid The oid of the operator
340
     *
341
     * @return \PHPPgAdmin\ADORecordSet Function info
342
     */
343
    public function getOperator($operator_oid)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $operator_oid is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
344
    {
345
        $this->clean($operator_oid);
346
347
        $sql = "
348
			SELECT
349
				po.oid, po.oprname,
350
				oprleft::pg_catalog.regtype AS oprleftname,
351
				oprright::pg_catalog.regtype AS oprrightname,
352
				oprresult::pg_catalog.regtype AS resultname,
353
				po.oprcanhash,
354
				oprcom::pg_catalog.regoperator AS oprcom,
355
				oprnegate::pg_catalog.regoperator AS oprnegate,
356
				oprlsortop::pg_catalog.regoperator AS oprlsortop,
357
				oprrsortop::pg_catalog.regoperator AS oprrsortop,
358
				oprltcmpop::pg_catalog.regoperator AS oprltcmpop,
359
				oprgtcmpop::pg_catalog.regoperator AS oprgtcmpop,
360
				po.oprcode::pg_catalog.regproc AS oprcode,
361
				po.oprrest::pg_catalog.regproc AS oprrest,
362
				po.oprjoin::pg_catalog.regproc AS oprjoin
363
			FROM
364
				pg_catalog.pg_operator po
365
			WHERE
366
				po.oid='{$operator_oid}'
367
		";
368
369
        return $this->selectSet($sql);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->selectSet($sql); of type integer|PHPPgAdmin\ADORecordSet adds the type integer to the return on line 369 which is incompatible with the return type documented by PHPPgAdmin\Database\Postgres82::getOperator of type PHPPgAdmin\ADORecordSet.
Loading history...
370
    }
371
372
    // Operator Class functions
373
374
    /**
375
     * Gets all opclasses.
376
     *
377
     * @return \PHPPgAdmin\ADORecordSet A recordset
378
     */
379
    public function getOpClasses()
380
    {
381
        $c_schema = $this->_schema;
382
        $this->clean($c_schema);
383
        $sql = "
384
			SELECT
385
				pa.amname,
386
				po.opcname,
387
				po.opcintype::pg_catalog.regtype AS opcintype,
388
				po.opcdefault,
389
				pg_catalog.obj_description(po.oid, 'pg_opclass') AS opccomment
390
			FROM
391
				pg_catalog.pg_opclass po, pg_catalog.pg_am pa, pg_catalog.pg_namespace pn
392
			WHERE
393
				po.opcamid=pa.oid
394
				AND po.opcnamespace=pn.oid
395
				AND pn.nspname='{$c_schema}'
396
			ORDER BY 1,2
397
		";
398
399
        return $this->selectSet($sql);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->selectSet($sql); of type integer|PHPPgAdmin\ADORecordSet adds the type integer to the return on line 399 which is incompatible with the return type documented by PHPPgAdmin\Database\Postgres82::getOpClasses of type PHPPgAdmin\ADORecordSet.
Loading history...
400
    }
401
402
    // Capabilities
403
404
    public function hasCreateTableLikeWithIndexes()
405
    {
406
        return false;
407
    }
408
409
    public function hasEnumTypes()
410
    {
411
        return false;
412
    }
413
414
    public function hasFTS()
415
    {
416
        return false;
417
    }
418
419
    public function hasFunctionCosting()
420
    {
421
        return false;
422
    }
423
424
    public function hasFunctionGUC()
425
    {
426
        return false;
427
    }
428
429
    public function hasVirtualTransactionId()
430
    {
431
        return false;
432
    }
433
}
434