Merged with development
diff --git a/application/config/migration.php b/application/config/migration.php
index 1f532f1..41b8962 100644
--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -1,71 +1,115 @@
-<?php defined('BASEPATH') OR exit('No direct script access allowed');

-/*

-|--------------------------------------------------------------------------

-| Enable/Disable Migrations

-|--------------------------------------------------------------------------

-|

-| Migrations are disabled by default for security reasons.

-| You should enable migrations whenever you intend to do a schema migration

-| and disable it back when you're done.

-|

-*/

-$config['migration_enabled'] = FALSE;

-

-/*

-|--------------------------------------------------------------------------

-| Migrations table

-|--------------------------------------------------------------------------

-|

-| This is the name of the table that will store the current migrations state.

-| When migrations runs it will store in a database table which migration 

-| level the system is at. It then compares the migration level in the this

-| table to the $config['migration_version'] if they are not the same it

-| will migrate up. This must be set.

-|

-*/

-$config['migration_table'] = 'migrations';

-

-

-/*

-|--------------------------------------------------------------------------

-| Auto Migrate To Latest

-|--------------------------------------------------------------------------

-|

-| If this is set to TRUE when you load the migrations class and have 

-| $config['migration_enabled'] set to TRUE the system will auto migrate

-| to your latest migration (whatever $config['migration_version'] is

-| set to). This way you do not have to call migrations anywhere else

-| in your code to have the latest migration.

-|

-*/

-$config['migration_auto_latest'] = FALSE;

-

-

-/*

-|--------------------------------------------------------------------------

-| Migrations version

-|--------------------------------------------------------------------------

-|

-| This is used to set migration version that the file system should be on.

-| If you run $this->migration->latest() this is the version that schema will

-| be upgraded / downgraded to.

-|

-*/

-$config['migration_version'] = 0;

-

-

-/*

-|--------------------------------------------------------------------------

-| Migrations Path

-|--------------------------------------------------------------------------

-|

-| Path to your migrations folder.

-| Typically, it will be within your application path.

-| Also, writing permission is required within the migrations path.

-|

-*/

-$config['migration_path'] = APPPATH . 'migrations/';

-

-

-/* End of file migration.php */

