Test Failed
Push — master ( a34e3e...fe03e3 )
by Adam
06:56
created

Database::serverVersion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
namespace DBAL;
3
4
use PDO;
5
use DBAL\Modifiers\SafeString;
6
use DBAL\Modifiers\Operators;
7
8
/**
9
 * PDO Database connection class
10
 *
11
 * @author Adam Binnersley <[email protected]>
12
 * @version PDO Database Class
13
 */
14
final class Database implements DBInterface{
0 ignored issues
show
Bug introduced by
There is one abstract method fulltextIndex in this class; you could implement it, or declare this class as abstract.
Loading history...
15
    protected $db;
16
    public $sql;
17
    private $key;
18
    
19
    protected $logLocation;
20
    public $logErrors = true;
21
    public $logQueries = false;
22
    public $displayErrors = false;
23
    
24
    protected $database;
25
    protected $cacheEnabled = false;
26
    protected $cacheObj;
27
    protected $cacheValue;
28
    protected $modified = false;
29
30
    private $query;
31
    private $values = [];
32
    private $prepare = [];
33
    
34
    private static $connectors = array(
35
        'cubrid' => 'cubrid:host=%s;port=%d;dbname=%s',
36
        'dblib' => 'dblib:host=%s:%d;dbname=%s',
37
        'mssql' => 'sqlsrv:Server=%s,%d;Database=%s',
38
        'mysql' => 'mysql:host=%s;port=%d;dbname=%s',
39
        'pgsql' => 'pgsql:host=%s;port=%d;dbname=%s',
40
        'sqlite' => 'sqlite::memory:'
41
    );
42
43
    /**
44
     * Connect to database using PDO connection
45
     * @param string $hostname This should be the host of the database e.g. 'localhost'
46
     * @param string $username This should be the username for the chosen database
47
     * @param string $password This should be the password for the chosen database 
48
     * @param string $database This should be the database that you wish to connect to
49
     * @param string|false $backuphost If you have a replication server set up put the hostname or IP address incase the primary server goes down
50
     * @param object|false $cache If you want to cache the queries with Memcache(d)/Redis/APC/Xcache This should be the object else set to false
51
     * @param boolean $persistent If you want a persistent database connection set to true
52
     * @param string $type The type of connection that you wish to make can be 'mysql', 'cubrid', 'dblib', 'mssql', 'odbc', 'pgsql, or 'sqlite'
53
     * @param int $port This should be the port number of the MySQL database connection
54
     */
55 1
    public function __construct($hostname, $username, $password, $database, $backuphost = false, $cache = false, $persistent = false, $type = 'mysql', $port = 3306) {
56 1
        $this->setLogLocation();
57
        try{
58 1
            $this->connectToServer($username, $password, $database, $hostname, $persistent, $type, $port);
59
        }
60 1
        catch(\Exception $e) {
61 1
            if($backuphost !== false) {
62
                $this->connectToServer($username, $password, $database, $backuphost, $persistent, $type, $port);
63
            }
64 1
            $this->error($e);
65
        }
66 1
        if(is_object($cache)) {
67
            $this->setCaching($cache);
68
        }
69 1
    }
70
    
71
    /**
72
     * Closes the PDO database connection when Database object unset
73
     */
74
    public function __destruct() {
75
        $this->closeDatabase();
76
    }
77
    
78
    /**
79
     * Connect to the database using PDO connection
80
     * @param string $username This should be the username for the chosen database
81
     * @param string $password This should be the password for the chosen database 
82
     * @param string $database This should be the database that you wish to connect to
83
     * @param string $hostname The hostname for the database
84
     * @param boolean $persistent If you want a persistent database connection set to true
85
     * @param string $type The type of connection that you wish to make can be 'mysql', 'cubrid', 'dblib', 'mssql', 'pgsql, or 'sqlite'
86
     * @param int $port The port number to connect to the MySQL server
87
     */
88 2
    protected function connectToServer($username, $password, $database, $hostname, $persistent = false, $type = 'mysql', $port = 3306) {
89 2
        if(!$this->db) {
90 2
            $this->database = $database;
91 2
            $this->db = new PDO(sprintf(self::$connectors[$type], $hostname, $port, $database), $username, $password,
92 2
                array_merge(
93 2
                    ($persistent !== false ? array(PDO::ATTR_PERSISTENT => true) : array()),
94 2
                    ($type === 'mysql' ? array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true, PDO::ATTR_EMULATE_PREPARES => true) : array())
95
                )
96
            );
97 2
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
98
        }
99 2
    }
