Passed
Push — develop ( 563aca...51557c )
by Felipe
04:28
created

ADOdbBase::hasDatabaseCollation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.40
5
 */
6
7
namespace PHPPgAdmin\Database;
8
9
/**
10
 * @file
11
 * Parent class of all ADODB objects.
12
 *
13
 * Id: ADOdbBase.php,v 1.24 2008/02/20 20:43:10 ioguix Exp $
14
 *
15
 * @package PHPPgAdmin
16
 */
17
class ADOdbBase
18
{
19
    use \PHPPgAdmin\HelperTrait;
1 ignored issue
show
introduced by
The trait PHPPgAdmin\HelperTrait requires some properties which are not provided by PHPPgAdmin\Database\ADOdbBase: $responseobj, $requestobj
Loading history...
20
21
    public $conn;
22
23
    // The backend platform.  Set to UNKNOWN by default.
24
    public $platform = 'UNKNOWN';
25
26
    public $major_version = 9.6;
27
    // Max object name length
28
    public $_maxNameLen = 63;
1 ignored issue
show
Coding Style introduced by
Public member variable "_maxNameLen" must not be prefixed with an underscore
Loading history...
29
    // Store the current schema
30
    public $_schema;
1 ignored issue
show
Coding Style introduced by
Public member variable "_schema" must not be prefixed with an underscore
Loading history...
31
    // Map of database encoding names to HTTP encoding names.  If a
32
    // database encoding does not appear in this list, then its HTTP
33
    // encoding name is the same as its database encoding name.
34
    public $codemap = [
35
        'BIG5'       => 'BIG5',
36
        'EUC_CN'     => 'GB2312',
37
        'EUC_JP'     => 'EUC-JP',
38
        'EUC_KR'     => 'EUC-KR',
39
        'EUC_TW'     => 'EUC-TW',
40
        'GB18030'    => 'GB18030',
41
        'GBK'        => 'GB2312',
42
        'ISO_8859_5' => 'ISO-8859-5',
43
        'ISO_8859_6' => 'ISO-8859-6',
44
        'ISO_8859_7' => 'ISO-8859-7',
45
        'ISO_8859_8' => 'ISO-8859-8',
46
        'JOHAB'      => 'CP1361',
47
        'KOI8'       => 'KOI8-R',
48
        'LATIN1'     => 'ISO-8859-1',
49
        'LATIN2'     => 'ISO-8859-2',
50
        'LATIN3'     => 'ISO-8859-3',
51
        'LATIN4'     => 'ISO-8859-4',
52
        'LATIN5'     => 'ISO-8859-9',
53
        'LATIN6'     => 'ISO-8859-10',
54
        'LATIN7'     => 'ISO-8859-13',
55
        'LATIN8'     => 'ISO-8859-14',
56
        'LATIN9'     => 'ISO-8859-15',
57
        'LATIN10'    => 'ISO-8859-16',
58
        'SJIS'       => 'SHIFT_JIS',
59
        'SQL_ASCII'  => 'US-ASCII',
60
        'UHC'        => 'WIN949',
61
        'UTF8'       => 'UTF-8',
62
        'WIN866'     => 'CP866',
63
        'WIN874'     => 'CP874',
64
        'WIN1250'    => 'CP1250',
65
        'WIN1251'    => 'CP1251',
66
        'WIN1252'    => 'CP1252',
67
        'WIN1256'    => 'CP1256',
68
        'WIN1258'    => 'CP1258',
69
    ];
70
    public $defaultprops = ['', '', ''];
71
    // Extra "magic" types.  BIGSERIAL was added in PostgreSQL 7.2.
72
    public $extraTypes = ['SERIAL', 'BIGSERIAL'];
73
    // Foreign key stuff.  First element MUST be the default.
74
    public $fkactions    = ['NO ACTION', 'RESTRICT', 'CASCADE', 'SET NULL', 'SET DEFAULT'];
75
    public $fkdeferrable = ['NOT DEFERRABLE', 'DEFERRABLE'];
76
    public $fkinitial    = ['INITIALLY IMMEDIATE', 'INITIALLY DEFERRED'];
77
    public $fkmatches    = ['MATCH SIMPLE', 'MATCH FULL'];
78
    // Function properties
79
    public $funcprops = [
80
        ['', 'VOLATILE', 'IMMUTABLE', 'STABLE'],
81
        ['', 'CALLED ON NULL INPUT', 'RETURNS NULL ON NULL INPUT'],
82
        ['', 'SECURITY INVOKER', 'SECURITY DEFINER'],
83
    ];
84
85
    // Default help URL
86
    public $help_base;
87
    // Help sub pages
88
    public $help_page;
89
    // Name of id column
90
    public $id = 'oid';
91
92
    // Supported join operations for use with view wizard
93
    public $joinOps = ['INNER JOIN' => 'INNER JOIN', 'LEFT JOIN' => 'LEFT JOIN', 'RIGHT JOIN' => 'RIGHT JOIN', 'FULL JOIN' => 'FULL JOIN'];
94
    // Map of internal language name to syntax highlighting name
95
    public $langmap = [
96
        'sql'       => 'SQL',
97
        'plpgsql'   => 'SQL',
98
        'php'       => 'PHP',
99
        'phpu'      => 'PHP',
100
        'plphp'     => 'PHP',
101
        'plphpu'    => 'PHP',
102
        'perl'      => 'Perl',
103
        'perlu'     => 'Perl',
104
        'plperl'    => 'Perl',
105
        'plperlu'   => 'Perl',
106
        'java'      => 'Java',
107
        'javau'     => 'Java',
108
        'pljava'    => 'Java',
109
        'pljavau'   => 'Java',
110
        'plj'       => 'Java',
111
        'plju'      => 'Java',
112
        'python'    => 'Python',
113
        'pythonu'   => 'Python',
114
        'plpython'  => 'Python',
115
        'plpythonu' => 'Python',
116
        'ruby'      => 'Ruby',
117
        'rubyu'     => 'Ruby',
118
        'plruby'    => 'Ruby',
119
        'plrubyu'   => 'Ruby',
120
    ];
121
    // Predefined size types
122
    public $predefined_size_types = [
123
        'abstime',
124
        'aclitem',
125
        'bigserial',
126
        'boolean',
127
        'bytea',
128
        'cid',
129
        'cidr',
130
        'circle',
131
        'date',
132
        'float4',
133
        'float8',
134
        'gtsvector',
135
        'inet',
136
        'int2',
137
        'int4',
138
        'int8',
139
        'macaddr',
140
        'money',
141
        'oid',
142
        'path',
143
        'polygon',
144
        'refcursor',
145
        'regclass',
146
        'regoper',
147
        'regoperator',
148
        'regproc',
149
        'regprocedure',
150
        'regtype',
151
        'reltime',
152
        'serial',
153
        'smgr',
154
        'text',
155
        'tid',
156
        'tinterval',
157
        'tsquery',
158
        'tsvector',
159
        'varbit',
160
        'void',
161
        'xid',
162
    ];
163
    // List of all legal privileges that can be applied to different types
164
    // of objects.
165
    public $privlist = [
166
        'table'      => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'],
167
        'view'       => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'],
168
        'sequence'   => ['SELECT', 'UPDATE', 'ALL PRIVILEGES'],
169
        'database'   => ['CREATE', 'TEMPORARY', 'CONNECT', 'ALL PRIVILEGES'],
170
        'function'   => ['EXECUTE', 'ALL PRIVILEGES'],
171
        'language'   => ['USAGE', 'ALL PRIVILEGES'],
172
        'schema'     => ['CREATE', 'USAGE', 'ALL PRIVILEGES'],
173
        'tablespace' => ['CREATE', 'ALL PRIVILEGES'],
174
        'column'     => ['SELECT', 'INSERT', 'UPDATE', 'REFERENCES', 'ALL PRIVILEGES'],
175
    ];
176
    // List of characters in acl lists and the privileges they
177
    // refer to.
178
    public $privmap = [
179
        'r' => 'SELECT',
180
        'w' => 'UPDATE',
181
        'a' => 'INSERT',
182
        'd' => 'DELETE',
183
        'D' => 'TRUNCATE',
184
        'R' => 'RULE',
185
        'x' => 'REFERENCES',
186
        't' => 'TRIGGER',
187
        'X' => 'EXECUTE',
188
        'U' => 'USAGE',
189
        'C' => 'CREATE',
190
        'T' => 'TEMPORARY',
191
        'c' => 'CONNECT',
192
    ];
193
    // Rule action types
194
    public $rule_events = ['SELECT', 'INSERT', 'UPDATE', 'DELETE'];
195
    // Select operators
196
    public $selectOps = [
197
        '='                   => 'i',
198
        '!='                  => 'i',
199
        '<'                   => 'i',
200
        '>'                   => 'i',
201
        '<='                  => 'i',
202
        '>='                  => 'i',
203
        '<<'                  => 'i',
204
        '>>'                  => 'i',
205
        '<<='                 => 'i',
206
        '>>='                 => 'i',
207
        'LIKE'                => 'i',
208
        'NOT LIKE'            => 'i',
209
        'ILIKE'               => 'i',
210
        'NOT ILIKE'           => 'i',
211
        'SIMILAR TO'          => 'i',
212
        'NOT SIMILAR TO'      => 'i',
213
        '~'                   => 'i',
214
        '!~'                  => 'i',
215
        '~*'                  => 'i',
216
        '!~*'                 => 'i',
217
        'IS NULL'             => 'p',
218
        'IS NOT NULL'         => 'p',
219
        'IN'                  => 'x',
220
        'NOT IN'              => 'x',
221
        '@@'                  => 'i',
222
        '@@@'                 => 'i',
223
        '@>'                  => 'i',
224
        '<@'                  => 'i',
225
        '@@ to_tsquery'       => 't',
226
        '@@@ to_tsquery'      => 't',
227
        '@> to_tsquery'       => 't',
228
        '<@ to_tsquery'       => 't',
229
        '@@ plainto_tsquery'  => 't',
230
        '@@@ plainto_tsquery' => 't',
231
        '@> plainto_tsquery'  => 't',
232
        '<@ plainto_tsquery'  => 't',
233
    ];
234
    // Array of allowed trigger events
235
    public $triggerEvents = [
236
        'INSERT',
237
        'UPDATE',
238
        'DELETE',
239
        'INSERT OR UPDATE',
240
        'INSERT OR DELETE',
241
        'DELETE OR UPDATE',
242
        'INSERT OR DELETE OR UPDATE',
243
    ];
244
    // When to execute the trigger
245
    public $triggerExecTimes = ['BEFORE', 'AFTER'];
246
    // How often to execute the trigger
247
    public $triggerFrequency = ['ROW', 'STATEMENT'];
248
    // Array of allowed type alignments
249
    public $typAligns = ['char', 'int2', 'int4', 'double'];
250
    // The default type alignment
251
    public $typAlignDef = 'int4';
252
    // Default index type
253
    public $typIndexDef = 'BTREE';
254
    // Array of allowed index types
255
    public $typIndexes = ['BTREE', 'RTREE', 'GIST', 'GIN', 'HASH'];
256
    // Array of allowed type storage attributes
257
    public $typStorages = ['plain', 'external', 'extended', 'main'];
258
    // The default type storage
259
    public $typStorageDef = 'plain';
260
261
    public $lang;
262
    public $conf;
263
    protected $container;
264
    /**
265
     * Base constructor.
266
     *
267
     * @param \ADONewConnection &$conn The connection object
0 ignored issues
show
Bug introduced by
The type ADONewConnection 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...
Coding Style introduced by
Doc comment for parameter &$conn does not match actual variable name $conn
Loading history...
268
     */
269
    public function __construct(&$conn, $container)
270
    {
271
        $this->container = $container;
272
273
        $this->lang = $container->get('lang');
274
        $this->conf = $container->get('conf');
275
276
        $this->prtrace('instanced connection class');
277
        $this->conn = $conn;
278
    }
279
280
    /**
281
     * Sets the comment for an object in the database.
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...
282
     *
283
     * @pre All parameters must already be cleaned
284
     *
285
     * @param      $obj_type One of 'TABLE' | 'COLUMN' | 'VIEW' | 'SCHEMA' | 'SEQUENCE' | 'TYPE' | 'FUNCTION' | 'AGGREGATE'
1 ignored issue
show
Bug introduced by
The type PHPPgAdmin\Database\One 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...
Coding Style introduced by
Parameter tags must be defined first in a doc comment
Loading history...
286
     * @param      $obj_name the name of the object for which to attach a comment
287
     * @param      $table    Name of table that $obj_name belongs to.  Ignored unless $obj_type is 'TABLE' or 'COLUMN'.
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\Database\Name 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...
Coding Style introduced by
Doc comment for parameter $obj_name does not match actual variable name $table
Loading history...
288
     * @param      $comment  the comment to add
289
     * @param null $basetype
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $basetype is correct as it would always require null to be passed?
Loading history...
290
     *
291
     * @return int 0 if operation was successful
292
     */
293
    public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null)