+<<<<<<< HEAD:application/config/migration.php
+<?php defined('BASEPATH') OR exit('No direct script access allowed');
+/*
+|--------------------------------------------------------------------------
+| Enable/Disable Migrations
+|--------------------------------------------------------------------------
+|
+| Migrations are disabled by default for security reasons.
+| You should enable migrations whenever you intend to do a schema migration
+| and disable it back when you're done.
+|
+*/
+$config['migration_enabled'] = FALSE;
+
+
+/*
+|--------------------------------------------------------------------------
+| Migrations version
+|--------------------------------------------------------------------------
+|
+| This is used to set migration version that the file system should be on.
+| If you run $this->migration->latest() this is the version that schema will
+| be upgraded / downgraded to.
+|
+*/
+$config['migration_version'] = 0;
+
+
+/*
+|--------------------------------------------------------------------------
+| Migrations Path
+|--------------------------------------------------------------------------
+|
+| Path to your migrations folder.
+| Typically, it will be within your application path.
+| Also, writing permission is required within the migrations path.
+|
+*/
+$config['migration_path'] = APPPATH . 'migrations/';
+
+
+/* End of file migration.php */
+=======
+<?php defined('BASEPATH') OR exit('No direct script access allowed');
+/*
+|--------------------------------------------------------------------------
+| Enable/Disable Migrations
+|--------------------------------------------------------------------------
+|
+| Migrations are disabled by default for security reasons.
+| You should enable migrations whenever you intend to do a schema migration
+| and disable it back when you're done.
+|
+*/
+$config['migration_enabled'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Migrations table
+|--------------------------------------------------------------------------
+|
+| This is the name of the table that will store the current migrations state.
+| When migrations runs it will store in a database table which migration 
+| level the system is at. It then compares the migration level in the this
+| table to the $config['migration_version'] if they are not the same it
+| will migrate up. This must be set.
+|
+*/
+$config['migration_table'] = 'migrations';
+
+
+/*
+|--------------------------------------------------------------------------
+| Auto Migrate To Latest
+|--------------------------------------------------------------------------
+|
+| If this is set to TRUE when you load the migrations class and have 
+| $config['migration_enabled'] set to TRUE the system will auto migrate
+| to your latest migration (whatever $config['migration_version'] is
+| set to). This way you do not have to call migrations anywhere else
+| in your code to have the latest migration.
+|
+*/
+$config['migration_auto_latest'] = FALSE;
+
+
+/*
+|--------------------------------------------------------------------------
+| Migrations version
+|--------------------------------------------------------------------------
+|
+| This is used to set migration version that the file system should be on.
+| If you run $this->migration->latest() this is the version that schema will
+| be upgraded / downgraded to.
+|
+*/
+$config['migration_version'] = 0;
+
+
+/*
+|--------------------------------------------------------------------------
+| Migrations Path
+|--------------------------------------------------------------------------
+|
+| Path to your migrations folder.
+| Typically, it will be within your application path.
+| Also, writing permission is required within the migrations path.
+|
+*/
+$config['migration_path'] = APPPATH . 'migrations/';
+
+
+/* End of file migration.php */
+>>>>>>> a2125a5d830fd390b4cf35f77e9bb0558cfa2dd7:application/config/migration.php
 /* Location: ./application/config/migration.php */
\ No newline at end of file
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
index 8351823..f99d13e 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_active_rec.php
@@ -28,39 +28,42 @@
  */
 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_keys				= array();
-	var $ar_limit				= FALSE;
-	var $ar_offset				= FALSE;
-	var $ar_order				= FALSE;
-	var $ar_orderby				= array();
-	var $ar_set					= array();
-	var $ar_wherein				= array();
-	var $ar_aliased_tables		= array();
-	var $ar_store_array			= array();
+	protected $return_delete_sql	= FALSE;
+	protected $reset_delete_data	= FALSE;
+	
+	protected $ar_select			= array();
+	protected $ar_distinct			= FALSE;
+	protected $ar_from				= array();
+	protected $ar_join				= array();
+	protected $ar_where				= array();
+	protected $ar_like				= array();
+	protected $ar_groupby			= array();
+	protected $ar_having			= array();
+	protected $ar_keys				= array();
+	protected $ar_limit				= FALSE;
+	protected $ar_offset			= FALSE;
+	protected $ar_order				= FALSE;
+	protected $ar_orderby			= array();
+	protected $ar_set				= array();
+	protected $ar_wherein			= array();
+	protected $ar_aliased_tables	= array();
+	protected $ar_store_array		= array();
 
 	// Active Record Caching variables
-	var $ar_caching				= FALSE;
-	var $ar_cache_exists		= array();
-	var $ar_cache_select		= array();
-	var $ar_cache_from			= array();
-	var $ar_cache_join			= array();
-	var $ar_cache_where			= array();
-	var $ar_cache_like			= array();
-	var $ar_cache_groupby		= array();
-	var $ar_cache_having		= array();
-	var $ar_cache_orderby		= array();
-	var $ar_cache_set			= array();
+	protected $ar_caching			= FALSE;
+	protected $ar_cache_exists		= array();
+	protected $ar_cache_select		= array();
+	protected $ar_cache_from		= array();
+	protected $ar_cache_join		= array();
+	protected $ar_cache_where		= array();
+	protected $ar_cache_like		= array();
+	protected $ar_cache_groupby		= array();
+	protected $ar_cache_having		= array();
+	protected $ar_cache_orderby		= array();
+	protected $ar_cache_set			= array();
 	
-	var $ar_no_escape 			= array();
-	var $ar_cache_no_escape     = array();
+	protected $ar_no_escape 		= array();
+	protected $ar_cache_no_escape    = array();
 
 	// --------------------------------------------------------------------
 
@@ -660,7 +663,7 @@
 			$prefix = (count($this->ar_like) == 0) ? '' : $type;
 
 			$v = $this->escape_like_str($v);
-			
+
 			if ($side == 'none')
 			{
 				$like_statement = $prefix." $k $not LIKE '{$v}'";
@@ -931,7 +934,37 @@
 
 		return $this;
 	}
+	
+	// --------------------------------------------------------------------
 
+	/**
+	 * Get SELECT query string
+	 *
+	 * Compiles a SELECT query string and returns the sql.
+	 *
+	 * @access	public
+	 * @param	string	the table name to select from (optional)
+	 * @param	boolean	TRUE: resets AR values; FALSE: leave AR vaules alone
+	 * @return	string
+	 */
+	public function get_compiled_select($table = '', $reset = TRUE) 
+	{
+		if ($table != '')
+		{
+			$this->_track_aliases($table);
+			$this->from($table);
+		}
+		
+		$select =  $this->_compile_select();
+		
+		if ($reset === TRUE)
+		{
+			$this->_reset_select();
+		}
+		
+		return $select;
+	}
+	
 	// --------------------------------------------------------------------
 
 	/**
@@ -1148,6 +1181,41 @@
 
 		return $this;
 	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get INSERT query string
+	 *
+	 * Compiles an insert query and returns the sql
+	 *
+	 * @access	public
+	 * @param	string	the table to insert into
+	 * @param	boolean	TRUE: reset AR values; FALSE: leave AR values alone
+	 * @return	string
+	 */
+	public function get_compiled_insert($table = '', $reset = TRUE)
+	{	
+		if ($this->_validate_insert($table) === FALSE)
+		{
+			return FALSE;
+		}
+		
+		$sql = $this->_insert(
+			$this->_protect_identifiers(
+				$this->ar_from[0], TRUE, NULL, FALSE
+			),
+			array_keys($this->ar_set), 
+			array_values($this->ar_set)
+		);
+		
+		if ($reset === TRUE)
+		{
+			$this->_reset_write();
+		}
+		
+		return $sql;
+	}
 
 	// --------------------------------------------------------------------
 
@@ -1156,17 +1224,50 @@
 	 *
 	 * Compiles an insert string and runs the query
 	 *
+	 * @access	public
 	 * @param	string	the table to insert data into
 	 * @param	array	an associative array of insert values
 	 * @return	object
 	 */
-	function insert($table = '', $set = NULL)
+	public function insert($table = '', $set = NULL)
 	{
 		if ( ! is_null($set))
 		{
 			$this->set($set);
 		}
+		
+		if ($this->_validate_insert($table) === FALSE)
+		{
+			return FALSE;
+		}
+		
+		$sql = $this->_insert(
+			$this->_protect_identifiers(
+				$this->ar_from[0], TRUE, NULL, FALSE
+			), 
+			array_keys($this->ar_set), 
+			array_values($this->ar_set)
+		);
 
+		$this->_reset_write();
+		return $this->query($sql);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Validate Insert
+	 *
+	 * This method is used by both insert() and get_compiled_insert() to
+	 * validate that the there data is actually being set and that table
+	 * has been chosen to be inserted into.
+	 *
+	 * @access	public
+	 * @param	string	the table to insert data into
+	 * @return	string
+	 */
+	protected function _validate_insert($table = '') 
+	{
 		if (count($this->ar_set) == 0)
 		{
 			if ($this->db_debug)
@@ -1186,14 +1287,13 @@
 				}
 				return FALSE;
 			}
-
-			$table = $this->ar_from[0];
 		}
-
-		$sql = $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));
-
-		$this->_reset_write();
-		return $this->query($sql);
+		else
+		{
+			$this->ar_from[0] = $table;
+		}
+		
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1242,7 +1342,39 @@
 		$this->_reset_write();
 		return $this->query($sql);
 	}
