Merge branch 'develop' of git://github.com/EllisLab/CodeIgniter into develop

Conflicts:
	system/core/Loader.php
	system/database/DB_query_builder.php
	system/database/drivers/cubrid/cubrid_driver.php
	system/database/drivers/mssql/mssql_driver.php
	system/database/drivers/mysql/mysql_driver.php
	system/database/drivers/mysqli/mysqli_driver.php
	system/database/drivers/oci8/oci8_driver.php
	system/database/drivers/odbc/odbc_driver.php
	system/database/drivers/pdo/pdo_driver.php
	system/database/drivers/postgre/postgre_driver.php
	system/database/drivers/sqlite/sqlite_driver.php
	user_guide_src/source/changelog.rst
	user_guide_src/source/database/query_builder.rst
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
index f2f88e7..c5018bf 100644
--- a/system/database/drivers/cubrid/cubrid_driver.php
+++ b/system/database/drivers/cubrid/cubrid_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CUBRID Database Adapter Class
  *
@@ -42,79 +40,102 @@
  */
 class CI_DB_cubrid_driver extends CI_DB {
 
-	// Default CUBRID Broker port. Will be used unless user
-	// explicitly specifies another one.
-	const DEFAULT_PORT = 33000;
-
-	var $dbdriver = 'cubrid';
+	public $dbdriver = 'cubrid';
 
 	// The character used for escaping - no need in CUBRID
-	var	$_escape_char = '';
+	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences - not used in CUBRID
-	var $_like_escape_str = '';
-	var $_like_escape_chr = '';
+	protected $_like_escape_str = '';
+	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(*) AS ';
-	var $_random_keyword = ' RAND()'; // database specific random keyword
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' RAND()'; // database specific random keyword
+
+	// CUBRID-specific properties
+	public $auto_commit = TRUE;
+
+	public function __construct($params)
+	{
+		parent::__construct($params);
+
+		if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:[^:]*:[^:]*:(\?.+)?$/', $this->dsn, $matches))
+		{
+			if (stripos($matches[2], 'autocommit=off') !== FALSE)
+			{
+				$this->auto_commit = FALSE;
+			}
+		}
+		else
+		{
+			// If no port is defined by the user, use the default value
+			$this->port == '' OR $this->port = 33000;
+		}
+	}
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		// If no port is defined by the user, use the default value
-		if ($this->port == '')
-		{
-			$this->port = self::DEFAULT_PORT;
-		}
-
-		$conn = cubrid_connect($this->hostname, $this->port, $this->database, $this->username, $this->password);
-
-		if ($conn)
-		{
-			// Check if a user wants to run queries in dry, i.e. run the
-			// queries but not commit them.
-			if (isset($this->auto_commit) && ! $this->auto_commit)
-			{
-				cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_FALSE);
-			}
-			else
-			{
-				cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_TRUE);
-				$this->auto_commit = TRUE;
-			}
-		}
-
-		return $conn;
+		return $this->_cubrid_connect();
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
 	 * Persistent database connection
+	 *
 	 * In CUBRID persistent DB connection is supported natively in CUBRID
 	 * engine which can be configured in the CUBRID Broker configuration
 	 * file by setting the CCI_PCONNECT parameter to ON. In that case, all
 	 * connections established between the client application and the