294
    {
295
        $sql      = "COMMENT ON {$obj_type} ";
296
        $f_schema = $this->_schema;
297
        $this->fieldClean($f_schema);
298
        $this->clean($comment); // Passing in an already cleaned comment will lead to double escaped data
299
        // So, while counter-intuitive, it is important to not clean comments before
300
        // calling setComment. We will clean it here instead.
301
        /*
302
        $this->fieldClean($table);
303
        $this->fieldClean($obj_name);
304
         */
305
306
        switch ($obj_type) {
307
            case 'TABLE':
308
                $sql .= "\"{$f_schema}\".\"{$table}\" IS ";
309
310
                break;
311
            case 'COLUMN':
312
                $sql .= "\"{$f_schema}\".\"{$table}\".\"{$obj_name}\" IS ";
313
314
                break;
315
            case 'SEQUENCE':
316
            case 'VIEW':
317
            case 'TEXT SEARCH CONFIGURATION':
318
            case 'TEXT SEARCH DICTIONARY':
319
            case 'TEXT SEARCH TEMPLATE':
320
            case 'TEXT SEARCH PARSER':
321
            case 'TYPE':
322
                $sql .= "\"{$f_schema}\".";
323
            // no break
324
            case 'DATABASE':
325
            case 'ROLE':
326
            case 'SCHEMA':
327
            case 'TABLESPACE':
328
                $sql .= "\"{$obj_name}\" IS ";
329
330
                break;
331
            case 'FUNCTION':
332
                $sql .= "\"{$f_schema}\".{$obj_name} IS ";
333
334
                break;
335
            case 'AGGREGATE':
336
                $sql .= "\"{$f_schema}\".\"{$obj_name}\" (\"{$basetype}\") IS ";
337
338
                break;
339
            default:
340
                // Unknown object type
341
                return -1;
342
        }
343
344
        if ($comment != '') {
345
            $sql .= "'{$comment}';";
346
        } else {
347
            $sql .= 'NULL;';
348
        }
349
350
        return $this->execute($sql);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->execute($sql) returns the type ADORecordSet which is incompatible with the documented return type integer.
Loading history...
351
    }