100
    
101
    /**
102
     * Enables the caching and set the caching object to the one provided
103
     * @param object $caching This should be class of the type of caching you are using
104
     */
105
    public function setCaching($caching) {
106
        if(is_object($caching)) {
107
            $this->cacheObj = $caching;
108
            $this->cacheEnabled = true;
109
        }
110
        return $this;
111
    }
112
    
113
    /**
114
     * This query function is used for more advanced SQL queries for which non of the other methods fit
115
     * @param string $sql This should be the SQL query which you wish to run
116
     * @param array $variables This should be an array of values to execute as the values in a prepared statement
117
     * @return array Returns array of results for the query that has just been run
118 1
     */
119
    public function query($sql, $variables = array(), $cache = true) {
120 1
        try{
121 1
            $this->sql = $sql;
122 1
            $this->query = $this->db->prepare($this->sql);
123 1
            $this->query->execute($variables);
124 1
            if(strpos($this->sql, 'SELECT') !== false) {
125
                return $this->query->fetchAll(PDO::FETCH_ASSOC);
126
            }
127
        }
128
        catch(\Exception $e) {
129
            $this->error($e);
130 1
        }
131
    }
132
    
133
    /**
134
     * Returns a single record for a select query for the chosen table
135
     * @param string $table This should be the table you wish to select the values from
136
     * @param array $where Should be the field names and values you wish to use as the where query e.g. array('fieldname' => 'value', 'fieldname2' => 'value2', etc).
137
     * @param string|array $fields This should be the records you wis to select from the table. It should be either set as '*' which is the default or set as an array in the following format array('field', 'field2', 'field3', etc).
138
     * @param array|string $order This is the order you wish the results to be ordered in should be formatted as follows array('fieldname' => 'ASC') or array("'fieldname', 'fieldname2'" => 'DESC')
139
     * @param boolean $cache If the query should be cached or loaded from cache set to true else set to false
140
     * @return array Returns a single table record as the standard array when running SQL queries
141 1
     */
142 1
    public function select($table, $where = array(), $fields = '*', $order = array(), $cache = true) {
143
        return $this->selectAll($table, $where, $fields, $order, 1, $cache);
0 ignored issues
show
Bug introduced by
It seems like $order defined by parameter $order on line 142 can also be of type string; however, DBAL\Database::selectAll() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
144
    }
145
    
146
    /**
147
     * Returns a multidimensional array of the results from the selected table given the given parameters
148
     * @param string $table This should be the table you wish to select the values from
149
     * @param array $where Should be the field names and values you wish to use as the where query e.g. array('fieldname' => 'value', 'fieldname2' => 'value2', etc).
150
     * @param string|array $fields This should be the records you wis to select from the table. It should be either set as '*' which is the default or set as an array in the following format array('field', 'field2', 'field3', etc).
151
     * @param array $order This is the order you wish the results to be ordered in should be formatted as follows array('fieldname' => 'ASC') or array("'fieldname', 'fieldname2'" => 'DESC')
152
     * @param integer|array $limit The number of results you want to return 0 is default and returns all results, else should be formated either as a standard integer or as an array as the start and end values e.g. array(0 => 150)
153
     * @param boolean $cache If the query should be cached or loaded from cache set to true else set to false
154
     * @return array Returns a multidimensional array with the chosen fields from the table
155 3
     */
156 3
    public function selectAll($table, $where = array(), $fields = '*', $order = array(), $limit = 0, $cache = true) {        
157 3
        $this->buildSelectQuery(SafeString::makeSafe($table), $where, $fields, $order, $limit);
158 3
        $result = $this->executeQuery($cache);
159 3
        if(!$result) {
160 2
            if($limit === 1) {$result = $this->query->fetch(PDO::FETCH_ASSOC);} // Reduce the memory usage if only one record and increase performance
161 3
            else{$result = $this->query->fetchAll(PDO::FETCH_ASSOC);}
162
            if($cache && $this->cacheEnabled) {$this->setCache($this->key, $result);}
163 3
        }
164
        return $result ? $result : false;
165
    }