-	 * server will become persistent. This is calling the same
-	 * @cubrid_connect function will establish persisten connection
-	 * considering that the CCI_PCONNECT is ON.
+	 * server will become persistent.
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		return $this->db_connect();
+		return $this->_cubrid_connect(TRUE);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * CUBRID connection
+	 *
+	 * A CUBRID-specific method to create a connection to the database.
+	 * Except for determining if a persistent connection should be used,
+	 * the rest of the logic is the same for db_connect() and db_pconnect().
+	 *
+	 * @param	bool
+	 * @return	resource
+	 */
+	protected function _cubrid_connect($persistent = FALSE)
+	{
+		if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:([^:]*):([^:]*):(\?.+)?$/', $this->dsn, $matches))
+		{
+			$_temp = ($persistent !== TRUE) ? 'cubrid_connect_with_url' : 'cubrid_pconnect_with_url';
+			$conn_id = ($matches[2] === '' && $matches[3] === '' && $this->username !== '' && $this->password !== '')
+					? $_temp($this->dsn, $this->username, $this->password)
+					: $_temp($this->dsn);
+		}
+		else
+		{
+			$_temp = ($persistent !== TRUE) ? 'cubrid_connect' : 'cubrid_pconnect';
+			$conn_id = ($this->username !== '')
+					? $_temp($this->hostname, $this->port, $this->database, $this->username, $this->password)
+					: $_temp($this->hostname, $this->port, $this->database);
+		}
+
+		return $conn_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -125,10 +146,9 @@
 	 * 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
 	 */
-	function reconnect()
+	public function reconnect()
 	{
 		if (cubrid_ping($this->conn_id) === FALSE)
 		{
@@ -139,23 +159,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		// In CUBRID there is no need to select a database as the database
-		// is chosen at the connection time.
-		// So, to determine if the database is "selected", all we have to
-		// do is ping the server and return that value.
-		return cubrid_ping($this->conn_id);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -172,42 +175,22 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @cubrid_query($sql, $this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access	private called by execute()
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	function _prep_query($sql)
-	{
-		// No need to prepare
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -238,10 +221,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -269,10 +251,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -300,12 +281,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		if (is_array($str))
 		{
@@ -352,10 +332,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		return @cubrid_insert_id($this->conn_id);
 	}
@@ -368,11 +347,10 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified table
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	string
+	 * @return	int
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
 		{
@@ -397,11 +375,10 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
 		$sql = "SHOW TABLES";
 
@@ -420,11 +397,10 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
 		return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE);
 	}
@@ -436,11 +412,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT * FROM ".$table." LIMIT 1";
 	}
@@ -460,46 +435,6 @@
 		return array('code' => cubrid_errno($this->conn_id), 'message' => cubrid_error($this->conn_id));
 	}
 
-	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	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);
-	}
-
 	// --------------------------------------------------------------------
 
 	/**
@@ -508,11 +443,10 @@
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -525,109 +459,16 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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
-	 * @return	string
-	 */
-	function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * Generates a platform-specific replace string from the supplied data
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	function _replace($table, $keys, $values)
-	{
-		return "REPLACE INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * 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
-	 * @return	string
-	 */
-	function _insert_batch($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES ".implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @access	public
-	 * @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
-	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = sprintf('"%s" = %s', $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;
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
 	 * @return	string
 	 */
-	function _update_batch($table, $values, $index, $where = NULL)
+	protected function _update_batch($table, $values, $index, $where = NULL)
 	{
 		$ids = array();
 		$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
@@ -667,72 +508,18 @@
 	}
 
 	// --------------------------------------------------------------------
-
-
-	/**
-	 * 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"
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	function _truncate($table)
-	{
-		return "TRUNCATE ".$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
-	}
-
-	// --------------------------------------------------------------------
-
+	
 	/**
 	 * Limit string
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
 		if ($offset == 0)
 		{
@@ -751,17 +538,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@cubrid_close($conn_id);
 	}
 
 }
 
-
 /* End of file cubrid_driver.php */
 /* Location: ./system/database/drivers/cubrid/cubrid_driver.php */
diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php
index 76002cb..16478ee 100644
--- a/system/database/drivers/cubrid/cubrid_forge.php
+++ b/system/database/drivers/cubrid/cubrid_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CUBRID Forge Class
  *
@@ -36,51 +34,21 @@
  */
 class CI_DB_cubrid_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		// CUBRID does not allow to create a database in SQL. The GUI tools
-		// have to be used for this purpose.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		// CUBRID does not allow to drop a database in SQL. The GUI tools
-		// have to be used for this purpose.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= FALSE;
+	protected $_drop_database	= FALSE;
 
 	/**
 	 * Process Fields
 	 *
-	 * @access	private
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	function _process_fields($fields)
+	protected function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
@@ -172,15 +140,14 @@
 	/**
 	 * Create Table
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @param	mixed	the fields
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -190,9 +157,7 @@
 			// As of version 8.4.0 CUBRID does not support this SQL syntax.
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
-
-		$sql .= $this->_process_fields($fields);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields);
 
 		// If there is a PK defined
 		if (count($primary_keys) > 0)
@@ -230,32 +195,18 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _drop_table($table)
-	{
-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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	array	fields
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -275,24 +226,7 @@
 		return $sql;
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'RENAME TABLE '.$this->db->protect_identifiers($table_name).' AS '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file cubrid_forge.php */
-/* Location: ./system/database/drivers/cubrid/cubrid_forge.php */
+/* Location: ./system/database/drivers/cubrid/cubrid_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php
index 4c0fede..58dcff2 100644
--- a/system/database/drivers/cubrid/cubrid_result.php
+++ b/system/database/drivers/cubrid/cubrid_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// --------------------------------------------------------------------
-
 /**
  * CUBRID Result Class
  *
@@ -41,10 +39,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		return @cubrid_num_rows($this->result_id);
 	}
@@ -54,10 +51,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return @cubrid_num_fields($this->result_id);
 	}
@@ -69,10 +65,9 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		return cubrid_column_names($this->result_id);
 	}
@@ -84,10 +79,9 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
 
@@ -147,9 +141,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if(is_resource($this->result_id) ||
 			get_resource_type($this->result_id) == "Unknown" &&
@@ -169,10 +163,9 @@
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @access	private
-	 * @return	array
+	 * @return	bool
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return cubrid_data_seek($this->result_id, $n);
 	}
@@ -184,10 +177,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return cubrid_fetch_assoc($this->result_id);
 	}
@@ -199,16 +191,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return cubrid_fetch_object($this->result_id);
 	}
 
 }
 
-
 /* End of file cubrid_result.php */
 /* Location: ./system/database/drivers/cubrid/cubrid_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php
index 750c0d8..274ff6a 100644
--- a/system/database/drivers/cubrid/cubrid_utility.php
+++ b/system/database/drivers/cubrid/cubrid_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CUBRID Utility Class
  *
@@ -39,75 +37,27 @@
 	/**
 	 * List databases
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _list_databases()
+	public function list_databases()
 	{
-		// CUBRID does not allow to see the list of all databases on the
-		// server. It is the way its architecture is designed. Every
-		// database is independent and isolated.
-		// For this reason we can return only the name of the currect
-		// connected database.
-		if ($this->conn_id)
+		if (isset($this->data_cache['db_names']))
 		{
-			return "SELECT '" . $this->database . "'";
+			return $this->data_cache['db_names'];
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return $this->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 * @link 	http://www.cubrid.org/manual/840/en/Optimize%20Database
-	 */
-	function _optimize_table($table)
-	{
-		// No SQL based support in CUBRID as of version 8.4.0. Database or
-		// table optimization can be performed using CUBRID Manager
-		// database administration tool. See the link above for more info.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 * @link 	http://www.cubrid.org/manual/840/en/Checking%20Database%20Consistency
-	 */
-	function _repair_table($table)
-	{
-		// Not supported in CUBRID as of version 8.4.0. Database or
-		// table consistency can be checked using CUBRID Manager
-		// database administration tool. See the link above for more info.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-	/**
 	 * CUBRID Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// No SQL based support in CUBRID as of version 8.4.0. Database or
 		// table backup can be performed using CUBRID Manager
diff --git a/system/database/drivers/interbase/interbase_driver.php b/system/database/drivers/interbase/interbase_driver.php
index bacb668..6587d72 100644
--- a/system/database/drivers/interbase/interbase_driver.php
+++ b/system/database/drivers/interbase/interbase_driver.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Firebird/Interbase Database Adapter Class
  *
@@ -56,8 +54,8 @@
 	 * database engines, so this string appears in each driver and is
 	 * used for the count_all() and count_all_results() functions.
 	 */
-	protected $_count_string = "SELECT COUNT(*) AS ";
-	protected $_random_keyword = ' Random()'; // database specific random keyword
+	protected $_count_string	= 'SELECT COUNT(*) AS ';
+	protected $_random_keyword	= ' Random()'; // database specific random keyword
 
 	// Keeps track of the resource for the current transaction
 	protected $trans;
@@ -87,34 +85,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Reconnect
-	 *
-	 * Keep / reestablish the db connection if no queries have been
-	 * sent for a length of time exceeding the server's idle timeout
-	 *
-	 * @return	void
-	 */
-	public function reconnect()
-	{
-		// not implemented in Interbase/Firebird
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @return	bool
-	 */
-	public function db_select()
-	{
-		// Connection selects the database
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -148,41 +118,20 @@
 	 */
 	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @ibase_query($this->conn_id, $sql);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	protected function _prep_query($sql)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
 	 * @return	bool
 	 */
 	public function trans_begin($test_mode = FALSE)
 	{
-		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;
 		}
@@ -190,7 +139,7 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+		$this->_trans_failure = ($test_mode === TRUE);
 
 		$this->trans = @ibase_trans($this->conn_id);
 
@@ -206,13 +155,8 @@
 	 */
 	public function trans_commit()
 	{
-		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;
 		}
@@ -229,13 +173,8 @@
 	 */
 	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;
 		}
@@ -267,9 +206,9 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(	array('%', '_', $this->_like_escape_chr),
-								array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
-								$str);
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
 		}
 
 		return $str;
@@ -280,7 +219,7 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @return	integer
+	 * @return	int
 	 */
 	public function affected_rows()
 	{
@@ -292,9 +231,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @param	string $generator_name
-	 * @param	integer $inc_by
-	 * @return	integer
+	 * @param	string	$generator_name
+	 * @param	int	$inc_by
+	 * @return	int
 	 */
 	public function insert_id($generator_name, $inc_by=0)
 	{
@@ -326,9 +265,9 @@
 			return 0;
 		}
 
-		$row = $query->row();
+		$query = $query->row();
 		$this->_reset_select();
-		return (int) $row->numrows;
+		return (int) $query->numrows;
 	}
 
 	// --------------------------------------------------------------------
@@ -338,21 +277,18 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
 	protected function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = <<<SQL
-			SELECT "RDB\$RELATION_NAME" FROM "RDB\$RELATIONS" 
-			WHERE "RDB\$RELATION_NAME" NOT LIKE 'RDB$%'
-			AND "RDB\$RELATION_NAME" NOT LIKE 'MON$%'
-SQL;
+		$sql = 'SELECT "RDB$RELATION_NAME" FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\'';
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix != '')
 		{
-			$sql .= ' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
+			return $sql.' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 		}
+
 		return $sql;
 	}
 
@@ -368,10 +304,7 @@
 	 */
 	protected function _list_columns($table = '')
 	{
-		return <<<SQL
-			SELECT "RDB\$FIELD_NAME" FROM "RDB\$RELATION_FIELDS" 
-			WHERE "RDB\$RELATION_NAME"='{$table}';
-SQL;
+		return 'SELECT "RDB$FIELD_NAME" FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = \''.$this->escape_str($table)."'";
 	}
 
 	// --------------------------------------------------------------------
@@ -382,14 +315,14 @@
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
 	protected function _field_data($table)
 	{
 		// Need to find a more efficient way to do this
 		// but Interbase/Firebird seems to lack the
 		// limit clause
-		return "SELECT * FROM {$table}";
+		return 'SELECT * FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -410,49 +343,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This public function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	protected function _escape_identifiers($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 public function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
 	protected function _from_tables($tables)
 	{
@@ -468,23 +365,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update statement
 	 *
 	 * Generates a platform-specific update string from the supplied data
@@ -493,27 +373,27 @@
 	 * @param	array	the update data
 	 * @param	array	the where clause
 	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach ($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		//$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
 
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
-		$sql = "UPDATE {$table} SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? ' WHERE '.implode(' ', $where) : '';
-
-		$sql .= $orderby;
-
-		return $sql;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
+			.$where
+			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '');
 	}
 
 
@@ -523,15 +403,16 @@
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This public 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 $this->_delete($table);
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -543,28 +424,18 @@
 	 *
 	 * @param	string	the table name
 	 * @param	array	the where clause
-	 * @param	string	the limit clause
+	 * @param	array	the like clause
+	 * @param	string	the limit clause (ignored)
 	 * @return	string
 	 */
 	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= ' AND ';
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		//$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM {$table}{$conditions}";
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -575,36 +446,25 @@
 	 * Generates a platform-specific LIMIT clause
 	 *
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		// Keep the current sql string safe for a moment
-		$orig_sql = $sql;
-
 		// Limit clause depends on if Interbase or Firebird
 		if (stripos($this->version(), 'firebird') !== FALSE)
 		{
-			$sql = 'FIRST '. (int) $limit;
-
-			if ($offset > 0)
-			{
-				$sql .= ' SKIP '. (int) $offset;
-			}
+			$select = 'FIRST '. (int) $limit
+				.($offset > 0 ? ' SKIP '. (int) $offset : '');
 		}
 		else
 		{
-			$sql = 'ROWS ' . (int) $limit;
-
-			if ($offset > 0)
-			{
-				$sql = 'ROWS '. (int) $offset . ' TO ' . ($limit + $offset);
-			}
+			$select = 'ROWS '
+				.($offset > 0 ? (int) $offset.' TO '.($limit + $offset) : (int) $limit);
 		}
 
-		return preg_replace('`SELECT`i', "SELECT {$sql}", $orig_sql);
+		return preg_replace('`SELECT`i', 'SELECT '.$select, $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -623,4 +483,4 @@
 }
 
 /* End of file interbase_driver.php */
-/* Location: ./system/database/drivers/interbase/interbase_driver.php */
+/* Location: ./system/database/drivers/interbase/interbase_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/interbase/interbase_forge.php b/system/database/drivers/interbase/interbase_forge.php
index 023d278..c850656 100644
--- a/system/database/drivers/interbase/interbase_forge.php
+++ b/system/database/drivers/interbase/interbase_forge.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Interbase/Firebird Forge Class
  *
@@ -36,18 +34,22 @@
  */
 class CI_DB_interbase_forge extends CI_DB_forge {
 
+	protected $_drop_table	= 'DROP TABLE %s';
+
 	/**
 	 * Create database
 	 *
 	 * @param	string	the database name
 	 * @return	string
 	 */
-	protected function _create_database($filename='')
+	public function create_database($db_name)
 	{
-		// Firebird databases are flat files, so a path is required 
+		// Firebird databases are flat files, so a path is required
+
 		// Hostname is needed for remote access
-		return 'CREATE DATABASE "'.$this->hostname.':'.$filename.'"';
-		
+		empty($this->db->hostname) OR $db_name = $this->hostname.':'.$db_name;
+
+		return parent::create_database('"'.$db_name.'"');
 	}
 
 	// --------------------------------------------------------------------
@@ -55,14 +57,20 @@
 	/**
 	 * Drop database
 	 *
-	 * @param	string	the database name - not used in this driver 
-	 *	- the current db is dropped
+	 * @param	string	the database name
+	 *		- not used in this driver, the current db is dropped
 	 * @return	bool
 	 */
-	protected function _drop_database($name='')
+	public function drop_database($db_name = '')
 	{
-		return ibase_drop_db($this->conn_id);
+		if ( ! ibase_drop_db($this->conn_id))
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
+		}
+
+		return TRUE;
 	}
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -72,7 +80,7 @@
 	 * @param	array	the fields
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	string
 	 */
 	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
@@ -167,18 +175,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @return	string
-	 */
-	protected function _drop_table($table)
-	{
-		return 'DROP TABLE '.$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -189,7 +185,7 @@
 	 * @param	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
@@ -222,21 +218,6 @@
 
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	protected function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
 }
 
 /* End of file interbase_forge.php */
diff --git a/system/database/drivers/interbase/interbase_result.php b/system/database/drivers/interbase/interbase_result.php
index 4b15eee..5ddb6fa 100644
--- a/system/database/drivers/interbase/interbase_result.php
+++ b/system/database/drivers/interbase/interbase_result.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Interbase/Firebird Result Class
  *
@@ -43,18 +41,18 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @return	integer
+	 * @return	int
 	 */
 	public function num_rows()
 	{
-		if( ! is_null($this->num_rows))
+		if (is_int($this->num_rows))
 		{
 			return $this->num_rows;
 		}
-		
-		//Get the results so that you can get an accurate rowcount
+
+		// Get the results so that you can get an accurate rowcount
 		$this->result();
-		
+
 		return $this->num_rows;
 	}
 
@@ -63,7 +61,7 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @return	integer
+	 * @return	int
 	 */
 	public function num_fields()
 	{
@@ -102,20 +100,17 @@
 	 */
 	public function field_data()
 	{
-		
 		$retval = array();
-		for ($i = 0, $num_fields = $this->num_fields(); $i < $num_fields; $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
 			$info = ibase_field_info($this->result_id, $i);
-		
-			$F				= new stdClass();
-			$F->name		= $info['name'];
-			$F->type		= $info['type'];
-			$F->max_length	= $info['length'];
-			$F->primary_key = 0;
-			$F->default		= '';
 
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $info['name'];
+			$retval[$i]->type		= $info['type'];
+			$retval[$i]->max_length		= $info['length'];
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -126,7 +121,7 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
 	public function free_result()
 	{
@@ -136,26 +131,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset.  We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @return	array
-	 */
-	protected function _data_seek($n = 0)
-	{
-		//Set the row count to 0
-		$this->num_rows = 0;
-	
-		//Interbase driver doesn't implement a suitable function
-		return FALSE;	
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
@@ -169,7 +144,7 @@
 			//Increment row count
 			$this->num_rows++;
 		}
-	
+
 		return $row;
 	}
 
@@ -189,10 +164,10 @@
 			//Increment row count
 			$this->num_rows++;
 		}
-		
+
 		return $row;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -202,29 +177,20 @@
 	 */
 	public function result_object()
 	{
-		if (count($this->result_object) > 0)
+		if (count($this->result_object) === $this->num_rows)
 		{
 			return $this->result_object;
 		}
-		
-		// Convert result array to object so that 
+
+		// Convert result array to object so that
 		// We don't have to get the result again
-		if (count($this->result_array) > 0)
+		if (($c = count($this->result_array)) > 0)
 		{
-			$i = 0;
-		
-			foreach ($this->result_array as $array)
+			for ($i = 0; $i < $c; $i++)
 			{
-				$this->result_object[$i] = new StdClass();
-			
-				foreach ($array as $key => $val)
-				{
-					$this->result_object[$i]->{$key} = $val;
-				}
-				
-				++$i;
+				$this->result_object[$i] = (object) $this->result_array[$i];
 			}
-			
+
 			return $this->result_object;
 		}
 
@@ -254,20 +220,20 @@
 	 */
 	public function result_array()
 	{
-		if (count($this->result_array) > 0)
+		if (count($this->result_array) === $this->num_rows)
 		{
 			return $this->result_array;
 		}
-		
+
 		// Since the object and array are really similar, just case
 		// the result object to an array  if need be
-		if (count($this->result_object) > 0)
+		if (($c = count($this->result_object)) > 0)
 		{
-			foreach ($this->result_object as $obj)
+			for ($i = 0; $i < $c; $i++)
 			{
-				$this->result_array[] = (array) $obj;
+				$this->result_array[$i] = (array) $this->result_object[$i];
 			}
-		
+
 			return $this->result_array;
 		}
 
diff --git a/system/database/drivers/interbase/interbase_utility.php b/system/database/drivers/interbase/interbase_utility.php
index 76a0497..1b92af9 100644
--- a/system/database/drivers/interbase/interbase_utility.php
+++ b/system/database/drivers/interbase/interbase_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Interbase/Firebird Utility Class
  *
@@ -36,56 +34,7 @@
  */
 class CI_DB_interbase_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * I don't believe you can do a database listing with Firebird
-	 * since each database is its own file.  I suppose we could
-	 * try reading a directory looking for Firebird files, but
-	 * that doesn't seem like a terribly good idea
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		if ($this->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Is optimization even supported in Interbase/Firebird?
-	 *
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	public function _optimize_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Table repairs are not supported in Interbase/Firebird
-	 *
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * Interbase/Firebird Export
@@ -93,22 +42,20 @@
 	 * @param	string	$filename
 	 * @return	mixed
 	 */
-	public function backup($filename)
+	protected function backup($filename)
 	{
 		if ($service = ibase_service_attach($this->db->hostname, $this->db->username, $this->db->password))
 		{
 			$res = ibase_backup($service, $this->db->database, $filename.'.fbk');
-			
-			//Close the service connection	
+
+			// Close the service connection
 			ibase_service_detach($service);
-			
 			return $res;
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return FALSE;
 	}
+
 }
 
 /* End of file interbase_utility.php */
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 563210c..f60ec81 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MS SQL Database Adapter Class
  *
@@ -42,30 +40,29 @@
  */
 class CI_DB_mssql_driver extends CI_DB {
 
-	var $dbdriver = 'mssql';
+	public $dbdriver = 'mssql';
 
 	// The character used for escaping
-	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.
+	 * used for the count_all() and count_all_results() methods.
 	 */
-	var $_count_string = "SELECT COUNT(*) AS ";
-	var $_random_keyword = ' ASC'; // not currently supported
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' NEWID()';
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
 		if ($this->port != '')
 		{
@@ -80,10 +77,9 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
 		if ($this->port != '')
 		{
@@ -96,22 +92,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Reconnect
-	 *
-	 * 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
-	 */
-	function reconnect()
-	{
-		// not implemented in MSSQL
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Select the database
 	 *
 	 * @param	string	database name
@@ -140,41 +120,22 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @mssql_query($sql, $this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access	private called by execute()
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	function _prep_query($sql)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -201,10 +162,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -226,10 +186,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -251,12 +210,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		if (is_array($str))
 		{
@@ -289,10 +247,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @mssql_rows_affected($this->conn_id);
 	}
@@ -300,14 +257,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Insert ID
-	*
-	* Returns the last id created in the Identity column.
-	*
-	* @access public
-	* @return integer
-	*/
-	function insert_id()
+	 * Insert ID
+	 *
+	 * Returns the last id created in the Identity column.
+	 *
+	 * @return	string
+	 */
+	public function insert_id()
 	{
 		$ver = self::_parse_major_version($this->version());
 		$sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id");
@@ -319,16 +275,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Parse major version
-	*
-	* Grabs the major version number from the
-	* database server version string passed in.
-	*
-	* @access private
-	* @param string $version
-	* @return int16 major version number
-	*/
-	function _parse_major_version($version)
+	 * Parse major version
+	 *
+	 * Grabs the major version number from the
+	 * database server version string passed in.
+	 *
+	 * @param	string	$version
+	 * @return	int	major version number
+	 */
+	protected function _parse_major_version($version)
 	{
 		preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);
 		return $ver_info[1]; // return the major version b/c that's all we're interested in.
@@ -337,10 +292,10 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Version number query string
-	*
-	* @return	string
-	*/
+	 * Version number query string
+	 *
+	 * @return	string
+	 */
 	protected function _version()
 	{
 		return 'SELECT @@VERSION AS ver';
@@ -354,11 +309,10 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
 		{
@@ -383,11 +337,10 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
 		$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
 
@@ -408,11 +361,10 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
 		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";
 	}
@@ -424,11 +376,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT TOP 1 * FROM ".$table;
 	}
@@ -453,58 +404,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	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
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -517,73 +425,51 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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
-	 * @return	string
-	 */
-	function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update statement
 	 *
 	 * Generates a platform-specific update string from the supplied data
 	 *
-	 * @access	public
 	 * @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 orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
-		foreach ($values as $key => $val)
+		foreach($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
 
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).' WHERE '.$where;
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * 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"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return "TRUNCATE ".$table;
+		return 'TRUNCATE TABLE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -593,31 +479,24 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
+		$conditions = (count($conditions) > 0) ? ' WHERE '.implode(' AND ', $conditions) : '';
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return ($limit)
+			? 'WITH ci_delete AS (SELECT TOP '.$limit.' * FROM '.$table.$conditions.') DELETE FROM ci_delete'
+			: 'DELETE FROM '.$table.$conditions;
 	}
 
 	// --------------------------------------------------------------------
@@ -627,13 +506,12 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
 		$i = $limit + $offset;
 
@@ -645,18 +523,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@mssql_close($conn_id);
 	}
 
 }
 
-
-
 /* End of file mssql_driver.php */
 /* Location: ./system/database/drivers/mssql/mssql_driver.php */
diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php
index ec97805..8f8e7c5 100644
--- a/system/database/drivers/mssql/mssql_forge.php
+++ b/system/database/drivers/mssql/mssql_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MS SQL Forge Class
  *
@@ -36,59 +34,19 @@
  */
 class CI_DB_mssql_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		return "DROP TABLE ".$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_table	= 'DROP TABLE %s';
 
 	/**
 	 * 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
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	string
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -97,10 +55,10 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
@@ -190,17 +148,16 @@
 	 * 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
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	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 = '')
+	protected 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);
 
@@ -235,25 +192,7 @@
 
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		// I think this syntax will work, but can find little documentation on renaming tables in MSSQL
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file mssql_forge.php */
-/* Location: ./system/database/drivers/mssql/mssql_forge.php */
+/* Location: ./system/database/drivers/mssql/mssql_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php
index bba2e62..4cc87f4 100644
--- a/system/database/drivers/mssql/mssql_result.php
+++ b/system/database/drivers/mssql/mssql_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MS SQL Result Class
  *
@@ -41,10 +39,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		return @mssql_num_rows($this->result_id);
 	}
@@ -54,10 +51,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return @mssql_num_fields($this->result_id);
 	}
@@ -69,10 +65,9 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		$field_names = array();
 		while ($field = mssql_fetch_field($this->result_id))
@@ -90,10 +85,9 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
 		while ($field = mssql_fetch_field($this->result_id))
@@ -116,9 +110,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -132,14 +126,13 @@
 	/**
 	 * 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
 	 *
-	 * @access	private
-	 * @return	array
+	 * @return	bool
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return mssql_data_seek($this->result_id, $n);
 	}
@@ -151,10 +144,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return mssql_fetch_assoc($this->result_id);
 	}
@@ -166,16 +158,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return mssql_fetch_object($this->result_id);
 	}
 
 }
 
-
 /* End of file mssql_result.php */
 /* Location: ./system/database/drivers/mssql/mssql_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php
index be6ed5b..6d47618 100644
--- a/system/database/drivers/mssql/mssql_utility.php
+++ b/system/database/drivers/mssql/mssql_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MS SQL Utility Class
  *
@@ -36,59 +34,16 @@
  */
 class CI_DB_mssql_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'EXEC sp_helpdb'; // Can also be: EXEC sp_databases
+	protected $_optimize_table	= 'ALTER INDEX all ON %s REORGANIZE';
 
 	/**
 	 * MSSQL Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 21fb171..32c5186 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -144,14 +144,11 @@
 	 * Set client character set
 	 *
 	 * @param	string
-	 * @param	string
 	 * @return	bool
 	 */
-	protected function _db_set_charset($charset, $collation)
+	protected function _db_set_charset($charset)
 	{
-		return function_exists('mysql_set_charset')
-			? @mysql_set_charset($charset, $this->conn_id)
-			: @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id);
+		return @mysql_set_charset($charset, $this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -289,18 +286,7 @@
 	   		return $str;
 	   	}
 
-		if (function_exists('mysql_real_escape_string') && is_resource($this->conn_id))
-		{
-			$str = mysql_real_escape_string($str, $this->conn_id);
-		}
-		elseif (function_exists('mysql_escape_string'))
-		{
-			$str = mysql_escape_string($str);
-		}
-		else
-		{
-			$str = addslashes($str);
-		}
+		$str = is_resource($this->conn_id) ? mysql_real_escape_string($str, $this->conn_id) : addslashes($str);
 
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
@@ -453,43 +439,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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)
-			{
-				$item = str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$item = str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
@@ -511,92 +460,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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).')';
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * Generates a platform-specific replace string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _replace($table, $keys, $values)
-	{
-		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch 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_batch($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * 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, $like = array())
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key.' = '.$val;
-		}
-
-		$where = ($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '';
-		if (count($like) > 0)
-		{
-			$where .= ($where == '' ? ' WHERE ' : ' AND ').implode(' ', $like);
-		}
-
-		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where
-			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
-			.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
@@ -638,53 +501,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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"
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	protected function _truncate($table)
-	{
-		return 'TRUNCATE '.$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ".implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= ' AND ';
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Limit string
 	 *
 	 * Generates a platform-specific LIMIT clause
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index a907b20..0e39aff 100644
--- a/system/database/drivers/mysql/mysql_forge.php
+++ b/system/database/drivers/mysql/mysql_forge.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,31 +34,7 @@
  */
 class CI_DB_mysql_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _create_database($name)
-	{
-		return 'CREATE DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _drop_database($name)
-	{
-		return 'DROP DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s';
 
 	/**
 	 * Process Fields
@@ -66,7 +42,7 @@
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	private function _process_fields($fields)
+	protected function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
@@ -138,7 +114,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -180,19 +156,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @param	string	table name
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -204,7 +167,7 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -218,23 +181,7 @@
 			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file mysql_forge.php */
-/* Location: ./system/database/drivers/mysql/mysql_forge.php */
+/* Location: ./system/database/drivers/mysql/mysql_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php
index 5a65d9c..14d6d07 100644
--- a/system/database/drivers/mysql/mysql_result.php
+++ b/system/database/drivers/mysql/mysql_result.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -128,7 +128,7 @@
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
@@ -166,4 +166,4 @@
 }
 
 /* End of file mysql_result.php */
-/* Location: ./system/database/drivers/mysql/mysql_result.php */
+/* Location: ./system/database/drivers/mysql/mysql_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php
index 952f887..642323d 100644
--- a/system/database/drivers/mysql/mysql_utility.php
+++ b/system/database/drivers/mysql/mysql_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,54 +34,17 @@
  */
 class CI_DB_mysql_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SHOW DATABASES';
-	}
+	protected $_list_databases	= 'SHOW DATABASES';
+	protected $_optimize_table	= 'OPTIMIZE TABLE %s';
+	protected $_repair_table	= 'REPAIR TABLE %s';
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'OPTIMIZE TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _repair_table($table)
-	{
-		return 'REPAIR TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
 	/**
 	 * MySQL Export
 	 *
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		if (count($params) === 0)
 		{
@@ -204,4 +167,4 @@
 }
 
 /* End of file mysql_utility.php */
-/* Location: ./system/database/drivers/mysql/mysql_utility.php */
+/* Location: ./system/database/drivers/mysql/mysql_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 677da13..e2684e4 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -72,8 +72,8 @@
 	public function db_connect()
 	{
 		return ($this->port != '')
-			? @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port)
-			: @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
+			? @new mysqli($this->hostname, $this->username, $this->password, $this->database, $this->port)
+			: @new mysqli($this->hostname, $this->username, $this->password, $this->database);
 	}
 
 	// --------------------------------------------------------------------
@@ -92,8 +92,8 @@
 		}
 
 		return ($this->port != '')
-			? @mysqli_connect('p:'.$this->hostname, $this->username, $this->password, $this->database, $this->port)
-			: @mysqli_connect('p:'.$this->hostname, $this->username, $this->password, $this->database);
+			? @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database, $this->port)
+			: @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database);
 	}
 
 	// --------------------------------------------------------------------
@@ -108,7 +108,7 @@
 	 */
 	public function reconnect()
 	{
-		if (mysqli_ping($this->conn_id) === FALSE)
+		if ($this->conn_id !== FALSE && $this->conn_id->ping() === FALSE)
 		{
 			$this->conn_id = FALSE;
 		}
@@ -129,7 +129,7 @@
 			$database = $this->database;
 		}
 
-		if (@mysqli_select_db($this->conn_id, $database))
+		if (@$this->conn_id->select_db($database))
 		{
 			$this->database = $database;
 			return TRUE;
@@ -144,14 +144,11 @@
 	 * Set client character set
 	 *
 	 * @param	string
-	 * @param	string
 	 * @return	bool
 	 */
-	protected function _db_set_charset($charset, $collation)
+	protected function _db_set_charset($charset)
 	{
-		return function_exists('mysqli_set_charset')
-			? @mysqli_set_charset($this->conn_id, $charset)
-			: @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
+		return @$this->conn_id->set_charset($charset);
 	}
 
 	// --------------------------------------------------------------------
@@ -165,7 +162,7 @@
 	{
 		return isset($this->data_cache['version'])
 			? $this->data_cache['version']
-			: $this->data_cache['version'] = @mysqli_get_server_info($this->conn_id);
+			: $this->data_cache['version'] = $this->conn_id->server_info;
 	}
 
 	// --------------------------------------------------------------------
@@ -178,7 +175,7 @@
 	 */
 	protected function _execute($sql)
 	{
-		return @mysqli_query($this->conn_id, $this->_prep_query($sql));
+		return @$this->conn_id->query($this->_prep_query($sql));
 	}
 
 	// --------------------------------------------------------------------
@@ -289,18 +286,7 @@
 			return $str;
 		}
 
-		if (function_exists('mysqli_real_escape_string') && is_object($this->conn_id))
-		{
-			$str = mysqli_real_escape_string($this->conn_id, $str);
-		}
-		elseif (function_exists('mysql_escape_string'))
-		{
-			$str = mysql_escape_string($str);
-		}
-		else
-		{
-			$str = addslashes($str);
-		}
+		$str = is_object($this->conn_id) ? $this->conn_id->real_escape_string($str) : addslashes($str);
 
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
@@ -320,7 +306,7 @@
 	 */
 	public function affected_rows()
 	{
-		return @mysqli_affected_rows($this->conn_id);
+		return $this->conn_id->affected_rows;
 	}
 
 	// --------------------------------------------------------------------
@@ -332,7 +318,7 @@
 	 */
 	public function insert_id()
 	{
-		return @mysqli_insert_id($this->conn_id);
+		return $this->conn_id->insert_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -371,7 +357,6 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
 	 * @param	bool
 	 * @return	string
 	 */
@@ -448,44 +433,7 @@
 	 */
 	public function error()
 	{
-		return array('code' => mysqli_errno($this->conn_id), 'message' => mysqli_error($this->conn_id));
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * 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)
-			{
-				$item = str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$item = str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
+		return array('code' => $this->conn_id->errno, 'message' => $this->conn_id->error);
 	}
 
 	// --------------------------------------------------------------------
@@ -512,85 +460,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch 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_batch($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * Generates a platform-specific replace string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _replace($table, $keys, $values)
-	{
-		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * 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;
-		}
-
-		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
-			.(($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '')
-			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
-			.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
@@ -634,52 +503,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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"
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	protected function _truncate($table)
-	{
-		return 'TRUNCATE '.$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ".implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= ' AND ';
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Limit string
 	 *
 	 * Generates a platform-specific LIMIT clause
@@ -705,7 +528,8 @@
 	 */
 	protected function _close($conn_id)
 	{
-		@mysqli_close($conn_id);
+		$this->conn_id->close();
+		$this->conn_id = FALSE;
 	}
 
 }
diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php
index 744525f..503574d 100644
--- a/system/database/drivers/mysqli/mysqli_forge.php
+++ b/system/database/drivers/mysqli/mysqli_forge.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,31 +34,7 @@
  */
 class CI_DB_mysqli_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _create_database($name)
-	{
-		return 'CREATE DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _drop_database($name)
-	{
-		return 'DROP DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s';
 
 	/**
 	 * Process Fields
@@ -66,7 +42,7 @@
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	public function _process_fields($fields)
+	protected function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
@@ -86,9 +62,32 @@
 
 				$sql .= "\n\t".$this->db->protect_identifiers($field)
 					.( ! empty($attributes['NAME']) ? ' '.$this->db->protect_identifiers($attributes['NAME']).' ' : '')
-					.( ! empty($attributes['TYPE']) ? ' '.$attributes['TYPE'] : '')
-					.( ! empty($attributes['CONSTRAINT']) ? '('.$attributes['CONSTRAINT'].')' : '')
-					.(( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE) ? ' UNSIGNED' : '')
+				;
+
+				if ( ! empty($attributes['TYPE']))
+				{
+					$sql .=  ' '.$attributes['TYPE'];
+
+					if ( ! empty($attributes['CONSTRAINT']))
+					{
+						switch (strtolower($attributes['TYPE']))
+						{
+							case 'decimal':
+							case 'float':
+							case 'numeric':
+								$sql .= '('.implode(',', $attributes['CONSTRAINT']).')';
+								break;
+							case 'enum':
+							case 'set':
+								$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
+								break;
+							default:
+								$sql .= '('.$attributes['CONSTRAINT'].')';
+						}
+					}
+				}
+
+				$sql .= (( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE) ? ' UNSIGNED' : '')
 					.(isset($attributes['DEFAULT']) ? " DEFAULT '".$attributes['DEFAULT']."'" : '')
 					.(( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL')
 					.(( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) ? ' AUTO_INCREMENT' : '');
@@ -116,7 +115,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -125,7 +124,7 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table).' ('.$this->_process_fields($fields);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields);
 
 		if (count($primary_keys) > 0)
 		{
@@ -158,18 +157,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return 'DROP TABLE IF EXISTS '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -181,7 +168,7 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -195,23 +182,7 @@
 			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file mysqli_forge.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_forge.php */
+/* Location: ./system/database/drivers/mysqli/mysqli_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php
index 8b909cc..9b4d494 100644
--- a/system/database/drivers/mysqli/mysqli_result.php
+++ b/system/database/drivers/mysqli/mysqli_result.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -43,7 +43,7 @@
 	 */
 	public function num_rows()
 	{
-		return @mysqli_num_rows($this->result_id);
+		return $this->result_id->num_rows;
 	}
 
 	// --------------------------------------------------------------------
@@ -55,7 +55,7 @@
 	 */
 	public function num_fields()
 	{
-		return @mysqli_num_fields($this->result_id);
+		return $this->result_id->field_count;
 	}
 
 	// --------------------------------------------------------------------
@@ -70,7 +70,7 @@
 	public function list_fields()
 	{
 		$field_names = array();
-		while ($field = mysqli_fetch_field($this->result_id))
+		while ($field = $this->result_id->fetch_field())
 		{
 			$field_names[] = $field->name;
 		}
@@ -90,7 +90,7 @@
 	public function field_data()
 	{
 		$retval = array();
-		$field_data = mysqli_fetch_fields($this->result_id);
+		$field_data = $this->result_id->fetch_fields();
 		for ($i = 0, $c = count($field_data); $i < $c; $i++)
 		{
 			$retval[$i]			= new stdClass();
@@ -115,7 +115,7 @@
 	{
 		if (is_object($this->result_id))
 		{
-			mysqli_free_result($this->result_id);
+			$this->result_id->free();
 			$this->result_id = FALSE;
 		}
 	}
@@ -125,15 +125,15 @@
 	/**
 	 * 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
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
-		return mysqli_data_seek($this->result_id, $n);
+		return $this->result_id->data_seek($n);
 	}
 
 	// --------------------------------------------------------------------
@@ -147,7 +147,7 @@
 	 */
 	protected function _fetch_assoc()
 	{
-		return mysqli_fetch_assoc($this->result_id);
+		return $this->result_id->fetch_assoc();
 	}
 
 	// --------------------------------------------------------------------
@@ -161,10 +161,10 @@
 	 */
 	protected function _fetch_object()
 	{
-		return mysqli_fetch_object($this->result_id);
+		return $this->result_id->fetch_object();
 	}
 
 }
 
 /* End of file mysqli_result.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_result.php */
+/* Location: ./system/database/drivers/mysqli/mysqli_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php
index 3fdc5c7..27d4ef8 100644
--- a/system/database/drivers/mysqli/mysqli_utility.php
+++ b/system/database/drivers/mysqli/mysqli_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,47 +34,9 @@
  */
 class CI_DB_mysqli_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SHOW DATABASES';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'OPTIMIZE TABLE '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _repair_table($table)
-	{
-		return 'REPAIR TABLE '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SHOW DATABASES';
+	protected $_optimize_table	= 'OPTIMIZE TABLE %s';
+	protected $_repair_table	= 'REPAIR TABLE %s';
 
 	/**
 	 * MySQLi Export
@@ -82,7 +44,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -90,4 +52,4 @@
 }
 
 /* End of file mysqli_utility.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_utility.php */
+/* Location: ./system/database/drivers/mysqli/mysqli_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 81eff70..33a89df 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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * oci8 Database Adapter Class
  *
@@ -48,48 +46,126 @@
  * permit access to oracle databases
  *
  * @author	  Kelly McArdle
- *
  */
-
 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;
+	public $commit_mode = 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;
+
+	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
 	 *
-	 * @access  private called by the base class
-	 * @return  resource
+	 * @return	resource
 	 */
 	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,43 +173,13 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access  private called by the base class
-	 * @return  resource
+	 * @return	resource
 	 */
 	public function db_pconnect()
 	{
-		return @oci_pconnect($this->username, $this->password, $this->hostname, $this->char_set);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Reconnect
-	 *
-	 * 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()
-	{
-		// not implemented in oracle
-		return;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @access  private called by the base class
-	 * @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);
 	}
 
 	// --------------------------------------------------------------------
@@ -155,63 +201,44 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access  protected  called by the base class
-	 * @param   string  an SQL query
-	 * @return  resource
+	 * @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);
-		return @oci_execute($this->stmt_id, $this->_commit);
+		return @oci_execute($this->stmt_id, $this->commit_mode);
 	}
 
 	/**
 	 * Generate a statement ID
 	 *
-	 * @access  private
-	 * @param   string  an SQL query
-	 * @return  none
+	 * @param	string	an SQL query
+	 * @return	void
 	 */
-	private function _set_stmt_id($sql)
+	protected function _set_stmt_id($sql)
 	{
 		if ( ! is_resource($this->stmt_id))
 		{
-			$this->stmt_id = oci_parse($this->conn_id, $this->_prep_query($sql));
+			$this->stmt_id = oci_parse($this->conn_id, $sql);
 		}
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
+	 * Get cursor. Returns a cursor from the database
 	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access  private called by execute()
-	 * @param   string  an SQL query
-	 * @return  string
-	 */
-	private function _prep_query($sql)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * getCursor.  Returns a cursor from the datbase
-	 *
-	 * @access  public
-	 * @return  cursor id
+	 * @return	cursor id
 	 */
 	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);
 	}
 
 	// --------------------------------------------------------------------
@@ -219,20 +246,19 @@
 	/**
 	 * 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
-	 * @return  array
+	 * @param	string	package name in which the stored procedure is in
+	 * @param	string	stored procedure name to execute
+	 * @param	array	parameters
+	 * @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)
 	{
@@ -247,24 +273,24 @@
 		}
 
 		// 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);
 	}
 
 	// --------------------------------------------------------------------
@@ -272,10 +298,9 @@
 	/**
 	 * Bind parameters
 	 *
-	 * @access  private
-	 * @return  none
+	 * @return	void
 	 */
-	private function _bind_params($params)
+	protected function _bind_params($params)
 	{
 		if ( ! is_array($params) OR ! is_resource($this->stmt_id))
 		{
@@ -301,7 +326,6 @@
 	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function trans_begin($test_mode = FALSE)
@@ -322,7 +346,7 @@
 		// 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;
 	}
 
@@ -331,7 +355,6 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function trans_commit()
@@ -347,9 +370,8 @@
 			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);
 	}
 
 	// --------------------------------------------------------------------
@@ -357,25 +379,18 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	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);
 	}
 
 	// --------------------------------------------------------------------
@@ -417,8 +432,7 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access  public
-	 * @return  integer
+	 * @return	int
 	 */
 	public function affected_rows()
 	{
@@ -430,8 +444,7 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access  public
-	 * @return  integer
+	 * @return	int
 	 */
 	public function insert_id()
 	{
@@ -447,9 +460,8 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access  public
-	 * @param   string
-	 * @return  string
+	 * @param	string
+	 * @return	int
 	 */
 	public function count_all($table = '')
 	{
@@ -476,17 +488,16 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	protected
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
 	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;
@@ -499,13 +510,12 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access  protected
-	 * @param   string  the table name
-	 * @return  string
+	 * @param	string	the table name
+	 * @return	string
 	 */
 	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.'\'';
 	}
 
 	// --------------------------------------------------------------------
@@ -515,13 +525,12 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access  public
-	 * @param   string  the table name
-	 * @return  object
+	 * @param	string	the table name
+	 * @return	string
 	 */
 	protected function _field_data($table)
 	{
-		return "SELECT * FROM ".$table." where rownum = 1";
+		return 'SELECT * FROM '.$table.' WHERE rownum = 1';
 	}
 
 	// --------------------------------------------------------------------
@@ -558,83 +567,17 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	protected
-	 * @param	string
-	 * @return	string
-	 */
-	protected 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
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	protected
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
 	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
-	 *
-	 * @access  public
-	 * @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;
 	}
 
 	// --------------------------------------------------------------------
@@ -644,10 +587,10 @@
 	 *
 	 * 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
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param 	array	the insert values
+	 * @return	string
 	 */
 	protected function _insert_batch($table, $keys, $values)
 	{
@@ -656,47 +599,10 @@
 
 		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
-	 *
-	 * @access	protected
-	 * @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';
 	}
 
 	// --------------------------------------------------------------------
@@ -705,16 +611,16 @@
 	 * 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"
 	 *
-	 * @access	protected
+	 * 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;
 	}
 
 	// --------------------------------------------------------------------
@@ -724,31 +630,21 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	protected
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
 	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
+		empty($limit) OR $conditions[] = 'rownum <= '.$limit;
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -758,26 +654,16 @@
 	 *
 	 * 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
-	 * @return  string
+	 * @param	string	the sql query string
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
+	 * @return	string
 	 */
 	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 : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -785,19 +671,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access  protected
-	 * @param   resource
-	 * @return  void
+	 * @param	resource
+	 * @return	void
 	 */
 	protected function _close($conn_id)
 	{
 		@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 48f98d0..bd265b6 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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Oracle Forge Class
  *
@@ -36,33 +34,9 @@
  */
 class CI_DB_oci8_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	public
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= FALSE;
+	protected $_drop_database	= FALSE;
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
@@ -72,9 +46,9 @@
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
-	 * @return	bool
+	 * @return	string
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -83,7 +57,7 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table).' (';
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
 		foreach ($fields as $field => $attributes)
@@ -132,7 +106,7 @@
 					$key = array($this->db->protect_identifiers($key));
 				}
 
-				$sql .= ",\n\tUNIQUE COLUMNS (".implode(', ', $key).")";
+				$sql .= ",\n\tUNIQUE COLUMNS (".implode(', ', $key).')';
 			}
 		}
 
@@ -142,87 +116,38 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	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 = '')
+	protected 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);
 
 		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		if ($alter_type === 'DROP')
 		{
 			return $sql;
 		}
 
-		$sql .= " $column_definition";
+		return $sql.' '.$column_definition
+			.($default_value != '' ? ' DEFAULT "'.$default_value.'"' : '')
+			.($null === NULL ? ' NULL' : ' NOT NULL')
+			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
 
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
 	}
 
 }
 
 /* End of file oci8_forge.php */
-/* Location: ./system/database/drivers/oci8/oci8_forge.php */
+/* Location: ./system/database/drivers/oci8/oci8_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index 383b9f1..7b05e0a 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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * oci8 Result Class
  *
@@ -41,6 +39,12 @@
 	public $stmt_id;
 	public $curs_id;
 	public $limit_used;
+	public $commit_mode;
+
+	/* Overwriting the parent here, so we have a way to know if it's
+	 * already called or not:
+	 */
+	public $num_rows;
 
 	public function __construct(&$driver_object)
 	{
@@ -48,30 +52,32 @@
 		$this->stmt_id = $driver_object->stmt_id;
 		$this->curs_id = $driver_object->curs_id;
 		$this->limit_used = $driver_object->limit_used;
+		$this->commit_mode =& $driver_object->commit_mode;
 		$driver_object->stmt_id = FALSE;
 	}
 
 	/**
 	 * 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
+	 * @return	int
 	 */
 	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)
 			{
-				@oci_execute($this->curs_id, OCI_DEFAULT);
+				return $this->num_rows = count($this->result_array);
 			}
+			elseif (count($this->result_object) > 0)
+			{
+				return $this->num_rows = count($this->result_object);
+			}
+
+			return $this->num_rows = count($this->result_array());
 		}
 
 		return $this->num_rows;
@@ -82,20 +88,14 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access  public
-	 * @return  integer
+	 * @return	int
 	 */
 	public function num_fields()
 	{
 		$count = @oci_num_fields($this->stmt_id);
 
 		// if we used a limit we subtract it
-		if ($this->limit_used)
-		{
-			$count = $count - 1;
-		}
-
-		return $count;
+		return ($this->limit_used) ? $count - 1 : $count;
 	}
 
 	// --------------------------------------------------------------------
@@ -105,7 +105,6 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
 	public function list_fields()
@@ -125,18 +124,17 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access  public
-	 * @return  array
+	 * @return	array
 	 */
 	public function field_data()
 	{
 		$retval = array();
 		for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++)
 		{
-			$F			= new stdClass();
-			$F->name		= oci_field_name($this->stmt_id, $c);
-			$F->type		= oci_field_type($this->stmt_id, $c);
-			$F->max_length		= oci_field_size($this->stmt_id, $c);
+			$F		= new stdClass();
+			$F->name	= oci_field_name($this->stmt_id, $c);
+			$F->type	= oci_field_type($this->stmt_id, $c);
+			$F->max_length	= oci_field_size($this->stmt_id, $c);
 
 			$retval[] = $F;
 		}
@@ -149,7 +147,7 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
 	public function free_result()
 	{
@@ -158,6 +156,17 @@
 			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;
+		}
 	}
 
 	// --------------------------------------------------------------------
@@ -167,8 +176,7 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access  protected
-	 * @return  array
+	 * @return	array
 	 */
 	protected function _fetch_assoc()
 	{
@@ -183,22 +191,20 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access  protected
-	 * @return  object
+	 * @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.  "array" version.
+	 * Query result. Array version.
 	 *
-	 * @access  public
-	 * @return  array
+	 * @return	array
 	 */
 	public function result_array()
 	{
@@ -206,14 +212,429 @@
 		{
 			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;
 		}
 
-		return $this->result_array;
+		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;
+		}
+
+		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 (isset($this->custom_result_object[$class_name]))
+		{
+			return $this->custom_result_object[$class_name];
+		}
+
+		if ( ! class_exists($class_name) OR $this->result_id === FALSE OR $this->num_rows() === 0)
+		{
+			return array();
+		}
+
+		/* Even if we didn't have result_array or result_object
+		 * set prior to custom_result_object() being called,
+		 * num_rows() has already done 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;
+		}
+
+		$this->custom_result_object[$class_name] = array();
+		for ($i = 0, $c = count($data); $i < $c; $i++)
+		{
+			$this->custom_result_object[$class_name][$i] = new $class_name();
+			foreach ($data[$i] as $key => $value)
+			{
+				$this->custom_result_object[$class_name][$i]->$key = $value;
+			}
+		}
+
+		return $this->custom_result_object[$class_name];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* 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);
+		}
+
+		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;
+		}
+
+		/* 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);
 	}
 
 	// --------------------------------------------------------------------
@@ -221,20 +642,59 @@
 	/**
 	 * 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 */
+/* Location: ./system/database/drivers/oci8/oci8_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php
index d60f98b..0183eda 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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Oracle Utility Class
  *
@@ -36,63 +34,20 @@
  */
 class CI_DB_oci8_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in Oracle?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		return FALSE; // Is this supported in Oracle?
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SELECT username FROM dba_users'; // Schemas are actual usernames
 
 	/**
 	 * Oracle Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
 	}
+
 }
 
 /* End of file oci8_utility.php */
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index a616c9d..e36f2d2 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * ODBC Database Adapter Class
  *
@@ -42,40 +40,44 @@
  */
 class CI_DB_odbc_driver extends CI_DB {
 
-	var $dbdriver = 'odbc';
+	public $dbdriver = 'odbc';
 
 	// the character used to excape - not necessary for ODBC
-	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(*) AS ";
-	var $_random_keyword;
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword;
 
-
-	function __construct($params)
+	public function __construct($params)
 	{
 		parent::__construct($params);
 
 		$this->_random_keyword = ' RND('.time().')'; // database specific random keyword
+
+		// Legacy support for DSN in the hostname field
+		if ($this->dsn == '')
+		{
+			$this->dsn = $this->hostname;
+		}
 	}
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		return @odbc_connect($this->hostname, $this->username, $this->password);
+		return @odbc_connect($this->dsn, $this->username, $this->password);
 	}
 
 	// --------------------------------------------------------------------
@@ -83,42 +85,11 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		return @odbc_pconnect($this->hostname, $this->username, $this->password);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Reconnect
-	 *
-	 * 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
-	 */
-	function reconnect()
-	{
-		// not implemented in odbc
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		// Not needed for ODBC
-		return TRUE;
+		return @odbc_pconnect($this->dsn, $this->username, $this->password);
 	}
 
 	// --------------------------------------------------------------------
@@ -126,41 +97,22 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @odbc_exec($this->conn_id, $sql);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access	private called by execute()
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	function _prep_query($sql)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -186,10 +138,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -212,10 +163,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -238,12 +188,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		if (is_array($str))
 		{
@@ -261,9 +210,9 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(	array('%', '_', $this->_like_escape_chr),
-								array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
-								$str);
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
 		}
 
 		return $str;
@@ -274,10 +223,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @odbc_num_rows($this->conn_id);
 	}
@@ -302,11 +250,10 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
 		{
@@ -332,11 +279,10 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
 		$sql = "SHOW TABLES FROM `".$this->database."`";
 
@@ -356,11 +302,10 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
 		return "SHOW COLUMNS FROM ".$table;
 	}
@@ -372,11 +317,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT TOP 1 FROM ".$table;
 	}
@@ -399,58 +343,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	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
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -463,107 +364,19 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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
-	 * @return	string
-	 */
-	function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @access	public
-	 * @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
-	 */
-	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;
-	}
-
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * 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"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -573,13 +386,12 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
 		// Does ODBC doesn't use the LIMIT clause?
 		return $sql;
@@ -590,19 +402,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@odbc_close($conn_id);
 	}
 
-
 }
 
-
-
 /* End of file odbc_driver.php */
 /* Location: ./system/database/drivers/odbc/odbc_driver.php */
diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php
index 51addf0..d59b8a9 100644
--- a/system/database/drivers/odbc/odbc_forge.php
+++ b/system/database/drivers/odbc/odbc_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * ODBC Forge Class
  *
@@ -36,58 +34,20 @@
  */
 class CI_DB_odbc_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database()
-	{
-		// ODBC has no "create database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		// ODBC has no "drop database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_database	= 'DROP DATABASE %s';
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * 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
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -96,10 +56,10 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
@@ -184,40 +144,21 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	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 = '')
+	protected 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);
 
@@ -252,25 +193,7 @@
 
 	}
 
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file odbc_forge.php */
-/* Location: ./system/database/drivers/odbc/odbc_forge.php */
+/* Location: ./system/database/drivers/odbc/odbc_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php
index de2c58c..ecba597 100644
--- a/system/database/drivers/odbc/odbc_result.php
+++ b/system/database/drivers/odbc/odbc_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * ODBC Result Class
  *
@@ -128,9 +126,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -142,33 +140,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset.  We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @access	private
-	 * @return	array
-	 */
-	function _data_seek($n = 0)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
-		if (function_exists('odbc_fetch_object'))
+		if (function_exists('odbc_fetch_array'))
 		{
 			return odbc_fetch_array($this->result_id);
 		}
@@ -185,10 +165,9 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		if (function_exists('odbc_fetch_object'))
 		{
@@ -200,6 +179,7 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
 
 	/**
 	 * Result - object
@@ -207,21 +187,24 @@
 	 * subsititutes the odbc_fetch_object function when
 	 * not available (odbc_fetch_object requires unixODBC)
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _odbc_fetch_object(& $odbc_result) {
+	protected function _odbc_fetch_object(& $odbc_result)
+	{
 		$rs = array();
 		$rs_obj = FALSE;
-		if (odbc_fetch_into($odbc_result, $rs)) {
-			foreach ($rs as $k=>$v) {
-				$field_name= odbc_field_name($odbc_result, $k+1);
+		if (odbc_fetch_into($odbc_result, $rs))
+		{
+			foreach ($rs as $k => $v)
+			{
+				$field_name = odbc_field_name($odbc_result, $k+1);
 				$rs_obj->$field_name = $v;
 			}
 		}
 		return $rs_obj;
 	}
 
+	// --------------------------------------------------------------------
 
 	/**
 	 * Result - array
@@ -229,16 +212,18 @@
 	 * subsititutes the odbc_fetch_array function when
 	 * not available (odbc_fetch_array requires unixODBC)
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _odbc_fetch_array(& $odbc_result) {
+	protected function _odbc_fetch_array(& $odbc_result)
+	{
 		$rs = array();
 		$rs_assoc = FALSE;
-		if (odbc_fetch_into($odbc_result, $rs)) {
-			$rs_assoc=array();
-			foreach ($rs as $k=>$v) {
-				$field_name= odbc_field_name($odbc_result, $k+1);
+		if (odbc_fetch_into($odbc_result, $rs))
+		{
+			$rs_assoc = array();
+			foreach ($rs as $k => $v)
+			{
+				$field_name = odbc_field_name($odbc_result, $k+1);
 				$rs_assoc[$field_name] = $v;
 			}
 		}
@@ -318,4 +303,4 @@
 }
 
 /* End of file odbc_result.php */
-/* Location: ./system/database/drivers/odbc/odbc_result.php */
+/* Location: ./system/database/drivers/odbc/odbc_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php
index bae3fe8..224d48d 100644
--- a/system/database/drivers/odbc/odbc_utility.php
+++ b/system/database/drivers/odbc/odbc_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * ODBC Utility Class
  *
@@ -36,74 +34,15 @@
  */
 class CI_DB_odbc_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		// Not sure if ODBC lets you list all databases...
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * ODBC Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index 83a9c31..f4c3a74 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * PDO Database Adapter Class
  *
@@ -42,28 +40,28 @@
  */
 class CI_DB_pdo_driver extends CI_DB {
 
-	var $dbdriver = 'pdo';
+	public $dbdriver = 'pdo';
 
 	// the character used to excape - not necessary for PDO
-	var $_escape_char = '';
+	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences
-	var $_like_escape_str;
-	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(*) AS ";
-	var $_random_keyword;
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword;
 
 	// need to track the pdo driver and options
-	var $pdodriver;
-	var $options = array();
+	public $pdodriver;
+	public $options = array();
 
-	function __construct($params)
+	public function __construct($params)
 	{
 		parent::__construct($params);
 
@@ -83,32 +81,30 @@
 		// this one depends on the driver being used
 		if ($this->pdodriver == 'mysql')
 		{
+			$this->_escape_char = '`';
 			$this->_like_escape_str = '';
 			$this->_like_escape_chr = '';
 		}
 		elseif ($this->pdodriver == 'odbc')
 		{
 			$this->_like_escape_str = " {escape '%s'} ";
-			$this->_like_escape_chr = '!';
 		}
-		else
+		elseif ( ! in_array($this->pdodriver, array('sqlsrv', 'mssql', 'dblib', 'sybase')))
 		{
-			$this->_like_escape_str = " ESCAPE '%s' ";
-			$this->_like_escape_chr = '!';
+			$this->_escape_char = '"';
 		}
-		
-		$this->trans_enabled   = FALSE;
+
+		$this->trans_enabled = FALSE;
 		$this->_random_keyword = ' RND('.time().')'; // database specific random keyword
 	}
 
 	/**
 	 * Connection String
 	 *
-	 * @access	private
 	 * @param	array
 	 * @return	void
 	 */
-	function _connect_string($params)
+	protected function _connect_string($params)
 	{
 		if (strpos($this->hostname, ':'))
 		{
@@ -138,7 +134,7 @@
 			$this->dsn = $this->pdodriver.':';
 
 			// Add hostname to the DSN for databases that need it
-			if ( ! empty($this->hostname) 
+			if ( ! empty($this->hostname)
 				&& strpos($this->hostname, ':') === FALSE
 				&& in_array($this->pdodriver, array('informix', 'mysql', 'pgsql', 'sybase', 'mssql', 'dblib', 'cubrid')))
 			{
@@ -153,7 +149,7 @@
 		}
 
 		// Add the database name to the DSN, if needed
-	    if (stripos($this->dsn, 'dbname') === FALSE 
+	    if (stripos($this->dsn, 'dbname') === FALSE
 	       && in_array($this->pdodriver, array('4D', 'pgsql', 'mysql', 'firebird', 'sybase', 'mssql', 'dblib', 'cubrid')))
 	    {
 	        $this->dsn .= 'dbname='.$this->database.';';
@@ -187,17 +183,16 @@
 	    }
 	}
 
+	// --------------------------------------------------------------------
+
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @return	object
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
-
-		return $this->pdo_connect();
+		return $this->_pdo_connect();
 	}
 
 	// --------------------------------------------------------------------
@@ -205,15 +200,11 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @return	object
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		$this->options[PDO::ATTR_ERRMODE]    = PDO::ERRMODE_SILENT;
-		$this->options[PDO::ATTR_PERSISTENT] = TRUE;
-	
-		return $this->pdo_connect();
+		return $this->_pdo_connect(TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -221,23 +212,31 @@
 	/**
 	 * PDO connection
 	 *
-	 * @access	private called by the PDO driver class
-	 * @return	resource
+	 * @param	bool
+	 * @return	object
 	 */
-	function pdo_connect()
+	protected function _pdo_connect($persistent = FALSE)
 	{
-		// Refer : http://php.net/manual/en/ref.pdo-mysql.connection.php
-		if ($this->pdodriver == 'mysql' && is_php('5.3.6'))
+		$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
+		$persistent === FALSE OR $this->options[PDO::ATTR_PERSISTENT] = TRUE;
+
+		/* Prior to PHP 5.3.6, even if the charset was supplied in the DSN
+		 * on connect - it was ignored. This is a work-around for the issue.
+		 *
+		 * Reference: http://www.php.net/manual/en/ref.pdo-mysql.connection.php
+		 */
+		if ($this->subdriver === 'mysql' && ! is_php('5.3.6') && ! empty($this->char_set))
 		{
-			$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES $this->char_set COLLATE '$this->dbcollat'";
+			$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$this->char_set
+					.( ! empty($this->db_collat) ? " COLLATE '".$this->dbcollat."'" : '');
 		}
 
 		// Connecting...
-		try 
+		try
 		{
-			$db = new PDO($this->dsn, $this->username, $this->password, $this->options);
-		} 
-		catch (PDOException $e) 
+			return new PDO($this->dsn, $this->username, $this->password, $this->options);
+		}
+		catch (PDOException $e)
 		{
 			if ($this->db_debug && empty($this->failover))
 			{
@@ -246,43 +245,6 @@
 
 			return FALSE;
 		}
-
-		return $db;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Reconnect
-	 *
-	 * 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
-	 */
-	function reconnect()
-	{
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		// Not needed for PDO
-		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -304,53 +266,12 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
-	 * @return	object
+	 * @return	mixed
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
-
-		$result_id = $this->conn_id->query($sql);
-		
-		if (is_object($result_id))
-		{
-			$this->affect_rows = $result_id->rowCount();
-		}
-		else
-		{
-			$this->affect_rows = 0;
-		}
-		
-		return $result_id;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access	private called by execute()
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	function _prep_query($sql)
-	{
-		if ($this->pdodriver === 'pgsql')
-		{
-			// Change the backtick(s) for Postgre
-			$sql = str_replace('`', '"', $sql);
-		}
-		elseif ($this->pdodriver === 'sqlite')
-		{
-			// Change the backtick(s) for SQLite
-			$sql = str_replace('`', '', $sql);
-		}
-
-		return $sql;
+		return $this->conn_id->query($sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -358,18 +279,12 @@
 	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
-		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;
 		}
@@ -377,7 +292,7 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = (bool) ($test_mode === TRUE);
+		$this->_trans_failure = ($test_mode === TRUE);
 
 		return $this->conn_id->beginTransaction();
 	}
@@ -387,25 +302,17 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
-		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 = $this->conn->commit();
-		
-		return $ret;
+		return $this->conn_id->commit();
 	}
 
 	// --------------------------------------------------------------------
@@ -413,25 +320,17 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	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 = $this->conn_id->rollBack();
-
-		return $ret;
+		return $this->conn_id->rollBack();
 	}
 
 	// --------------------------------------------------------------------
@@ -439,12 +338,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		if (is_array($str))
 		{
@@ -455,24 +353,22 @@
 
 			return $str;
 		}
-		
-		//Escape the string
+
+		// Escape the string
 		$str = $this->conn_id->quote($str);
-		
-		//If there are duplicated quotes, trim them away
+
+		// If there are duplicated quotes, trim them away
 		if (strpos($str, "'") === 0)
 		{
 			$str = substr($str, 1, -1);
 		}
-		
+
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(	array('%', '_', $this->_like_escape_chr),
-								array($this->_like_escape_chr.'%', 
-								      $this->_like_escape_chr.'_', 
-								      $this->_like_escape_chr.$this->_like_escape_chr),
-								$str);
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
 		}
 
 		return $str;
@@ -483,12 +379,11 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
-		return $this->affect_rows;
+		return is_object($this->result_id) ? $this->result_id->rowCount() : 0;
 	}
 
 	// --------------------------------------------------------------------
@@ -496,6 +391,7 @@
 	/**
 	 * Insert ID
 	 *
+	 * @param	string
 	 * @return	int
 	 */
 	public function insert_id($name = NULL)
@@ -518,11 +414,10 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
 		{
@@ -550,25 +445,29 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
 		if ($this->pdodriver == 'pgsql')
 		{
 			// Analog function to show all tables in postgre
 			$sql = "SELECT * FROM information_schema.tables WHERE table_schema = 'public'";
 		}
+		elseif ($this->pdodriver == 'sqlite')
+		{
+			// Analog function to show all tables in sqlite
+			$sql = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'";
+		}
 		else
 		{
-			$sql = "SHOW TABLES FROM `".$this->database."`";
+			$sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database);
 		}
 
 		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
 		{
-			return FALSE; 
+			return FALSE;
 		}
 
 		return $sql;
@@ -581,13 +480,12 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
-		return 'SHOW COLUMNS FROM '.$this->_from_tables($table);
+		return 'SHOW COLUMNS FROM '.$this->escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -597,13 +495,28 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
-		return 'SELECT TOP 1 FROM '.$this->_from_tables($table);
+		if ($this->pdodriver == 'mysql' or $this->pdodriver == 'pgsql')
+		{
+			// Analog function for mysql and postgre
+			return 'SELECT * FROM '.$this->escape_identifiers($table).' LIMIT 1';
+		}
+		elseif ($this->pdodriver == 'oci')
+		{
+			// Analog function for oci
+			return 'SELECT * FROM '.$this->escape_identifiers($table).' WHERE ROWNUM <= 1';
+		}
+		elseif ($this->pdodriver == 'sqlite')
+		{
+			// Analog function for sqlite
+			return 'PRAGMA table_info('.$this->escape_identifiers($table).')';
+		}
+
+		return 'SELECT TOP 1 FROM '.$this->escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -638,150 +551,37 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	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);
-			$str .= $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
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
 			$tables = array($tables);
 		}
 
-		return (count($tables) == 1) ? '`'.$tables[0].'`' : '('.implode(', ', $tables).')';
+		return (count($tables) === 1) ? $tables[0] : '('.implode(', ', $tables).')';
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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
-	 * @return	string
-	 */
-	function _insert($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$this->_from_tables($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-	
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * 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
-	 * @return  string
-	 */
-	function _insert_batch($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$this->_from_tables($table).' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @access	public
-	 * @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
-	 */
-	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 '.$this->_from_tables($table).' SET '.implode(', ', $valstr);
-		$sql .= ($where != '' && count($where) >= 1) ? ' WHERE '.implode(' ', $where) : '';
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-	
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
 	 * @return	string
 	 */
-	function _update_batch($table, $values, $index, $where = NULL)
+	protected function _update_batch($table, $values, $index, $where = NULL)
 	{
 		$ids   = array();
 		$where = ($where != '' && count($where) >=1) ? implode(" ", $where).' AND ' : '';
@@ -799,7 +599,7 @@
 			}
 		}
 
-		$sql   = 'UPDATE '.$this->_from_tables($table).' SET ';
+		$sql   = 'UPDATE '.$table.' SET ';
 		$cases = '';
 
 		foreach ($final as $k => $v)
@@ -820,58 +620,22 @@
 		return $sql;
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * 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"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions  = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return 'DELETE FROM '.$this->_from_tables($table).$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -881,13 +645,12 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
 		if ($this->pdodriver == 'cubrid' OR $this->pdodriver == 'sqlite')
 		{
@@ -899,7 +662,7 @@
 		{
 			$sql .= 'LIMIT '.$limit;
 			$sql .= ($offset > 0) ? ' OFFSET '.$offset : '';
-			
+
 			return $sql;
 		}
 	}
@@ -909,13 +672,12 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
-	 * @param	resource
+	 * @param	object
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
-		$this->conn_id = null;
+		$this->conn_id = NULL;
 	}
 
 }
diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php
index b4ddca5..ca8657a 100644
--- a/system/database/drivers/pdo/pdo_forge.php
+++ b/system/database/drivers/pdo/pdo_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * PDO Forge Class
  *
@@ -36,58 +34,20 @@
  */
 class CI_DB_pdo_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database()
-	{
-		// PDO has no "create database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		// PDO has no "drop database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_database	= 'DROP DATABASE %s';
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * 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
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -96,10 +56,10 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= '`'.$this->db->_escape_identifiers($table).'` (';
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
@@ -189,40 +149,21 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	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 = '')
+	protected 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);
 
@@ -257,25 +198,7 @@
 
 	}
 
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file pdo_forge.php */
-/* Location: ./system/database/drivers/pdo/pdo_forge.php */
+/* Location: ./system/database/drivers/pdo/pdo_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php
index c333abc..19aee1d 100644
--- a/system/database/drivers/pdo/pdo_result.php
+++ b/system/database/drivers/pdo/pdo_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * PDO Result Class
  *
@@ -51,10 +49,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		if (empty($this->result_id) OR ! is_object($this->result_id))
 		{
@@ -74,10 +71,9 @@
 	/**
 	 * Fetch the result handler
 	 *
-	 * @access	public
 	 * @return	mixed
 	 */
-	function result_assoc()
+	public function result_assoc()
 	{
 		// If the result already fetched before, use that one
 		if (count($this->result_array) > 0 OR $this->is_fetched)
@@ -94,9 +90,8 @@
 			// Define the method and handler
 			$res_method  = '_fetch_'.$type;
 			$res_handler = 'result_'.$type;
-			
+
 			$this->$res_handler = array();
-			$this->_data_seek(0);
 
 			while ($row = $this->$res_method())
 			{
@@ -116,10 +111,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return $this->result_id->columnCount();
 	}
@@ -131,16 +125,15 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
-	 * @return	array
+	 * @return	bool
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		if ($this->db->db_debug)
 		{
 			return $this->db->display_error('db_unsuported_feature');
 		}
-		
+
 		return FALSE;
 	}
 
@@ -151,20 +144,58 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$data = array();
-	
+
 		try
 		{
-			for($i = 0; $i < $this->num_fields(); $i++)
+			if (strpos($this->result_id->queryString, 'PRAGMA') !== FALSE)
 			{
-				$data[] = $this->result_id->getColumnMeta($i);
+				foreach ($this->result_array() as $field)
+				{
+					preg_match('/([a-zA-Z]+)(\(\d+\))?/', $field['type'], $matches);
+
+					$F		= new stdClass();
+					$F->name	= $field['name'];
+					$F->type	= ( ! empty($matches[1])) ? $matches[1] : NULL;
+					$F->default	= NULL;
+					$F->max_length	= ( ! empty($matches[2])) ? preg_replace('/[^\d]/', '', $matches[2]) : NULL;
+					$F->primary_key = (int) $field['pk'];
+					$F->pdo_type	= NULL;
+
+					$data[] = $F;
+				}
 			}
-			
+			else
+			{
+				for($i = 0, $max = $this->num_fields(); $i < $max; $i++)
+				{
+					$field = $this->result_id->getColumnMeta($i);
+
+					$F		= new stdClass();
+					$F->name	= $field['name'];
+					$F->type	= $field['native_type'];
+					$F->default	= NULL;
+					$F->pdo_type	= $field['pdo_type'];
+
+					if ($field['precision'] < 0)
+					{
+						$F->max_length	= NULL;
+						$F->primary_key = 0;
+					}
+					else
+					{
+						$F->max_length	= ($field['len'] > 255) ? 0 : $field['len'];
+						$F->primary_key = (int) ( ! empty($field['flags']) && in_array('primary_key', $field['flags']));
+					}
+
+					$data[] = $F;
+				}
+			}
+
 			return $data;
 		}
 		catch (Exception $e)
@@ -183,9 +214,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_object($this->result_id))
 		{
@@ -196,31 +227,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset.  We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @access	private
-	 * @return	array
-	 */
-	function _data_seek($n = 0)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return $this->result_id->fetch(PDO::FETCH_ASSOC);
 	}