352
353
    /**
354
     * Turns on or off query debugging.
355
     *
356
     * @param $debug True to turn on debugging, false otherwise
357
     */
358
    public function setDebug($debug)
359
    {
360
        $this->conn->debug = $debug;
361
    }
362
363
    /**
364
     * Cleans (escapes) an array of field names.
365
     *
366
     * @param $arr The array to clean, by reference
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...
367
     *
368
     * @return The cleaned array
369
     */
370
    public function fieldArrayClean(&$arr)
371
    {
372
        foreach ($arr as $k => $v) {
373
            if ($v === null) {
374
                continue;
375
            }
376
377
            $arr[$k] = str_replace('"', '""', $v);
378
        }
379
380
        return $arr;
381
    }
382
383
    /**
384
     * Cleans (escapes) an array.
385
     *
386
     * @param $arr The array to clean, by reference
387
     *
388
     * @return The cleaned array
389
     */
390
    public function arrayClean(&$arr)
391
    {
392
        reset($arr);
393
        //while (list($k, $v) = each($arr)) {
394
        foreach ($arr as $k => $v) {
395
            $arr[$k] = addslashes($v);
396
        }
397
398
        return $arr;
399
    }
400
401
    /**
402
     * Executes a query on the underlying connection.
403
     *
404
     * @param $sql The SQL query to execute
405
     *
406
     * @return \ADORecordSet A recordset
407
     */