166
    
167
    /**
168
     * Returns a single column value for a given query
169
     * @param string $table This should be the table you wish to select the values from
170
     * @param array $where Should be the field names and values you wish to use as the where query e.g. array('fieldname' => 'value', 'fieldname2' => 'value2', etc).
171
     * @param array $fields This should be the records you wis to select from the table. It should be either set as '*' which is the default or set as an array in the following format array('field', 'field2', 'field3', etc).
172
     * @param int $colNum This should be the column number you wish to get (starts at 0)
173
     * @param array $order This is the order you wish the results to be ordered in should be formatted as follows array('fieldname' => 'ASC') or array("'fieldname', 'fieldname2'" => 'DESC') so it can be done in both directions
174
     * @param boolean $cache If the query should be cached or loaded from cache set to true else set to false
175
     * @return mixed If a result is found will return the value of the colum given else will return false
176
     */
177
    public function fetchColumn($table, $where = array(), $fields = '*', $colNum = 0, $order = array(), $cache = true) {
178
        $this->buildSelectQuery(SafeString::makeSafe($table), $where, $fields, $order, 1);
179
        $result = $this->executeQuery($cache);
180
        if(!$result) {
181
            $result = $this->query->fetchColumn(intval($colNum));
182
            if($cache && $this->cacheEnabled) {$this->setCache($this->key, $result);}
183
        }
184
        return $result;
185
    }
186
    
187
    /**
188
     * Inserts into database using the prepared PDO statements 
189
     * @param string $table This should be the table you wish to insert the values into
190
     * @param array $records This should be the field names and values in the format of array('fieldname' => 'value', 'fieldname2' => 'value2', etc.)
191
     * @return boolean If data is inserted returns true else returns false
192 2
     */
193 2
    public function insert($table, $records) {
194
        unset($this->prepare);
195 2
        
196 2
        $this->sql = sprintf("INSERT INTO `%s` (%s) VALUES (%s);", SafeString::makeSafe($table), $this->fields($records, true), implode(', ', $this->prepare));
197 2
        $this->executeQuery(false);
198
        return $this->numRows() ? true : false;
199
    }
200
    
201
    /**
202
     * Updates values in a database using the provide variables
203
     * @param string $table This should be the table you wish to update the values for
204
     * @param array $records This should be the field names and new values in the format of array('fieldname' => 'newvalue', 'fieldname2' => 'newvalue2', etc.)
205
     * @param array $where Should be the field names and values you wish to update in the form of an array e.g. array('fieldname' => 'value', 'fieldname2' => 'value2', etc).
206
     * @param int $limit The number of results you want to return 0 is default and will update all results that match the query, else should be formated as a standard integer
207
     * @return boolean Returns true if update is successful else returns false
208 2
     */
209 2
    public function update($table, $records, $where = array(), $limit = 0) {
210 2
        $this->sql = sprintf("UPDATE `%s` SET %s %s%s;", SafeString::makeSafe($table), $this->fields($records), $this->where($where), $this->limit($limit));
211 2
        $this->executeQuery(false);
212
        return $this->numRows() ? true : false;
213
    }
214
    
215
    /**
216
     * Deletes records from the given table based on the variables given
217
     * @param string $table This should be the table you wish to delete the records from
218
     * @param array $where This should be an array of for the where statement
219
     * @param int $limit The number of results you want to return 0 is default and will delete all results that match the query, else should be formated as a standard integer
220 2
     */
221 2
    public function delete($table, $where, $limit = 0) {
222 2
        $this->sql = sprintf("DELETE FROM `%s` %s%s;", SafeString::makeSafe($table), $this->where($where), $this->limit($limit));
223 2
        $this->executeQuery(false);
224
        return $this->numRows() ? true : false;
225
    }
226
    
227
    /**
228
     * Count the number of return results 
229
     * @param string $table The table you wish to count the result of 
230
     * @param array $where Should be the field names and values you wish to use as the where query e.g. array('fieldname' => 'value', 'fieldname2' => 'value2', etc).
231
     * @param boolean $cache If the query should be cached or loaded from cache set to true else set to false
232
     * @return int Returns the number of results
233 1
     */