@@ -232,11 +245,10 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
-	{	
+	protected function _fetch_object()
+	{
 		return $this->result_id->fetchObject();
 	}
 
diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php
index 971ec88..9308421 100644
--- a/system/database/drivers/pdo/pdo_utility.php
+++ b/system/database/drivers/pdo/pdo_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * PDO Utility Class
  *
@@ -36,74 +34,15 @@
  */
 class CI_DB_pdo_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		// Not sure if PDO lets you list all databases...
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases = FALSE;
 
 	/**
 	 * PDO Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 9f21e9b..d858f01 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Postgre Database Adapter Class
  *
@@ -42,47 +40,81 @@
  */
 class CI_DB_postgre_driver extends CI_DB {
 
-	var $dbdriver = 'postgre';
+	public $dbdriver = 'postgre';
 
-	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(*) AS ";
-	var $_random_keyword = ' RANDOM()'; // database specific random keyword
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' RANDOM()'; // database specific random keyword
 
 	/**
-	 * Connection String
+	 * Constructor
 	 *
-	 * @access	private
-	 * @return	string
+	 * Creates a DSN string to be used for db_connect() and db_pconnect()
+	 *
+	 * @return	void
 	 */
-	function _connect_string()
+	public function __construct($params)
 	{
-		$components = array(
-								'hostname'	=> 'host',
-								'port'		=> 'port',
-								'database'	=> 'dbname',
-								'username'	=> 'user',
-								'password'	=> 'password'
-							);
+		parent::__construct($params);
 
-		$connect_string = "";
-		foreach ($components as $key => $val)
+		if ( ! empty($this->dsn))
 		{
-			if (isset($this->$key) && $this->$key != '')
+			return;
+		}
+
+		$this->dsn === '' OR $this->dsn = '';
+
+		if (strpos($this->hostname, '/') !== FALSE)
+		{
+			// If UNIX sockets are used, we shouldn't set a port
+			$this->port = '';
+		}
+
+		$this->hostname === '' OR $this->dsn = 'host='.$this->hostname.' ';
+
+		if ( ! empty($this->port) && ctype_digit($this->port))
+		{
+			$this->dsn .= 'port='.$this->port.' ';
+		}
+
+		if ($this->username !== '')
+		{
+			$this->dsn .= 'user='.$this->username.' ';
+
+			/* An empty password is valid!
+			 *
+			 * $db['password'] = NULL must be done in order to ignore it.
+			 */
+			$this->password === NULL OR $this->dsn .= "password='".$this->password."' ";
+		}
+
+		$this->database === '' OR $this->dsn .= 'dbname='.$this->database.' ';
+
+		/* We don't have these options as elements in our standard configuration
+		 * array, but they might be set by parse_url() if the configuration was
+		 * provided via string. Example:
+		 *
+		 * postgre://username:password@localhost:5432/database?connect_timeout=5&sslmode=1
+		 */
+		foreach (array('connect_timeout', 'options', 'sslmode', 'service') as $key)
+		{
+			if (isset($this->$key) && is_string($this->key) && $this->key !== '')
 			{
-				$connect_string .= " $val=".$this->$key;
+				$this->dsn .= $key."='".$this->key."' ";
 			}
 		}
-		return trim($connect_string);
+
+		$this->dsn = rtrim($this->dsn);
 	}
 
 	// --------------------------------------------------------------------
@@ -90,12 +122,11 @@
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		return @pg_connect($this->_connect_string());
+		return @pg_connect($this->dsn);
 	}
 
 	// --------------------------------------------------------------------
@@ -103,12 +134,11 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		return @pg_pconnect($this->_connect_string());
+		return @pg_pconnect($this->dsn);
 	}
 
 	// --------------------------------------------------------------------