408
    public function execute($sql)
409
    {
410
        // Execute the statement
411
        $rs = $this->conn->Execute($sql);
1 ignored issue
show
Unused Code introduced by
The assignment to $rs is dead and can be removed.
Loading history...
412
413
        // If failure, return error value
414
        return $this->conn->ErrorNo();
415
    }
416
417
    /**
418
     * Closes the connection the database class
419
     * relies on.
420
     */
421
    public function close()
422
    {
423
        $this->conn->close();
424
    }
425
426
    /**
427
     * Retrieves a ResultSet from a query.
428
     *
429
     * @param $sql The SQL statement to be executed
430
     *
431
     * @return \ADORecordSet A recordset
432
     */
433
    public function selectSet($sql)
434
    {
435
        // Execute the statement
436
        $rs = $this->conn->Execute($sql);
437
438
        if (!$rs) {
439
            return $this->conn->ErrorNo();
440
        }
441
442
        return $rs;
443
    }
444
445
    /**
446
     * Retrieves a single value from a query.
447
     *
448
     * @@ assumes that the query will return only one row - returns field value in the first row
449
     *
450
     * @param $sql   The SQL statement to be executed
1 ignored issue
show
Coding Style introduced by
Parameter tags must be defined first in a doc comment
Loading history...
451
     * @param $field The field name to be returned
452
     *
453
     * @return A  single field value
454
     * @return -1 No rows were found
0 ignored issues
show
Coding Style introduced by
Only 1 @return tag is allowed in a function comment
Loading history...
455
     */
456
    public function selectField($sql, $field)
457
    {
458
        // Execute the statement
459
        $rs = $this->conn->Execute($sql);
460
461
        // If failure, or no rows returned, return error value
462
        if (!$rs) {
463
            return $this->conn->ErrorNo();
464
        }
465
466
        if ($rs->RecordCount() == 0) {
467
            return -1;
0 ignored issues
show
Bug Best Practice introduced by
The expression return -1 returns the type integer which is incompatible with the documented return type PHPPgAdmin\Database\A.
Loading history...
468
        }
469
470
        return $rs->fields[$field];
471
    }
472
473
    /**
474
     * Delete from the database.
475
     *
476
     * @param        $table      The name of the table
477
     * @param        $conditions (array) A map of field names to conditions
478
     * @param string $schema     (optional) The table's schema
479
     *
480
     * @return int 0 success
481
     */
482
    public function delete($table, $conditions, $schema = '')
483
    {
484
        $this->fieldClean($table);
485
486
        reset($conditions);
487
488
        if (!empty($schema)) {
489
            $this->fieldClean($schema);
490
            $schema = "\"{$schema}\".";
491
        }
492
493
        // Build clause
494
        $sql = '';
495
        //while (list($key, $value) = each($conditions)) {
496
        foreach ($conditions as $key => $value) {
497
            $this->clean($key);
498
            $this->clean($value);
499
            if ($sql) {
500
                $sql .= " AND \"{$key}\"='{$value}'";
501
            } else {
502
                $sql = "DELETE FROM {$schema}\"{$table}\" WHERE \"{$key}\"='{$value}'";
503
            }
504
        }
505
506
        // Check for failures
507
        if (!$this->conn->Execute($sql)) {
508
            // Check for referential integrity failure
509
            if (stristr($this->conn->ErrorMsg(), 'referential')) {
510
                return -1;
511
            }
512
        }
513
514
        // Check for no rows modified
515
        if ($this->conn->Affected_Rows() == 0) {
516
            return -2;
517
        }
518
519
        return $this->conn->ErrorNo();
520
    }