+	
+	// --------------------------------------------------------------------
 
+	/**
+	 * Get UPDATE query string
+	 *
+	 * Compiles an update query and returns the sql
+	 *
+	 * @access	public
+	 * @param	string	the table to update
+	 * @param	boolean	TRUE: reset AR values; FALSE: leave AR values alone
+	 * @return	string
+	 */
+	public function get_compiled_update($table = '', $reset = TRUE)
+	{
+		// Combine any cached components with the current statements
+		$this->_merge_cache();
+	
+		if ($this->_validate_update($table) === FALSE)
+		{
+			return FALSE;
+		}
+		
+		$sql = $this->_update($this->_protect_identifiers($this->ar_from[0], TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
+		
+		if ($reset === TRUE)
+		{
+			$this->_reset_write();
+		}
+		
+		return $sql;
+	}
+	
 	// --------------------------------------------------------------------
 
 	/**
@@ -1265,6 +1397,42 @@
 			$this->set($set);
 		}
 
+		if ($this->_validate_update($table) === FALSE)
+		{
+			return FALSE;
+		}
+
+		if ($where != NULL)
+		{
+			$this->where($where);
+		}
+
+		if ($limit != NULL)
+		{
+			$this->limit($limit);
+		}
+
+		$sql = $this->_update($this->_protect_identifiers($this->ar_from[0], TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
+
+		$this->_reset_write();
+		return $this->query($sql);
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Validate Update
+	 *
+	 * This method is used by both update() and get_compiled_update() to
+	 * validate that data is actually being set and that a table has been
+	 * chosen to be update.
+	 *
+	 * @access	public
+	 * @param	string	the table to update data on
+	 * @return	string
+	 */
+	protected function _validate_update($table = '')
+	{
 		if (count($this->ar_set) == 0)
 		{
 			if ($this->db_debug)
@@ -1284,27 +1452,13 @@
 				}
 				return FALSE;
 			}
-
-			$table = $this->ar_from[0];
 		}
-
-		if ($where != NULL)
+		else
 		{
-			$this->where($where);
+			$this->ar_from[0] = $table;
 		}
-
-		if ($limit != NULL)
-		{
-			$this->limit($limit);
-		}
-
-		$sql = $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
-
-		$this->_reset_write();
-		return $this->query($sql);
 	}