@@ -119,10 +149,9 @@
 	 * 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
 	 */
-	function reconnect()
+	public function reconnect()
 	{
 		if (pg_ping($this->conn_id) === FALSE)
 		{
@@ -133,20 +162,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		// Not needed for Postgre so we'll return TRUE
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Set client character set
 	 *
 	 * @param       string
@@ -191,35 +206,17 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @pg_query($this->conn_id, $sql);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access	private called by execute()
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	function _prep_query($sql)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
 	 * @return	bool
@@ -281,12 +278,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		if (is_array($str))
 		{
@@ -303,9 +299,9 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(	array('%', '_', $this->_like_escape_chr),
-								array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
-								$str);
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
 		}
 
 		return $str;
@@ -316,10 +312,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @pg_affected_rows($this->result_id);
 	}
@@ -329,10 +324,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	string
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		$v = $this->version();
 
@@ -372,11 +366,10 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
 		{
@@ -401,11 +394,10 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
 		$sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";
 
@@ -424,11 +416,10 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
 		return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";
 	}
@@ -440,11 +431,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	object
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT * FROM ".$table." LIMIT 1";
 	}
@@ -467,58 +457,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	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
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -531,84 +478,33 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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
-	 * @return	string
-	 */
-	function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * 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
-	 * @return  string
-	 */
-	function _insert_batch($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update statement
 	 *
 	 * Generates a platform-specific update string from the supplied data
 	 *
-	 * @access	public
 	 * @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 orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach ($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
 
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * 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"
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	function _truncate($table)
-	{
-		return "TRUNCATE ".$table;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where;
 	}
 
 	// --------------------------------------------------------------------
@@ -618,29 +514,20 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
-	 * @param	string	the limit clause
+	 * @param	array	the like clause
+	 * @param	string	the limit clause (ignored)
 	 * @return	string
 	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return "DELETE FROM ".$table.$conditions;
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -649,13 +536,12 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
 		$sql .= "LIMIT ".$limit;
 
@@ -672,18 +558,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@pg_close($conn_id);
 	}
 
-
 }
 