521
522
    /**
523
     * Cleans (escapes) an object name (eg. table, field).
524
     *
525
     * @param $str The string to clean, by reference
526
     *
527
     * @return The cleaned string
528
     */
529
    public function fieldClean(&$str)
530
    {
531
        $str = str_replace('"', '""', $str);
532
533
        return $str;
534
    }
535
536
    /**
537
     * Cleans (escapes) a string.
538
     *
539
     * @param string $str The string to clean, by reference
540
     *
541
     * @return string The cleaned string
542
     */
543
    public function clean(&$str)
544
    {
545
        $str = addslashes($str);
546
547
        return $str;
548
    }
549
550
    /**
551
     * Escapes bytea data for display on the screen.
552
     *
553
     * @param string $data The bytea data
554
     *
555
     * @return string Data formatted for on-screen display
556
     */
557
    public function escapeBytea($data)
558
    {
559
        return htmlentities($data, ENT_QUOTES, 'UTF-8');
560
    }
561
562
    /**
563
     * Insert a set of values into the database.
564
     *
565
     * @param $table The table to insert into
566
     * @param $vars  (array) A mapping of the field names to the values to be inserted
567
     *
568
     * @return int 0 success
569
     */
570
    public function insert($table, $vars)
571
    {
572
        $this->fieldClean($table);
573
574
        // Build clause
575
        if (sizeof($vars) > 0) {
576
            $fields = '';
577
            $values = '';
578
            foreach ($vars as $key => $value) {
579
                $this->clean($key);
580
                $this->clean($value);
581
582
                if ($fields) {
583
                    $fields .= ", \"{$key}\"";
584
                } else {
585
                    $fields = "INSERT INTO \"{$table}\" (\"{$key}\"";
586
                }
587
588
                if ($values) {
589
                    $values .= ", '{$value}'";
590
                } else {
591
                    $values = ") VALUES ('{$value}'";
592
                }
593
            }
594
            $sql = $fields . $values . ')';
595
        }
596
597
        // Check for failures
598
        if (!$this->conn->Execute($sql)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sql does not seem to be defined for all execution paths leading up to this point.
Loading history...
599
            // Check for unique constraint failure
600
            if (stristr($this->conn->ErrorMsg(), 'unique')) {
601
                return -1;
602
            }
603
604
            if (stristr($this->conn->ErrorMsg(), 'referential')) {
605
                return -2;
606
            } // Check for referential integrity failure
607
        }
608
609
        return $this->conn->ErrorNo();
610
    }
611
612
    /**
613
     * Update a row in the database.
614
     *
615
     * @param       $table The table that is to be updated
616
     * @param       $vars  (array) A mapping of the field names to the values to be updated
617
     * @param       $where (array) A mapping of field names to values for the where clause
618
     * @param array $nulls (array, optional) An array of fields to be set null
619
     *
620
     * @return int 0 success
621
     */
622
    public function update($table, $vars, $where, $nulls = [])
623
    {
624
        $this->fieldClean($table);
625
626
        $setClause   = '';
627
        $whereClause = '';
628
629
        // Populate the syntax arrays
630
        reset($vars);
631
        //while (list($key, $value) = each($vars)) {
632
        foreach ($vars as $key => $value) {
633
            $this->fieldClean($key);
634
            $this->clean($value);
635
            if ($setClause) {
636
                $setClause .= ", \"{$key}\"='{$value}'";
637
            } else {
638
                $setClause = "UPDATE \"{$table}\" SET \"{$key}\"='{$value}'";
639
            }
640
        }
641
642
        reset($nulls);
643
        //while (list(, $value) = each($nulls)) {
644
        foreach ($nulls as $key => $value) {
645
            $this->fieldClean($value);
646
            if ($setClause) {
647
                $setClause .= ", \"{$value}\"=NULL";
648
            } else {
649
                $setClause = "UPDATE \"{$table}\" SET \"{$value}\"=NULL";
650
            }
651
        }
652
653
        reset($where);
654
        //while (list($key, $value) = each($where)) {
655
        foreach ($where as $key => $value) {
656
            $this->fieldClean($key);
657
            $this->clean($value);
658
            if ($whereClause) {
659
                $whereClause .= " AND \"{$key}\"='{$value}'";
660
            } else {
661
                $whereClause = " WHERE \"{$key}\"='{$value}'";
662
            }
663
        }
664
665
        // Check for failures
666
        if (!$this->conn->Execute($setClause . $whereClause)) {
667
            // Check for unique constraint failure
668
            if (stristr($this->conn->ErrorMsg(), 'unique')) {
669
                return -1;
670
            }
671
672
            if (stristr($this->conn->ErrorMsg(), 'referential')) {
673
                return -2;
674
            } // Check for referential integrity failure
675
        }
676
677
        // Check for no rows modified
678
        if ($this->conn->Affected_Rows() == 0) {
679
            return -3;
680
        }
681
682
        return $this->conn->ErrorNo();
683
    }
