Test Failed
Branch develop (db5506)
by Felipe
03:46
created

ADOdbBase::arrayClean()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace PHPPgAdmin\Database;
4
5
/*
6
 * Parent class of all ADODB objects.
7
 *
8
 * $Id: ADOdbBase.php,v 1.24 2008/02/20 20:43:10 ioguix Exp $
9
 */
10
11
class ADOdbBase
12
{
13
    use \PHPPgAdmin\HelperTrait;
14
15
    public $conn;
16
17
    // The backend platform.  Set to UNKNOWN by default.
18
    public $platform = 'UNKNOWN';
19
20
    /**
21
     * Base constructor
22
     *
23
     * @param &$conn The connection object
24
     */
25
    public function __construct(&$conn)
26
    {
27
        $this->prtrace('instanced connection class');
28
        $this->conn = $conn;
29
    }
30
31
    /**
32
     * Turns on or off query debugging
33
     *
34
     * @param $debug True to turn on debugging, false otherwise
35
     */
36
    public function setDebug($debug)
37
    {
38
        $this->conn->debug = $debug;
39
    }
40
41
    /**
42
     * Cleans (escapes) an array
43
     *
44
     * @param $arr The array to clean, by reference
45
     * @return The cleaned array
46
     */
47
    public function arrayClean(&$arr)
48
    {
49
        reset($arr);
50
        while (list($k, $v) = each($arr)) {
51
            $arr[$k] = addslashes($v);
52
        }
53
54
        return $arr;
55
    }
56
57
    /**
58
     * Executes a query on the underlying connection
59
     *
60
     * @param $sql The SQL query to execute
61
     * @return A recordset
62
     */
63
    public function execute($sql)
64
    {
65
        // Execute the statement
66
        $rs = $this->conn->Execute($sql);
67
68
        // If failure, return error value
69
        return $this->conn->ErrorNo();
70
    }
71
72
    /**
73
     * Closes the connection the database class
74
     * relies on.
75
     */
76
    public function close()
77
    {
78
        $this->conn->close();
79
    }
80
81
    /**
82
     * Retrieves a ResultSet from a query
83
     *
84
     * @param $sql The SQL statement to be executed
85
     * @return A recordset
86
     */
87
    public function selectSet($sql)
88
    {
89
        // Execute the statement
90
        $rs = $this->conn->Execute($sql);
91
92
        if (!$rs) {
93
            return $this->conn->ErrorNo();
94
        }
95
96
        return $rs;
97
    }
98
99
    /**
100
     * Retrieves a single value from a query
101
     *
102
     * @@ assumes that the query will return only one row - returns field value in the first row
103
     *
104
     * @param $sql   The SQL statement to be executed
105
     * @param $field The field name to be returned
106
     * @return A single field value
107
     * @return -1 No rows were found
108
     */
109
    public function selectField($sql, $field)
110
    {
111
        // Execute the statement
112
        $rs = $this->conn->Execute($sql);
113
114
        // If failure, or no rows returned, return error value
115
        if (!$rs) {
116
            return $this->conn->ErrorNo();
117
        }
118
119
        if ($rs->RecordCount() == 0) {
120
            return -1;
121
        }
122
123
        return $rs->fields[$field];
124
    }
125
126
    /**
127
     * Delete from the database
128
     *
129
     * @param        $table      The name of the table
130
     * @param        $conditions (array) A map of field names to conditions
131
     * @param string $schema     (optional) The table's schema
132
     * @return int 0 success
133
     */
134
    public function delete($table, $conditions, $schema = '')
135
    {
136
        $this->fieldClean($table);
137
138
        reset($conditions);
139
140
        if (!empty($schema)) {
141
            $this->fieldClean($schema);
142
            $schema = "\"{$schema}\".";
143
        }
144
145
        // Build clause
146
        $sql = '';
147
        while (list($key, $value) = each($conditions)) {
148
            $this->clean($key);
149
            $this->clean($value);
150
            if ($sql) {
151
                $sql .= " AND \"{$key}\"='{$value}'";
152
            } else {
153
                $sql = "DELETE FROM {$schema}\"{$table}\" WHERE \"{$key}\"='{$value}'";
154
            }
155
        }
156
157
        // Check for failures
158
        if (!$this->conn->Execute($sql)) {
159
            // Check for referential integrity failure
160
            if (stristr($this->conn->ErrorMsg(), 'referential')) {
161
                return -1;
162
            }
163
        }
164
165
        // Check for no rows modified
166
        if ($this->conn->Affected_Rows() == 0) {
167
            return -2;
168
        }
169
170
        return $this->conn->ErrorNo();
171
    }
172
173
    /**
174
     * Cleans (escapes) an object name (eg. table, field)
175
     *
176
     * @param $str The string to clean, by reference
177
     * @return The cleaned string
178
     */
179
    public function fieldClean(&$str)
180
    {
181
        $str = str_replace('"', '""', $str);
182
183
        return $str;
184
    }
185
186
    /**
187
     * Cleans (escapes) a string
188
     *
189
     * @param  string $str The string to clean, by reference
190
     * @return string The cleaned string
191
     */
192
    public function clean(&$str)
193
    {
194
        $str = addslashes($str);
195
196
        return $str;
197
    }
198
199
    /**
200
     * Insert a set of values into the database
201
     *
202
     * @param $table The table to insert into
203
     * @param $vars  (array) A mapping of the field names to the values to be inserted
204
     * @return int 0 success
205
     */
206
    public function insert($table, $vars)
207
    {
208
        $this->fieldClean($table);
209
210
        // Build clause
211
        if (sizeof($vars) > 0) {
212
            $fields = '';
213
            $values = '';
214
            foreach ($vars as $key => $value) {
215
                $this->clean($key);
216
                $this->clean($value);
217
218
                if ($fields) {
219
                    $fields .= ", \"{$key}\"";
220
                } else {
221
                    $fields = "INSERT INTO \"{$table}\" (\"{$key}\"";
222
                }
223
224
                if ($values) {
225
                    $values .= ", '{$value}'";
226
                } else {
227
                    $values = ") VALUES ('{$value}'";
228
                }
229
            }
230
            $sql = $fields . $values . ')';
231
        }
232
233
        // Check for failures
234 View Code Duplication
        if (!$this->conn->Execute($sql)) {
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...
235
            // Check for unique constraint failure
236
            if (stristr($this->conn->ErrorMsg(), 'unique')) {
237
                return -1;
238
            }
239
240
            if (stristr($this->conn->ErrorMsg(), 'referential')) {
241
                return -2;
242
            } // Check for referential integrity failure
243
        }
244
245
        return $this->conn->ErrorNo();
246
    }
247
248
    /**
249
     * Update a row in the database
250
     *
251
     * @param       $table The table that is to be updated
252
     * @param       $vars  (array) A mapping of the field names to the values to be updated
253
     * @param       $where (array) A mapping of field names to values for the where clause
254
     * @param array $nulls (array, optional) An array of fields to be set null
255
     * @return int 0 success
256
     */
257
    public function update($table, $vars, $where, $nulls = [])
258
    {
259
        $this->fieldClean($table);
260
261
        $setClause   = '';
262
        $whereClause = '';
263
264
        // Populate the syntax arrays
265
        reset($vars);
266 View Code Duplication
        while (list($key, $value) = each($vars)) {
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...
267
            $this->fieldClean($key);
268
            $this->clean($value);
269
            if ($setClause) {
270
                $setClause .= ", \"{$key}\"='{$value}'";
271
            } else {
272
                $setClause = "UPDATE \"{$table}\" SET \"{$key}\"='{$value}'";
273
            }
274
        }
275
276
        reset($nulls);
277
        while (list(, $value) = each($nulls)) {
278
            $this->fieldClean($value);
279
            if ($setClause) {
280
                $setClause .= ", \"{$value}\"=NULL";
281
            } else {
282
                $setClause = "UPDATE \"{$table}\" SET \"{$value}\"=NULL";
283
            }
284
        }
285
286
        reset($where);
287 View Code Duplication
        while (list($key, $value) = each($where)) {
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...
288
            $this->fieldClean($key);
289
            $this->clean($value);
290
            if ($whereClause) {
291
                $whereClause .= " AND \"{$key}\"='{$value}'";
292
            } else {
293
                $whereClause = " WHERE \"{$key}\"='{$value}'";
294
            }
295
        }
296
297
        // Check for failures
298 View Code Duplication
        if (!$this->conn->Execute($setClause . $whereClause)) {
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...
299
            // Check for unique constraint failure
300
            if (stristr($this->conn->ErrorMsg(), 'unique')) {
301
                return -1;
302
            }
303
304
            if (stristr($this->conn->ErrorMsg(), 'referential')) {
305
                return -2;
306
            } // Check for referential integrity failure
307
        }
308
309
        // Check for no rows modified
310
        if ($this->conn->Affected_Rows() == 0) {
311
            return -3;
312
        }
313
314
        return $this->conn->ErrorNo();
315
    }
316
317
    /**
318
     * Begin a transaction
319
     *
320
     * @return bool 0 success
321
     */
322
    public function beginTransaction()
323
    {
324
        return !$this->conn->BeginTrans();
325
    }
326
327
    /**
328
     * End a transaction
329
     *
330
     * @return bool 0 success
331
     */
332
    public function endTransaction()
333
    {
334
        return !$this->conn->CommitTrans();
335
    }
336
337
    /**
338
     * Roll back a transaction
339
     *
340
     * @return bool 0 success
341
     */
342
    public function rollbackTransaction()
343
    {
344
        return !$this->conn->RollbackTrans();
345
    }
346
347
    /**
348
     * Get the backend platform
349
     *
350
     * @return The backend platform
351
     */
352
    public function getPlatform()
353
    {
354
        //return $this->conn->platform;
355
        return 'UNKNOWN';
356
    }
357
358
    // Type conversion routines
359
360
    /**
361
     * Change the value of a parameter to database representation depending on whether it evaluates to true or false
362
     *
363
     * @param $parameter the parameter
364
     * @return \PHPPgAdmin\Database\the
365
     */
366
    public function dbBool(&$parameter)
367
    {
368
        return $parameter;
369
    }
370
371
    /**
372
     * Change a parameter from database representation to a boolean, (others evaluate to false)
373
     *
374
     * @param $parameter the parameter
375
     * @return \PHPPgAdmin\Database\the
376
     */
377
    public function phpBool($parameter)
378
    {
379
        return $parameter;
380
    }
381
382
    /**
383
     * Change a db array into a PHP array
384
     *
385
     * @param $dbarr
386
     * @return \PHPPgAdmin\Database\A PHP array
387
     * @internal param String $arr representing the DB array
388
     */
389
    public function phpArray($dbarr)
390
    {
391
        // Take off the first and last characters (the braces)
392
        $arr = substr($dbarr, 1, strlen($dbarr) - 2);
393
394
        // Pick out array entries by carefully parsing.  This is necessary in order
395
        // to cope with double quotes and commas, etc.
396
        $elements  = [];
397
        $i         = $j         = 0;
398
        $in_quotes = false;
399 View Code Duplication
        while ($i < strlen($arr)) {
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...
400
            // If current char is a double quote and it's not escaped, then
401
            // enter quoted bit
402
            $char = substr($arr, $i, 1);
403
            if ($char == '"' && ($i == 0 || substr($arr, $i - 1, 1) != '\\')) {
404
                $in_quotes = !$in_quotes;
405
            } elseif ($char == ',' && !$in_quotes) {
406
                // Add text so far to the array
407
                $elements[] = substr($arr, $j, $i - $j);
408
                $j          = $i + 1;
409
            }
410
            $i++;
411
        }
412
        // Add final text to the array
413
        $elements[] = substr($arr, $j);
414
415
        // Do one further loop over the elements array to remote double quoting
416
        // and escaping of double quotes and backslashes
417
        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...
418
            $v = $elements[$i];
419 View Code Duplication
            if (strpos($v, '"') === 0) {
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...
420
                $v            = substr($v, 1, strlen($v) - 2);
421
                $v            = str_replace('\\"', '"', $v);
422
                $v            = str_replace('\\\\', '\\', $v);
423
                $elements[$i] = $v;
424
            }
425
        }
426
427
        return $elements;
428
    }
429
}
430