-
-
+	
 	// --------------------------------------------------------------------
 
 	/**
@@ -1503,7 +1657,27 @@
 
 		return $this->query($sql);
 	}
+	
+	// --------------------------------------------------------------------
 
+	/**
+	 * Get DELETE query string
+	 *
+	 * Compiles a delete query string and returns the sql
+	 *
+	 * @access	public
+	 * @param	string	the table to delete from
+	 * @param	boolean	TRUE: reset AR values; FALSE: leave AR values alone
+	 * @return	string
+	 */
+	public function get_compiled_delete($table = '', $reset = TRUE)
+	{
+		$this->return_delete_sql = TRUE;
+		$sql = $this->delete($table, '', NULL, $reset);
+		$this->return_delete_sql = FALSE;
+		return $sql;
+	}
+	
 	// --------------------------------------------------------------------
 
 	/**
@@ -1576,10 +1750,15 @@
 		{
 			$this->_reset_write();
 		}
+		
+		if ($this->return_delete_sql === true)
+		{
+			return $sql;
+		}
 
 		return $this->query($sql);
 	}
-
+	
 	// --------------------------------------------------------------------
 
 	/**
@@ -1659,7 +1838,7 @@
 			}
 		}
 	}
-
+	
 	// --------------------------------------------------------------------
 
 	/**
@@ -1965,6 +2144,22 @@
 
 		$this->ar_no_escape = $this->ar_cache_no_escape;
 	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Reset Active Record values.
+	 * 
+	 * Publicly-visible method to reset the AR values.
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	public function reset_query()
+	{
+		$this->_reset_select();
+		$this->_reset_write();
+	}
 
 	// --------------------------------------------------------------------