684
685
    /**
686
     * Begin a transaction.
687
     *
688
     * @return bool 0 success
689
     */
690
    public function beginTransaction()
691
    {
692
        return !$this->conn->BeginTrans();
693
    }
694
695
    /**
696
     * End a transaction.
697
     *
698
     * @return bool 0 success
699
     */
700
    public function endTransaction()
701
    {
702
        return !$this->conn->CommitTrans();
703
    }
704
705
    /**
706
     * Roll back a transaction.
707
     *
708
     * @return bool 0 success
709
     */
710
    public function rollbackTransaction()
711
    {
712
        return !$this->conn->RollbackTrans();
713
    }
714
715
    /**
716
     * Get the backend platform.
717
     *
718
     * @return The backend platform
719
     */
720
    public function getPlatform()
721
    {
722
        //return $this->conn->platform;
723
        return 'UNKNOWN';
0 ignored issues
show
Bug Best Practice introduced by
The expression return 'UNKNOWN' returns the type string which is incompatible with the documented return type PHPPgAdmin\Database\The.
Loading history...
724
    }
725
726
    // Type conversion routines
727
728
    /**
729
     * Change the value of a parameter to database representation depending on whether it evaluates to true or false.
730
     *
731
     * @param $parameter the parameter
732
     *
733
     * @return \PHPPgAdmin\Database\the
734
     */
735
    public function dbBool(&$parameter)
736
    {
737
        return $parameter;
738
    }
739
740
    /**
741
     * Change a parameter from database representation to a boolean, (others evaluate to false).
742
     *
743
     * @param $parameter the parameter
744
     *
745
     * @return \PHPPgAdmin\Database\the
746
     */
747
    public function phpBool($parameter)
748
    {
749
        return $parameter;
750
    }
751
752
    /**
753
     * Change a db array into a PHP array.
754
     *
755
     * @param $dbarr
756
     *
757
     * @return array A PHP array
758
     *
759
     * @internal param String $arr representing the DB array
760
     */
761
    public function phpArray($dbarr)
762
    {
763
        // Take off the first and last characters (the braces)
764
        $arr = substr($dbarr, 1, strlen($dbarr) - 2);
765
766
        // Pick out array entries by carefully parsing.  This is necessary in order
767
        // to cope with double quotes and commas, etc.
768
        $elements  = [];
769
        $i         = $j         = 0;
770
        $in_quotes = false;
771
        while ($i < strlen($arr)) {
772
            // If current char is a double quote and it's not escaped, then
773
            // enter quoted bit
774
            $char = substr($arr, $i, 1);
775
            if ($char == '"' && ($i == 0 || substr($arr, $i - 1, 1) != '\\')) {
776
                $in_quotes = !$in_quotes;
1 ignored issue
show
introduced by
$in_quotes is of type mixed, thus it always evaluated to false.
Loading history...
777
            } elseif ($char == ',' && !$in_quotes) {
778
                // Add text so far to the array
779
                $elements[] = substr($arr, $j, $i - $j);
780
                $j          = $i + 1;
781
            }
782
            ++$i;
783
        }
784
        // Add final text to the array
785
        $elements[] = substr($arr, $j);
786
787
        // Do one further loop over the elements array to remote double quoting
788
        // and escaping of double quotes and backslashes
789
        for ($i = 0; $i < sizeof($elements); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
790
            $v = $elements[$i];
791
            if (strpos($v, '"') === 0) {
792
                $v            = substr($v, 1, strlen($v) - 2);
793
                $v            = str_replace('\\"', '"', $v);
794
                $v            = str_replace('\\\\', '\\', $v);
795
                $elements[$i] = $v;
796
            }
797
        }
798
799
        return $elements;
800
    }
801
802
    /**
803
     * Determines if it has tablespaces.
804
     *
805
     * @return bool true if has tablespaces, False otherwise
806
     */
807
    public function hasTablespaces()
808
    {
809
        return true;
810
    }
811
812
    /**
813
     * Determines if it has shared comments.
814
     *
815
     * @return bool true if has shared comments, False otherwise
816
     */
817
    public function hasSharedComments()
818
    {
819
        return true;
820
    }
821
822
    /**
823
     * Determines if it has roles.
824
     *
825
     * @return bool true if has roles, False otherwise
826
     */
827
    public function hasRoles()
828
    {
829
        return true;
830
    }
831
832
    /**
833
     * Determines if it has grant option.
834
     *
835
     * @return bool true if has grant option, False otherwise
836
     */
837
    public function hasGrantOption()
838
    {
839
        return true;
840
    }
841
842
    /**
843
     * Determines if it has create table like with constraints.
844
     *
845
     * @return bool true if has create table like with constraints, False otherwise
846
     */
