Initial Import
diff --git a/system/drivers/DB_active_record.php b/system/drivers/DB_active_record.php
new file mode 100644
index 0000000..373c0f6
--- /dev/null
+++ b/system/drivers/DB_active_record.php
@@ -0,0 +1,875 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Rick Ellis
+ * @copyright	Copyright (c) 2006, pMachine, Inc.
+ * @license		http://www.codeignitor.com/user_guide/license.html 
+ * @link		http://www.codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+ 
+// ------------------------------------------------------------------------
+
+/**
+ * Active Record Class
+ * 
+ * This is the platform-independent base Active Record implementation class.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_active_record extends CI_DB_driver {
+
+	var $ar_select		= array();
+	var $ar_distinct	= FALSE;
+	var $ar_from		= array();
+	var $ar_join		= array();
+	var $ar_where		= array();
+	var $ar_like		= array();
+	var $ar_groupby		= array();
+	var $ar_having		= array();
+	var $ar_limit		= FALSE;
+	var $ar_offset		= FALSE;
+	var $ar_order		= FALSE;
+	var $ar_orderby		= array();
+	var $ar_set			= array();	
+
+
+	/**
+	 * Select
+	 *
+	 * Generates the SELECT portion of the query
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	object
+	 */
+	function select($select = '*')
+	{
+		if (is_string($select))
+		{
+			$select = explode(',', $select);
+		}
+	
+		foreach ($select as $val)
+		{
+			$val = trim($val);
+		
+			if ($val != '')
+				$this->ar_select[] = $val;
+		}
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * DISTINCT
+	 *
+	 * Sets a flag which tells the query string compiler to add DISTINCT
+	 *
+	 * @access	public
+	 * @param	bool
+	 * @return	object
+	 */
+	function distinct($val = TRUE)
+	{
+		$this->ar_distinct = (is_bool($val)) ? $val : TRUE;
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * From
+	 *
+	 * Generates the FROM portion of the query
+	 *
+	 * @access	public
+	 * @param	mixed	can be a string or array
+	 * @return	object
+	 */
+	function from($from)
+	{
+		foreach ((array)$from as $val)
+		{
+			$this->ar_from[] = $this->dbprefix.$val;
+		}
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Join
+	 *
+	 * Generates the JOIN portion of the query
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string	the join condition
+	 * @param	string	the type of join
+	 * @return	object
+	 */
+	function join($table, $cond, $type = '')
+	{		
+		if ($type != '')
+		{
+			$type = strtoupper(trim($type));
+
+			if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER')))
+			{
+				$type = '';
+			}
+			else
+			{
+				$type .= ' ';
+			}
+		}
+	
+		$this->ar_join[] = $type.'JOIN '.$table.' ON '.$cond;
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where
+	 *
+	 * Generates the WHERE portion of the query. Separates
+	 * multiple calls with AND
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function where($key, $value = NULL)
+	{
+		return $this->_where($key, $value, 'AND ');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * OR Where
+	 *
+	 * Generates the WHERE portion of the query. Separates
+	 * multiple calls with OR
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function orwhere($key, $value = NULL)
+	{
+		return $this->_where($key, $value, 'OR ');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where
+	 *
+	 * Called by where() or orwhere()
+	 *
+	 * @access	private
+	 * @param	mixed
+	 * @param	mixed
+	 * @param	string
+	 * @return	object
+	 */
+	function _where($key, $value = NULL, $type = 'AND ')
+	{
+		if ( ! is_array($key))
+		{
+			$key = array($key => $value);
+		}
+ 	 	
+		foreach ($key as $k => $v)
+		{
+			$prefix = (count($this->ar_where) == 0) ? '' : $type;
+			
+			if ( ! is_null($v))
+			{
+				if ( ! $this->_has_operator($k))
+				{
+					$k .= ' =';
+				}
+			
+				$v = ' '.$this->escape($v);
+			}
+						
+			$this->ar_where[] = $prefix.$k.$v;
+		}
+		return $this;
+	}
+	
+	
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Like
+	 *
+	 * Generates a %LIKE% portion of the query. Separates
+	 * multiple calls with AND
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function like($field, $match = '')
+	{
+		return $this->_like($field, $match, 'AND ');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * OR Like
+	 *
+	 * Generates a %LIKE% portion of the query. Separates
+	 * multiple calls with OR
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function orlike($field, $match = '')
+	{
+		return $this->_like($field, $match, 'OR ');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Like
+	 *
+	 * Called by like() or olike()
+	 *
+	 * @access	private
+	 * @param	mixed
+	 * @param	mixed
+	 * @param	string
+	 * @return	object
+	 */
+	function _like($field, $match = '', $type = 'AND ')
+	{
+		if ( ! is_array($field))
+		{
+			$field = array($field => $match);
+		}
+ 	
+		foreach ($field as $k => $v)
+		{
+			$prefix = (count($this->ar_like) == 0) ? '' : $type;
+			
+			$v = $this->escape_str($v);
+									
+			$this->ar_like[] = $prefix." $k LIKE '%{$v}%'";
+		}
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * GROUP BY
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	object
+	 */
+	function groupby($by)
+	{
+		if (is_string($by))
+		{
+			$by = explode(',', $by);
+		}
+	
+		foreach ($by as $val)
+		{
+			$val = trim($val);
+		
+			if ($val != '')
+				$this->ar_groupby[] = $val;
+		}
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the HAVING value
+	 *
+	 * Separates multiple calls with AND
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	object
+	 */
+	function having($key, $value = '')
+	{
+		return $this->_having($key, $value, 'AND ');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the OR HAVING value
+	 *
+	 * Separates multiple calls with OR
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	object
+	 */
+	function orhaving($key, $value = '')
+	{
+		return $this->_having($key, $value, 'OR ');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the OR HAVING value
+	 *
+	 * Called by having() or orhaving()
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	object
+	 */
+	function _having($key, $value = '', $type = 'AND ')
+	{
+		if ( ! is_array($key))
+		{
+			$key = array($key => $value);
+		}
+	
+		foreach ($key as $k => $v)
+		{
+			$prefix = (count($this->ar_having) == 0) ? '' : $type;
+			
+			if ($v != '')
+			{
+				$v = ' '.$this->escape($v);
+			}
+			
+			$this->ar_having[] = $prefix.$k.$v;
+		}
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the ORDER BY value
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string	direction: asc or desc
+	 * @return	object
+	 */
+	function orderby($orderby, $direction = '')
+	{
+		if (trim($direction) != '')
+		{
+			$direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'))) ? ' '.$direction : ' ASC';
+		}
+		
+		$this->ar_orderby[] = $orderby.$direction;
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the LIMIT value
+	 *
+	 * @access	public
+	 * @param	integer	the limit value
+	 * @param	integer	the offset value
+	 * @return	object
+	 */
+	function limit($value, $offset = '')
+	{
+		$this->ar_limit = $value;
+		
+		if ($offset != '')
+			$this->ar_offset = $offset;
+		
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the OFFSET value
+	 *
+	 * @access	public
+	 * @param	integer	the offset value
+	 * @return	object
+	 */
+	function offset($value)
+	{
+		$this->ar_offset = $value;
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The "set" function.  Allows key/value pairs to be set for inserting or updating
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	string
+	 * @return	object
+	 */
+	function set($key, $value = '')
+	{
+		$key = $this->_object_to_array($key);
+	
+		if ( ! is_array($key))
+		{
+			$key = array($key => $value);
+		}	
+
+		foreach ($key as $k => $v)
+		{
+			$this->ar_set[$k] = $this->escape($v);
+		}
+		
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get
+	 *
+	 * Compiles the select statement based on the other functions called
+	 * and runs the query
+	 *
+	 * @access	public
+	 * @param	string	the limit clause
+	 * @param	string	the offset clause
+	 * @return	object
+	 */
+	function get($table = '', $limit = null, $offset = null)
+	{
+		if ($table != '')
+		{
+			$this->from($table);
+		}
+		
+		if ( ! is_null($limit))
+		{
+			$this->limit($limit, $offset);
+		}
+			
+		$sql = $this->_compile_select();
+
+		$this->_reset_select();
+		return $this->query($sql);		
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * GetWhere
+	 *
+	 * Allows the where clause, limit and offset to be added directly
+	 *
+	 * @access	public
+	 * @param	string	the where clause
+	 * @param	string	the limit clause
+	 * @param	string	the offset clause
+	 * @return	object
+	 */
+	function getwhere($table = '', $where = null, $limit = null, $offset = null)
+	{
+		if ($table != '')
+		{
+			$this->from($table);
+		}
+
+		if ( ! is_null($where))
+		{
+			$this->where($where);
+		}
+		
+		if ( ! is_null($limit))
+		{
+			$this->limit($limit, $offset);
+		}
+			
+		$sql = $this->_compile_select();
+
+		$this->_reset_select();
+		return $this->query($sql);		
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert
+	 *
+	 * Compiles an insert string and runs the query
+	 *
+	 * @access	public
+	 * @param	string	the table to retrieve the results from
+	 * @param	array	an associative array of insert values
+	 * @return	object
+	 */
+	function insert($table = '', $set = NULL)
+	{
+		if ( ! is_null($set))
+		{
+			$this->set($set);
+		}
+	
+		if (count($this->ar_set) == 0)
+		{
+            if ($this->db_debug)
+            {
+				return $this->display_error('db_must_use_set');
+            }
+            return FALSE;        
+		}
+
+		if ($table == '')
+		{
+			if ( ! isset($this->ar_from[0]))
+			{
+				if ($this->db_debug)
+				{
+					return $this->display_error('db_must_set_table');
+				}
+				return FALSE;
+			}
+			
+			$table = $this->ar_from[0];
+		}
+					
+		$sql = $this->_insert($this->dbprefix.$table, array_keys($this->ar_set), array_values($this->ar_set));
+		
+		$this->_reset_write();
+		return $this->query($sql);		
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update
+	 *
+	 * Compiles an update string and runs the query
+	 *
+	 * @access	public
+	 * @param	string	the table to retrieve the results from
+	 * @param	array	an associative array of update values
+	 * @param	mixed	the where clause
+	 * @return	object
+	 */
+	function update($table = '', $set = NULL, $where = null)
+	{
+		if ( ! is_null($set))
+		{
+			$this->set($set);
+		}
+	
+		if (count($this->ar_set) == 0)
+		{
+            if ($this->db_debug)
+            {
+				return $this->display_error('db_must_use_set');
+            }
+            return FALSE;        
+		}
+
+		if ($table == '')
+		{
+			if ( ! isset($this->ar_from[0]))
+			{
+				if ($this->db_debug)
+				{
+					return $this->display_error('db_must_set_table');
+				}
+				return FALSE;
+			}
+			
+			$table = $this->ar_from[0];
+		}
+		
+		if ($where != null)
+		{
+			$this->where($where);
+		}
+		
+		$sql = $this->_update($this->dbprefix.$table, $this->ar_set, $this->ar_where);
+		
+		$this->_reset_write();
+		return $this->query($sql);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete
+	 *
+	 * Compiles a delete string and runs the query
+	 *
+	 * @access	public
+	 * @param	string	the table to retrieve the results from
+	 * @param	mixed	the where clause
+	 * @return	object
+	 */
+	function delete($table = '', $where = '')
+	{
+		if ($table == '')
+		{
+			if ( ! isset($this->ar_from[0]))
+			{
+				if ($this->db_debug)
+				{
+					return $this->display_error('db_must_set_table');
+				}
+				return FALSE;
+			}
+			
+			$table = $this->ar_from[0];
+		}
+
+		if ($where != '')
+		{
+			$this->where($where);
+		}
+
+		if (count($this->ar_where) == 0)
+		{
+            if ($this->debug)
+            {
+				return $this->display_error('db_del_must_use_where');
+            }
+            return FALSE;        
+		}		
+		
+		$sql = $this->_delete($this->dbprefix.$table, $this->ar_where);
+
+		$this->_reset_write();
+		return $this->query($sql);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Use Table - DEPRECATED 
+	 *
+	 * @deprecated	use $this->db->from instead
+	 */
+	function use_table($table)
+	{
+		return $this->from($table);
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * ORDER BY - DEPRECATED
+	 *
+	 * @deprecated	use $this->db->orderby() instead
+	 */
+	function order_by($orderby, $direction = '')
+	{
+		return $this->orderby($orderby, $direction);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Tests whether the string has an SQL operator
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	bool
+	 */
+	function _has_operator($str)
+	{
+		$str = trim($str);
+		if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str))
+		{
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Compile the SELECT statement
+	 *
+	 * Generates a query string based on which functions were used. 
+	 * Should not be called directly.  The get() function calls it.
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _compile_select()
+	{
+		$sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
+	
+		$sql .= (count($this->ar_select) == 0) ? '*' : implode(', ', $this->ar_select);
+
+		if (count($this->ar_from) > 0)
+		{
+			$sql .= "\nFROM ";
+			$sql .= implode(', ', $this->ar_from);
+		}
+
+		if (count($this->ar_join) > 0)
+		{		
+			$sql .= "\n";
+			$sql .= implode("\n", $this->ar_join);
+		}
+
+		if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)
+		{
+			$sql .= "\nWHERE ";
+		}
+
+		$sql .= implode("\n", $this->ar_where);
+		
+		if (count($this->ar_like) > 0)
+		{
+			if (count($this->ar_where) > 0)
+			{
+				$sql .= " AND ";
+			}
+
+			$sql .= implode("\n", $this->ar_like);
+		}
+		
+		if (count($this->ar_groupby) > 0)
+		{
+			$sql .= "\nGROUP BY ";
+			$sql .= implode(', ', $this->ar_groupby);
+		}
+		
+		if (count($this->ar_having) > 0)
+		{
+			$sql .= "\nHAVING ";
+			$sql .= implode("\n", $this->ar_having);
+		}
+
+		if (count($this->ar_orderby) > 0)
+		{
+			$sql .= "\nORDER BY ";
+			$sql .= implode(', ', $this->ar_orderby);
+			
+			if ($this->ar_order !== FALSE)
+			{
+				$sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
+			}		
+		}
+		
+		if (ctype_digit($this->ar_limit))
+		{
+			$sql .= "\n";
+			$sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);
+		}
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Object to Array
+	 *
+	 * Takes an object as input and convers the class variables to array key/vals
+	 *
+	 * @access	public
+	 * @param	object
+	 * @return	array
+	 */
+	function _object_to_array($object)
+	{
+		if ( ! is_object($object))
+		{
+			return $object;
+		}
+		
+		$array = array();
+		foreach (get_object_vars($object) as $key => $val)
+		{
+			if ( ! is_object($val) AND ! is_array($val))
+			{
+				$array[$key] = $val;
+			}
+		}
+	
+		return $array;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Resets the active record values.  Called by the get() function
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _reset_select()
+	{
+		$this->ar_select	= array();
+		$this->ar_distinct	= FALSE;
+		$this->ar_from		= array();
+		$this->ar_join		= array();
+		$this->ar_where		= array();
+		$this->ar_like		= array();
+		$this->ar_groupby	= array();
+		$this->ar_having	= array();
+		$this->ar_limit		= FALSE;
+		$this->ar_offset	= FALSE;
+		$this->ar_order		= FALSE;
+		$this->ar_orderby	= array();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Resets the active record "write" values.
+	 *
+	 * Called by the insert() or update() functions
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _reset_write()
+	{
+		$this->ar_set		= array();
+		$this->ar_from		= array();
+		$this->ar_where		= array();
+	}
+	
+}
+
+?>
\ No newline at end of file
diff --git a/system/drivers/DB_driver.php b/system/drivers/DB_driver.php
new file mode 100644
index 0000000..ed18d54
--- /dev/null
+++ b/system/drivers/DB_driver.php
@@ -0,0 +1,948 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Rick Ellis
+ * @copyright	Copyright (c) 2006, pMachine, Inc.
+ * @license		http://www.codeignitor.com/user_guide/license.html 
+ * @link		http://www.codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+ 
+// ------------------------------------------------------------------------
+
+/**
+ * Database Driver Class
+ * 
+ * This is the platform-independent base DB implementation class.
+ * This class will not be called directly. Rather, the adapter
+ * class for the specific database will extend and instantiate it.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_driver {
+
+	var $username;
+	var $password;
+	var $hostname;
+	var $database;
+	var $dbdriver		= 'mysql';
+	var $dbprefix		= '';
+	var $pconnect		= FALSE;
+	var $conn_id		= FALSE;
+	var $result_id		= FALSE;
+	var $db_debug		= FALSE;
+	var $benchmark		= 0;
+	var $query_count	= 0;
+	var $bind_marker	= '?';
+	var $queries		= array();
+	
+	/**
+	 * Constructor.  Accepts one parameter containing the database
+	 * connection settings. 
+	 *
+	 * Database settings can be passed as discreet 
+	 * parameters or as a data source name in the first 
+	 * parameter. DSNs must have this prototype:
+	 * $dsn = 'driver://username:password@hostname/database';
+	 *
+	 * @param mixed. Can be an array or a DSN string
+	 */	
+	function CI_DB_driver($params)
+	{
+		$this->initialize($params);
+		log_message('debug', 'Database Driver Class Initialized');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize Database Settings
+	 *
+	 * @access	private Called by the constructor
+	 * @param	mixed
+	 * @return	void
+	 */	
+	function initialize($params = '')
+	{	
+		if (is_array($params))
+		{
+			foreach (array('hostname' => '', 'username' => '', 'password' => '', 'database' => '', 'dbdriver' => 'mysql', 'dbprefix' => '', 'pconnect' => FALSE, 'db_debug' => FALSE) as $key => $val)
+			{
+				$this->$key = ( ! isset($params[$key])) ? $val : $params[$key];
+			}
+		}
+		elseif (strpos($params, '://'))
+		{
+			if (FALSE === ($dsn = @parse_url($params)))
+			{
+				log_message('error', 'Invalid DB Connection String');
+			
+				if ($this->debug)
+				{
+					return $this->display_error('db_invalid_connection_str');
+				}
+				return FALSE;			
+			}
+			
+			$this->hostname = ( ! isset($dsn['host'])) ? '' : rawurldecode($dsn['host']);
+			$this->username = ( ! isset($dsn['user'])) ? '' : rawurldecode($dsn['user']);
+			$this->password = ( ! isset($dsn['pass'])) ? '' : rawurldecode($dsn['pass']);
+			$this->database = ( ! isset($dsn['path'])) ? '' : rawurldecode(substr($dsn['path'], 1));
+		}
+	
+		if ($this->pconnect == FALSE)
+		{
+			$this->conn_id = $this->db_connect();
+		}
+		else
+		{
+			$this->conn_id = $this->db_pconnect();
+		}	
+       
+        if ( ! $this->conn_id)
+        { 
+			log_message('error', 'Unable to connect to the database');
+			
+            if ($this->db_debug)
+            {
+				$this->display_error('db_unable_to_connect');
+            }
+        }
+		else
+		{
+			if ( ! $this->db_select())
+			{
+				log_message('error', 'Unable to select database: '.$this->database);
+			
+				if ($this->db_debug)
+				{
+					$this->display_error('db_unable_to_select', $this->database);
+				}
+			}	
+		}	
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Database Version Number.  Returns a string containing the 
+	 * version of the database being used
+	 *
+	 * @access	public
+	 * @return	string	
+	 */	
+	function version()
+	{
+		if (FALSE === ($sql = $this->_version()))
+		{
+            if ($this->db_debug)
+            {
+				return $this->display_error('db_unsupported_function');
+            }
+            return FALSE;        
+		}
+	
+		$query = $this->query($sql);
+		$row = $query->row();
+		return $row->ver;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * Accepts an SQL string as input and returns a result object upon 
+	 * successful execution of a "read" type query.  Returns boolean TRUE 
+	 * upon successful execution of a "write" type query. Returns boolean 
+	 * FALSE upon failure, and if the $db_debug variable is set to TRUE 
+	 * will raise an error.
+	 * 
+	 * @access	public
+	 * @param	string	An SQL query string
+	 * @param	array	An array of binding data
+	 * @return	mixed		 
+	 */	
+    function query($sql, $binds = FALSE)
+    {    
+		if ( ! $this->conn_id)
+		{
+			$this->initialize();
+		}
+
+		if ($sql == '')
+		{
+            if ($this->db_debug)
+            {
+				log_message('error', 'Invalid query: '.$sql);
+				return $this->display_error('db_invalid_query');
+            }
+            return FALSE;        
+		}
+		
+		// Compile binds if needed
+		if ($binds !== FALSE)
+		{
+			$sql = $this->compile_binds($sql, $binds);
+		}
+
+		// Start the Query Timer
+        $time_start = list($sm, $ss) = explode(' ', microtime());
+        
+        // Save the  query for debugging
+        $this->queries[] = $sql;
+        
+		// Run the Query
+        if (FALSE === ($this->result_id = $this->execute($sql, $this->conn_id)))
+        { 
+            if ($this->db_debug)
+            {
+				log_message('error', 'Query error: '.$this->error_message());
+				return $this->display_error(
+										array(
+												'Error Number: '.$this->error_number(), 
+												$this->error_message(),
+												$sql
+											)
+										);
+            }
+          
+          return FALSE;
+        }
+        
+		// Stop and aggregate the query time results
+		$time_end = list($em, $es) = explode(' ', microtime());
+		$this->benchmark += ($em + $es) - ($sm + $ss);
+
+		// Increment the query counter
+        $this->query_count++;
+        
+		// Was the query a "write" type?
+		// If so we'll return simply return true
+		if ($this->is_write_type($sql) === TRUE)
+		{
+			return TRUE;
+		}
+
+		// Instantiate and return the DB result object
+		$result = 'CI_DB_'.$this->dbdriver.'_result';
+		
+        $RES = new $result();
+        $RES->conn_id	= $this->conn_id;
+        $RES->db_debug	= $this->db_debug;
+        $RES->result_id	= $this->result_id;
+
+		return $RES;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Enables a native PHP function to be run, using a platform agnostic wrapper.
+	 * 
+	 * @access	public
+	 * @param	string	the function name
+	 * @param	mixed	any parameters needed by the function
+	 * @return	mixed		 
+	 */	
+	function call_function($function)
+	{
+		$driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
+	
+		if (FALSE === strpos($driver, $function))
+		{
+			$function = $driver.$function;
+		}
+		
+		if ( ! function_exists($function))
+		{ 
+			if ($this->debug)
+			{
+				return $this->display_error('db_unsupported_function');
+			}
+			return FALSE;			
+		}
+		else
+		{
+			$args = (func_num_args() > 1) ? array_shift(func_get_args()) : null;
+			
+			return call_user_func_array($function, $args); 
+		}
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Determines if a query is a "write" type. 
+	 * 
+	 * @access	public
+	 * @param	string	An SQL query string
+	 * @return	boolean		 
+	 */	
+	function is_write_type($sql)
+	{
+		if ( ! preg_match('/^\s*"?(INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql)) 
+		{
+			return FALSE;
+		}
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Calculate the aggregate query elapsed time 
+	 * 
+	 * @access	public
+	 * @param	intiger	The number of decimal places
+	 * @return	integer		 
+	 */	
+	function elapsed_time($decimals = 6)
+	{
+		return number_format($this->benchmark, $decimals);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the total number of queries
+	 * 
+	 * @access	public
+	 * @return	integer		 
+	 */	
+	function total_queries()
+	{
+		return $this->query_count;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the last query that was executed
+	 * 
+	 * @access	public
+	 * @return	void		 
+	 */	
+	function last_query()
+	{
+		return end($this->queries);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Smart" Escape String
+	 *
+	 * Escapes data based on type
+	 * Sets boolean and null types
+	 * 
+	 * @access	public
+	 * @param	string
+	 * @return	integer		 
+	 */	
+	function escape($str)
+	{	
+		if ( ! ctype_digit($str)) // bug fix to ensure that numbers are not treated as strings.
+		{
+			switch (gettype($str))
+			{
+				case 'string'	:	$str = "'".$this->escape_str($str)."'";
+					break;
+				case 'boolean'	:	$str = ($str === FALSE) ? 0 : 1;
+					break;
+				default			:	$str = ($str === NULL) ? 'NULL' : $str;
+					break;
+			}		
+		}
+	
+		return $str;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns an array of table names
+	 * 
+	 * @access	public
+	 * @return	array		 
+	 */	
+	function tables()
+	{      
+		if (FALSE === ($sql = $this->_show_tables()))
+		{
+            if ($this->db_debug)
+            {
+				return $this->display_error('db_unsupported_function');
+            }
+            return FALSE;        
+		}
+
+		$retval = array();
+		$query = $this->query($sql);
+		
+		if ($query->num_rows() > 0)
+		{
+			foreach($query->result_array() as $row)
+			{
+				$retval[] = array_shift($row);
+			}
+		}
+
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Determine if a particular table exists
+	 * @access	public
+	 * @return	boolean
+	 */
+	function table_exists($table_name)
+	{		
+		return ( ! in_array($this->dbprefix.$table_name, $this->tables())) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch MySQL Field Names
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	array		 
+	 */
+    function field_names($table = '')
+    {
+    	if ($table == '')
+    	{
+			if ($this->debug)
+			{
+				return $this->display_error('db_field_param_missing');
+			}
+			return FALSE;			
+    	}
+    	
+		if (FALSE === ($sql = $this->_show_columns($this->dbprefix.$table)))
+		{
+            if ($this->db_debug)
+            {
+				return $this->display_error('db_unsupported_function');
+            }
+            return FALSE;        
+		}
+    	
+    	$query = $this->query($sql);
+    	
+    	$retval = array();
+		foreach($query->result_array() as $row)
+		{
+			if ($this->dbdriver == 'mssql' AND isset($row['COLUMN_NAME']))
+			{
+				$retval[] = $row['COLUMN_NAME'];
+			}
+			else
+			{
+				$retval[] = current($row);
+			}    	
+		}
+    	
+    	return $retval;
+    }
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns an object with field data
+	 * 
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	object		 
+	 */	
+	function field_data($table = '')
+	{
+    	if ($table == '')
+    	{
+			if ($this->debug)
+			{
+				return $this->display_error('db_field_param_missing');
+			}
+			return FALSE;			
+    	}
+    	
+    	return $this->_field_data($this->dbprefix.$table);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Primary
+	 *
+	 * Retrieves the primary key.  It assumes that the row in the first
+	 * position is the primary key
+	 * 
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string		 
+	 */	
+	function primary($table = '')
+	{	
+		$fields = $this->field_names($table);
+		
+		if ( ! is_array($fields))
+		{
+			return FALSE;
+		}
+
+		return current($fields);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Compile Bindings
+	 * 
+	 * @access	public
+	 * @param	string	the sql statement
+	 * @param	array	an array of bind data
+	 * @return	string		 
+	 */	
+	function compile_binds($sql, $binds)
+	{	
+		if (FALSE === strpos($sql, $this->bind_marker))
+		{
+			return $sql;
+		}
+		
+		if ( ! is_array($binds))
+		{
+			$binds = array($binds);
+		}
+		
+		foreach ($binds as $val)
+		{
+			$val = $this->escape($val);
+					
+			// Just in case the replacement string contains the bind
+			// character we'll temporarily replace it with a marker
+			$val = str_replace($this->bind_marker, '{%bind_marker%}', $val);
+			$sql = preg_replace("#".preg_quote($this->bind_marker)."#", $val, $sql, 1);
+		}
+
+		return str_replace('{%bind_marker%}', $this->bind_marker, $sql);		
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate an insert string
+	 * 
+	 * @access	public
+	 * @param	string	the table upon which the query will be performed
+	 * @param	array	an associative array data of key/values
+	 * @return	string		 
+	 */	
+	function insert_string($table, $data)
+	{
+		$fields = array();      
+		$values = array();
+		
+		foreach($data as $key => $val) 
+		{
+			$fields[] = $key;
+			$values[] = $this->escape($val);
+		}
+
+		return $this->_insert($this->dbprefix.$table, $fields, $values);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate an update string
+	 * 
+	 * @access	public
+	 * @param	string	the table upon which the query will be performed
+	 * @param	array	an associative array data of key/values
+	 * @param	mixed	the "where" statement
+	 * @return	string		 
+	 */	
+	function update_string($table, $data, $where)
+	{
+		if ($where == '')
+			return false;
+					
+		$fields = array();
+		foreach($data as $key => $val) 
+		{
+			$fields[$key] = $this->escape($val);
+		}
+
+		if ( ! is_array($where))
+		{
+			$dest = array($where);
+		}
+		else
+		{
+			$dest = array();
+			foreach ($where as $key => $val)
+			{
+				$prefix = (count($dest) == 0) ? '' : ' AND ';
+	
+				if ($val != '')
+				{
+					if ( ! $this->_has_operator($key))
+					{
+						$key .= ' =';
+					}
+				
+					$val = ' '.$this->escape($val);
+				}
+							
+				$dest[] = $prefix.$key.$val;
+			}
+		}		
+
+		return $this->_update($this->dbprefix.$table, $fields, $dest);
+	}    
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 * 
+	 * @access	public
+	 * @return	void		 
+	 */	
+    function close()
+    {
+        if (is_resource($this->conn_id))
+        {
+            $this->destroy($this->conn_id);
+		}   
+		$this->conn_id = FALSE;
+    }
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Display an error message
+	 * 
+	 * @access	public
+	 * @param	string	the error message
+	 * @param	string	any "swap" values
+	 * @param	boolean	whether to localize the message
+	 * @return	string	sends the application/errror_db.php template		 
+	 */	
+    function display_error($error = '', $swap = '', $native = FALSE) 
+    {
+		$LANG = new CI_Language();
+		$LANG->load('db');
+
+		$heading = 'MySQL Error';
+		
+		if ($native == TRUE)
+		{
+			$message = $error;
+		}
+		else
+		{
+			$message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
+		}
+
+		if ( ! class_exists('CI_Exceptions'))
+		{
+			include_once(BASEPATH.'libraries/Exceptions.php');
+		}
+		
+		$error = new CI_Exceptions();
+		echo $error->show_error('An Error Was Encountered', $message, 'error_db');
+		exit;
+
+    }  
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field Data - old version - DEPRECATED
+	 * 
+	 * @deprecated	use $this->db->field_data() instead
+	 */	
+	function fields($table = '')
+	{
+		return $this->field_data($table);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Smart Escape String - old version - DEPRECATED
+	 * 
+	 * @deprecated	use $this->db->escape() instead
+	 */	
+	function smart_escape_str($str)
+	{
+		return $this->escape($str);
+	}
+}
+
+
+/**
+ * Database Result Class
+ * 
+ * This is the platform-independent result class.
+ * This class will not be called directly. Rather, the adapter
+ * class for the specific database will extend and instantiate it.
+ *
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_result {
+
+	var $conn_id		= FALSE;
+	var $result_id		= FALSE;
+	var $db_debug		= FALSE;
+	var $result_array	= array();
+	var $result_object	= array();
+	var $current_row 	= 0;
+
+	/**
+	 * Query result.  Acts as a wrapper function for the following functions.
+	 * 
+	 * @access	public
+	 * @param	string	can be "object" or "array"
+	 * @return	mixed	either a result object or array	 
+	 */	
+	function result($type = 'object')
+	{
+		return ($type == 'object') ? $this->result_object() : $this->result_array();
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  "object" version.
+	 * 
+	 * @access	public
+	 * @return	object 
+	 */	
+	function result_object()
+	{
+		if (count($this->result_object) > 0)
+		{
+			return $this->result_object;
+		}
+
+		while ($row = $this->_fetch_object())
+		{
+			$this->result_object[] = $row;
+		}
+		
+		if (count($this->result_object) == 0)
+		{
+			return FALSE;
+		}
+		
+		return $this->result_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  "array" version.
+	 * 
+	 * @access	public
+	 * @return	array 
+	 */	
+	function result_array()
+	{
+		if (count($this->result_array) > 0)
+		{
+			return $this->result_array;
+		}
+			
+		while ($row = $this->_fetch_assoc())
+		{
+			$this->result_array[] = $row;
+		}
+		
+		if (count($this->result_array) == 0)
+		{
+			return FALSE;
+		}
+		
+		return $this->result_array;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  Acts as a wrapper function for the following functions.
+	 * 
+	 * @access	public
+	 * @param	string	can be "object" or "array"
+	 * @return	mixed	either a result object or array	 
+	 */	
+	function row($n = 0, $type = 'object')
+	{
+		return ($type == 'object') ? $this->row_object($n) : $this->row_array($n);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns a single result row - object version
+	 * 
+	 * @access	public
+	 * @return	object 
+	 */	
+	function row_object($n = 0)
+	{
+		if (FALSE ===  ($result = $this->result_object()))
+		{
+			return FALSE;
+		}
+			
+		if ($n != $this->current_row AND isset($result[$n]))
+		{
+			$this->current_row = $n;
+		}
+		
+		return $result[$this->current_row];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns a single result row - array version
+	 * 
+	 * @access	public
+	 * @return	array 
+	 */	
+	function row_array($n = 0)
+	{
+		if (FALSE ===  ($result = $this->result_array()))
+		{
+			return FALSE;
+		}
+			
+		if ($n != $this->current_row AND isset($result[$n]))
+		{
+			$this->current_row = $n;
+		}
+		
+		return $result[$this->current_row];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the "next" row
+	 * 
+	 * @access	public
+	 * @return	object 
+	 */	
+	function next_row($type = 'object')
+	{
+		if (FALSE ===  ($result = $this->result($type)))
+		{
+			return FALSE;
+		}
+
+		if (isset($result[$this->current_row + 1]))
+		{
+			++$this->current_row;
+		}
+				
+		return $result[$this->current_row];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the "previous" row
+	 * 
+	 * @access	public
+	 * @return	object 
+	 */	
+	function previous_row($type = 'object')
+	{
+		if (FALSE ===  ($result = $this->result($type)))
+		{
+			return FALSE;
+		}
+
+		if (isset($result[$this->current_row - 1]))
+		{
+			--$this->current_row;
+		}
+		return $result[$this->current_row];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the "first" row
+	 * 
+	 * @access	public
+	 * @return	object 
+	 */	
+	function first_row($type = 'object')
+	{
+		if (FALSE ===  ($result = $this->result($type)))
+		{
+			return FALSE;
+		}
+		return $result[0];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the "last" row
+	 * 
+	 * @access	public
+	 * @return	object 
+	 */	
+	function last_row($type = 'object')
+	{
+		if (FALSE ===  ($result = $this->result($type)))
+		{
+			return FALSE;
+		}
+		return $result[count($result) -1];
+	}	
+
+}
+
+
+
+/**
+ * Database Field Class
+ * 
+ * This class will contain the field meta-data.  It 
+ * is called by one of the field result functions
+ *
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_field {
+	var $name;
+	var $type;
+	var $default;
+	var $max_length;
+	var $primary_key;
+}
+
+?>
\ No newline at end of file
diff --git a/system/drivers/DB_mssql.php b/system/drivers/DB_mssql.php
new file mode 100644
index 0000000..6156ec3
--- /dev/null
+++ b/system/drivers/DB_mssql.php
@@ -0,0 +1,472 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Rick Ellis
+ * @copyright	Copyright (c) 2006, pMachine, Inc.
+ * @license		http://www.codeignitor.com/user_guide/license.html 
+ * @link		http://www.codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+ 
+// ------------------------------------------------------------------------
+
+/**
+ * MS SQL 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		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_mssql extends CI_DB {
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		return mssql_connect($this->hostname, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		return mssql_pconnect($this->hostname, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		return @mssql_select_db($this->database, $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 @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;
+    }
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{	
+		// MS SQL doesn't require escaping
+		return $str;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function destroy($conn_id)
+	{
+		mssql_close($conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @mssql_rows_affected($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		// Not supported in MS SQL?
+		return 0;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query("SELECT COUNT(*) AS numrows FROM `".$this->dbprefix.$table."`");
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function error_message()
+	{
+		// Are errros even supported in MS SQL?
+		return '';
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function error_number()
+	{
+		// Are error numbers supported?
+		return '';
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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	public
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	function escape_table($table)
+	{
+		if (stristr($table, '.'))
+		{
+			$table = preg_replace("/\./", "`.`", $table);
+		}
+		
+		return $table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		$sql = "SELECT TOP 1 FROM ".$this->escape_table($table);
+		$query = $this->query($sql);
+		return $query->field_data();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	string
+	 */
+	function _update($table, $values, $where)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+	
+		return "UPDATE ".$this->escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @return	string
+	 */	
+	function _delete($table, $where)
+	{
+		return "DELETE FROM ".$this->escape_table($table)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _show_tables()
+	{
+		return "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";		
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show columnn 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 _show_columns($table = '')
+	{
+		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->escape_table($table)."'";	
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		$i = $limit + $offset;
+	
+		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);		
+	}
+
+}
+
+
+
+/**
+ * MS SQL Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_mssql_result extends CI_DB_result {
+	
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @mssql_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @mssql_num_fields($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		while ($field = mssql_fetch_field($this->result_id))
+		{	
+			$F 				= new CI_DB_field();
+			$F->name 		= $field->name;
+			$F->type 		= $field->type;
+			$F->max_length	= $field->max_length;
+			$F->primary_key = 0;
+			$F->default		= '';
+			
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return mssql_fetch_assoc($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		return mssql_fetch_object($this->result_id);
+	}
+
+}
+
+?>
\ No newline at end of file
diff --git a/system/drivers/DB_mysql.php b/system/drivers/DB_mysql.php
new file mode 100644
index 0000000..18c080b
--- /dev/null
+++ b/system/drivers/DB_mysql.php
@@ -0,0 +1,495 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Rick Ellis
+ * @copyright	Copyright (c) 2006, pMachine, Inc.
+ * @license		http://www.codeignitor.com/user_guide/license.html 
+ * @link		http://www.codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+ 
+// ------------------------------------------------------------------------
+
+/**
+ * MySQL 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		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_mysql extends CI_DB {
+
+	/**
+	 * Whether to use the MySQL "delete hack" which allows the number
+	 * of affected rows to be shown. Uses a preg_replace when enabled, 
+	 * adding a bit more processing to all queries.
+	 */	
+	var $delete_hack = TRUE; 
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		return mysql_connect($this->hostname, $this->username, $this->password, TRUE);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		return mysql_pconnect($this->hostname, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		return @mysql_select_db($this->database, $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 @mysql_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)
+    {
+		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies 
+		// the query so that it returns the number of affected rows
+		if ($this->delete_hack === TRUE)
+		{
+			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) 
+			{
+				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
+			}
+		}
+		
+		return $sql;
+    }
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{	
+		if (get_magic_quotes_gpc())
+		{
+			$str = stripslashes($str); 
+		}
+		return mysql_real_escape_string($str);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function destroy($conn_id)
+	{
+		mysql_close($conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @mysql_affected_rows($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @mysql_insert_id($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query("SELECT COUNT(*) AS numrows FROM `".$this->dbprefix.$table."`");
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function error_message()
+	{
+		return mysql_error($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function error_number()
+	{
+		return mysql_errno($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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	public
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	function escape_table($table)
+	{
+		if (stristr($table, '.'))
+		{
+			$table = preg_replace("/\./", "`.`", $table);
+		}
+		
+		return $table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		$sql = "SELECT * FROM ".$this->escape_table($table)." LIMIT 1";
+		$query = $this->query($sql);
+		return $query->field_data();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	string
+	 */
+	function _update($table, $values, $where)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+	
+		return "UPDATE ".$this->escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @return	string
+	 */	
+	function _delete($table, $where)
+	{
+		return "DELETE FROM ".$this->escape_table($table)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _show_tables()
+	{	  
+		return "SHOW TABLES FROM `".$this->database."`";		
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show columnn 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 _show_columns($table = '')
+	{
+		return "SHOW COLUMNS FROM ".$this->escape_table($table);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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;
+	}
+
+}
+
+
+/**
+ * MySQL Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_mysql_result extends CI_DB_result {
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @mysql_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @mysql_num_fields($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		while ($field = mysql_fetch_field($this->result_id))
+		{	
+			$F 				= new CI_DB_field();
+			$F->name 		= $field->name;
+			$F->type 		= $field->type;
+			$F->default		= $field->def;
+			$F->max_length	= $field->max_length;
+			$F->primary_key = $field->primary_key;
+			
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return mysql_fetch_assoc($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{	
+		return mysql_fetch_object($this->result_id);
+	}
+	
+}
+
+?>
\ No newline at end of file
diff --git a/system/drivers/DB_mysqli.php b/system/drivers/DB_mysqli.php
new file mode 100644
index 0000000..f8cb19d
--- /dev/null
+++ b/system/drivers/DB_mysqli.php
@@ -0,0 +1,496 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Rick Ellis
+ * @copyright	Copyright (c) 2006, pMachine, Inc.
+ * @license		http://www.codeignitor.com/user_guide/license.html 
+ * @link		http://www.codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+ 
+// ------------------------------------------------------------------------
+
+/**
+ * MySQLi Database Adapter Class - MySQLi only works with PHP 5
+ *
+ * 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		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_mysqli extends CI_DB {
+
+	/**
+	 * Whether to use the MySQL "delete hack" which allows the number
+	 * of affected rows to be shown. Uses a preg_replace when enabled, 
+	 * adding a bit more processing to all queries.
+	 */	
+	var $delete_hack = TRUE; 
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		return mysqli_connect($this->hostname, $this->username, $this->password);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		return $this->db_connect();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		return @mysqli_select_db($this->conn_id, $this->database);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 @mysqli_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)
+    {
+		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies 
+		// the query so that it returns the number of affected rows
+		if ($this->delete_hack === TRUE)
+		{
+			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) 
+			{
+				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
+			}
+		}
+		
+		return $sql;
+    }
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{	
+		if (get_magic_quotes_gpc())
+		{
+			$str = stripslashes($str); 
+		}
+		return mysqli_real_escape_string($this->conn_id, $str);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function destroy($conn_id)
+	{
+		mysqli_close($conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @mysqli_affected_rows($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @mysqli_insert_id($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query("SELECT COUNT(*) AS numrows FROM `".$this->dbprefix.$table."`");
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function error_message()
+	{
+		return mysqli_error($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function error_number()
+	{
+		return mysqli_errno($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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	public
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	function escape_table($table)
+	{
+		if (stristr($table, '.'))
+		{
+			$table = preg_replace("/\./", "`.`", $table);
+		}
+		
+		return $table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		$sql = "SELECT * FROM ".$this->escape_table($table)." LIMIT 1";
+		$query = $this->query($sql);
+		return $query->field_data();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	string
+	 */
+	function _update($table, $values, $where)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+	
+		return "UPDATE ".$this->escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @return	string
+	 */	
+	function _delete($table, $where)
+	{
+		return "DELETE FROM ".$this->escape_table($table)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _show_tables()
+	{	  
+		return "SHOW TABLES FROM `".$this->database."`";		
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show columnn 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 _show_columns($table = '')
+	{
+		return "SHOW COLUMNS FROM ".$this->escape_table($table);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{	
+		$sql .= "LIMIT ".$limit;
+	
+		if ($offset > 0)
+		{
+			$sql .= " OFFSET ".$offset;
+		}
+		
+		return $sql;
+	}
+
+}
+
+
+
+/**
+ * MySQLi Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_mysqli_result extends CI_DB_result {
+	
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @mysqli_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @mysqli_num_fields($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		while ($field = mysqli_fetch_field($this->result_id))
+		{	
+			$F 				= new CI_DB_field();
+			$F->name 		= $field->name;
+			$F->type 		= $field->type;
+			$F->default		= $field->def;
+			$F->max_length	= $field->max_length;
+			$F->primary_key = 0;
+			
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return mysqli_fetch_assoc($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		return mysqli_fetch_object($this->result_id);
+	}
+	
+}
+
+?>
\ No newline at end of file
diff --git a/system/drivers/DB_odbc.php b/system/drivers/DB_odbc.php
new file mode 100644
index 0000000..fac4490
--- /dev/null
+++ b/system/drivers/DB_odbc.php
@@ -0,0 +1,468 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Rick Ellis
+ * @copyright	Copyright (c) 2006, pMachine, Inc.
+ * @license		http://www.codeignitor.com/user_guide/license.html 
+ * @link		http://www.codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+ 
+// ------------------------------------------------------------------------
+
+/**
+ * ODBC 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		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_odbc extends CI_DB {
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		return odbc_connect($this->database, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		return odbc_pconnect($this->database, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		// Not needed for ODBC
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 @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;
+    }
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{
+		// ODBC doesn't require escaping
+		return $str;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function destroy($conn_id)
+	{
+		odbc_close($conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @odbc_num_rows($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @odbc_insert_id($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query("SELECT COUNT(*) AS numrows FROM `".$this->dbprefix.$table."`");
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function error_message()
+	{
+		return odbc_errormsg($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function error_number()
+	{
+		return odbc_error($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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	public
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	function escape_table($table)
+	{
+		if (stristr($table, '.'))
+		{
+			$table = preg_replace("/\./", "`.`", $table);
+		}
+		
+		return $table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		$sql = "SELECT TOP 1 FROM ".$this->escape_table($table);
+		$query = $this->query($sql);
+		return $query->field_data();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	string
+	 */
+	function _update($table, $values, $where)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+	
+		return "UPDATE ".$this->escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @return	string
+	 */	
+	function _delete($table, $where)
+	{
+		return "DELETE FROM ".$this->escape_table($table)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _show_tables()
+	{	  
+		return "SHOW TABLES FROM `".$this->database."`";		
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show columnn 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 _show_columns($table = '')
+	{
+		return "SHOW COLUMNS FROM ".$this->escape_table($table);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		// Does ODBC doesn't use the LIMIT clause?
+		return $sql;
+	}
+	
+}
+
+
+/**
+ * ODBC Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_odbc_result extends CI_DB_result {
+	
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @odbc_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @odbc_num_fields($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$F 				= new CI_DB_field();
+			$F->name 		= odbc_field_name($this->result_id, $i);
+			$F->type 		= odbc_field_type($this->result_id, $i);
+			$F->max_length	= odbc_field_len($this->result_id, $i);
+			$F->primary_key = 0;
+			$F->default		= '';
+
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return odbc_fetch_array($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		return odbc_fetch_object($this->result_id);
+	}
+	
+}
+
+?>
\ No newline at end of file
diff --git a/system/drivers/DB_postgre.php b/system/drivers/DB_postgre.php
new file mode 100644
index 0000000..01d4b3d
--- /dev/null
+++ b/system/drivers/DB_postgre.php
@@ -0,0 +1,476 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Rick Ellis
+ * @copyright	Copyright (c) 2006, pMachine, Inc.
+ * @license		http://www.codeignitor.com/user_guide/license.html 
+ * @link		http://www.codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+ 
+// ------------------------------------------------------------------------
+
+/**
+ * Postgre 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		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_postgre extends CI_DB {
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		return pg_connect("host=".$this->hostname." dbname=".$this->database." user=".$this->username." password=".$this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		return pg_pconnect("host=".$this->hostname." dbname=".$this->database." user=".$this->username." password=".$this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 @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;
+    }
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{	
+		if (get_magic_quotes_gpc())
+		{
+			$str = stripslashes($str); 
+		}
+		return pg_escape_string($str);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function destroy($conn_id)
+	{
+		pg_close($conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @pg_affected_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return pg_last_oid($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query("SELECT COUNT(*) AS numrows FROM `".$this->dbprefix.$table."`");
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function error_message()
+	{
+		return pg_last_error($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function error_number()
+	{
+		return '';
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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	public
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	function escape_table($table)
+	{
+		if (stristr($table, '.'))
+		{
+			$table = preg_replace("/\./", "`.`", $table);
+		}
+		
+		return $table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		$sql = "SELECT * FROM ".$this->escape_table($table)." LIMIT 1";
+		$query = $this->query($sql);
+		return $query->field_data();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	string
+	 */
+	function _update($table, $values, $where)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+	
+		return "UPDATE ".$this->escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @return	string
+	 */	
+	function _delete($table, $where)
+	{
+		return "DELETE FROM ".$this->escape_table($table)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _show_tables()
+	{	  
+		return "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";	
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show columnn 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 _show_columns($table = '')
+	{
+		return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$this->escape_table($table)."'"; 	
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{	
+		$sql .= "LIMIT ".$limit;
+	
+		if ($offset > 0)
+		{
+			$sql .= " OFFSET ".$offset;
+		}
+		
+		return $sql;
+	}
+
+}
+
+
+
+/**
+ * Postgres Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_postgre_result extends CI_DB_result {
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @pg_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @pg_num_fields($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$F 				= new CI_DB_field();
+			$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;
+		}
+		
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return pg_fetch_assoc($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		return pg_fetch_object($this->result_id);
+	}
+	
+}
+
+?>
\ No newline at end of file
diff --git a/system/drivers/DB_sqlite.php b/system/drivers/DB_sqlite.php
new file mode 100644
index 0000000..6428dd5
--- /dev/null
+++ b/system/drivers/DB_sqlite.php
@@ -0,0 +1,501 @@
+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		Rick Ellis
+ * @copyright	Copyright (c) 2006, pMachine, Inc.
+ * @license		http://www.codeignitor.com/user_guide/license.html 
+ * @link		http://www.codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+ 
+// ------------------------------------------------------------------------
+
+
+
+/**
+ * SQLite 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		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_sqlite extends CI_DB {
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		if ( ! $conn_id = sqlite_open($this->database, 0666, $error))
+		{
+			log_message('error', $error);
+			
+            if ($this->db_debug)
+            {
+				$this->display_error($error, '', TRUE);
+            }		
+		}
+		
+		return $conn_id;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		if ( ! $conn_id = sqlite_popen($this->database, 0666, $error))
+		{
+			log_message('error', $error);
+			
+            if ($this->db_debug)
+            {
+				$this->display_error($error, '', TRUE);
+            }		
+		}
+		
+		return $conn_id;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 @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;
+    }
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{
+		if (get_magic_quotes_gpc())
+		{
+			$str = stripslashes($str); 
+		}
+		return sqlite_escape_string($str);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function destroy($conn_id)
+	{
+		sqlite_close($conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return sqlite_changes($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @sqlite_last_insert_rowid($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query("SELECT COUNT(*) AS numrows FROM `".$this->dbprefix.$table."`");
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function error_message()
+	{
+		return sqlite_error_string(sqlite_last_error($this->conn_id));
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function error_number()
+	{
+		return sqlite_last_error($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function version()
+	{
+		return sqlite_libversion();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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	public
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	function escape_table($table)
+	{
+		if (stristr($table, '.'))
+		{
+			$table = preg_replace("/\./", "`.`", $table);
+		}
+		
+		return $table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		$sql = "SELECT * FROM ".$this->escape_table($table)." LIMIT 1";
+		$query = $this->query($sql);
+		return $query->field_data();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	string
+	 */
+	function _update($table, $values, $where)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+	
+		return "UPDATE ".$this->escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @return	string
+	 */	
+	function _delete($table, $where)
+	{
+		return "DELETE FROM ".$this->escape_table($table)." WHERE ".implode(" ", $where);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _show_tables()
+	{
+		return "SELECT name from sqlite_master WHERE type='table'";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show columnn 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 _show_columns($table = '')
+	{
+		// Not supported
+		return FALSE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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;
+	}
+
+}
+
+
+/**
+ * SQLite Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ * 
+ * @category	Database
+ * @author		Rick Ellis
+ * @link		http://www.codeigniter.com/user_guide/libraries/database/
+ */
+class CI_DB_sqlite_result extends CI_DB_result {
+	
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @sqlite_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @sqlite_num_fields($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$F 				= new CI_DB_field();
+			$F->name 		= sqlite_field_name($this->result_id, $i);
+			$F->type 		= 'varchar';
+			$F->max_length	= 0;
+			$F->primary_key = 0;
+			$F->default		= '';
+
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return sqlite_fetch_array($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		return sqlite_fetch_object($this->result_id);
+	}
+
+}
+
+?>
\ No newline at end of file
diff --git a/system/drivers/index.html b/system/drivers/index.html
new file mode 100644
index 0000000..5a1f5d6
--- /dev/null
+++ b/system/drivers/index.html
@@ -0,0 +1,15 @@
+<html>

+

+<head>

+

+<title>403 Forbidden</title>

+

+</head>

+

+<body bgcolor='#ffffff'>

+

+<p>Directory access is forbidden.<p>

+

+</body>

+

+</html>
\ No newline at end of file