summaryrefslogtreecommitdiffstats
path: root/system/database/drivers/oci8
diff options
context:
space:
mode:
authorAndrey Andreev <narf@bofh.bg>2012-01-05 19:40:15 +0100
committerAndrey Andreev <narf@bofh.bg>2012-01-05 19:40:15 +0100
commit24abcb98d4281dcf857cb08a86a58af286a2f94a (patch)
tree275449fd18c03c7b4bac72f4490a05e1152a5a7b /system/database/drivers/oci8
parent43fcdbcac05a0cdc5c2a77c79c641849c41caa9e (diff)
Numerous improvements to the Oracle (oci8) driver and DB_driver
Diffstat (limited to 'system/database/drivers/oci8')
-rw-r--r--system/database/drivers/oci8/oci8_driver.php82
-rw-r--r--system/database/drivers/oci8/oci8_forge.php45
-rw-r--r--system/database/drivers/oci8/oci8_result.php624
-rw-r--r--system/database/drivers/oci8/oci8_utility.php36
4 files changed, 646 insertions, 141 deletions
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index c6621901b..cc9557e7d 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -1,13 +1,13 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* NOTICE OF LICENSE
- *
+ *
* Licensed under the Open Software License version 3.0
- *
+ *
* This source file is subject to the Open Software License (OSL 3.0) that is
* bundled with this package in the files license.txt / license.rst. It is
* also available through the world wide web at this URL:
@@ -53,38 +53,37 @@
class CI_DB_oci8_driver extends CI_DB {
- var $dbdriver = 'oci8';
+ public $dbdriver = 'oci8';
// The character used for excaping
- var $_escape_char = '"';
+ protected $_escape_char = '"';
// clause and character used for LIKE escape sequences
- var $_like_escape_str = " escape '%s' ";
- var $_like_escape_chr = '!';
+ 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
* used for the count_all() and count_all_results() functions.
*/
- var $_count_string = "SELECT COUNT(1) AS ";
- var $_random_keyword = ' ASC'; // not currently supported
+ protected $_count_string = 'SELECT COUNT(1) AS ';
+ protected $_random_keyword = ' ASC'; // not currently supported
// Set "auto commit" by default
- var $_commit = OCI_COMMIT_ON_SUCCESS;
+ protected $_commit = OCI_COMMIT_ON_SUCCESS;
// need to track statement id and cursor id
- var $stmt_id;
- var $curs_id;
+ public $stmt_id;
+ public $curs_id;
// if we use a limit, we will add a field that will
// throw off num_fields later
- var $limit_used;
+ public $limit_used;
/**
* Non-persistent database connection
*
- * @access private called by the base class
* @return resource
*/
public function db_connect()
@@ -97,7 +96,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Persistent database connection
*
- * @access private called by the base class
* @return resource
*/
public function db_pconnect()
@@ -113,7 +111,6 @@ class CI_DB_oci8_driver extends CI_DB {
* Keep / reestablish the db connection if no queries have been
* sent for a length of time exceeding the server's idle timeout
*
- * @access public
* @return void
*/
public function reconnect()
@@ -127,7 +124,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Select the database
*
- * @access private called by the base class
* @return resource
*/
public function db_select()
@@ -141,7 +137,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Set client character set
*
- * @access public
* @param string
* @param string
* @return resource
@@ -157,7 +152,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Version number query string
*
- * @access protected
* @return string
*/
protected function _version()
@@ -170,14 +164,14 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Execute the query
*
- * @access protected called by the base class
* @param string an SQL query
* @return resource
*/
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);
@@ -187,7 +181,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Generate a statement ID
*
- * @access private
* @param string an SQL query
* @return none
*/
@@ -206,7 +199,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* If needed, each database adapter can prep the query string
*
- * @access private called by execute()
* @param string an SQL query
* @return string
*/
@@ -220,7 +212,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* getCursor. Returns a cursor from the datbase
*
- * @access public
* @return cursor id
*/
public function get_cursor()
@@ -234,7 +225,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Stored Procedure. Executes a stored procedure
*
- * @access public
* @param package package stored procedure is in
* @param procedure stored procedure to execute
* @param params array of parameters
@@ -287,7 +277,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Bind parameters
*
- * @access private
* @return none
*/
private function _bind_params($params)
@@ -316,7 +305,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Begin Transaction
*
- * @access public
* @return bool
*/
public function trans_begin($test_mode = FALSE)
@@ -337,7 +325,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 = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
return TRUE;
}
@@ -346,7 +334,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Commit Transaction
*
- * @access public
* @return bool
*/
public function trans_commit()
@@ -362,9 +349,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;
+ return oci_commit($this->conn_id);
}
// --------------------------------------------------------------------
@@ -372,7 +358,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Rollback Transaction
*
- * @access public
* @return bool
*/
public function trans_rollback()
@@ -388,9 +373,8 @@ class CI_DB_oci8_driver extends CI_DB {
return TRUE;
}
- $ret = oci_rollback($this->conn_id);
$this->_commit = OCI_COMMIT_ON_SUCCESS;
- return $ret;
+ return oci_rollback($this->conn_id);
}
// --------------------------------------------------------------------
@@ -398,7 +382,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Escape String
*
- * @access public
* @param string
* @param bool whether or not the string will be used in a LIKE condition
* @return string
@@ -434,7 +417,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Affected Rows
*
- * @access public
* @return integer
*/
public function affected_rows()
@@ -447,7 +429,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Insert ID
*
- * @access public
* @return integer
*/
public function insert_id()
@@ -464,7 +445,6 @@ class CI_DB_oci8_driver extends CI_DB {
* Generates a platform-specific query string that counts all records in
* the specified database
*
- * @access public
* @param string
* @return string
*/
@@ -494,7 +474,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* Generates a platform-specific query string so that the table names can be fetched
*
- * @access protected
* @param boolean
* @return string
*/
@@ -517,7 +496,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* Generates a platform-specific query string so that the column names can be fetched
*
- * @access protected
* @param string the table name
* @return string
*/
@@ -533,7 +511,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* Generates a platform-specific query so that the column data can be retrieved
*
- * @access public
* @param string the table name
* @return object
*/
@@ -547,7 +524,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* The error message string
*
- * @access protected
* @return string
*/
protected function _error_message()
@@ -562,7 +538,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* The error message number
*
- * @access protected
* @return integer
*/
protected function _error_number()
@@ -579,7 +554,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* This function escapes column and table names
*
- * @access protected
* @param string
* @return string
*/
@@ -622,7 +596,6 @@ class CI_DB_oci8_driver extends CI_DB {
* This function implicitly groups FROM tables so there is no confusion
* about operator precedence in harmony with SQL standards
*
- * @access protected
* @param type
* @return type
*/
@@ -643,7 +616,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* Generates a platform-specific insert string from the supplied data
*
- * @access public
* @param string the table name
* @param array the insert keys
* @param array the insert values
@@ -688,7 +660,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* Generates a platform-specific update string from the supplied data
*
- * @access protected
* @param string the table name
* @param array the update data
* @param array the where clause
@@ -705,12 +676,10 @@ class CI_DB_oci8_driver extends CI_DB {
$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) : '';
+ $orderby = (count($orderby) > 0) ? ' ORDER BY '.implode(', ', $orderby) : '';
+ $sql = 'UPDATE '.$table.' SET '.implode(', ', $valstr);
+ $sql .= ($where != '' AND count($where) > 0) ? ' WHERE '.implode(' ', $where) : '';
$sql .= $orderby.$limit;
return $sql;
@@ -725,7 +694,6 @@ class CI_DB_oci8_driver extends CI_DB {
* If the database does not support the truncate() command
* This function maps to "DELETE FROM table"
*
- * @access protected
* @param string the table name
* @return string
*/
@@ -741,7 +709,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* Generates a platform-specific delete string from the supplied data
*
- * @access protected
* @param string the table name
* @param array the where clause
* @param string the limit clause
@@ -775,7 +742,6 @@ class CI_DB_oci8_driver extends CI_DB {
*
* Generates a platform-specific LIMIT clause
*
- * @access protected
* @param string the sql query string
* @param integer the number of rows to limit the query to
* @param integer the offset value
@@ -802,7 +768,6 @@ class CI_DB_oci8_driver extends CI_DB {
/**
* Close DB Connection
*
- * @access protected
* @param resource
* @return void
*/
@@ -811,10 +776,7 @@ class CI_DB_oci8_driver extends CI_DB {
@oci_close($conn_id);
}
-
}
-
-
/* End of file oci8_driver.php */
/* Location: ./system/database/drivers/oci8/oci8_driver.php */
diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php
index b4a24cdca..6975f2a5f 100644
--- a/system/database/drivers/oci8/oci8_forge.php
+++ b/system/database/drivers/oci8/oci8_forge.php
@@ -1,13 +1,13 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* NOTICE OF LICENSE
- *
+ *
* Licensed under the Open Software License version 3.0
- *
+ *
* This source file is subject to the Open Software License (OSL 3.0) that is
* bundled with this package in the files license.txt / license.rst. It is
* also available through the world wide web at this URL:
@@ -39,12 +39,12 @@ class CI_DB_oci8_forge extends CI_DB_forge {
/**
* Create database
*
- * @access public
* @param string the database name
* @return bool
*/
- function _create_database($name)
+ public function _create_database($name)
{
+ // Not supported - schemas in Oracle are actual usernames
return FALSE;
}
@@ -53,12 +53,12 @@ class CI_DB_oci8_forge extends CI_DB_forge {
/**
* Drop database
*
- * @access private
* @param string the database name
* @return bool
*/
- function _drop_database($name)
+ public function _drop_database($name)
{
+ // Not supported - schemas in Oracle are actual usernames
return FALSE;
}
@@ -67,15 +67,14 @@ class CI_DB_oci8_forge extends CI_DB_forge {
/**
* Create Table
*
- * @access private
* @param string the table name
* @param array the fields
* @param mixed primary key(s)
* @param mixed key(s)
* @param boolean should 'IF NOT EXISTS' be added to the SQL
- * @return bool
+ * @return string
*/
- function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+ public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
{
$sql = 'CREATE TABLE ';
@@ -100,9 +99,7 @@ class CI_DB_oci8_forge extends CI_DB_forge {
{
$attributes = array_change_key_case($attributes, CASE_UPPER);
- $sql .= "\n\t".$this->db->_protect_identifiers($field);
-
- $sql .= ' '.$attributes['TYPE'];
+ $sql .= "\n\t".$this->db->_protect_identifiers($field).' '.$attributes['TYPE'];
if (array_key_exists('CONSTRAINT', $attributes))
{
@@ -127,11 +124,6 @@ class CI_DB_oci8_forge extends CI_DB_forge {
{
$sql .= ' NOT NULL';
}
-
- if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
- {
- $sql .= ' AUTO_INCREMENT';
- }
}
// don't add a comma on the end of the last field
@@ -174,12 +166,11 @@ class CI_DB_oci8_forge extends CI_DB_forge {
/**
* Drop Table
*
- * @access private
- * @return bool
+ * @return string
*/
- function _drop_table($table)
+ public function _drop_table($table)
{
- return FALSE;
+ return 'DROP TABLE ' . $this->db->_protect_identifiers($table);
}
// --------------------------------------------------------------------
@@ -190,7 +181,6 @@ class CI_DB_oci8_forge extends CI_DB_forge {
* Generates a platform-specific query so that a table can be altered
* Called by add_column(), drop_column(), and column_alter(),
*
- * @access private
* @param string the ALTER type (ADD, DROP, CHANGE)
* @param string the column name
* @param string the table name
@@ -198,9 +188,9 @@ class CI_DB_oci8_forge extends CI_DB_forge {
* @param string the default value
* @param boolean should 'NOT NULL' be added
* @param string the field after which we should add the new field
- * @return object
+ * @return string
*/
- function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+ public function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
{
$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);
@@ -242,12 +232,11 @@ class CI_DB_oci8_forge extends CI_DB_forge {
*
* Generates a platform-specific query so that a table can be renamed
*
- * @access private
* @param string the old table name
* @param string the new table name
* @return string
*/
- function _rename_table($table_name, $new_table_name)
+ public function _rename_table($table_name, $new_table_name)
{
$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
return $sql;
@@ -257,4 +246,4 @@ class CI_DB_oci8_forge extends CI_DB_forge {
}
/* End of file oci8_forge.php */
-/* Location: ./system/database/drivers/oci8/oci8_forge.php */ \ No newline at end of file
+/* Location: ./system/database/drivers/oci8/oci8_forge.php */
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index 0f69fa9ef..cbf4bec52 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -1,13 +1,13 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* NOTICE OF LICENSE
- *
+ *
* Licensed under the Open Software License version 3.0
- *
+ *
* This source file is subject to the Open Software License (OSL 3.0) that is
* bundled with this package in the files license.txt / license.rst. It is
* also available through the world wide web at this URL:
@@ -38,31 +38,40 @@
*/
class CI_DB_oci8_result extends CI_DB_result {
- var $stmt_id;
- var $curs_id;
- var $limit_used;
+ public $stmt_id;
+ public $curs_id;
+ public $limit_used;
+
+ // This will be changed by CI_DB_driver, but it's good to have a default:
+ public $commit_mode = OCI_DEFAULT;
+
+ /* Overwriting the parent here, so we have a way to know if it's
+ * already called or not:
+ */
+ public $num_rows;
/**
* Number of rows in the result set.
*
- * Oracle doesn't have a graceful way to retun the number of rows
+ * Oracle doesn't have a graceful way to return the number of rows
* so we have to use what amounts to a hack.
*
- *
- * @access public
* @return integer
*/
public function num_rows()
{
- if ($this->num_rows === 0 && count($this->result_array()) > 0)
+ if ( ! is_int($this->num_rows))
{
- $this->num_rows = count($this->result_array());
- @oci_execute($this->stmt_id, OCI_DEFAULT);
-
- if ($this->curs_id)
+ if (count($this->result_array) > 0)
+ {
+ return $this->num_rows = count($this->result_array);
+ }
+ elseif (count($this->result_object) > 0)
{
- @oci_execute($this->curs_id, OCI_DEFAULT);
+ return $this->num_rows = count($this->result_array);
}
+
+ return $this->num_rows = count($this->result_array());
}
return $this->num_rows;
@@ -73,7 +82,6 @@ class CI_DB_oci8_result extends CI_DB_result {
/**
* Number of fields in the result set
*
- * @access public
* @return integer
*/
public function num_fields()
@@ -83,7 +91,7 @@ class CI_DB_oci8_result extends CI_DB_result {
// if we used a limit we subtract it
if ($this->limit_used)
{
- $count = $count - 1;
+ return $count - 1;
}
return $count;
@@ -96,7 +104,6 @@ class CI_DB_oci8_result extends CI_DB_result {
*
* Generates an array of column names
*
- * @access public
* @return array
*/
public function list_fields()
@@ -116,7 +123,6 @@ class CI_DB_oci8_result extends CI_DB_result {
*
* Generates an array of objects containing field meta-data
*
- * @access public
* @return array
*/
public function field_data()
@@ -140,7 +146,7 @@ class CI_DB_oci8_result extends CI_DB_result {
/**
* Free the result
*
- * @return null
+ * @return void
*/
public function free_result()
{
@@ -149,6 +155,17 @@ class CI_DB_oci8_result extends CI_DB_result {
oci_free_statement($this->result_id);
$this->result_id = FALSE;
}
+
+ if (is_resource($this->stmt_id))
+ {
+ oci_free_statement($this->stmt_id);
+ }
+
+ if (is_resource($this->curs_id))
+ {
+ oci_cancel($this->curs_id);
+ $this->curs_id = NULL;
+ }
}
// --------------------------------------------------------------------
@@ -158,7 +175,6 @@ class CI_DB_oci8_result extends CI_DB_result {
*
* Returns the result set as an array
*
- * @access protected
* @return array
*/
protected function _fetch_assoc()
@@ -174,22 +190,47 @@ class CI_DB_oci8_result extends CI_DB_result {
*
* Returns the result set as an object
*
- * @access protected
* @return object
*/
protected function _fetch_object()
{
$id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
- return @oci_fetch_object($id);
+ return oci_fetch_object($id);
+ }
+
+ // --------------------------------------------------------------------
+
+ /* Query result
+ *
+ * Acts as a wrapper for result_array(), result_object()
+ * and custom_result_object().
+ *
+ * @param string ('object', 'array' or a custom class name)
+ * @return array
+ */
+
+ public function result($type = 'object')
+ {
+ if ($type === 'object')
+ {
+ return $this->result_object();
+ }
+ elseif ($type === 'array')
+ {
+ return $this->result_array();
+ }
+ else
+ {
+ return $this->custom_result_object($type);
+ }
}
// --------------------------------------------------------------------
/**
- * Query result. "array" version.
+ * Query result. "array" version.
*
- * @access public
- * @return array
+ * @return array
*/
public function result_array()
{
@@ -197,14 +238,488 @@ class CI_DB_oci8_result extends CI_DB_result {
{
return $this->result_array;
}
+ elseif (count($this->result_object) > 0)
+ {
+ for ($i = 0, $c = count($this->result_object); $i < $c; $i++)
+ {
+ $this->result_array[$i] = (array) $this->result_object[$i];
+ }
+
+ return $this->result_array;
+ }
+ elseif (is_array($this->row_data))
+ {
+ if (count($this->row_data) === 0)
+ {
+ return $this->result_array;
+ }
+ else
+ {
+ $row_index = count($this->row_data);
+ }
+ }
+ else
+ {
+ $row_index = 0;
+ $this->row_data = array();
+ }
$row = NULL;
while ($row = $this->_fetch_assoc())
{
- $this->result_array[] = $row;
+ $this->row_data[$row_index++] = $row;
+ }
+
+ // Un-comment the following line, in case it becomes needed
+ // $this->_data_seek();
+ return $this->result_array = $this->row_data;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Query result. "object" version.
+ *
+ * @return array
+ */
+ public function result_object()
+ {
+ if (count($this->result_object) > 0)
+ {
+ return $this->result_object;
+ }
+ elseif (count($this->result_array) > 0)
+ {
+ for ($i = 0, $c = count($this->result_array); $i < $c; $i++)
+ {
+ $this->result_object[] = (object) $this->result_array[$i];
+ }
+
+ return $this->result_object;
+ }
+ elseif (is_array($this->row_data))
+ {
+ if (count($this->row_data) === 0)
+ {
+ return $this->result_object;
+ }
+ else
+ {
+ $row_index = count($this->row_data);
+ for ($i = 0; $i < $row_index; $i++)
+ {
+ $this->result_object[$i] = (object) $this->row_data[$i];
+ }
+ }
+ }
+ else
+ {
+ $row_index = 0;
+ $this->row_data = array();
+ }
+
+ $row = NULL;
+ while ($row = $this->_fetch_object())
+ {
+ $this->row_data[$row_index] = (array) $row;
+ $this->result_object[$row_index++] = $row;
+ }
+
+ // Un-comment the following line, in case it becomes needed
+ // $this->_data_seek();
+ return $this->result_object;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Query result. Custom object version.
+ *
+ * @param string class name used to instantiate rows to
+ * @return array
+ */
+ public function custom_result_object($class_name)
+ {
+ if (array_key_exists($class_name, $this->custom_result_object))
+ {
+ return $this->custom_result_object[$class_name];
+ }
+
+ if ( ! class_exists($class_name) OR $this->result_id === FALSE OR $this->num_rows() === 0)
+ {
+ return array();
+ }
+
+ // add the data to the object
+ $result_object = array();
+ $data = NULL;
+
+ /* First check if we don't already have the data.
+ * If so - pass by reference, as we don't know how
+ * large it might be and we don't want 1000 row
+ * sets being copied.
+ */
+ if (count($this->result_array) > 0)
+ {
+ $data = &$this->result_array;
+ }
+ elseif (count($this->result_object) > 0)
+ {
+ $data = &$this->result_object;
+ }
+
+ if ( ! is_null($data))
+ {
+ for ($i = 0, $c = count($data); $i < $c; $i++)
+ {
+ $result_object[$i] = new $class_name();
+ foreach ($data[$i] as $key => $value)
+ {
+ $result_object[$i]->$key = $value;
+ }
+ }
+ }
+ else
+ {
+ // No prefetched result set
+ if (is_array($this->row_data))
+ {
+ $row_index = count($this->row_data);
+ if ($row_index === 0)
+ {
+ return array();
+ }
+ else
+ {
+ for ($i = 0; $i < $row_index; $i++)
+ {
+ $result_object[$i] = new $class_name();
+ foreach ($this->row_data[$i] as $key => $value)
+ {
+ $result_object[$i]->$key = $value;
+ }
+ }
+ }
+ }
+ else
+ {
+ $row_index = 0;
+ $this->row_data = array();
+ }
+
+ while ($row = $this->_fetch_assoc())
+ {
+ $data = new $class_name();
+ foreach ($row as $key => $value)
+ {
+ $data->$key = $value;
+ }
+
+ $this->row_data[$row_index] = $row;
+ $result_object[$row_index++] = $data;
+ }
+ // Un-comment the following line, in case it becomes needed
+ // $this->_data_seek();
+ }
+
+ /* As described for the num_rows() method - there's no easy
+ * way to get the number of rows selected. Our work-around
+ * solution (as in here as well) first checks if result_array
+ * or result_object exist and returns their count. It doesn't
+ * however check for a custom_object_result, so - do it here.
+ */
+ if ( ! is_int($this->num_rows))
+ {
+ $this->num_rows = count($result_object);
+ }
+
+ // Cache and return the array
+ return $this->custom_result_object[$class_name] = $result_object;
+ }
+
+ // --------------------------------------------------------------------
+
+ /* Single row result.
+ *
+ * Acts as a wrapper for row_object(), row_array()
+ * and custom_row_object(). Also used by first_row(), next_row()
+ * and previous_row().
+ *
+ * @param int row index
+ * @param string ('object', 'array' or a custom class name)
+ * @return mixed whatever was passed to the second parameter
+ */
+
+ public function row($n = 0, $type = 'object')
+ {
+ if ($type === 'object') return $this->row_object($n);
+ elseif ($type === 'array') return $this->row_array($n);
+ else return $this->custom_row_object($n, $type);
+ }
+
+ // --------------------------------------------------------------------
+
+ /* Single row result. Array version.
+ *
+ * @param int row index
+ * @return array
+ */
+
+ public function row_array($n = 0)
+ {
+ // Make sure $n is not a string
+ if ( ! is_int($n))
+ {
+ $n = (int) $n;
}
- return $this->result_array;
+ /* If row_data is initialized, it means that we've already tried
+ * (at least) to fetch some data, so ... check if we already have
+ * this row.
+ */
+ if (is_array($this->row_data))
+ {
+ /* If we already have row_data[$n] - return it.
+ *
+ * If we enter the elseif, there's a number of reasons to
+ * return an empty array:
+ *
+ * - count($this->row_data) === 0 means there are no results
+ * - num_rows being set, result_array and/or result_object
+ * having count() > 0 means that we've already fetched all
+ * data and $n is greater than our highest row index available
+ * - $n < $this->current_row means that if such row existed,
+ * we would've already returned it, therefore $n is an
+ * invalid index
+ */
+ if (isset($this->row_data[$n])) // We already have this row
+ {
+ $this->current_row = $n;
+ return $this->row_data[$n];
+ }
+ elseif (count($this->row_data) === 0 OR is_int($this->num_rows)
+ OR count($this->result_array) > 0 OR count($this->result_object) > 0
+ OR $n < $this->current_row)
+ {
+ // No such row exists
+ return array();
+ }
+
+ // Get the next row index that would actually need to be fetched
+ $current_row = ($this->current_row < count($this->row_data)) ? count($this->row_data) : $this->current_row + 1;
+ }
+ else
+ {
+ $current_row = $this->current_row = 0;
+ $this->row_data = array();
+ }
+
+ /* Fetch more data, if available
+ *
+ * NOTE: Operator precedence is important here, if you change
+ * 'AND' with '&&' - it WILL BREAK the results, as
+ * $row will be assigned the scalar value of both
+ * expressions!
+ */
+ while ($row = $this->_fetch_assoc() AND $current_row <= $n)
+ {
+ $this->row_data[$current_row++] = $row;
+ }
+
+ // This would mean that there's no (more) data to fetch
+ if ( ! is_array($this->row_data) OR ! isset($this->row_data[$n]))
+ {
+ // Cache what we already have
+ if (is_array($this->row_data))
+ {
+ $this->num_rows = count($this->row_data);
+ /* Usually, row_data could have less elements than result_array,
+ * but at this point - they should be exactly the same.
+ */
+ $this->result_array = $this->row_data;
+ }
+ else
+ {
+ $this->num_rows = 0;
+ }
+
+ return array();
+ }
+
+ $this->current_row = $n;
+ return $this->row_data[$n];
+ }
+
+ // --------------------------------------------------------------------
+
+ /* Single row result. Object version.
+ *
+ * @param int row index
+ * @return mixed object if row found; empty array if not
+ */
+ public function row_object($n = 0)
+ {
+ // Make sure $n is not a string
+ if ( ! is_int($n))
+ {
+ $n = (int) $n;
+ }
+ /* Logic here is exactly the same as in row_array,
+ * except we have to cast row_data[$n] to an object.
+ *
+ * If we already have result_object though - we can
+ * directly return from it.
+ */
+ if (isset($this->result_object[$n]))
+ {
+ $this->current_row = $n;
+ // Set this, if not already done.
+ if ( ! is_int($this->num_rows))
+ {
+ $this->num_rows = count($this->result_object);
+ }
+
+ return $this->result_object[$n];
+ }
+
+ $row = $this->row_array($n);
+ // Cast only if the row exists
+ if (count($row) > 0)
+ {
+ $this->current_row = $n;
+ return (object) $row;
+ }
+
+ return array();
+ }
+
+ // --------------------------------------------------------------------
+
+ /* Single row result. Custom object version.
+ *
+ * @param int row index
+ * @param string custom class name
+ * @return mixed custom object if row found; empty array otherwise
+ */
+
+ public function custom_row_object($n = 0, $class_name)
+ {
+ // Make sure $n is not a string
+ if ( ! is_int($n))
+ {
+ $n = (int) $n;
+ }
+
+ if (array_key_exists($class_name, $this->custom_result_object))
+ {
+ /* We already have a the whole result set with this class_name,
+ * return the specified row if it exists, and an empty array if
+ * it doesn't.
+ */
+ if (isset($this->custom_result_object[$class_name][$n]))
+ {
+ $this->current_row = $n;
+ return $this->custom_result_object[$class_name][$n];
+ }
+ else
+ {
+ return array();
+ }
+ }
+ elseif ( ! class_exists($class_name)) // No such class exists
+ {
+ return array();
+ }
+
+ $row = $this->row_array($n);
+ // An array would mean that the row doesn't exist
+ if (is_array($row))
+ {
+ return $row;
+ }
+
+ // Convert to the desired class and return
+ $row_object = new $class_name();
+ foreach ($row as $key => $value)
+ {
+ $row_object->$key = $value;
+ }
+
+ $this->current_row = $n;
+ return $row_object;
+ }
+
+ // --------------------------------------------------------------------
+
+ /* First row result.
+ *
+ * @param string ('object', 'array' or a custom class name)
+ * @return mixed whatever was passed to the second parameter
+ */
+
+ public function first_row($type = 'object')
+ {
+ return $this->row(0, $type);
+ }
+
+ // --------------------------------------------------------------------
+
+ /* Last row result.
+ *
+ * @param string ('object', 'array' or a custom class name)
+ * @return mixed whatever was passed to the second parameter
+ */
+ public function last_row($type = 'object')
+ {
+ $result = &$this->result($type);
+ if ( ! isset($this->num_rows))
+ {
+ $this->num_rows = count($result);
+ }
+ $this->current_row = $this->num_rows - 1;
+ return $result[$this->current_row];
+ }
+
+ // --------------------------------------------------------------------
+
+ /* Next row result.
+ *
+ * @param string ('object', 'array' or a custom class name)
+ * @return mixed whatever was passed to the second parameter
+ */
+ public function next_row($type = 'object')
+ {
+ if (is_array($this->row_data))
+ {
+ $count = count($this->row_data);
+ if ($this->current_row > $count OR ($this->current_row === 0 && $count === 0))
+ {
+ $n = $count;
+ }
+ else
+ {
+ $n = $this->current_row + 1;
+ }
+ }
+ else
+ {
+ $n = 0;
+ }
+
+ return $this->row($n, $type);
+ }
+
+ // --------------------------------------------------------------------
+
+ /* Previous row result.
+ *
+ * @param string ('object', 'array' or a custom class name)
+ * @return mixed whatever was passed to the second parameter
+ */
+ public function previous_row($type = 'object')
+ {
+ $n = ($this->current_row !== 0) ? $this->current_row - 1 : 0;
+ return $this->row($n, $type);
}
// --------------------------------------------------------------------
@@ -212,20 +727,59 @@ class CI_DB_oci8_result extends CI_DB_result {
/**
* Data Seek
*
- * Moves the internal pointer to the desired offset. We call
+ * Moves the internal pointer to the desired offset. We call
* this internally before fetching results to make sure the
- * result set starts at zero
+ * result set starts at zero.
*
- * @access protected
- * @return array
+ * Oracle's PHP extension doesn't have an easy way of doing this
+ * and the only workaround is to (re)execute the statement or cursor
+ * in order to go to the first (zero) index of the result set.
+ * Then, we would need to "dummy" fetch ($n - 1) rows to get to the
+ * right one.
+ *
+ * This is as ridiculous as it sounds and it's the reason why every
+ * other method that is fetching data tries to use an already "cached"
+ * result set. Keeping this just in case it becomes needed at
+ * some point in the future, but it will only work for resetting the
+ * pointer to zero.
+ *
+ * @return bool
*/
- protected function _data_seek($n = 0)
+ protected function _data_seek()
{
- return FALSE; // Not needed
+ /* The PHP manual says that if OCI_NO_AUTO_COMMIT mode
+ * is used, and oci_rollback() and/or oci_commit() are
+ * not subsequently called - this will cause an unnecessary
+ * rollback to be triggered at the end of the script execution.
+ *
+ * Therefore we'll try to avoid using that mode flag
+ * if we're not currently in the middle of a transaction.
+ */
+ if ($this->commit_mode !== OCI_COMMIT_ON_SUCCESS)
+ {
+ $result = @oci_execute($this->stmt_id, $this->commit_mode);
+ }
+ else
+ {
+ $result = @oci_execute($this->stmt_id);
+ }
+
+ if ($result && $this->curs_id)
+ {
+ if ($this->commit_mode !== OCI_COMMIT_ON_SUCCESS)
+ {
+ return @oci_execute($this->curs_id, $this->commit_mode);
+ }
+ else
+ {
+ return @oci_execute($this->curs_id);
+ }
+ }
+
+ return $result;
}
}
-
/* End of file oci8_result.php */
/* Location: ./system/database/drivers/oci8/oci8_result.php */
diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php
index d60f98bc4..317ff91eb 100644
--- a/system/database/drivers/oci8/oci8_utility.php
+++ b/system/database/drivers/oci8/oci8_utility.php
@@ -1,13 +1,13 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* NOTICE OF LICENSE
- *
+ *
* Licensed under the Open Software License version 3.0
- *
+ *
* This source file is subject to the Open Software License (OSL 3.0) that is
* bundled with this package in the files license.txt / license.rst. It is
* also available through the world wide web at this URL:
@@ -39,12 +39,14 @@ class CI_DB_oci8_utility extends CI_DB_utility {
/**
* List databases
*
- * @access private
- * @return bool
+ * Generates a platform-specific query so that we get a list of schemas
+ * Those are actually usernames in Oracle.
+ *
+ * @return string
*/
- function _list_databases()
+ public function _list_databases()
{
- return FALSE;
+ return 'SELECT username FROM dba_users';
}
// --------------------------------------------------------------------
@@ -54,13 +56,12 @@ class CI_DB_oci8_utility extends CI_DB_utility {
*
* Generates a platform-specific query so that a table can be optimized
*
- * @access private
* @param string the table name
- * @return object
+ * @return bool
*/
- function _optimize_table($table)
+ public function _optimize_table($table)
{
- return FALSE; // Is this supported in Oracle?
+ return FALSE; // Not supported in Oracle
}
// --------------------------------------------------------------------
@@ -70,13 +71,12 @@ class CI_DB_oci8_utility extends CI_DB_utility {
*
* Generates a platform-specific query so that a table can be repaired
*
- * @access private
* @param string the table name
- * @return object
+ * @return bool
*/
- function _repair_table($table)
+ public function _repair_table($table)
{
- return FALSE; // Is this supported in Oracle?
+ return FALSE; // Not supported in Oracle
}
// --------------------------------------------------------------------
@@ -84,16 +84,16 @@ class CI_DB_oci8_utility extends CI_DB_utility {
/**
* Oracle Export
*
- * @access private
* @param array Preferences
* @return mixed
*/
- function _backup($params = array())
+ public function _backup($params = array())
{
// Currently unsupported
return $this->db->display_error('db_unsuported_feature');
}
+
}
/* End of file oci8_utility.php */
-/* Location: ./system/database/drivers/oci8/oci8_utility.php */ \ No newline at end of file
+/* Location: ./system/database/drivers/oci8/oci8_utility.php */