847
    public function hasCreateTableLikeWithConstraints()
848
    {
849
        return true;
850
    }
851
852
    /**
853
     * Determines if it has create table like with indexes.
854
     *
855
     * @return bool true if has create table like with indexes, False otherwise
856
     */
857
    public function hasCreateTableLikeWithIndexes()
858
    {
859
        return true;
860
    }
861
862
    /**
863
     * Determines if it has create field with constraints.
864
     *
865
     * @return bool true if has create field with constraints, False otherwise
866
     */
867
    public function hasCreateFieldWithConstraints()
868
    {
869
        return true;
870
    }
871
872
    /**
873
     * Determines if it has domain constraints.
874
     *
875
     * @return bool true if has domain constraints, False otherwise
876
     */
877
    public function hasDomainConstraints()
878
    {
879
        return true;
880
    }
881
882
    /**
883
     * Determines if it has function alter owner.
884
     *
885
     * @return bool true if has function alter owner, False otherwise
886
     */
887
    public function hasFunctionAlterOwner()
888
    {
889
        return true;
890
    }
891
892
    /**
893
     * Determines if it has function alter schema.
894
     *
895
     * @return bool true if has function alter schema, False otherwise
896
     */
897
    public function hasFunctionAlterSchema()
898
    {
899
        return true;
900
    }
901
902
    /**
903
     * Determines if it has read only queries.
904
     *
905
     * @return bool true if has read only queries, False otherwise
906
     */
907
    public function hasReadOnlyQueries()
908
    {
909
        return true;
910
    }
911
912
    /**
913
     * Determines if it has aggregate sort operation.
914
     *
915
     * @return bool true if has aggregate sort operation, False otherwise
916
     */
917
    public function hasAggregateSortOp()
918
    {
919
        return true;
920
    }
921
922
    /**
923
     * Determines if it has alter aggregate.
924
     *
925
     * @return bool true if has alter aggregate, False otherwise
926
     */
927
    public function hasAlterAggregate()
928
    {
929
        return true;
930
    }
931
932
    /**
933
     * Determines if it has alter column type.
934
     *
935
     * @return bool true if has alter column type, False otherwise
936
     */
937
    public function hasAlterColumnType()
938
    {
939
        return true;
940
    }
941
942
    /**
943
     * Determines if it has alter database owner.
944
     *
945
     * @return bool true if has alter database owner, False otherwise
946
     */
947
    public function hasAlterDatabaseOwner()
948
    {
949
        return true;
950
    }
951
952
    /**
953
     * Determines if it has alter schema.
954
     *
955
     * @return bool true if has alter schema, False otherwise
956
     */
957
    public function hasAlterSchema()
958
    {
959
        return true;
960
    }
961
962
    /**
963
     * Determines if it has alter schema owner.
964
     *
965
     * @return bool true if has alter schema owner, False otherwise
966
     */
967
    public function hasAlterSchemaOwner()
968
    {
969
        return true;
970
    }
971
972
    /**
973
     * Determines if it has alter sequence schema.
974
     *
975
     * @return bool true if has alter sequence schema, False otherwise
976
     */
977
    public function hasAlterSequenceSchema()
978
    {
979
        return true;
980
    }
981
982
    /**
983
     * Determines if it has alter sequence start.
984
     *
985
     * @return bool true if has alter sequence start, False otherwise
986
     */
987
    public function hasAlterSequenceStart()
988
    {
989
        return true;
990
    }
991
992
    /**
993
     * Determines if it has alter table schema.
994
     *
995
     * @return bool true if has alter table schema, False otherwise
996
     */
997
    public function hasAlterTableSchema()
998
    {
999
        return true;
1000
    }
1001
1002
    /**
1003
     * Determines if it has autovacuum.
1004
     *
1005
     * @return bool true if has autovacuum, False otherwise
1006
     */
1007
    public function hasAutovacuum()
1008
    {
1009
        return true;
1010
    }
1011
1012
    /**
1013
     * Determines if it has create table like.
1014
     *
1015
     * @return bool true if has create table like, False otherwise
1016
     */
1017
    public function hasCreateTableLike()
1018
    {
1019
        return true;
1020
    }
1021
1022
    /**
1023
     * Determines if it has disable triggers.
1024
     *
1025
     * @return bool true if has disable triggers, False otherwise
1026
     */
1027
    public function hasDisableTriggers()
1028
    {
1029
        return true;
1030
    }
1031
1032
    /**
1033
     * Determines if it has alter domains.
1034
     *
1035
     * @return bool true if has alter domains, False otherwise
1036
     */
1037
    public function hasAlterDomains()
1038
    {
1039
        return true;
1040
    }
1041
1042
    /**
1043
     * Determines if it has enum types.
1044
     *
1045
     * @return bool true if has enum types, False otherwise
1046
     */
1047
    public function hasEnumTypes()
1048
    {
1049
        return true;
1050
    }