-
 /* End of file postgre_driver.php */
 /* Location: ./system/database/drivers/postgre/postgre_driver.php */
diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php
index 4a7348a..8b214eb 100644
--- a/system/database/drivers/postgre/postgre_forge.php
+++ b/system/database/drivers/postgre/postgre_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Postgre Forge Class
  *
@@ -36,46 +34,20 @@
  */
 class CI_DB_postgre_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
+	protected $_drop_table	= 'DROP TABLE IF EXISTS %s CASCADE';
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-	
 	/**
 	 * Process Fields
 	 *
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	function _process_fields($fields, $primary_keys=array())
+	protected function _process_fields($fields, $primary_keys=array())
 	{
 		$sql = '';
 		$current_field_count = 0;
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
@@ -168,7 +140,7 @@
 				$sql .= ',';
 			}
 		}
-		
+
 		return $sql;
 	}
 
@@ -177,15 +149,14 @@
 	/**
 	 * 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
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -198,8 +169,7 @@
 			}
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
-		$sql .= $this->_process_fields($fields, $primary_keys);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields, $primary_keys);
 
 		if (count($primary_keys) > 0)
 		{
@@ -240,22 +210,11 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 */
-	function _drop_table($table)
-	{
-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table)." CASCADE";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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
@@ -263,9 +222,9 @@
 	 * @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, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
  	{
  		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -285,23 +244,7 @@
  		return $sql;
  	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
 }
 
 /* End of file postgre_forge.php */
