Added CUBRID Database Driver
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 10e8ed0..f3e824d 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -218,7 +218,7 @@
 
 		// Some DBs have functions that return the version, and don't run special
 		// SQL queries per se. In these instances, just return the result.
-		$driver_version_exceptions = array('oci8', 'sqlite');
+		$driver_version_exceptions = array('oci8', 'sqlite', 'cubrid');
 
 		if (in_array($this->dbdriver, $driver_version_exceptions))
 		{
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
new file mode 100644
index 0000000..ef0b5b4
--- /dev/null
+++ b/system/database/drivers/cubrid/cubrid_driver.php
@@ -0,0 +1,775 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Esen Sagynov
+ * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 2.0.2
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CUBRID 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		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+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';
+
+	// The character used for escaping - no need in CUBRID
+	var	$_escape_char = '';
+
+	// clause and character used for LIKE escape sequences - not used in CUBRID
+	var $_like_escape_str = '';
+	var $_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
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */
+	function db_connect()
+	{
+		if ($this->port == '')
+		{
+			$this->port = self::DEFAULT_PORT;
+        }
+
+        $conn = cubrid_connect($this->hostname, $this->port, $this->database, $this->username, $this->password);
+
+        if ($conn){
+            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;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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.
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */
+	function db_pconnect()
+	{
+		return $this->db_connect();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 (cubrid_ping($this->conn_id) === FALSE)
+		{
+			$this->conn_id = FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 return the connection identifier which can be later
+		// checked if it has been established or not.
+		return cubrid_ping($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set client character set
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function db_set_charset($charset, $collation)
+	{
+		// In CUBRID, there is no need to set charset or collation.
+		// This is why returning true will allow the application continue
+		// its normal process.
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+    
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return cubrid_get_server_info($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @access	private called by the base class
+	 * @param	string	an SQL query
+	 * @return	resource
+	 */
+	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)
+	{
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	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)
+		{
+			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) ? TRUE : FALSE;
+
+        if (cubrid_get_autocommit($this->conn_id))
+            cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	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)
+		{
+			return TRUE;
+		}
+
+		cubrid_commit($this->conn_id);
+
+        if ($this->auto_commit && !cubrid_get_autocommit($this->conn_id))
+            cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
+        
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	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)
+		{
+			return TRUE;
+		}
+
+		cubrid_rollback($this->conn_id);
+
+        if ($this->auto_commit && !cubrid_get_autocommit($this->conn_id))
+            cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
+        
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		if (is_array($str))
+		{
+			foreach ($str as $key => $val)
+	   		{
+				$str[$key] = $this->escape_str($val, $like);
+	   		}
+
+	   		return $str;
+	   	}
+
+		if (function_exists('cubrid_real_escape_string') AND is_resource($this->conn_id))
+		{
+			$str = cubrid_real_escape_string($str, $this->conn_id);
+		}
+		else
+		{
+			$str = addslashes($str);
+		}
+
+		// escape LIKE condition wildcards
+		if ($like === TRUE)
+		{
+			//TODO: check this
+			$str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @cubrid_affected_rows($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @cubrid_insert_id($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified table
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+		{
+			return 0;
+		}
+		
+		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+
+		if ($query->num_rows() == 0)
+		{
+			return 0;
+		}
+
+		$row = $query->row();
+		return (int) $row->numrows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * List table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	private
+	 * @param	boolean
+	 * @return	string
+	 */
+	function _list_tables($prefix_limit = FALSE)
+	{
+		$sql = "SHOW TABLES";
+
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
+		}
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * 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 = '')
+	{
+		return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * 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)
+	{
+		return "SELECT * FROM ".$table." LIMIT 1";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _error_message()
+	{
+		return cubrid_error($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	private
+	 * @return	integer
+	 */
+	function _error_number()
+	{
+		return cubrid_errno($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);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 */
+	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
+	 */
+	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[] = $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)
+	{
+		$ids = array();
+		$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
+
+		foreach ($values as $key => $val)
+		{
+			$ids[] = $val[$index];
+
+			foreach (array_keys($val) as $field)
+			{
+				if ($field != $index)
+				{
+					$final[$field][] =  'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
+				}
+			}
+		}
+
+		$sql = "UPDATE ".$table." SET ";
+		$cases = '';
+
+		foreach ($final as $k => $v)
+		{
+			$cases .= $k.' = CASE '."\n";
+			foreach ($v as $row)
+			{
+				$cases .= $row."\n";
+			}
+
+			$cases .= 'ELSE '.$k.' END, ';
+		}
+
+		$sql .= substr($cases, 0, -2);
+
+		$sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
+
+		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;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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->ar_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
+	 * @return	string
+	 */
+	function _limit($sql, $limit, $offset)
+	{
+		if ($offset == 0)
+		{
+			$offset = '';
+		}
+		else
+		{
+			$offset .= ", ";
+		}
+
+		return $sql."LIMIT ".$offset.$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function _close($conn_id)
+	{
+		@cubrid_close($conn_id);
+	}
+
+}
+
+
+/* End of file cubrid_driver.php */
+/* Location: ./system/database/drivers/cubrid/cubrid_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php
new file mode 100644
index 0000000..c2c553f
--- /dev/null
+++ b/system/database/drivers/cubrid/cubrid_forge.php
@@ -0,0 +1,284 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Esen Sagynov
+ * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CUBRID Forge Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+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;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Process Fields
+	 *
+	 * @access	private
+	 * @param	mixed	the fields
+	 * @return	string
+	 */
+	function _process_fields($fields)
+	{
+		$current_field_count = 0;
+		$sql = '';
+
+		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);
+
+				if (array_key_exists('NAME', $attributes))
+				{
+					$sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';
+				}
+
+				if (array_key_exists('TYPE', $attributes))
+				{
+					$sql .=  ' '.$attributes['TYPE'];
+
+					if (array_key_exists('CONSTRAINT', $attributes))
+					{
+						switch ($attributes['TYPE'])
+						{
+							case 'decimal':
+							case 'float':
+							case 'numeric':
+								$sql .= '('.implode(',', $attributes['CONSTRAINT']).')';
+								break;
+							case 'enum': 	// As of version 8.4.0 CUBRID does not support
+											// enum data type.
+											break;
+							case 'set':
+								$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
+								break;
+							default:
+								$sql .= '('.$attributes['CONSTRAINT'].')';
+						}
+					}
+				}
+
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					//$sql .= ' UNSIGNED';
+					// As of version 8.4.0 CUBRID does not support UNSIGNED INTEGER data type.
+					// Will be supported in the next release as a part of MySQL Compatibility.
+				}
+
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+				}
+
+				if (array_key_exists('NULL', $attributes))
+				{
+					$sql .= ($attributes['NULL'] === TRUE) ? '' : ' NOT NULL';
+				}
+
+				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+                
+                if (array_key_exists('UNIQUE', $attributes) && $attributes['UNIQUE'] === TRUE)
+				{
+					$sql .= ' UNIQUE';
+				}
+			}
+
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	bool
+	 */
+	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+
+		if ($if_not_exists === TRUE)
+		{
+			//$sql .= 'IF NOT EXISTS ';
+			// As of version 8.4.0 CUBRID does not support this SQL syntax.
+		}
+
+		$sql .= $this->db->_escape_identifiers($table)." (";
+
+		$sql .= $this->_process_fields($fields);
+
+		// If there is a PK defined
+		if (count($primary_keys) > 0)
+		{
+			$key_name = "pk_" . $table . "_" .
+				$this->db->_protect_identifiers(implode('_', $primary_keys));
+			
+			$primary_keys = $this->db->_protect_identifiers($primary_keys);
+			$sql .= ",\n\tCONSTRAINT " . $key_name . " PRIMARY KEY(" . implode(', ', $primary_keys) . ")";
+		}
+
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key_name = $this->db->_protect_identifiers(implode('_', $key));
+					$key = $this->db->_protect_identifiers($key);
+				}
+				else
+				{
+					$key_name = $this->db->_protect_identifiers($key);
+					$key = array($key_name);
+				}
+				
+				$sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";
+			}
+		}
+
+		$sql .= "\n);";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 */
+	function _alter_table($alter_type, $table, $fields, $after_field = '')
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";
+
+		// DROP has everything it needs now.
+		if ($alter_type == 'DROP')
+		{
+			return $sql.$this->db->_protect_identifiers($fields);
+		}
+
+		$sql .= $this->_process_fields($fields);
+
+		if ($after_field != '')
+		{
+			$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)
+	{
+		$sql = 'RENAME TABLE '.$this->db->_protect_identifiers($table_name)." AS ".$this->db->_protect_identifiers($new_table_name);
+		return $sql;
+	}
+
+}
+
+/* End of file 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
new file mode 100644
index 0000000..06613e3
--- /dev/null
+++ b/system/database/drivers/cubrid/cubrid_result.php
@@ -0,0 +1,201 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Esen Sagynov
+ * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 2.0.2
+ * @filesource
+ */
+
+// --------------------------------------------------------------------
+
+/**
+ * CUBRID Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_cubrid_result extends CI_DB_result {
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @cubrid_num_rows($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @cubrid_num_fields($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_fields()
+	{
+		return cubrid_column_names($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+
+		$tablePrimaryKeys = array();
+
+		while ($field = cubrid_fetch_field($this->result_id))
+		{
+			$F				= new stdClass();
+			$F->name		= $field->name;
+			$F->type		= $field->type;
+			$F->default		= $field->def;
+			$F->max_length	= $field->max_length;
+
+			// At this moment primary_key property is not returned when
+			// cubrid_fetch_field is called. The following code will
+			// provide a patch for it. primary_key property will be added
+			// in the next release.
+
+			// TODO: later version of CUBRID will provide primary_key
+			// property.
+			// When PK is defined in CUBRID, an index is automatically
+			// created in the db_index system table in the form of
+			// pk_tblname_fieldname. So the following will count how many
+			// columns are there which satisfy this format.
+			// The query will search for exact single columns, thus
+			// compound PK is not supported.
+			$res = cubrid_query($this->conn_id,
+				"SELECT COUNT(*) FROM db_index WHERE class_name = '" . $field->table .
+				"' AND is_primary_key = 'YES' AND index_name = 'pk_" .
+				$field->table . "_" . $field->name . "'"
+			);
+
+			if ($res)
+			{
+				$row = cubrid_fetch_array($res, CUBRID_NUM);
+				$F->primary_key = ($row[0] > 0 ? 1 : null);
+			}
+			else{
+				$F->primary_key = null;
+			}
+
+			if (is_resource($res))
+			{
+				cubrid_close_request($res);
+				$this->result_id = FALSE;
+			}
+
+			$retval[] = $F;
+		}
+
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */
+	function free_result()
+	{
+        if(is_resource($this->result_id) ||
+                get_resource_type($this->result_id) == "Unknown" &&
+                preg_match('/Resource id #/', strval($this->result_id)))
+		{
+			cubrid_close_request($this->result_id);
+			$this->result_id = FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 cubrid_data_seek($this->result_id, $n);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return cubrid_fetch_assoc($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	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
new file mode 100644
index 0000000..9cf8b2e
--- /dev/null
+++ b/system/database/drivers/cubrid/cubrid_utility.php
@@ -0,0 +1,107 @@
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Esen Sagynov
+ * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CUBRID Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_cubrid_utility extends CI_DB_utility {
+
+	/**
+	 * List databases
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	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)
+		{
+			return "SELECT '" . $this->database . "'";
+		}
+		else{
+			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
+	 * @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())
+	{
+		// No SQL based support in CUBRID as of version 8.4.0. Database or
+		// table backup can be performed using CUBRID Manager
+		// database administration tool.
+		return $this->db->display_error('db_unsuported_feature');
+	}
+}
+
+/* End of file cubrid_utility.php */
+/* Location: ./system/database/drivers/cubrid/cubrid_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/cubrid/index.html b/system/database/drivers/cubrid/index.html
new file mode 100644
index 0000000..c942a79
--- /dev/null
+++ b/system/database/drivers/cubrid/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