1051
1052
    /**
1053
     * Determines if it has fts.
1054
     *
1055
     * @return bool true if has fts, False otherwise
1056
     */
1057
    public function hasFTS()
1058
    {
1059
        return true;
1060
    }
1061
1062
    /**
1063
     * Determines if it has function costing.
1064
     *
1065
     * @return bool true if has function costing, False otherwise
1066
     */
1067
    public function hasFunctionCosting()
1068
    {
1069
        return true;
1070
    }
1071
1072
    /**
1073
     * Determines if it has function guc.
1074
     *
1075
     * @return bool true if has function guc, False otherwise
1076
     */
1077
    public function hasFunctionGUC()
1078
    {
1079
        return true;
1080
    }
1081
1082
    /**
1083
     * Determines if it has named parameters.
1084
     *
1085
     * @return bool true if has named parameters, False otherwise
1086
     */
1087
    public function hasNamedParams()
1088
    {
1089
        return true;
1090
    }
1091
1092
    /**
1093
     * Determines if it has prepare.
1094
     *
1095
     * @return bool true if has prepare, False otherwise
1096
     */
1097
    public function hasPrepare()
1098
    {
1099
        return true;
1100
    }
1101
1102
    /**
1103
     * Determines if it has prepared xacts.
1104
     *
1105
     * @return bool true if has prepared xacts, False otherwise
1106
     */
1107
    public function hasPreparedXacts()
1108
    {
1109
        return true;
1110
    }
1111
1112
    /**
1113
     * Determines if it has recluster.
1114
     *
1115
     * @return bool true if has recluster, False otherwise
1116
     */
1117
    public function hasRecluster()
1118
    {
1119
        return true;
1120
    }
1121
1122
    /**
1123
     * Determines if it has server admin funcs.
1124
     *
1125
     * @return bool true if has server admin funcs, False otherwise
1126
     */
1127
    public function hasServerAdminFuncs()
1128
    {
1129
        return true;
1130
    }
1131
1132
    /**
1133
     * Determines if it has query cancel.
1134
     *
1135
     * @return bool true if has query cancel, False otherwise
1136
     */
1137
    public function hasQueryCancel()
1138
    {
1139
        return true;
1140
    }
1141
1142
    /**
1143
     * Determines if it has user rename.
1144
     *
1145
     * @return bool true if has user rename, False otherwise
1146
     */
1147
    public function hasUserRename()
1148
    {
1149
        return true;
1150
    }
1151
1152
    /**
1153
     * Determines if it has user signals.
1154
     *
1155
     * @return bool true if has user signals, False otherwise
1156
     */
1157
    public function hasUserSignals()
1158
    {
1159
        return true;
1160
    }
1161
1162
    /**
1163
     * Determines if it has virtual transaction identifier.
1164
     *
1165
     * @return bool true if has virtual transaction identifier, False otherwise
1166
     */
1167
    public function hasVirtualTransactionId()
1168
    {
1169
        return true;
1170
    }
1171
1172
    /**
1173
     * Determines if it has alter database.
1174
     *
1175
     * @return bool true if has alter database, False otherwise
1176
     */
1177
    public function hasAlterDatabase()
1178
    {
1179
        return $this->hasAlterDatabaseRename();
1180
    }
1181
1182
    /**
1183
     * Determines if it has alter database rename.
1184
     *
1185
     * @return bool true if has alter database rename, False otherwise
1186
     */
1187
    public function hasAlterDatabaseRename()
1188
    {
1189
        return true;
1190
    }
1191
1192
    /**
1193
     * Determines if it has database collation.
1194
     *
1195
     * @return bool true if has database collation, False otherwise
1196
     */
1197
    public function hasDatabaseCollation()
1198
    {
1199
        return true;
1200
    }
1201
1202
    /**
1203
     * Determines if it has magic types.
1204
     *
1205
     * @return bool true if has magic types, False otherwise
1206
     */
1207
    public function hasMagicTypes()
1208
    {
1209
        return true;
1210
    }
1211
1212
    /**
1213
     * Determines if it has query kill.
1214
     *
1215
     * @return bool true if has query kill, False otherwise
1216
     */
1217
    public function hasQueryKill()
1218
    {
1219
        return true;
1220
    }
1221
1222
    /**
1223
     * Determines if it has concurrent index build.
1224
     *
1225
     * @return bool true if has concurrent index build, False otherwise
1226
     */
1227
    public function hasConcurrentIndexBuild()
1228
    {
1229
        return true;
1230
    }
1231
1232
    /**
1233
     * Determines if it has force reindex.
1234
     *
1235
     * @return bool true if has force reindex, False otherwise
1236
     */
1237
    public function hasForceReindex()
1238
    {
1239
        return false;
1240
    }
1241
1242
    /**
1243
     * Determines if it has bytea hexadecimal default.
1244
     *
1245
     * @return bool true if has bytea hexadecimal default, False otherwise
1246
     */
1247
    public function hasByteaHexDefault()
1248
    {
1249
        return true;
1250
    }
1251
}
1252