234 1
    public function count($table, $where = array(), $cache = true) {
235 1
        $this->sql = sprintf("SELECT count(*) FROM `%s`%s;", SafeString::makeSafe($table), $this->where($where));
236
        $this->key = md5($this->database.$this->sql.serialize($this->values));
237 1
        
238 1
        $result = $this->executeQuery($cache);
239 1
        if(!$result) {
240 1
            $result = $this->query->fetchColumn();
241
            if($cache && $this->cacheEnabled) {$this->setCache($this->key, $result);}
242 1
        }
243
        return $result;
244
    }
245
    
246
    /**
247
     * Truncates a given table from the selected database so there are no values in the table
248
     * @param string $table This should be the table you wish to truncate
249
     * @return boolean If the table is emptied returns true else returns false
250
     */
251
    public function truncate($table) {
252
        try{
253
            $this->sql = sprintf("TRUNCATE TABLE `%s`", SafeString::makeSafe($table));
254
            $this->query = $this->db->exec($this->sql);
255
        }
256
        catch(\Exception $e) {
257
            $this->error($e);
258
        }
259
        return $this->query ? true : false;
260
    }
261
    
262
    /**
263
     * Returns the number of rows for the last query sent
264
     * @return int Returns the number of rows for the last query
265 7
     */
266 7
    public function numRows() {
267 7
        if(isset($this->query)) {
268
            return $this->query->rowCount();
269
        }
270
        return 0;
271
    }
272
    
273
    /**
274
     * Returns the number of rows for the last query sent (Looks a the numRows() function just added incase of habbit)
275
     * @return int Returns the number of rows for the last query
276 1
     */
277 1
    public function rowCount() {
278
        return $this->numRows();
279
    }
280
    
281
    /**
282
     * Returns the ID of the last record last inserted 
283
     * @param string $name This should be the name of the sequence object you wish to retrieve
284
     * @return int|string Returns the last inserted ID of the last insert item if $name is null else returns string with sequenced object
285 1
     */
286 1
    public function lastInsertId($name = null) {
287
        return $this->db->lastInsertId($name);
288
    }
289
    
290
    /**
291
     * Checks to see if a connection has been made to the server
292
     * @return boolean
293
     */
294
    public function isConnected() {
295
        return is_object($this->db) ? true : false;
296
    }
297
    
298
    /**
299
     * Returns the server version information
300
     */
301
    public function serverVersion() {
302
        return $this->db->getAttribute(PDO::ATTR_SERVER_VERSION);
303
    }
304
    
305
    /**
306
     * Sets the location of the log files
307
     * @param string $location This should be where you wish the logs to be stored
308
     * @return $this
309
     */
310
    public function setLogLocation($location = false) {
311
        if($location === false) {
312
            $location = dirname(__FILE__).DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR;
313
        }
314
        $this->logLocation = $location;
315
        if (!file_exists($location)) {
316
            mkdir($location, 0777, true);
317
        }
318
        return $this;
319
    }
320
    
321
    /**
322 2
     * Displays the error massage which occurs
323 2
     * @param \Exception $error This should be an instance of Exception
324
     */
325
    private function error($error) {
326
        if($this->logErrors) {
327
            $file = $this->logLocation.'db-errors.txt';
328
            $current = file_get_contents($file);
329
            $current .= date('d/m/Y H:i:s')." ERROR: ".$error->getMessage()." on ".$this->sql."\n";
330
            file_put_contents($file, $current);
331
        }
332
        if($this->displayErrors) {
333
            die('ERROR: '.$error->getMessage().' on '.$this->sql);
334
        }
335
    }
336
    
337
    /**
338
     * Writes all queries to a log file
339
     */
340
    public function writeQueryToLog() {
341
        $file = $this->logLocation.'queries.txt';
342
        $current = file_get_contents($file);
343
        $current .= "SQL: ".$this->sql.":".serialize($this->values)."\n";
344
        file_put_contents($file, $current);
345
    }
346
    
347
    /**
348
     * Closes the PDO database connection by setting the connection to NULL 
349
     */
350
    public function closeDatabase() {
351
        $this->db = null;
352
    }
353 1
    