-/* Location: ./system/database/drivers/postgre/postgre_forge.php */
+/* Location: ./system/database/drivers/postgre/postgre_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php
index 9161bf9..f913bc9 100644
--- a/system/database/drivers/postgre/postgre_result.php
+++ b/system/database/drivers/postgre/postgre_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Postgres Result Class
  *
@@ -41,10 +39,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		return @pg_num_rows($this->result_id);
 	}
@@ -54,10 +51,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return @pg_num_fields($this->result_id);
 	}
@@ -69,13 +65,12 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		$field_names = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
 			$field_names[] = pg_field_name($this->result_id, $i);
 		}
@@ -90,22 +85,19 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$F				= new stdClass();
-			$F->name		= pg_field_name($this->result_id, $i);
-			$F->type		= pg_field_type($this->result_id, $i);
-			$F->max_length	= pg_field_size($this->result_id, $i);
-			$F->primary_key = 0;
-			$F->default		= '';
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= pg_field_name($this->result_id, $i);
+			$retval[$i]->type		= pg_field_type($this->result_id, $i);
+			$retval[$i]->max_length		= pg_field_size($this->result_id, $i);
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -116,9 +108,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -132,14 +124,13 @@
 	/**
 	 * 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
 	 *
-	 * @access	private
-	 * @return	array
+	 * @return	bool
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return pg_result_seek($this->result_id, $n);
 	}
@@ -151,10 +142,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return pg_fetch_assoc($this->result_id);
 	}
@@ -166,16 +156,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return pg_fetch_object($this->result_id);
 	}
 
 }
 
-
 /* End of file postgre_result.php */
 /* Location: ./system/database/drivers/postgre/postgre_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php
index c426b36..c95e6df 100644
--- a/system/database/drivers/postgre/postgre_utility.php
+++ b/system/database/drivers/postgre/postgre_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,43 +34,8 @@
  */
 class CI_DB_postgre_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SELECT datname FROM pg_database';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'REINDEX TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SELECT datname FROM pg_database';
