added LIKE condition escaping to all drivers and Active Record
updated all DB drivers to accept arrays in escape_str()
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
index c757e6a..d48f43e 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_active_rec.php
@@ -707,7 +707,7 @@
 
 			$prefix = (count($this->ar_like) == 0) ? '' : $type;
 
-			$v = $this->escape_str($v);
+			$v = $this->escape_like_str($v);
 
 			if ($side == 'before')
 			{
@@ -722,6 +722,12 @@
 				$like_statement = $prefix." $k $not LIKE '%{$v}%'";
 			}
 			
+			// some platforms require an escape sequence definition for LIKE wildcards
+			if ($this->_like_escape_str != '')
+			{
+				$like_statement = $like_statement.sprintf($this->_like_escape_str, $this->_like_escape_char);
+			}
+			
 			$this->ar_like[] = $like_statement;
 			if ($this->ar_caching === TRUE)
 			{
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 9385870..729af5b 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -670,7 +670,7 @@
 	 *
 	 * @access	public
 	 * @param	string
-	 * @return	integer		
+	 * @return	mixed		
 	 */	
 	function escape($str)
 	{
@@ -691,7 +691,24 @@
 	}
 
 	// --------------------------------------------------------------------
+	
+	/**
+	 * Smart Escape LIKE String
+	 *
+	 * Calls the individual driver for platform
+	 * specific escaping for LIKE conditions
+	 * 
+	 * @access	public
+	 * @param	string
+	 * @return	mixed
+	 */
+    function escape_like_str($str)    
+    {    
+    	return $this->escape_str($str, TRUE);
+	}
 
+	// --------------------------------------------------------------------
+	
 	/**
 	 * Primary
 	 *
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index addbd6b..c89e254 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -34,6 +34,11 @@
 	
 	// The character used for escaping
 	var $_escape_char = '';
+
+	// clause and character used for LIKE escape sequences
+	var $_like_escape_str = " ESCAPE '%s' ";
+	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
@@ -225,15 +230,36 @@
 	 *
 	 * @access	public
 	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str)	
+	function escape_str($str, $like = FALSE)
 	{
+		if (is_array($str))
+		{
+			foreach($str as $key => $val)
+	   		{
+				$str[$key] = $this->escape_str($val, $like);
+	   		}
+   		
+	   		return $str;
+	   	}
+
 		// Access the CI object
 		$CI =& get_instance();
 		
 		// Escape single quotes
-		return str_replace("'", "''", $CI->input->_remove_invisible_characters($str));
+		$str = str_replace("'", "''", $CI->input->_remove_invisible_characters($str));
+		
+		// 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;
 	}
 	
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index a0cdb58..5b2ba62 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -34,7 +34,11 @@
 
 	// The character used for escaping
 	var	$_escape_char = '`';
-	
+
+	// clause and character used for LIKE escape sequences - not used in MySQL
+	var $_like_escape_str = '';
+	var $_like_escape_chr = '';
+
 	/**
 	 * Whether to use the MySQL "delete hack" which allows the number
 	 * of affected rows to be shown. Uses a preg_replace when enabled,
@@ -256,15 +260,16 @@
 	 *
 	 * @access	public
 	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str)	
+	function escape_str($str, $like = FALSE)	
 	{	
 		if (is_array($str))
 		{
 			foreach($str as $key => $val)
 	   		{
-				$str[$key] = $this->escape_str($val);
+				$str[$key] = $this->escape_str($val, $like);
 	   		}
    		
 	   		return $str;
@@ -272,16 +277,24 @@
 
 		if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))
 		{
-			return mysql_real_escape_string($str, $this->conn_id);
+			$str = mysql_real_escape_string($str, $this->conn_id);
 		}
 		elseif (function_exists('mysql_escape_string'))
 		{
-			return mysql_escape_string($str);
+			$str = mysql_escape_string($str);
 		}
 		else
 		{
-			return addslashes($str);
+			$str = addslashes($str);
 		}
+		
+		// escape LIKE condition wildcards
+		if ($like === TRUE)
+		{
+			$str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+		}
+		
+		return $str;
 	}
 		
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 9ef18e0..92d8711 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -35,6 +35,10 @@
 	// The character used for escaping
 	var $_escape_char = '`';
 
+	// clause and character used for LIKE escape sequences - not used in MySQL
+	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
@@ -257,22 +261,41 @@
 	 *
 	 * @access	public
 	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str)	
+	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('mysqli_real_escape_string') AND is_object($this->conn_id))
 		{
-			return mysqli_real_escape_string($this->conn_id, $str);
+			$str = mysqli_real_escape_string($this->conn_id, $str);
 		}
 		elseif (function_exists('mysql_escape_string'))
 		{
-			return mysql_escape_string($str);
+			$str = mysql_escape_string($str);
 		}
 		else
 		{
-			return addslashes($str);
+			$str = addslashes($str);
 		}
+		
+		// escape LIKE condition wildcards
+		if ($like === TRUE)
+		{
+			$str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+		}
+		
+		return $str;
 	}
 		
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 42dd517..1fdb1bc 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -47,7 +47,11 @@
 	
 	// The character used for excaping
 	var $_escape_char = '"';
-
+	
+	// clause and character used for LIKE escape sequences
+	var $_like_escape_str = " escape '%s' ";
+	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
@@ -368,14 +372,35 @@
 	 *
 	 * @access  public
 	 * @param   string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return  string
 	 */
-	function escape_str($str)
+	function escape_str($str, $like = FALSE)
 	{
+		if (is_array($str))
+		{
+			foreach($str as $key => $val)
+	   		{
+				$str[$key] = $this->escape_str($val, $like);
+	   		}
+   		
+	   		return $str;
+	   	}
+
 		// Access the CI object
 		$CI =& get_instance();
 
-		return $CI->input->_remove_invisible_characters($str);
+		$str = $CI->input->_remove_invisible_characters($str);
+		
+		// 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;
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index 0f8b420..a14aaa1 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -34,7 +34,11 @@
 	
 	// the character used to excape - not necessary for ODBC
 	var $_escape_char = '';
-
+	
+	// clause and character used for LIKE escape sequences
+	var $_like_escape_str = " {escape '%s'} ";
+	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
@@ -237,15 +241,36 @@
 	 *
 	 * @access	public
 	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str)	
+	function escape_str($str, $like = FALSE)
 	{
+		if (is_array($str))
+		{
+			foreach($str as $key => $val)
+	   		{
+				$str[$key] = $this->escape_str($val, $like);
+	   		}
+   		
+	   		return $str;
+	   	}
+
 		// Access the CI object
 		$CI =& get_instance();
-
+		
 		// ODBC doesn't require escaping
-		return $CI->_remove_invisible_characters($str);
+		$str = $CI->input->_remove_invisible_characters($str);
+		
+		// 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;
 	}
 	
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 9d53b1e..8d0d890 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -34,6 +34,10 @@
 	
 	var $_escape_char = '"';
 
+	// clause and character used for LIKE escape sequences
+	var $_like_escape_str = " ESCAPE '%s' ";
+	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
@@ -253,11 +257,32 @@
 	 *
 	 * @access	public
 	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str)	
-	{	
-		return pg_escape_string($str);
+	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 = pg_escape_string($str);
+		
+		// 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;
 	}
 		
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index 3ef88db..104a3bc 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_driver.php
@@ -37,6 +37,10 @@
 	// The character used to escape with - not needed for SQLite
 	var $_escape_char = '';
 
+	// clause and character used for LIKE escape sequences
+ 	var $_like_escape_str = " ESCAPE '%s' ";
+	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
@@ -253,11 +257,32 @@
 	 *
 	 * @access	public
 	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str)	
+	function escape_str($str, $like = FALSE)
 	{
-		return sqlite_escape_string($str);
+		if (is_array($str))
+		{
+			foreach($str as $key => $val)
+	   		{
+				$str[$key] = $this->escape_str($val, $like);
+	   		}
+   		
+	   		return $str;
+	   	}
+	
+		$str = sqlite_escape_string($str);
+		
+		// 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;
 	}
 		
 	// --------------------------------------------------------------------