354 1
    /**
355 1
     * Build the SQL query but doesn't execute it
356 1
     * @param string $table This should be the table you wish to select the values from
357 1
     * @param array $where Should be the field names and values you wish to use as the where query e.g. array('fieldname' => 'value', 'fieldname2' => 'value2', etc).
358 1
     * @param string|array $fields This should be the records you wis to select from the table. It should be either set as '*' which is the default or set as an array in the following format array('field', 'field2', 'field3', etc).
359
     * @param array $order This is the order you wish the results to be ordered in should be formatted as follows array('fieldname' => 'ASC') or array("'fieldname', 'fieldname2'" => 'DESC') so it can be done in both directions
360 1
     * @param integer|array $limit The number of results you want to return 0 is default and returns all results, else should be formated either as a standard integer or as an array as the start and end values e.g. array(0 => 150)
361
     */
362
    protected function buildSelectQuery($table, $where = array(), $fields = '*', $order = array(), $limit = 0) {
363 1
        if(is_array($fields)) {
364
            $selectfields = array();
365
            foreach($fields as $field => $value) {
366
                $selectfields[] = sprintf("`%s`", SafeString::makeSafe($value));
367
            }
368
            $fieldList = implode(', ', $selectfields);
369
        }
370
        else{$fieldList = '*';}
371
        
372
        $this->sql = sprintf("SELECT %s FROM `%s`%s%s%s;", $fieldList, SafeString::makeSafe($table), $this->where($where), $this->orderBy($order), $this->limit($limit));
373
        $this->key = md5($this->database.$this->sql.serialize($this->values));
374
    }
375
    
376
    /**
377
     * Execute the current query if no cache value is available
378
     * @param boolean $cache If the cache should be checked for the checked for the values of the query set to true else set to false 
379
     * @return mixed If a cached value exists will be returned else if cache is not checked and query is executed will not return anything
380
     */
381
    protected function executeQuery($cache = true) {
382
        if($this->logQueries) {$this->writeQueryToLog();}
383
        if($cache && $this->cacheEnabled && $this->getCache($this->key)) {
384
            return $this->cacheValue;
385
        }
386
        try{
387
            $this->query = $this->db->prepare($this->sql);
388
            $this->bindValues($this->values);
389
            $this->query->execute();
390 3
            unset($this->values);
391 3
            $this->values = [];
392
        }
393
        catch(\Exception $e) {
394
            $this->error($e);
395
        }
396
}
397
	
398 3
    /**
399
     * This outputs the SQL where query based on a given array
400 3
     * @param array $where This should be an array that you wish to create the where query for in the for array('field1' => 'test') or array('field1' => array('>=', 0))
401 3
     * @return string|false If the where query is an array will return the where string and set the values else returns false if no array sent
402 3
     */
403
    private function where($where) {
404
        if(is_array($where) && !empty($where)) {
405
            $wherefields = array();
406
            foreach($where as $field => $value) {
407
                $wherefields[] = $this->formatValues($field, $value);
408
            }
409 10
            if(!empty($wherefields)) {
410 10
                return " WHERE ".implode(' AND ', $wherefields);
411 10
            }
412
        }
413
        return false;
414
    }
415 10
    
416 10
    /**
417 10
     * Sets the order sting for the SQL query based on an array or string
418 9
     * @param array|string $order This should be either set to array('fieldname' => 'ASC/DESC') or RAND()
419 9
     * @return string|false If the SQL query has an valid order by will return a string else returns false
420
     */
421 2
    private function orderBy($order) {
422 2
        if(is_array($order) && !empty(array_filter($order))) {
423
            $string = array();
424 10
            foreach($order as $fieldorder => $fieldvalue) {
425
                if(!empty($fieldorder) && !empty($fieldvalue)) {
426
                    $string[] = sprintf("`%s` %s", SafeString::makeSafe($fieldorder), strtoupper(SafeString::makeSafe($fieldvalue)));
427
                }
428
                elseif($fieldvalue === 'RAND()') {
429
                    $string[] = $fieldvalue;
430
                }
431
            }
432
            return sprintf(" ORDER BY %s", implode(", ", $string));
433
        }
434
        elseif($order == 'RAND()') {
435
            return " ORDER BY RAND()";
436
        }
437
        return false;
438
    }
439
    
440
    /**
441
     * Build the field list for the query
442
     * @param array $records This should be an array listing all of the fields
443
     * @param boolean $insert If this is an insert statement should be set to true to create the correct amount of queries for the prepared statement
444
     * @return string The fields list will be returned as a string to insert into the SQL query
445
     */