+	protected $_optimize_table	= 'REINDEX TABLE %s';
 
 	/**
 	 * Postgre Export
@@ -78,7 +43,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -86,4 +51,4 @@
 }
 
 /* End of file postgre_utility.php */
-/* Location: ./system/database/drivers/postgre/postgre_utility.php */
+/* Location: ./system/database/drivers/postgre/postgre_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index 69de12e..551704f 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,10 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
-
-
 /**
  * SQLite Database Adapter Class
  *
@@ -44,30 +40,29 @@
  */
 class CI_DB_sqlite_driver extends CI_DB {
 
-	var $dbdriver = 'sqlite';
+	public $dbdriver = 'sqlite';
 
 	// The character used to escape with - not needed for SQLite
-	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(*) AS ";
-	var $_random_keyword = ' Random()'; // database specific random keyword
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' Random()'; // database specific random keyword
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
 		if ( ! $conn_id = @sqlite_open($this->database, FILE_WRITE_MODE, $error))
 		{
@@ -89,10 +84,9 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
 		if ( ! $conn_id = @sqlite_popen($this->database, FILE_WRITE_MODE, $error))
 		{
@@ -112,35 +106,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Reconnect
-	 *
-	 * 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
-	 */
-	function reconnect()
-	{
-		// not implemented in SQLite
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -157,41 +122,22 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @sqlite_query($this->conn_id, $sql);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access	private called by execute()
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	function _prep_query($sql)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -218,10 +164,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -243,10 +188,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -268,12 +212,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		if (is_array($str))
 		{
@@ -290,9 +233,9 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(	array('%', '_', $this->_like_escape_chr),
-								array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
-								$str);
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
 		}
 
 		return $str;
@@ -303,10 +246,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return sqlite_changes($this->conn_id);
 	}
@@ -316,10 +258,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		return @sqlite_last_insert_rowid($this->conn_id);
 	}
@@ -332,11 +273,10 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
 		{
@@ -361,11 +301,10 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
 		$sql = "SELECT name from sqlite_master WHERE type='table'";
 
@@ -383,11 +322,10 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	string
+	 * @return	bool
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
 		// Not supported
 		return FALSE;
@@ -400,11 +338,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT * FROM ".$table." LIMIT 1";
 	}
@@ -429,58 +366,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	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
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -493,107 +387,36 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
+	 * Replace statement
 	 *
-	 * Generates a platform-specific insert string from the supplied data
+	 * Generates a platform-specific replace string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert($table, $keys, $values)
+	protected function _replace($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return 'INSERT OR '.parent::_replace($table, $keys, $values);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @access	public
-	 * @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
-	 */
-	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;
-	}
-
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * 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"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this function maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -603,13 +426,12 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
 		if ($offset == 0)
 		{
@@ -628,18 +450,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@sqlite_close($conn_id);
 	}
 
-
 }
 
-
 /* End of file sqlite_driver.php */
 /* Location: ./system/database/drivers/sqlite/sqlite_driver.php */
diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php
index 4f379d9..dd6f0f7 100644
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ b/system/database/drivers/sqlite/sqlite_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLite Forge Class
  *
@@ -39,11 +37,10 @@
 	/**
 	 * Create database
 	 *
-	 * @access	public
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function _create_database()
+	public function create_database($db_name = '')
 	{
 		// In SQLite, a database is created when you connect to the database.
 		// We'll return TRUE so that an error isn't generated
@@ -55,36 +52,32 @@
 	/**
 	 * Drop database
 	 *
-	 * @access	private
-	 * @param	string	the database name
+	 * @param	string	the database name (ignored)
 	 * @return	bool
 	 */
-	function _drop_database($name)
+	public function drop_database($db_name = '')
 	{
 		if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))
 		{
-			if ($this->db->db_debug)
-			{
-				return $this->db->display_error('db_unable_to_drop');
-			}
-			return FALSE;
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
 		}
+
 		return TRUE;
 	}
+
 	// --------------------------------------------------------------------
 
 	/**
 	 * 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
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -94,10 +87,10 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)."(";
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
@@ -182,41 +175,21 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 *  Unsupported feature in SQLite
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return array();
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	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 = '')
+	protected 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);
 
@@ -254,24 +227,7 @@
 
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file sqlite_forge.php */
-/* Location: ./system/database/drivers/sqlite/sqlite_forge.php */
+/* Location: ./system/database/drivers/sqlite/sqlite_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php
index 74c0dc5..741dc9d 100644
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ b/system/database/drivers/sqlite/sqlite_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLite Result Class
  *
@@ -41,10 +39,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		return @sqlite_num_rows($this->result_id);
 	}
@@ -54,10 +51,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return @sqlite_num_fields($this->result_id);
 	}
@@ -69,15 +65,14 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		$field_names = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$field_names[] = sqlite_field_name($this->result_id, $i);
+			$field_names[$i] = sqlite_field_name($this->result_id, $i);
 		}
 
 		return $field_names;
@@ -90,22 +85,19 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$F				= new stdClass();
-			$F->name		= sqlite_field_name($this->result_id, $i);
-			$F->type		= 'varchar';
-			$F->max_length	= 0;
-			$F->primary_key = 0;
-			$F->default		= '';
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= sqlite_field_name($this->result_id, $i);
+			$retval[$i]->type		= 'varchar';
+			$retval[$i]->max_length		= 0;
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -114,28 +106,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Free the result
-	 *
-	 * @return	null
-	 */
-	function free_result()
-	{
-		// Not implemented in SQLite
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * 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
 	 *
-	 * @access	private
-	 * @return	array
+	 * @return	bool
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return sqlite_seek($this->result_id, $n);
 	}
@@ -147,10 +126,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return sqlite_fetch_array($this->result_id);
 	}
@@ -162,30 +140,20 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		if (function_exists('sqlite_fetch_object'))
 		{
 			return sqlite_fetch_object($this->result_id);
 		}
-		else
-		{
-			$arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);
-			if (is_array($arr))
-			{
-				$obj = (object) $arr;
-				return $obj;
-			} else {
-				return NULL;
-			}
-		}
+
+		$arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);
+		return is_array($arr) ? (object) $arr : FALSE;
 	}
 
 }
 
-
 /* End of file sqlite_result.php */
 /* Location: ./system/database/drivers/sqlite/sqlite_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php
index 8fefcd9..1bcb42d 100644
--- a/system/database/drivers/sqlite/sqlite_utility.php
+++ b/system/database/drivers/sqlite/sqlite_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,50 +34,7 @@
  */
 class CI_DB_sqlite_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * I don't believe you can do a database listing with SQLite
