340 lines
8.4 KiB
PHP
340 lines
8.4 KiB
PHP
<?php
|
|
/**
|
|
* <pre>
|
|
* Invision Power Services
|
|
* IP.Board v3.4.5
|
|
* Back Up Model
|
|
* Last Updated: $Date: 2012-05-10 21:10:13 +0100 (Thu, 10 May 2012) $
|
|
* </pre>
|
|
*
|
|
* @author Matt Mecham
|
|
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
|
|
* @license http://www.invisionpower.com/company/standards.php#license
|
|
* @package IP.Board
|
|
* @link http://www.invisionpower.com
|
|
* @since Tue. 15th June 2012
|
|
* @version $Rev: 10721 $
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Back up database class
|
|
* @author matt
|
|
*
|
|
*/
|
|
class ipsBackup_db extends db_driver_mysql
|
|
{
|
|
/* Current DB method */
|
|
private $_method = '';
|
|
|
|
/* Current table */
|
|
private $_table = '';
|
|
|
|
/* Back up class */
|
|
private $Backup = '';
|
|
|
|
/* Shut down queries */
|
|
private $_shutDownData = array();
|
|
|
|
private $_isMysqli = false;
|
|
|
|
private $_insertId = null;
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->_isMysqli = ( extension_loaded('mysqli') AND ! defined( 'FORCE_MYSQL_ONLY' ) ) ? true : false;
|
|
|
|
return parent::__construct();
|
|
}
|
|
|
|
/**
|
|
* Can't load back-up class at INIT because it requires
|
|
* that ipsRegistry is set up
|
|
*/
|
|
private function _backup()
|
|
{
|
|
if ( ! is_object( $this->Backup ) )
|
|
{
|
|
/* Fetch back up class */
|
|
require_once( IPS_ROOT_PATH . 'sources/classes/backup.php' );
|
|
$this->Backup = new ipsBackup();
|
|
}
|
|
|
|
return $this->Backup;
|
|
}
|
|
|
|
/**
|
|
* Delete data from a table
|
|
*
|
|
* @param string Table name
|
|
* @param string [Optional] Where clause
|
|
* @param string [Optional] Order by
|
|
* @param array [Optional] Limit clause
|
|
* @param boolean [Optional] Run on shutdown
|
|
* @return @e resource
|
|
*/
|
|
public function delete( $table, $where='', $orderBy='', $limit=array(), $shutdown=false )
|
|
{
|
|
$this->_table = '';
|
|
$this->_method = '';
|
|
|
|
/* Want to capture? */
|
|
if ( $this->_backup()->isOkToGetThisTableData( $table ) )
|
|
{
|
|
$this->_table = $table;
|
|
$this->_method = 'delete';
|
|
}
|
|
|
|
parent::delete( $table, $where, $orderBy, $limit, $shutdown );
|
|
}
|
|
|
|
/**
|
|
* Insert data into a table
|
|
*
|
|
* @param string Table name
|
|
* @param array Array of field => values
|
|
* @param boolean Run on shutdown
|
|
* @return @e resource
|
|
*/
|
|
public function insert( $table, $set, $shutdown=false )
|
|
{
|
|
$this->_table = '';
|
|
$this->_method = '';
|
|
|
|
/* Want to capture? */
|
|
if ( $this->_backup()->isOkToGetThisTableData( $table ) )
|
|
{
|
|
$this->_table = $table;
|
|
$this->_method = 'insert';
|
|
}
|
|
|
|
if ( $table !== 'backup_queue' )
|
|
{
|
|
/* Reset insert ID ready for next query
|
|
unless we're adding to the queue table
|
|
in which case we want to preserve insertID from preceeding query */
|
|
$this->_insertId = null;
|
|
}
|
|
|
|
return parent::insert( $table, $set, $shutdown );
|
|
}
|
|
|
|
/**
|
|
* Insert record into table if not present, otherwise update existing record
|
|
*
|
|
* @param string Table name
|
|
* @param array Array of field => values
|
|
* @param array Array of fields to check
|
|
* @param boolean [Optional] Run on shutdown
|
|
* @return @e resource
|
|
*/
|
|
public function replace( $table, $set, $where, $shutdown=false )
|
|
{
|
|
$this->_table = '';
|
|
$this->_method = '';
|
|
|
|
/* Want to capture? */
|
|
if ( $this->_backup()->isOkToGetThisTableData( $table ) )
|
|
{
|
|
$this->_table = $table;
|
|
$this->_method = 'replace';
|
|
}
|
|
|
|
return parent::replace( $table, $set, $where, $shutdown );
|
|
}
|
|
|
|
/**
|
|
* Update data in a table
|
|
*
|
|
* @param string Table name
|
|
* @param mixed Array of field => values, or pre-formatted "SET" clause
|
|
* @param string [Optional] Where clause
|
|
* @param boolean [Optional] Run on shutdown
|
|
* @param boolean [Optional] $set is already pre-formatted
|
|
* @return @e resource
|
|
*/
|
|
public function update( $table, $set, $where='', $shutdown=false, $preformatted=false, $debug=false )
|
|
{
|
|
$this->_table = '';
|
|
$this->_method = '';
|
|
|
|
/* Want to capture? */
|
|
if ( $this->_backup()->isOkToGetThisTableData( $table ) )
|
|
{
|
|
$this->_table = $table;
|
|
$this->_method = 'update';
|
|
}
|
|
|
|
return parent::update( $table, $set, $where, $shutdown, $preformatted, $debug );
|
|
}
|
|
|
|
/**
|
|
* Generates and executes SQL query, and returns the all results in an array
|
|
*
|
|
* @param array Set commands (select, from, where, order, limit, etc)
|
|
* @param string Key to index array on (member_id, for example)
|
|
* @return @e array
|
|
*/
|
|
public function buildAndFetchAll( $data, $arrayIndex=null )
|
|
{
|
|
if ( substr( $data['from'], 0, 7 ) == 'backup_' )
|
|
{
|
|
$this->_method = '';
|
|
}
|
|
else
|
|
{
|
|
return parent::buildAndFetchAll( $data, $arrayIndex );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build a query based on template from cache file
|
|
*
|
|
* @param string Name of query file method to use
|
|
* @param array Optional arguments to be parsed inside query function
|
|
* @param string Optional class name
|
|
* @return @e void
|
|
*/
|
|
public function buildFromCache( $method, $args=array(), $class='sql_queries' )
|
|
{
|
|
$backup = $this->_backup();
|
|
|
|
parent::buildFromCache( $method, $args, $class );
|
|
|
|
if ( $this->cur_query )
|
|
{
|
|
if ( preg_match( '#^(?:insert|update|replace|delete|truncate)#i', $this->cur_query ) )
|
|
{
|
|
/* Ghetto ->query() method used */
|
|
preg_match( '#^(TRUNCATE TABLE|DELETE FROM|INSERT INTO|UPDATE|REPLACE INTO)(?:\s+?)?(\S+)(\s+?)?#i', $this->cur_query, $matches );
|
|
|
|
if ( count( $matches ) && ! empty( $matches[1] ) )
|
|
{
|
|
$this->_method = trim( str_replace( array( 'table', 'from', 'into' ), '', strtolower( $matches[1] ) ) );
|
|
$this->_table = trim( $matches[2] );
|
|
|
|
if ( $this->_backup()->isOkToGetThisTableData( $this->_table ) )
|
|
{
|
|
/* Do this now if query ran OK */
|
|
$this->_backup()->addRawQueryToLog( $the_query, $this->_table );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute a direct database query
|
|
*
|
|
* @param string Database query
|
|
* @param boolean [Optional] Do not convert table prefix
|
|
* @return @e resource
|
|
*/
|
|
public function query( $the_query, $bypass=false )
|
|
{
|
|
$val = parent::query( $the_query, $bypass );
|
|
|
|
if ( $this->_isShutDown && in_array( md5( $the_query ), array_keys( $this->_shutDownData ) ) )
|
|
{
|
|
$_data = $this->_shutDownData[ md5( $the_query ) ];
|
|
|
|
if ( $this->_backup()->isOkToGetThisTableData( $_data[1] ) )
|
|
{
|
|
$this->_method = $_data[0];
|
|
$this->_table = $_data[1];
|
|
}
|
|
}
|
|
|
|
if ( $this->_method )
|
|
{
|
|
/* Fetch real insert ID */
|
|
$this->_insertId = null;
|
|
$this->_insertId = $this->getInsertId();
|
|
|
|
/* Clear method now or it will retain the current table when query log is run below */
|
|
$this->_method = '';
|
|
|
|
/* Do this now if query ran OK */
|
|
$this->_backup()->addRawQueryToLog( $the_query, $this->_table );
|
|
}
|
|
else if ( preg_match( '#^(?:insert|update|replace|delete|truncate)#i', $the_query ) )
|
|
{
|
|
/* Ghetto ->query() method used */
|
|
preg_match( '#^(TRUNCATE TABLE|DELETE FROM|INSERT INTO|UPDATE|REPLACE INTO)(?:\s+?)?(\S+)(\s+?)?#i', $the_query, $matches );
|
|
|
|
if ( count( $matches ) && ! empty( $matches[1] ) )
|
|
{
|
|
$this->_method = trim( str_replace( array( 'table', 'from', 'into' ), '', strtolower( $matches[1] ) ) );
|
|
$this->_table = trim( $matches[2] );
|
|
|
|
if ( $this->_backup()->isOkToGetThisTableData( $this->_table ) )
|
|
{
|
|
/* Fetch real insert ID */
|
|
$this->_insertId = null;
|
|
$this->_insertId = $this->getInsertId();
|
|
|
|
/* Do this now if query ran OK */
|
|
$this->_backup()->addRawQueryToLog( $the_query, $this->_table );
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->_method = '';
|
|
$this->_table = '';
|
|
|
|
return $val;
|
|
}
|
|
|
|
/**
|
|
* Retrieve latest autoincrement insert id
|
|
*
|
|
* @return @e integer
|
|
*/
|
|
public function getInsertId()
|
|
{
|
|
if ( $this->_insertId === null )
|
|
{
|
|
$this->_insertId = parent::getInsertId();
|
|
}
|
|
|
|
return $this->_insertId;
|
|
}
|
|
|
|
/**
|
|
* Determine if query is shutdown and run it
|
|
*
|
|
* @param string Query
|
|
* @param boolean [Optional] Run on shutdown
|
|
* @return @e mixed
|
|
*/
|
|
protected function _determineShutdownAndRun( $query, $shutdown=false )
|
|
{
|
|
if ( $shutdown && $this->obj['use_shutdown'] )
|
|
{
|
|
/* store data for later execution */
|
|
$this->_shutDownData[ md5($query ) ] = array( $this->_method, $this->_table );
|
|
|
|
/* Prevent it from storing attributes that won't be cleared as query isn't run */
|
|
$this->_method = '';
|
|
$this->_table = '';
|
|
}
|
|
|
|
return parent::_determineShutdownAndRun( $query, $shutdown );
|
|
}
|
|
|
|
/* Have to define this as inherited class */
|
|
public function _getErrorString()
|
|
{
|
|
return parent::_getErrorString();
|
|
}
|
|
|
|
public function _getErrorNumber()
|
|
{
|
|
return parent::_getErrorNumber();
|
|
}
|
|
}
|
|
|