diff options
author | Andrey Andreev <narf@bofh.bg> | 2012-04-06 20:26:09 +0200 |
---|---|---|
committer | Andrey Andreev <narf@bofh.bg> | 2012-04-06 20:26:09 +0200 |
commit | d65c3b5d057f4bc48e25cf3f968ceec844ebd155 (patch) | |
tree | 5636e0e5479f0ec71b4e3ef0b38496cc5acd0d0f /system/database/drivers/oci8/oci8_driver.php | |
parent | 2a23e4ad2b71f26262964ac49819ef0a7aebbb9a (diff) | |
parent | ea09a8a5552f2aacdeab0c88a605fe44047ebd0a (diff) |
Merge upstream branch
Diffstat (limited to 'system/database/drivers/oci8/oci8_driver.php')
-rw-r--r-- | system/database/drivers/oci8/oci8_driver.php | 305 |
1 files changed, 128 insertions, 177 deletions
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php index c9e791d63..6e225ee1f 100644 --- a/system/database/drivers/oci8/oci8_driver.php +++ b/system/database/drivers/oci8/oci8_driver.php @@ -46,7 +46,6 @@ * permit access to oracle databases * * @author Kelly McArdle - * */ class CI_DB_oci8_driver extends CI_DB { @@ -68,7 +67,7 @@ class CI_DB_oci8_driver extends CI_DB { protected $_random_keyword = ' ASC'; // not currently supported // Set "auto commit" by default - protected $_commit = OCI_COMMIT_ON_SUCCESS; + public $commit_mode = OCI_COMMIT_ON_SUCCESS; // need to track statement id and cursor id public $stmt_id; @@ -78,6 +77,85 @@ class CI_DB_oci8_driver extends CI_DB { // throw off num_fields later public $limit_used; + public function __construct($params) + { + parent::__construct($params); + + $valid_dsns = array( + 'tns' => '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS + // Easy Connect string (Oracle 10g+) + 'ec' => '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i', + 'in' => '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora) + ); + + /* Space characters don't have any effect when actually + * connecting, but can be a hassle while validating the DSN. + */ + $this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn); + + if ($this->dsn !== '') + { + foreach ($valid_dsns as $regexp) + { + if (preg_match($regexp, $this->dsn)) + { + return; + } + } + } + + // Legacy support for TNS in the hostname configuration field + $this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname); + if (preg_match($valid_dsns['tns'], $this->hostname)) + { + $this->dsn = $this->hostname; + return; + } + elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE + && (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== '')) + { + /* If the hostname field isn't empty, doesn't contain + * ':' and/or '/' and if port and/or database aren't + * empty, then the hostname field is most likely indeed + * just a hostname. Therefore we'll try and build an + * Easy Connect string from these 3 settings, assuming + * that the database field is a service name. + */ + $this->dsn = $this->hostname + .(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '') + .($this->database !== '' ? '/'.ltrim($this->database, '/') : ''); + + if (preg_match($valid_dsns['ec'], $this->dsn)) + { + return; + } + } + + /* At this point, we can only try and validate the hostname and + * database fields separately as DSNs. + */ + if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname)) + { + $this->dsn = $this->hostname; + return; + } + + $this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database); + foreach ($valid_dsns as $regexp) + { + if (preg_match($regexp, $this->database)) + { + return; + } + } + + /* Well - OK, an empty string should work as well. + * PHP will try to use environment variables to + * determine which Oracle instance to connect to. + */ + $this->dsn = ''; + } + /** * Non-persistent database connection * @@ -85,7 +163,9 @@ class CI_DB_oci8_driver extends CI_DB { */ public function db_connect() { - return @oci_connect($this->username, $this->password, $this->hostname, $this->char_set); + return ( ! empty($this->char_set)) + ? @oci_connect($this->username, $this->password, $this->dsn, $this->char_set) + : @oci_connect($this->username, $this->password, $this->dsn); } // -------------------------------------------------------------------- @@ -97,20 +177,9 @@ class CI_DB_oci8_driver extends CI_DB { */ public function db_pconnect() { - return @oci_pconnect($this->username, $this->password, $this->hostname, $this->char_set); - } - - // -------------------------------------------------------------------- - - /** - * Select the database - * - * @return resource - */ - public function db_select() - { - // Not in Oracle - schemas are actually usernames - return TRUE; + return ( ! empty($this->char_set)) + ? @oci_pconnect($this->username, $this->password, $this->dsn, $this->char_set) + : @oci_pconnect($this->username, $this->password, $this->dsn); } // -------------------------------------------------------------------- @@ -137,12 +206,13 @@ class CI_DB_oci8_driver extends CI_DB { */ protected function _execute($sql) { - // oracle must parse the query before it is run. All of the actions with - // the query are based on the statement id returned by ociparse + /* Oracle must parse the query before it is run. All of the actions with + * the query are based on the statement id returned by oci_parse(). + */ $this->stmt_id = FALSE; $this->_set_stmt_id($sql); oci_set_prefetch($this->stmt_id, 1000); - return @oci_execute($this->stmt_id, $this->_commit); + return @oci_execute($this->stmt_id, $this->commit_mode); } /** @@ -168,8 +238,7 @@ class CI_DB_oci8_driver extends CI_DB { */ public function get_cursor() { - $this->curs_id = oci_new_cursor($this->conn_id); - return $this->curs_id; + return $this->curs_id = oci_new_cursor($this->conn_id); } // -------------------------------------------------------------------- @@ -177,19 +246,19 @@ class CI_DB_oci8_driver extends CI_DB { /** * Stored Procedure. Executes a stored procedure * - * @param string package stored procedure is in - * @param string stored procedure to execute + * @param string package name in which the stored procedure is in + * @param string stored procedure name to execute * @param array parameters - * @return object + * @return mixed * * params array keys * * KEY OPTIONAL NOTES - * name no the name of the parameter should be in :<param_name> format - * value no the value of the parameter. If this is an OUT or IN OUT parameter, - * this should be a reference to a variable - * type yes the type of the parameter - * length yes the max size of the parameter + * name no the name of the parameter should be in :<param_name> format + * value no the value of the parameter. If this is an OUT or IN OUT parameter, + * this should be a reference to a variable + * type yes the type of the parameter + * length yes the max size of the parameter */ public function stored_procedure($package, $procedure, $params) { @@ -204,24 +273,24 @@ class CI_DB_oci8_driver extends CI_DB { } // build the query string - $sql = "begin $package.$procedure("; + $sql = 'BEGIN '.$package.'.'.$procedure.'('; $have_cursor = FALSE; foreach ($params as $param) { - $sql .= $param['name'] . ","; + $sql .= $param['name'].','; - if (array_key_exists('type', $param) && ($param['type'] === OCI_B_CURSOR)) + if (isset($param['type']) && $param['type'] === OCI_B_CURSOR) { $have_cursor = TRUE; } } - $sql = trim($sql, ",") . "); end;"; + $sql = trim($sql, ',') . '); END;'; $this->stmt_id = FALSE; $this->_set_stmt_id($sql); $this->_bind_params($params); - $this->query($sql, FALSE, $have_cursor); + return $this->query($sql, FALSE, $have_cursor); } // -------------------------------------------------------------------- @@ -277,7 +346,7 @@ class CI_DB_oci8_driver extends CI_DB { // even if the queries produce a successful result. $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; - $this->_commit = OCI_DEFAULT; + $this->commit_mode = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT; return TRUE; } @@ -301,9 +370,8 @@ class CI_DB_oci8_driver extends CI_DB { return TRUE; } - $ret = oci_commit($this->conn_id); - $this->_commit = OCI_COMMIT_ON_SUCCESS; - return $ret; + $this->commit_mode = OCI_COMMIT_ON_SUCCESS; + return oci_commit($this->conn_id); } // -------------------------------------------------------------------- @@ -315,20 +383,14 @@ class CI_DB_oci8_driver extends CI_DB { */ public function trans_rollback() { - if ( ! $this->trans_enabled) - { - return TRUE; - } - // When transactions are nested we only begin/commit/rollback the outermost ones - if ($this->_trans_depth > 0) + if ( ! $this->trans_enabled OR $this->_trans_depth > 0) { return TRUE; } - $ret = oci_rollback($this->conn_id); - $this->_commit = OCI_COMMIT_ON_SUCCESS; - return $ret; + $this->commit_mode = OCI_COMMIT_ON_SUCCESS; + return oci_rollback($this->conn_id); } // -------------------------------------------------------------------- @@ -399,7 +461,7 @@ class CI_DB_oci8_driver extends CI_DB { * the specified database * * @param string - * @return string + * @return int */ public function count_all($table = '') { @@ -431,11 +493,11 @@ class CI_DB_oci8_driver extends CI_DB { */ protected function _list_tables($prefix_limit = FALSE) { - $sql = "SELECT TABLE_NAME FROM ALL_TABLES"; + $sql = 'SELECT TABLE_NAME FROM ALL_TABLES'; - if ($prefix_limit !== FALSE AND $this->dbprefix != '') + if ($prefix_limit !== FALSE && $this->dbprefix != '') { - $sql .= " WHERE TABLE_NAME LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr); + return $sql." WHERE TABLE_NAME LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr); } return $sql; @@ -453,7 +515,7 @@ class CI_DB_oci8_driver extends CI_DB { */ protected function _list_columns($table = '') { - return "SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '$table'"; + return 'SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = \''.$table.'\''; } // -------------------------------------------------------------------- @@ -468,7 +530,7 @@ class CI_DB_oci8_driver extends CI_DB { */ protected function _field_data($table) { - return "SELECT * FROM ".$table." where rownum = 1"; + return 'SELECT * FROM '.$table.' WHERE rownum = 1'; } // -------------------------------------------------------------------- @@ -505,47 +567,6 @@ class CI_DB_oci8_driver extends CI_DB { // -------------------------------------------------------------------- /** - * Escape the SQL Identifiers - * - * This function escapes column and table names - * - * @param string - * @return string - */ - public function _escape_identifiers($item) - { - if ($this->_escape_char == '') - { - return $item; - } - - foreach ($this->_reserved_identifiers as $id) - { - if (strpos($item, '.'.$id) !== FALSE) - { - $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item); - - // remove duplicates if the user already included the escape - return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str); - } - } - - if (strpos($item, '.') !== FALSE) - { - $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char; - } - else - { - $str = $this->_escape_char.$item.$this->_escape_char; - } - - // remove duplicates if the user already included the escape - return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str); - } - - // -------------------------------------------------------------------- - - /** * From Tables * * This function implicitly groups FROM tables so there is no confusion @@ -556,29 +577,7 @@ class CI_DB_oci8_driver extends CI_DB { */ protected function _from_tables($tables) { - if ( ! is_array($tables)) - { - $tables = array($tables); - } - - return implode(', ', $tables); - } - - // -------------------------------------------------------------------- - - /** - * Insert statement - * - * Generates a platform-specific insert string from the supplied data - * - * @param string the table name - * @param array the insert keys - * @param array the insert values - * @return string - */ - protected function _insert($table, $keys, $values) - { - return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + return is_array($tables) ? implode(', ', $tables) : $tables; } // -------------------------------------------------------------------- @@ -600,46 +599,10 @@ class CI_DB_oci8_driver extends CI_DB { for ($i = 0, $c = count($values); $i < $c; $i++) { - $sql .= ' INTO ' . $table . ' (' . $keys . ') VALUES ' . $values[$i] . "\n"; + $sql .= ' INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n"; } - $sql .= 'SELECT * FROM dual'; - - return $sql; - } - - // -------------------------------------------------------------------- - - /** - * Update statement - * - * Generates a platform-specific update string from the supplied data - * - * @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 - * @return string - */ - protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE) - { - foreach ($values as $key => $val) - { - $valstr[] = $key." = ".$val; - } - - $limit = ( ! $limit) ? '' : ' LIMIT '.$limit; - - $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):''; - - $sql = "UPDATE ".$table." SET ".implode(', ', $valstr); - - $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : ''; - - $sql .= $orderby.$limit; - - return $sql; + return $sql.'SELECT * FROM dual'; } // -------------------------------------------------------------------- @@ -648,15 +611,16 @@ class CI_DB_oci8_driver extends CI_DB { * Truncate statement * * Generates a platform-specific truncate string from the supplied data - * If the database does not support the truncate() command - * This function maps to "DELETE FROM table" + * + * If the database does not support the truncate() command, + * then this method maps to 'DELETE FROM table' * * @param string the table name * @return string */ protected function _truncate($table) { - return "TRUNCATE TABLE ".$table; + return 'TRUNCATE TABLE '.$table; } // -------------------------------------------------------------------- @@ -674,22 +638,18 @@ class CI_DB_oci8_driver extends CI_DB { protected function _delete($table, $where = array(), $like = array(), $limit = FALSE) { $conditions = ''; - if (count($where) > 0 OR count($like) > 0) { - $conditions = "\nWHERE "; - $conditions .= implode("\n", $this->ar_where); + $conditions = "\nWHERE ".implode("\n", $this->ar_where); if (count($where) > 0 && count($like) > 0) { - $conditions .= " AND "; + $conditions .= ' AND '; } $conditions .= implode("\n", $like); } - $limit = ( ! $limit) ? '' : ' LIMIT '.$limit; - - return "DELETE FROM ".$table.$conditions.$limit; + return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit); } // -------------------------------------------------------------------- @@ -706,18 +666,9 @@ class CI_DB_oci8_driver extends CI_DB { */ protected function _limit($sql, $limit, $offset) { - $limit = $offset + $limit; - $newsql = "SELECT * FROM (select inner_query.*, rownum rnum FROM ($sql) inner_query WHERE rownum < $limit)"; - - if ($offset != 0) - { - $newsql .= " WHERE rnum >= $offset"; - } - - // remember that we used limits $this->limit_used = TRUE; - - return $newsql; + return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($offset + $limit).')' + .($offset != 0 ? ' WHERE rnum >= '.$offset : ''); } // -------------------------------------------------------------------- |