-	 * since each database is its own file. I suppose we could
-	 * try reading a directory looking for SQLite files, but
-	 * that doesn't seem like a terribly good idea
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		return ($this->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _optimize_table($table)
-	{
-		// Not supported
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		// Not supported
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * SQLite Export
@@ -85,7 +42,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -94,4 +51,4 @@
 }
 
 /* End of file sqlite_utility.php */
-/* Location: ./system/database/drivers/sqlite/sqlite_utility.php */
+/* Location: ./system/database/drivers/sqlite/sqlite_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/index.html b/system/database/drivers/sqlite3/index.html
new file mode 100644
index 0000000..c942a79
--- /dev/null
+++ b/system/database/drivers/sqlite3/index.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php
new file mode 100644
index 0000000..fb45bee
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_driver.php
@@ -0,0 +1,431 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.2.4 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:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		Andrey Andreev
+ * @link		http://codeigniter.com/user_guide/database/
+ * @since		Version 3.0
+ */
+class CI_DB_sqlite3_driver extends CI_DB {
+
+	public $dbdriver = 'sqlite3';
+
+	// The character used for escaping
+	protected $_escape_char = '"';
+
+	// 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
+	 * used for the count_all() and count_all_results() functions.
+	 */
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' RANDOM()';
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @return	object	type SQLite3
+	 */
+	public function db_connect()
+	{
+		try
+		{
+			return ( ! $this->password)
+				? new SQLite3($this->database)
+				: new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password);
+		}
+		catch (Exception $e)
+		{
+			return FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @return  object	type SQLite3
+	 */
+	public function db_pconnect()
+	{
+		log_message('debug', 'SQLite3 doesn\'t support persistent connections');
+		return $this->db_pconnect();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Database version number
+	 *
+	 * @return	string
+	 */
+	public function version()
+	{
+		if (isset($this->data_cache['version']))
+		{
+			return $this->data_cache['version'];
+		}
+
+		$version = $this->conn_id->version();
+		return $this->data_cache['version'] = $version['versionString'];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @param	string	an SQL query
+	 * @return	mixed	SQLite3Result object or bool
+	 */
+	protected function _execute($sql)
+	{
+		// TODO: Implement use of SQLite3::querySingle(), if needed
+
+		return $this->is_write_type($sql)
+			? $this->conn_id->exec($sql)
+			: $this->conn_id->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_begin($test_mode = FALSE)
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE);
+
+		return $this->conn_id->exec('BEGIN TRANSACTION');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_commit()
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		return $this->conn_id->exec('END TRANSACTION');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_rollback()
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		return $this->conn_id->exec('ROLLBACK');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
+	 * @return	string
+	 */
+	public function escape_str($str, $like = FALSE)
+	{
+		if (is_array($str))
+		{
+			foreach ($str as $key => $val)
+			{
+				$str[$key] = $this->escape_str($val, $like);
+			}
+
+			return $str;
+		}
+
+		$str = $this->conn_id->escapeString(remove_invisible_characters($str));
+
+		// escape LIKE condition wildcards
+		if ($like === TRUE)
+		{
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @return	int
+	 */
+	public function affected_rows()
+	{
+		return $this->conn_id->changes();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @return	int
+	 */
+	public function insert_id()
+	{
+		return $this->conn_id->lastInsertRowID();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @param	string
+	 * @return	int
+	 */
+	public function count_all($table = '')
+	{
+		if ($table == '')
+		{
+			return 0;
+		}
+
+		$result = $this->conn_id->querySingle($this->_count_string.$this->protect_identifiers('numrows')
+							.' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
+
+		return empty($result) ? 0 : (int) $result;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @param	bool
+	 * @return	string
+	 */
+	protected function _list_tables($prefix_limit = FALSE)
+	{
+		return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''
+			.(($prefix_limit !== FALSE && $this->dbprefix != '')
+				? ' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix).'%\' '.sprintf($this->_like_escape_str, $this->_like_escape_chr)
+				: '');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * Generates a platform-specific query string so that the column names can be fetched
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _list_columns($table = '')
+	{
+		// Not supported
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * Generates a platform-specific query so that the column data can be retrieved
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _field_data($table)
+	{
+		return 'SELECT * FROM '.$table.' LIMIT 0,1';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @return	string
+	 */
+	protected function _error_message()
+	{
+		return $this->conn_id->lastErrorMsg();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @return	int
+	 */
+	protected function _error_number()
+	{
+		return $this->conn_id->lastErrorCode();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @param	string
+	 * @return	string
+	 */
+	protected function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+
+		return '('.implode(', ', $tables).')';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Replace statement
+	 *
+	 * Generates a platform-specific replace string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _replace($table, $keys, $values)
+	{
+		return 'INSERT OR '.parent::_replace($table, $keys, $values);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 *
+	 * If the database does not support the truncate() command, then,
+	 * then this method maps to 'DELETE FROM table'
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _truncate($table)
+	{
+		return 'DELETE FROM '.$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @param	string	the sql query string
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
+	 * @return	string
+	 */
+	protected function _limit($sql, $limit, $offset)
+	{
+		return $sql.' LIMIT '.($offset ? $offset.',' : '').$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @param	object (ignored)
+	 * @return	void
+	 */
+	protected function _close($conn_id)
+	{
+		$this->conn_id->close();
+	}
+
+}
+
+/* End of file sqlite3_driver.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php
new file mode 100644
index 0000000..20f1e6f
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_forge.php
@@ -0,0 +1,195 @@
+<?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:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Forge Class
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	public function create_database($db_name = '')
+	{
+		// In SQLite, a database is created when you connect to the database.
+		// We'll return TRUE so that an error isn't generated
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @param	string	the database name (ignored)
+	 * @return	bool
+	 */
+	public function drop_database($db_name = '')
+	{
+		// In SQLite, a database is dropped when we delete a file
+		if (@file_exists($this->db->database))
+		{
+			// We need to close the pseudo-connection first
+			$this->db->close();
+			if ( ! @unlink($this->db->database))
+			{
+				return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE;
+			}
+
+			return TRUE;
+		}
+
+		return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+
+		// IF NOT EXISTS added to SQLite in 3.3.0
+		if ($if_not_exists === TRUE && version_compare($this->db->version(), '3.3.0', '>=') === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+
+		$sql .= $this->db->escape_identifiers($table).' (';
+		$current_field_count = 0;
+
+		foreach ($fields as $field => $attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t".$attributes;
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+
+				$sql .= "\n\t".$this->db->protect_identifiers($field)
+					.' '.$attributes['TYPE']
+					.( ! empty($attributes['CONSTRAINT']) ? '('.$attributes['CONSTRAINT'].')' : '')
+					.(( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE) ? ' UNSIGNED' : '')
+					.(isset($attributes['DEFAULT']) ? ' DEFAULT \''.$attributes['DEFAULT'].'\'' : '')
+					.(( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL')
+					.(( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) ? ' AUTO_INCREMENT' : '');
+			}
+
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+
+		if (count($primary_keys) > 0)
+		{
+			$primary_keys = $this->db->protect_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $primary_keys).')';
+		}
+
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key = $this->db->protect_identifiers($key);
+				}
+				else
+				{
+					$key = array($this->db->protect_identifiers($key));
+				}
+
+				$sql .= ",\n\tUNIQUE (".implode(', ', $key).')';
+			}
+		}
+
+		return $sql."\n)";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	string	the table name
+	 * @param	string	the column definition
+	 * @param	string	the default value
+	 * @param	bool	should 'NOT NULL' be added
+	 * @param	string	the field after which we should add the new field
+	 * @return	string
+	 */
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	{
+		/* SQLite only supports adding new columns and it does
+		 * NOT support the AFTER statement. Each new column will
+		 * be added as the last one in the table.
+		 */
+		if ($alter_type !== 'ADD COLUMN')
+		{
+			// Not supported
+			return FALSE;
+		}
+
+		return 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name)
+			.' '.$column_definition
+			.($default_value != '' ? ' DEFAULT '.$default_value : '')
+			// If NOT NULL is specified, the field must have a DEFAULT value other than NULL
+			.(($null !== NULL && $default_value !== 'NULL') ? ' NOT NULL' : ' NULL');
+	}
+
+}
+
+/* End of file sqlite3_forge.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php
new file mode 100644
index 0000000..d83d6b2
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_result.php
@@ -0,0 +1,615 @@
+<?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:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_result extends CI_DB_result {
+
+	// Overwriting the parent here, so we have a way to know if it's already set
+	public $num_rows;
+
+	// num_fields() might be called multiple times, so we'll use this one to cache it's result
+	protected $_num_fields;
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @return	int
+	 */
+	public function num_rows()
+	{
+		/* The SQLite3 driver doesn't have a graceful way to do this,
+		 * so we'll have to do it on our own.
+		 */
+		return is_int($this->num_rows)
+			? $this->num_rows
+			: $this->num_rows = count($this->result_array());
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @return	int
+	 */
+	public function num_fields()
+	{
+		return ( ! is_int($this->_num_fields))
+			? $this->_num_fields = $this->result_id->numColumns()
+			: $this->_num_fields;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @return	array
+	 */
+	public function list_fields()
+	{
+		$field_names = array();
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
+		{
+			$field_names[] = $this->result_id->columnName($i);
+		}
+
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @return	array
+	 */
+	public function field_data()
+	{
+		$retval = array();
+		for ($i = 0, $c = $this->num_fields(); $i < $this->num_fields(); $i++)
+		{
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $this->result_id->columnName($i);
+			$retval[$i]->type		= 'varchar';
+			$retval[$i]->max_length		= 0;
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
+		}
+
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	void
+	 */
+	public function free_result()
+	{
+		if (is_object($this->result_id))
+		{
+			$this->result_id->finalize();
+			$this->result_id = NULL;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @return	array
+	 */
+	protected function _fetch_assoc()
+	{
+		return $this->result_id->fetchArray(SQLITE3_ASSOC);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @return	object
+	 */
+	protected function _fetch_object()
+	{
+		// No native support for fetching as an object
+		$row = $this->_fetch_assoc();
+		return ($row !== FALSE) ? (object) $row : FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. "array" version.
+	 *
+	 * return	array
+	 */
+	public function result_array()
+	{
+		if (count($this->result_array) > 0)
+		{
+			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->row_data[$row_index++] = $row;
+		}
+
+		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_assoc())
+		{
+			$this->row_data[$row_index] = $row;
+			$this->result_object[$row_index++] = (object) $row;
+		}
+
+		$this->result_array = $this->row_data;
+
+		/* 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
+		 * exists and returns its count. It doesn't however check for
+		 * custom_object_result, so - do it here.
+		 */
+		if ( ! is_int($this->num_rows))
+		{
+			$this->num_rows = count($this->result_object);
+		}
+
+		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 ! is_object($this->result_id) OR $this->num_rows() === 0)
+		{
+			return array();
+		}
+
+		/* Even if result_array hasn't been set prior to custom_result_object being called,
+		 * num_rows() has done it.
+		*/
+		$data = &$this->result_array;
+
+		$result_object = array();
+		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;
+			}
+		}
+
+		/* 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
+		 * exists and returns its count. It doesn't however check for
+		 * 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);
+		}
+
+		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;
+		}
+
+		/* 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 or result_array 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 $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;
+			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);
+			$n = ($this->current_row > $count OR ($this->current_row === 0 && $count === 0)) ? $count : $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);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset. We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @return	array
+	 */
+	protected function _data_seek($n = 0)
+	{
+		// Only resetting to the start of the result set is supported
+		return $this->result_id->reset();
+	}
+
+}
+
+/* End of file sqlite3_result.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_utility.php b/system/database/drivers/sqlite3/sqlite3_utility.php
new file mode 100644
index 0000000..965c838
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_utility.php
@@ -0,0 +1,54 @@
+<?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:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Utility Class
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_utility extends CI_DB_utility {
+
+	protected $_list_databases	= FALSE;
+
+	/**
+	 * SQLite Export
+	 *
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	protected function _backup($params = array())
+	{
+		// Not supported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+
+}
+
+/* End of file sqlite3_utility.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 6665b50..8cc500f 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLSRV Database Adapter Class
  *
@@ -42,46 +40,46 @@
  */
 class CI_DB_sqlsrv_driver extends CI_DB {
 
-	var $dbdriver = 'sqlsrv';
+	public $dbdriver = 'sqlsrv';
 
 	// The character used for escaping
-	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(*) AS ";
-	var $_random_keyword = ' ASC'; // not currently supported
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' NEWID()'; // not currently supported
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect($pooling = false)
+	public function db_connect($pooling = FALSE)
 	{
 		// Check for a UTF-8 charset being passed as CI's default 'utf8'.
 		$character_set = (0 === strcasecmp('utf8', $this->char_set)) ? 'UTF-8' : $this->char_set;
 
 		$connection = array(
-			'UID'				=> empty($this->username) ? '' : $this->username,
-			'PWD'				=> empty($this->password) ? '' : $this->password,
-			'Database'			=> $this->database,
-			'ConnectionPooling' => $pooling ? 1 : 0,
+			'UID'			=> empty($this->username) ? '' : $this->username,
+			'PWD'			=> empty($this->password) ? '' : $this->password,
+			'Database'		=> $this->database,
+			'ConnectionPooling'	=> $pooling ? 1 : 0,
 			'CharacterSet'		=> $character_set,
-			'ReturnDatesAsStrings' => 1
+			'ReturnDatesAsStrings'	=> 1
 		);
-		
-		// If the username and password are both empty, assume this is a 
+
+		// If the username and password are both empty, assume this is a
 		// 'Windows Authentication Mode' connection.
-		if(empty($connection['UID']) && empty($connection['PWD'])) {
+		if (empty($connection['UID']) && empty($connection['PWD']))
+		{
 			unset($connection['UID'], $connection['PWD']);
 		}
 
@@ -93,10 +91,9 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
 		return $this->db_connect(TRUE);
 	}
@@ -104,22 +101,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Reconnect
-	 *
-	 * 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
-	 */
-	function reconnect()
-	{
-		// not implemented in MSSQL
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Select the database
 	 *
 	 * @param	string	database name
@@ -146,33 +127,16 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
-		return sqlsrv_query($this->conn_id, $sql, null, array(
-			'Scrollable'				=> SQLSRV_CURSOR_STATIC,
-			'SendStreamParamsAtExec'	=> true
-		));
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access	private called by execute()
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	function _prep_query($sql)
-	{
-		return $sql;
+		return sqlsrv_query($this->conn_id,
+					$sql,
+					NULL,
+					array('Scrollable'=> SQLSRV_CURSOR_STATIC, 'SendStreamParamsAtExec' => TRUE)
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -180,10 +144,9 @@
 	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -209,10 +172,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -233,10 +195,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -257,12 +218,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		// Escape single quotes
 		return str_replace("'", "''", $str);
@@ -273,10 +233,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @sqlrv_rows_affected($this->conn_id);
 	}
@@ -284,34 +243,17 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Insert ID
-	*
-	* Returns the last id created in the Identity column.
-	*
-	* @access public
-	* @return integer
-	*/
-	function insert_id()
+	 * Insert ID
+	 *
+	 * Returns the last id created in the Identity column.
+	 *
+	 * @return	string
+	 */
+	public function insert_id()
 	{
-		return $this->query('select @@IDENTITY as insert_id')->row('insert_id');
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	* Parse major version
-	*
-	* Grabs the major version number from the
-	* database server version string passed in.
-	*
-	* @access private
-	* @param string $version
-	* @return int16 major version number
-	*/
-	function _parse_major_version($version)
-	{
-		preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);
-		return $ver_info[1]; // return the major version b/c that's all we're interested in.
+		$query = $this->query('SELECT @@IDENTITY AS insert_id');
+		$query = $query->row();
+		return $query->insert_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -344,23 +286,25 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	string
+	 * @return	int
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
-			return '0';
-	
+		{
+			return 0;
+		}
+
 		$query = $this->query("SELECT COUNT(*) AS numrows FROM " . $this->dbprefix . $table);
-		
 		if ($query->num_rows() == 0)
-			return '0';
+		{
+			return 0;
+		}
 
 		$row = $query->row();
 		$this->_reset_select();
-		return $row->numrows;
+		return (int) $row->numrows;
 	}
 
 	// --------------------------------------------------------------------
@@ -370,11 +314,10 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
 		return "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
 	}
@@ -386,13 +329,12 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
-		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->_escape_table($table)."'";
+		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";
 	}
 
 	// --------------------------------------------------------------------
@@ -402,13 +344,12 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
-		return "SELECT TOP 1 * FROM " . $this->_escape_table($table);	
+		return 'SELECT TOP 1 * FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -452,48 +393,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape Table Name
-	 *
-	 * This function adds backticks if the table name has a period
-	 * in it. Some DBs will get cranky unless periods are escaped
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	function _escape_table($table)
-	{
-		return $table;
-	}	
-
-
-	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _escape_identifiers($item)
-	{
-		return $item;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -506,62 +414,51 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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
-	 * @return	string
-	 */
-	function _insert($table, $keys, $values)
-	{	
-		return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update statement
 	 *
 	 * Generates a platform-specific update string from the supplied data
 	 *
-	 * @access	public
 	 * @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 orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
-	
-		return "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
+
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
+
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
+
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
 	 * 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"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return "TRUNCATE ".$table;
+		return 'TRUNCATE TABLE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -571,15 +468,24 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	function _delete($table, $where)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		return "DELETE FROM ".$this->_escape_table($table)." WHERE ".implode(" ", $where);
+		$conditions = array();
+
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
+
+		$conditions = (count($conditions) > 0) ? ' WHERE '.implode(' AND ', $conditions) : '';
+
+		return ($limit)
+			? 'WITH ci_delete AS (SELECT TOP '.$limit.' * FROM '.$table.$conditions.') DELETE FROM ci_delete'
+			: 'DELETE FROM '.$table.$conditions;
 	}
 
 	// --------------------------------------------------------------------
@@ -589,17 +495,14 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
-		$i = $limit + $offset;
-	
-		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);		
+		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.($limit + $offset).' ', $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -607,18 +510,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@sqlsrv_close($conn_id);
 	}
 
 }
 
-
-
-/* End of file mssql_driver.php */
-/* Location: ./system/database/drivers/mssql/mssql_driver.php */
+/* End of file sqlsrv_driver.php */
+/* Location: ./system/database/drivers/sqlsrv/sqlsrv_driver.php */
diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php
index 1521922..e9143b2 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_forge.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLSRV Forge Class
  *
@@ -36,59 +34,19 @@
  */
 class CI_DB_sqlsrv_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		return "DROP TABLE ".$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_table	= 'DROP TABLE %s';
 
 	/**
 	 * 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
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -97,10 +55,10 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
@@ -190,17 +148,16 @@
 	 * 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
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	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 = '')
+	protected 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);
 
@@ -235,25 +192,7 @@
 
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		// I think this syntax will work, but can find little documentation on renaming tables in MSSQL
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file sqlsrv_forge.php */
-/* Location: ./system/database/drivers/sqlsrv/sqlsrv_forge.php */
+/* Location: ./system/database/drivers/sqlsrv/sqlsrv_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php
index 1ee19c2..0802677 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLSRV Result Class
  *
@@ -41,10 +39,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		return @sqlsrv_num_rows($this->result_id);
 	}
@@ -54,10 +51,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return @sqlsrv_num_fields($this->result_id);
 	}
@@ -69,17 +65,16 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		$field_names = array();
-		foreach(sqlsrv_field_metadata($this->result_id) as $offset => $field)
+		foreach (sqlsrv_field_metadata($this->result_id) as $offset => $field)
 		{
 			$field_names[] = $field['Name'];
 		}
-		
+
 		return $field_names;
 	}
 
@@ -90,13 +85,12 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
-		foreach(sqlsrv_field_metadata($this->result_id) as $offset => $field)
+		foreach (sqlsrv_field_metadata($this->result_id) as $offset => $field)
 		{
 			$F 				= new stdClass();
 			$F->name 		= $field['Name'];
@@ -104,10 +98,10 @@
 			$F->max_length	= $field['Size'];
 			$F->primary_key = 0;
 			$F->default		= '';
-			
+
 			$retval[] = $F;
 		}
-		
+
 		return $retval;
 	}
 
@@ -116,9 +110,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -130,31 +124,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset.  We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @access	private
-	 * @return	array
-	 */
-	function _data_seek($n = 0)
-	{
-		// Not implemented
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return sqlsrv_fetch_array($this->result_id, SQLSRV_FETCH_ASSOC);
 	}
@@ -166,16 +142,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return sqlsrv_fetch_object($this->result_id);
 	}
 
 }
 
-
-/* End of file mssql_result.php */
-/* Location: ./system/database/drivers/mssql/mssql_result.php */
\ No newline at end of file
+/* End of file sqlsrv_result.php */
+/* Location: ./system/database/drivers/sqlsrv/sqlsrv_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php
index e96df96..394964b 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_utility.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLSRV Utility Class
  *
@@ -36,59 +34,16 @@
  */
 class CI_DB_sqlsrv_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'EXEC sp_helpdb'; // Can also be: EXEC sp_databases
+	protected $_optimize_table	= 'ALTER INDEX all ON %s REORGANIZE';
 
 	/**
-	 * Optimize table query
+	 * SQLSRV Export
 	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * MSSQL Export
-	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -96,5 +51,5 @@
 
 }
 
-/* End of file mssql_utility.php */
-/* Location: ./system/database/drivers/mssql/mssql_utility.php */
\ No newline at end of file
+/* End of file sqlsrv_utility.php */
+/* Location: ./system/database/drivers/sqlsrv/sqlsrv_utility.php */
\ No newline at end of file