446
    private function fields($records, $insert = false) {
447
        $fields = array();
448
        
449 1
        foreach($records as $field => $value) {
450 1
            if($insert === true) {
451 1
                $fields[] = sprintf("`%s`", SafeString::makeSafe($field));
452 1
                $this->prepare[] = '?';
453 1
            }
454 1
            else{
455
                $fields[] = sprintf("`%s` = ?", SafeString::makeSafe($field));
456
            }
457 1
            $this->values[] = $value;
458
        }
459
        return implode(', ', $fields);
460 1
    }
461
    
462
    /**
463
     * Returns the limit SQL for the current query as a string
464
     * @param integer|array $limit This should either be set as an integer or should be set as an array with a start and end value  
465
     * @return string|false Will return the LIMIT string for the current query if it is valid else returns false
466
     */
467
    private function limit($limit = 0) {
468
        if(is_array($limit) && !empty(array_filter($limit))) {
469
            foreach($limit as $start => $end) {
470
                 return " LIMIT ".intval($start).", ".intval($end);
471
            }
472
        }
473
        elseif((int)$limit > 0) {
474
            return " LIMIT ".intval($limit);
475
        }
476
        return false;
477
    }
478
    
479
    
480
    /**
481
     * Set the cache with a key and value
482
     * @param string $key The unique key to store the value against
483
     * @param mixed $value The value of the MYSQL query 
484
     */
485
    public function setCache($key, $value) {
486
        if($this->cacheEnabled) {
487
            $this->cacheObj->save($key, $value);
488
        }
489
    }
490
    
491
    /**
492
     * Get the results for a given key
493
     * @param string $key The unique key to check for stored variables
494
     * @return mixed Returned the cached results from
495 1
     */
496 1
    public function getCache($key) {
497
        if($this->modified === true || !$this->cacheEnabled) {return false;}
498
        else{
499
            $this->cacheValue = $this->cacheObj->fetch($key);
500
            return $this->cacheValue;
501 1
        }
502 1
    }
503
    
504 1
    /**
505
     * Clears the cache
506
     */
507
    public function flushDB() {
508
        $this->cacheObj->deleteAll();
509
    }
510
    
511
    /**
512
     * Format the where queries and set the prepared values
513
     * @param string $field This should be the field name in the database
514
     * @param mixed $value This should be the value which should either be a string or an array if it contains an operator
515
     * @return string This should be the string to add to the SQL query
516
     */
517
    protected function formatValues($field, $value) {
518
        if(!is_array($value) && Operators::isOperatorValid($value) && !Operators::isOperatorPrepared($value)) {
519
            return sprintf("`%s` %s", SafeString::makeSafe($field), Operators::getOperatorFormat($value));
520
        }
521
        elseif(is_array($value)) {
522
            if(!is_array(array_values($value)[0])) {
523
                $this->values[] = (isset($value[1]) ? $value[1] : array_values($value)[0]);
524
                $operator = (isset($value[0]) ? $value[0] : key($value));
525
            }
526
            else{
527
                foreach(array_values($value)[0] as $op => $array_value) {
528
                    $this->values[] = $array_value;
529
                }
530
                $operator = key($value);
531
            }
532
            return sprintf("`%s` %s", SafeString::makeSafe($field), Operators::getOperatorFormat($operator));
533
            
534
        }
535
        $this->values[] = $value;
536
        return sprintf("`%s` = ?", SafeString::makeSafe($field));
537
    }
538
    
539
    /**
540
     * Band values to use in the query
541
     * @param array $values This should be the values being used in the query
542
     */
543
    protected function bindValues($values) {
544
        if(is_array($values)) {
545 2
            foreach($values as $i => $value) {
546 2
                if(is_numeric($value) && intval($value) == $value) {$type = PDO::PARAM_INT; $value = intval($value);}
547
                elseif(is_null($value) || $value === 'NULL') {$type = PDO::PARAM_NULL; $value = NULL;}
548
                elseif(is_bool($value)) {$type = PDO::PARAM_BOOL;}
549 2
                else{$type = PDO::PARAM_STR;}
550 2
                $this->query->bindValue(intval($i + 1), $value, $type);
551 2
            }
552 2
        }
553
    }
554
}
555