Add improvements from @CUBRID's implementation
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
index 147e463..aa8e997 100644
--- a/system/database/drivers/cubrid/cubrid_driver.php
+++ b/system/database/drivers/cubrid/cubrid_driver.php
@@ -43,7 +43,7 @@
 	public $dbdriver = 'cubrid';
 
 	// The character used for escaping - no need in CUBRID
-	protected $_escape_char = '';
+	protected $_escape_char = '`';
 
 	// clause and character used for LIKE escape sequences - not used in CUBRID
 	protected $_like_escape_str = '';
@@ -135,12 +135,6 @@
 					: $_temp($this->hostname, $this->port, $this->database);
 		}
 
-		if ($conn_id)
-		{
-			$_temp = ($this->auto_commit) ? CUBRID_AUTOCOMMIT_TRUE : CUBRID_AUTOCOMMIT_FALSE;
-			cubrid_set_autocommit($conn_id, $_temp);
-		}
-
 		return $conn_id;
 	}
 
@@ -332,7 +326,9 @@
 			return $str;
 		}
 
-		if (function_exists('cubrid_real_escape_string') && is_resource($this->conn_id))
+		if (function_exists('cubrid_real_escape_string') &&
+			(is_resource($this->conn_id)
+				OR (get_resource_type($this->conn_id) === 'Unknown' && preg_match('/Resource id #/', strval($this->conn_id)))))
 		{
 			$str = cubrid_real_escape_string($str, $this->conn_id);
 		}
@@ -359,7 +355,7 @@
 	 */
 	public function affected_rows()
 	{
-		return @cubrid_affected_rows($this->conn_id);
+		return @cubrid_affected_rows();
 	}
 
 	// --------------------------------------------------------------------
@@ -550,7 +546,7 @@
 	 */
 	protected function _insert($table, $keys, $values)
 	{
-		return 'INSERT INTO '.$table.' ("'.implode('", "', $keys).'") VALUES ('.implode(', ', $values).')';
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -568,7 +564,7 @@
 	 */
 	protected function _replace($table, $keys, $values)
 	{
-		return 'REPLACE INTO '.$table.' ("'.implode('", "', $keys).'") VALUES ('.implode(', ', $values).')';
+		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -585,7 +581,7 @@
 	 */
 	protected function _insert_batch($table, $keys, $values)
 	{
-		return 'INSERT INTO '.$table.' ("'.implode('", "', $keys).'") VALUES '.implode(', ', $values);
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
 	}
 
 	// --------------------------------------------------------------------
@@ -602,15 +598,20 @@
 	 * @param	array	the limit 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[] = sprintf('"%s" = %s', $key, $val);
+			$valstr[] = $key.' = '.$val;
 		}
 
-		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
-			.(($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '')
+		$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);
 	}
diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php
index 11143a0..5f79857 100644
--- a/system/database/drivers/cubrid/cubrid_forge.php
+++ b/system/database/drivers/cubrid/cubrid_forge.php
@@ -21,7 +21,7 @@
  * @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
+ * @since		Version 3.0
  * @filesource
  */
 
@@ -42,8 +42,8 @@
 	 */
 	public function _create_database($name)
 	{
-		// CUBRID does not allow to create a database in SQL. The GUI tools
-		// have to be used for this purpose.
+		// CUBRID does not allow to create a database in SQL. GUI or
+		// command line tools have to be used for this purpose.
 		return FALSE;
 	}
 
@@ -57,8 +57,8 @@
 	 */
 	public function _drop_database($name)
 	{
-		// CUBRID does not allow to drop a database in SQL. The GUI tools
-		// have to be used for this purpose.
+		// CUBRID does not allow to drop a database in SQL. GUI or
+		// command line tools have to be used for this purpose.
 		return FALSE;
 	}
 
