diff options
Diffstat (limited to 'system/database/DB_driver.php')
-rw-r--r-- | system/database/DB_driver.php | 87 |
1 files changed, 58 insertions, 29 deletions
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index d63a1d955..e8286aaa1 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -51,6 +51,7 @@ abstract class CI_DB_driver { public $char_set = 'utf8'; public $dbcollat = 'utf8_general_ci'; public $autoinit = TRUE; // Whether to automatically initialize the DB + public $encrypt = FALSE; public $swap_pre = ''; public $port = ''; public $pconnect = FALSE; @@ -78,6 +79,10 @@ abstract class CI_DB_driver { protected $_protect_identifiers = TRUE; protected $_reserved_identifiers = array('*'); // Identifiers that should NOT be escaped + // clause and character used for LIKE escape sequences + protected $_like_escape_str = " ESCAPE '%s' "; + protected $_like_escape_chr = '!'; + /** * The syntax to count rows is slightly different across different * database engines, so this string appears in each driver and is @@ -305,8 +310,9 @@ abstract class CI_DB_driver { * FALSE upon failure, and if the $db_debug variable is set to TRUE * will raise an error. * - * @param string An SQL query string - * @param array An array of binding data + * @param string $sql + * @param array $binds = FALSE An array of binding data + * @param bool $return_object = NULL * @return mixed */ public function query($sql, $binds = FALSE, $return_object = NULL) @@ -509,6 +515,7 @@ abstract class CI_DB_driver { * If strict mode is disabled, each group is treated autonomously, meaning * a failure of one group will not affect any others * + * @param bool $mode = TRUE * @return void */ public function trans_strict($mode = TRUE) @@ -521,6 +528,7 @@ abstract class CI_DB_driver { /** * Start Transaction * + * @param bool $test_mode = FALSE * @return void */ public function trans_start($test_mode = FALSE) @@ -632,7 +640,7 @@ abstract class CI_DB_driver { // Make sure not to replace a chunk inside a string that happens to match the bind marker if ($c = preg_match_all("/'[^']*'/i", $sql, $matches)) { - $c = preg_match_all('/'.preg_quote($this->bind_marker).'/i', + $c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', str_replace($matches[0], str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]), $sql, $c), @@ -644,7 +652,7 @@ abstract class CI_DB_driver { return $sql; } } - elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker).'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) + elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker, '/').'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count) { return $sql; } @@ -669,7 +677,7 @@ abstract class CI_DB_driver { */ public function is_write_type($sql) { - return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql); + return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql); } // -------------------------------------------------------------------- @@ -805,6 +813,7 @@ abstract class CI_DB_driver { /** * Returns an array of table names * + * @param string $constrain_by_prefix = FALSE * @return array */ public function list_tables($constrain_by_prefix = FALSE) @@ -859,6 +868,7 @@ abstract class CI_DB_driver { /** * Determine if a particular table exists * + * @param string $table_name * @return bool */ public function table_exists($table_name) @@ -997,13 +1007,13 @@ abstract class CI_DB_driver { if (is_array($this->_escape_char)) { $preg_ec = array( - preg_quote($this->_escape_char[0]), preg_quote($this->_escape_char[1]), + preg_quote($this->_escape_char[0], '/'), preg_quote($this->_escape_char[1], '/'), $this->_escape_char[0], $this->_escape_char[1] ); } else { - $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char); + $preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char, '/'); $preg_ec[2] = $preg_ec[3] = $this->_escape_char; } } @@ -1119,30 +1129,19 @@ abstract class CI_DB_driver { * * @param string the table name * @param array the update data - * @param array the where clause - * @param array the orderby clause - * @param array the limit clause - * @param array the like clause * @return string */ - protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array()) + protected function _update($table, $values) { foreach ($values as $key => $val) { $valstr[] = $key.' = '.$val; } - $where = empty($where) ? '' : ' WHERE '.implode(' ', $where); - - if ( ! empty($like)) - { - $where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like); - } - return 'UPDATE '.$table.' SET '.implode(', ', $valstr) - .$where - .(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '') - .($limit ? ' LIMIT '.$limit : ''); + .$this->_compile_wh('qb_where') + .$this->_compile_order_by() + .($this->qb_limit ? ' LIMIT '.$this->qb_limit : ''); } // -------------------------------------------------------------------- @@ -1155,7 +1154,7 @@ abstract class CI_DB_driver { */ protected function _has_operator($str) { - return (bool) preg_match('/(\s|<|>|!|=|IS NULL|IS NOT NULL|BETWEEN)/i', trim($str)); + return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str)); } // -------------------------------------------------------------------- @@ -1168,8 +1167,30 @@ abstract class CI_DB_driver { */ protected function _get_operator($str) { - return preg_match('/(=|!|<|>| IS NULL| IS NOT NULL| BETWEEN)/i', $str, $match) - ? $match[1] : FALSE; + static $_operators; + + if (empty($_operators)) + { + $_les = ($this->_like_escape_str !== '') + ? '\s+'.preg_quote(trim(sprintf($this->_like_escape_str, $this->_like_escape_chr)), '/') + : ''; + $_operators = array( + '\s*(?:<|>|!)?=\s*', // =, <=, >=, != + '\s*<>?\s*', // <, <> + '\s*>\s*', // > + '\s+IS NULL', // IS NULL + '\s+IS NOT NULL', // IS NOT NULL + '\s+BETWEEN\s+\S+\s+AND\s+\S+', // BETWEEN value AND value + '\s+IN\s*\([^\)]+\)', // IN(list) + '\s+NOT IN\s*\([^\)]+\)', // NOT IN (list) + '\s+LIKE\s+\S+'.$_les, // LIKE 'expr'[ ESCAPE '%s'] + '\s+NOT LIKE\s+\S+'.$_les // NOT LIKE 'expr'[ ESCAPE '%s'] + ); + + } + + return preg_match('/'.implode('|', $_operators).'/i', $str, $match) + ? $match[0] : FALSE; } // -------------------------------------------------------------------- @@ -1177,8 +1198,8 @@ abstract class CI_DB_driver { /** * Enables a native PHP function to be run, using a platform agnostic wrapper. * - * @param string the function name - * @param mixed any parameters needed by the function + * @param string $function the function name + * @param mixed $param,... optional parameters needed by the function * @return mixed */ public function call_function($function) @@ -1242,6 +1263,8 @@ abstract class CI_DB_driver { /** * Delete the cache files associated with a particular URI * + * @param string $segment_one = '' + * @param string $segment_two = '' * @return bool */ public function cache_delete($segment_one = '', $segment_two = '') @@ -1343,7 +1366,7 @@ abstract class CI_DB_driver { } else { - $message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error; + $message = is_array($error) ? $error : array(str_replace('%s', $swap, $LANG->line($error))); } // Find the most likely culprit of the error by going through @@ -1352,7 +1375,13 @@ abstract class CI_DB_driver { $trace = debug_backtrace(); foreach ($trace as $call) { - if (isset($call['file']) && strpos($call['file'], BASEPATH.'database') === FALSE) + // We'll need this on Windows, as APPPATH and BASEPATH will always use forward slashes + if (DIRECTORY_SEPARATOR !== '/') + { + $call['file'] = str_replace('\\', '/', $call['file']); + } + + if (isset($call['file'], $call['class']) && strpos($call['file'], BASEPATH.'database') === FALSE && strpos($call['class'], 'Loader') !== FALSE) { // Found it - use a relative path for safety $message[] = 'Filename: '.str_replace(array(APPPATH, BASEPATH), '', $call['file']); |