@@ -88,7 +88,7 @@
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t\"".$this->db->protect_identifiers($field).'"'
+				$sql .= "\n\t".$this->db->protect_identifiers($field)
 					.( ! empty($attributes['NAME']) ? ' '.$this->db->protect_identifiers($attributes['NAME']).' ' : '');
 
 				if ( ! empty($attributes['TYPE']))
@@ -104,7 +104,9 @@
 							case 'numeric':
 								$sql .= '('.implode(',', $attributes['CONSTRAINT']).')';
 								break;
-							case 'enum': // As of version 8.4.0 CUBRID does not support enum data type
+							case 'enum':
+								// Will be supported in the future as part a part of
+								// MySQL compatibility features.
 								break;
 							case 'set':
 								$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
@@ -115,7 +117,7 @@
 					}
 				}
 
-			/* As of version 8.4.0 CUBRID does not support UNSIGNED INTEGER data type.
+			/* As of version 8.4.1 CUBRID does not support UNSIGNED INTEGER data type.
 			 * Will be supported in the next release as a part of MySQL Compatibility.
 			 *
 				if (isset($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
@@ -156,7 +158,7 @@
 	{
 		$sql = 'CREATE TABLE ';
 
-		/* As of version 8.4.0 CUBRID does not support this SQL syntax.
+		/* As of version 8.4.1 CUBRID does not support this SQL syntax.
 		if ($if_not_exists === TRUE)
 		{
 			$sql .= 'IF NOT EXISTS ';
@@ -168,7 +170,7 @@
 		// If there is a PK defined
 		if (count($primary_keys) > 0)
 		{
-			$key_name = 'pk_'.$table.'_'.$this->db->protect_identifiers(implode('_', $primary_keys));
+			$key_name = $this->db->protect_identifiers('pk_'.$table.'_'.implode('_', $primary_keys));
 			$sql .= ",\n\tCONSTRAINT ".$key_name.' PRIMARY KEY('.implode(', ', $this->db->protect_identifiers($primary_keys)).')';
 		}
 
@@ -178,12 +180,12 @@
 			{
 				if (is_array($key))
 				{
-					$key_name = $this->db->protect_identifiers(implode('_', $key));
+					$key_name = $this->db->protect_identifiers('idx_'.$table.implode('_', $key));
 					$key = $this->db->protect_identifiers($key);
 				}
 				else
 				{
-					$key_name = $this->db->protect_identifiers($key);
+					$key_name = $this->db->protect_identifiers('idx_'.$table.$key);
 					$key = array($key_name);
 				}
 
diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php
index 7a72cdd..3351b34 100644
--- a/system/database/drivers/cubrid/cubrid_result.php
+++ b/system/database/drivers/cubrid/cubrid_result.php
@@ -83,51 +83,21 @@
 	 */
 	public function field_data()
 	{
-		$retval = $tablePrimaryKeys = array();
+		$retval = array();
+		$i = 0;
 
 		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;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $field->name;
+			// CUBRID returns type as e.g. varchar(100),
+			// so we need to remove all digits and brackets.
+			$retval[$i]->type		= preg_replace('/[\d()]/', '', $field->type);
+			$retval[$i]->default		= $field->def;
+			// Use CUBRID's native API to obtain column's max_length,
+			// otherwise $field->max_length has incorrect info
+			$retval[$i]->max_length		= cubrid_field_len($this->result_id, $i);
+			$retval[$i++]->primary_key	= $field->primary_key;
 		}
 
 		return $retval;
diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php
index dbfbe5f..ab9056f 100644
--- a/system/database/drivers/cubrid/cubrid_utility.php
+++ b/system/database/drivers/cubrid/cubrid_utility.php
@@ -21,7 +21,7 @@
  * @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
+ * @since		Version 3.0
  * @filesource
  */
 
@@ -39,14 +39,9 @@
 	 *
 	 * @return	array
 	 */
-	public 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.
-		return "SELECT '".$this->database."'";
+		return $this->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id);
 	}
 
 	// --------------------------------------------------------------------