diff options
Diffstat (limited to 'phpBB/includes/db/driver/driver.php')
| -rw-r--r-- | phpBB/includes/db/driver/driver.php | 1044 | 
1 files changed, 0 insertions, 1044 deletions
| diff --git a/phpBB/includes/db/driver/driver.php b/phpBB/includes/db/driver/driver.php deleted file mode 100644 index b915ee081b..0000000000 --- a/phpBB/includes/db/driver/driver.php +++ /dev/null @@ -1,1044 +0,0 @@ -<?php -/** -* -* @package dbal -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -/** -* Database Abstraction Layer -* @package dbal -*/ -class phpbb_db_driver -{ -	var $db_connect_id; -	var $query_result; -	var $return_on_error = false; -	var $transaction = false; -	var $sql_time = 0; -	var $num_queries = array(); -	var $open_queries = array(); - -	var $curtime = 0; -	var $query_hold = ''; -	var $html_hold = ''; -	var $sql_report = ''; - -	var $persistency = false; -	var $user = ''; -	var $server = ''; -	var $dbname = ''; - -	// Set to true if error triggered -	var $sql_error_triggered = false; - -	// Holding the last sql query on sql error -	var $sql_error_sql = ''; -	// Holding the error information - only populated if sql_error_triggered is set -	var $sql_error_returned = array(); - -	// Holding transaction count -	var $transactions = 0; - -	// Supports multi inserts? -	var $multi_insert = false; - -	/** -	* Current sql layer -	*/ -	var $sql_layer = ''; - -	/** -	* Wildcards for matching any (%) or exactly one (_) character within LIKE expressions -	*/ -	var $any_char; -	var $one_char; - -	/** -	* Exact version of the DBAL, directly queried -	*/ -	var $sql_server_version = false; - -	/** -	* Constructor -	*/ -	function __construct() -	{ -		$this->num_queries = array( -			'cached'	=> 0, -			'normal'	=> 0, -			'total'		=> 0, -		); - -		// Fill default sql layer based on the class being called. -		// This can be changed by the specified layer itself later if needed. -		$this->sql_layer = substr(get_class($this), strlen('phpbb_db_driver_')); - -		// Do not change this please! This variable is used to easy the use of it - and is hardcoded. -		$this->any_char = chr(0) . '%'; -		$this->one_char = chr(0) . '_'; -	} - -	/** -	* return on error or display error message -	*/ -	function sql_return_on_error($fail = false) -	{ -		$this->sql_error_triggered = false; -		$this->sql_error_sql = ''; - -		$this->return_on_error = $fail; -	} - -	/** -	* Return number of sql queries and cached sql queries used -	*/ -	function sql_num_queries($cached = false) -	{ -		return ($cached) ? $this->num_queries['cached'] : $this->num_queries['normal']; -	} - -	/** -	* Add to query count -	*/ -	function sql_add_num_queries($cached = false) -	{ -		$this->num_queries['cached'] += ($cached !== false) ? 1 : 0; -		$this->num_queries['normal'] += ($cached !== false) ? 0 : 1; -		$this->num_queries['total'] += 1; -	} - -	/** -	* DBAL garbage collection, close sql connection -	*/ -	function sql_close() -	{ -		if (!$this->db_connect_id) -		{ -			return false; -		} - -		if ($this->transaction) -		{ -			do -			{ -				$this->sql_transaction('commit'); -			} -			while ($this->transaction); -		} - -		foreach ($this->open_queries as $query_id) -		{ -			$this->sql_freeresult($query_id); -		} - -		// Connection closed correctly. Set db_connect_id to false to prevent errors -		if ($result = $this->_sql_close()) -		{ -			$this->db_connect_id = false; -		} - -		return $result; -	} - -	/** -	* Build LIMIT query -	* Doing some validation here. -	*/ -	function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		if (empty($query)) -		{ -			return false; -		} - -		// Never use a negative total or offset -		$total = ($total < 0) ? 0 : $total; -		$offset = ($offset < 0) ? 0 : $offset; - -		return $this->_sql_query_limit($query, $total, $offset, $cache_ttl); -	} - -	/** -	* Fetch all rows -	*/ -	function sql_fetchrowset($query_id = false) -	{ -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if ($query_id !== false) -		{ -			$result = array(); -			while ($row = $this->sql_fetchrow($query_id)) -			{ -				$result[] = $row; -			} - -			return $result; -		} - -		return false; -	} - -	/** -	* Seek to given row number -	* rownum is zero-based -	*/ -	function sql_rowseek($rownum, &$query_id) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if ($cache && $cache->sql_exists($query_id)) -		{ -			return $cache->sql_rowseek($rownum, $query_id); -		} - -		if ($query_id === false) -		{ -			return false; -		} - -		$this->sql_freeresult($query_id); -		$query_id = $this->sql_query($this->last_query_text); - -		if ($query_id === false) -		{ -			return false; -		} - -		// We do not fetch the row for rownum == 0 because then the next resultset would be the second row -		for ($i = 0; $i < $rownum; $i++) -		{ -			if (!$this->sql_fetchrow($query_id)) -			{ -				return false; -			} -		} - -		return true; -	} - -	/** -	* Fetch field -	* if rownum is false, the current row is used, else it is pointing to the row (zero-based) -	*/ -	function sql_fetchfield($field, $rownum = false, $query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if ($query_id !== false) -		{ -			if ($rownum !== false) -			{ -				$this->sql_rowseek($rownum, $query_id); -			} - -			if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) -			{ -				return $cache->sql_fetchfield($query_id, $field); -			} - -			$row = $this->sql_fetchrow($query_id); -			return (isset($row[$field])) ? $row[$field] : false; -		} - -		return false; -	} - -	/** -	* Correctly adjust LIKE expression for special characters -	* Some DBMS are handling them in a different way -	* -	* @param string $expression The expression to use. Every wildcard is escaped, except $this->any_char and $this->one_char -	* @return string LIKE expression including the keyword! -	*/ -	function sql_like_expression($expression) -	{ -		$expression = utf8_str_replace(array('_', '%'), array("\_", "\%"), $expression); -		$expression = utf8_str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression); - -		return $this->_sql_like_expression('LIKE \'' . $this->sql_escape($expression) . '\''); -	} - -	/** -	* Build a case expression -	* -	* Note: The two statements action_true and action_false must have the same data type (int, vchar, ...) in the database! -	* -	* @param	string	$condition		The condition which must be true, to use action_true rather then action_else -	* @param	string	$action_true	SQL expression that is used, if the condition is true -	* @param	string	$action_else	SQL expression that is used, if the condition is false, optional -	* @return	string			CASE expression including the condition and statements -	*/ -	public function sql_case($condition, $action_true, $action_false = false) -	{ -		$sql_case = 'CASE WHEN ' . $condition; -		$sql_case .= ' THEN ' . $action_true; -		$sql_case .= ($action_false !== false) ? ' ELSE ' . $action_false : ''; -		$sql_case .= ' END'; -		return $sql_case; -	} - -	/** -	* Build a concatenated expression -	* -	* @param	string	$expr1		Base SQL expression where we append the second one -	* @param	string	$expr2		SQL expression that is appended to the first expression -	* @return	string		Concatenated string -	*/ -	public function sql_concatenate($expr1, $expr2) -	{ -		return $expr1 . ' || ' . $expr2; -	} - -	/** -	* Returns whether results of a query need to be buffered to run a transaction while iterating over them. -	* -	* @return bool Whether buffering is required. -	*/ -	function sql_buffer_nested_transactions() -	{ -		return false; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				// If we are within a transaction we will not open another one, but enclose the current one to not loose data (prevening auto commit) -				if ($this->transaction) -				{ -					$this->transactions++; -					return true; -				} - -				$result = $this->_sql_transaction('begin'); - -				if (!$result) -				{ -					$this->sql_error(); -				} - -				$this->transaction = true; -			break; - -			case 'commit': -				// If there was a previously opened transaction we do not commit yet... but count back the number of inner transactions -				if ($this->transaction && $this->transactions) -				{ -					$this->transactions--; -					return true; -				} - -				// Check if there is a transaction (no transaction can happen if there was an error, with a combined rollback and error returning enabled) -				// This implies we have transaction always set for autocommit db's -				if (!$this->transaction) -				{ -					return false; -				} - -				$result = $this->_sql_transaction('commit'); - -				if (!$result) -				{ -					$this->sql_error(); -				} - -				$this->transaction = false; -				$this->transactions = 0; -			break; - -			case 'rollback': -				$result = $this->_sql_transaction('rollback'); -				$this->transaction = false; -				$this->transactions = 0; -			break; - -			default: -				$result = $this->_sql_transaction($status); -			break; -		} - -		return $result; -	} - -	/** -	* Build sql statement from array for insert/update/select statements -	* -	* Idea for this from Ikonboard -	* Possible query values: INSERT, INSERT_SELECT, UPDATE, SELECT -	* -	*/ -	function sql_build_array($query, $assoc_ary = false) -	{ -		if (!is_array($assoc_ary)) -		{ -			return false; -		} - -		$fields = $values = array(); - -		if ($query == 'INSERT' || $query == 'INSERT_SELECT') -		{ -			foreach ($assoc_ary as $key => $var) -			{ -				$fields[] = $key; - -				if (is_array($var) && is_string($var[0])) -				{ -					// This is used for INSERT_SELECT(s) -					$values[] = $var[0]; -				} -				else -				{ -					$values[] = $this->_sql_validate_value($var); -				} -			} - -			$query = ($query == 'INSERT') ? ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')' : ' (' . implode(', ', $fields) . ') SELECT ' . implode(', ', $values) . ' '; -		} -		else if ($query == 'MULTI_INSERT') -		{ -			trigger_error('The MULTI_INSERT query value is no longer supported. Please use sql_multi_insert() instead.', E_USER_ERROR); -		} -		else if ($query == 'UPDATE' || $query == 'SELECT') -		{ -			$values = array(); -			foreach ($assoc_ary as $key => $var) -			{ -				$values[] = "$key = " . $this->_sql_validate_value($var); -			} -			$query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values); -		} - -		return $query; -	} - -	/** -	* Build IN or NOT IN sql comparison string, uses <> or = on single element -	* arrays to improve comparison speed -	* -	* @access public -	* @param	string	$field				name of the sql column that shall be compared -	* @param	array	$array				array of values that are allowed (IN) or not allowed (NOT IN) -	* @param	bool	$negate				true for NOT IN (), false for IN () (default) -	* @param	bool	$allow_empty_set	If true, allow $array to be empty, this function will return 1=1 or 1=0 then. Default to false. -	*/ -	function sql_in_set($field, $array, $negate = false, $allow_empty_set = false) -	{ -		if (!sizeof($array)) -		{ -			if (!$allow_empty_set) -			{ -				// Print the backtrace to help identifying the location of the problematic code -				$this->sql_error('No values specified for SQL IN comparison'); -			} -			else -			{ -				// NOT IN () actually means everything so use a tautology -				if ($negate) -				{ -					return '1=1'; -				} -				// IN () actually means nothing so use a contradiction -				else -				{ -					return '1=0'; -				} -			} -		} - -		if (!is_array($array)) -		{ -			$array = array($array); -		} - -		if (sizeof($array) == 1) -		{ -			@reset($array); -			$var = current($array); - -			return $field . ($negate ? ' <> ' : ' = ') . $this->_sql_validate_value($var); -		} -		else -		{ -			return $field . ($negate ? ' NOT IN ' : ' IN ') . '(' . implode(', ', array_map(array($this, '_sql_validate_value'), $array)) . ')'; -		} -	} - -	/** -	* Run binary AND operator on DB column. -	* Results in sql statement: "{$column_name} & (1 << {$bit}) {$compare}" -	* -	* @param string $column_name The column name to use -	* @param int $bit The value to use for the AND operator, will be converted to (1 << $bit). Is used by options, using the number schema... 0, 1, 2...29 -	* @param string $compare Any custom SQL code after the check (for example "= 0") -	*/ -	function sql_bit_and($column_name, $bit, $compare = '') -	{ -		if (method_exists($this, '_sql_bit_and')) -		{ -			return $this->_sql_bit_and($column_name, $bit, $compare); -		} - -		return $column_name . ' & ' . (1 << $bit) . (($compare) ? ' ' . $compare : ''); -	} - -	/** -	* Run binary OR operator on DB column. -	* Results in sql statement: "{$column_name} | (1 << {$bit}) {$compare}" -	* -	* @param string $column_name The column name to use -	* @param int $bit The value to use for the OR operator, will be converted to (1 << $bit). Is used by options, using the number schema... 0, 1, 2...29 -	* @param string $compare Any custom SQL code after the check (for example "= 0") -	*/ -	function sql_bit_or($column_name, $bit, $compare = '') -	{ -		if (method_exists($this, '_sql_bit_or')) -		{ -			return $this->_sql_bit_or($column_name, $bit, $compare); -		} - -		return $column_name . ' | ' . (1 << $bit) . (($compare) ? ' ' . $compare : ''); -	} - -	/** -	* Returns SQL string to cast a string expression to an int. -	* -	* @param  string $expression An expression evaluating to string -	* @return string             Expression returning an int -	*/ -	function cast_expr_to_bigint($expression) -	{ -		return $expression; -	} - -	/** -	* Returns SQL string to cast an integer expression to a string. -	* -	* @param  string $expression An expression evaluating to int -	* @return string             Expression returning a string -	*/ -	function cast_expr_to_string($expression) -	{ -		return $expression; -	} - -	/** -	* Run LOWER() on DB column of type text (i.e. neither varchar nor char). -	* -	* @param string $column_name	The column name to use -	* -	* @return string				A SQL statement like "LOWER($column_name)" -	*/ -	function sql_lower_text($column_name) -	{ -		return "LOWER($column_name)"; -	} - -	/** -	* Run more than one insert statement. -	* -	* @param string $table table name to run the statements on -	* @param array $sql_ary multi-dimensional array holding the statement data. -	* -	* @return bool false if no statements were executed. -	* @access public -	*/ -	function sql_multi_insert($table, $sql_ary) -	{ -		if (!sizeof($sql_ary)) -		{ -			return false; -		} - -		if ($this->multi_insert) -		{ -			$ary = array(); -			foreach ($sql_ary as $id => $_sql_ary) -			{ -				// If by accident the sql array is only one-dimensional we build a normal insert statement -				if (!is_array($_sql_ary)) -				{ -					return $this->sql_query('INSERT INTO ' . $table . ' ' . $this->sql_build_array('INSERT', $sql_ary)); -				} - -				$values = array(); -				foreach ($_sql_ary as $key => $var) -				{ -					$values[] = $this->_sql_validate_value($var); -				} -				$ary[] = '(' . implode(', ', $values) . ')'; -			} - -			return $this->sql_query('INSERT INTO ' . $table . ' ' . ' (' . implode(', ', array_keys($sql_ary[0])) . ') VALUES ' . implode(', ', $ary)); -		} -		else -		{ -			foreach ($sql_ary as $ary) -			{ -				if (!is_array($ary)) -				{ -					return false; -				} - -				$result = $this->sql_query('INSERT INTO ' . $table . ' ' . $this->sql_build_array('INSERT', $ary)); - -				if (!$result) -				{ -					return false; -				} -			} -		} - -		return true; -	} - -	/** -	* Function for validating values -	* @access private -	*/ -	function _sql_validate_value($var) -	{ -		if (is_null($var)) -		{ -			return 'NULL'; -		} -		else if (is_string($var)) -		{ -			return "'" . $this->sql_escape($var) . "'"; -		} -		else -		{ -			return (is_bool($var)) ? intval($var) : $var; -		} -	} - -	/** -	* Build sql statement from array for select and select distinct statements -	* -	* Possible query values: SELECT, SELECT_DISTINCT -	*/ -	function sql_build_query($query, $array) -	{ -		$sql = ''; -		switch ($query) -		{ -			case 'SELECT': -			case 'SELECT_DISTINCT'; - -				$sql = str_replace('_', ' ', $query) . ' ' . $array['SELECT'] . ' FROM '; - -				// Build table array. We also build an alias array for later checks. -				$table_array = $aliases = array(); -				$used_multi_alias = false; - -				foreach ($array['FROM'] as $table_name => $alias) -				{ -					if (is_array($alias)) -					{ -						$used_multi_alias = true; - -						foreach ($alias as $multi_alias) -						{ -							$table_array[] = $table_name . ' ' . $multi_alias; -							$aliases[] = $multi_alias; -						} -					} -					else -					{ -						$table_array[] = $table_name . ' ' . $alias; -						$aliases[] = $alias; -					} -				} - -				// We run the following code to determine if we need to re-order the table array. ;) -				// The reason for this is that for multi-aliased tables (two equal tables) in the FROM statement the last table need to match the first comparison. -				// DBMS who rely on this: Oracle, PostgreSQL and MSSQL. For all other DBMS it makes absolutely no difference in which order the table is. -				if (!empty($array['LEFT_JOIN']) && sizeof($array['FROM']) > 1 && $used_multi_alias !== false) -				{ -					// Take first LEFT JOIN -					$join = current($array['LEFT_JOIN']); - -					// Determine the table used there (even if there are more than one used, we only want to have one -					preg_match('/(' . implode('|', $aliases) . ')\.[^\s]+/U', str_replace(array('(', ')', 'AND', 'OR', ' '), '', $join['ON']), $matches); - -					// If there is a first join match, we need to make sure the table order is correct -					if (!empty($matches[1])) -					{ -						$first_join_match = trim($matches[1]); -						$table_array = $last = array(); - -						foreach ($array['FROM'] as $table_name => $alias) -						{ -							if (is_array($alias)) -							{ -								foreach ($alias as $multi_alias) -								{ -									($multi_alias === $first_join_match) ? $last[] = $table_name . ' ' . $multi_alias : $table_array[] = $table_name . ' ' . $multi_alias; -								} -							} -							else -							{ -								($alias === $first_join_match) ? $last[] = $table_name . ' ' . $alias : $table_array[] = $table_name . ' ' . $alias; -							} -						} - -						$table_array = array_merge($table_array, $last); -					} -				} - -				$sql .= $this->_sql_custom_build('FROM', implode(' CROSS JOIN ', $table_array)); - -				if (!empty($array['LEFT_JOIN'])) -				{ -					foreach ($array['LEFT_JOIN'] as $join) -					{ -						$sql .= ' LEFT JOIN ' . key($join['FROM']) . ' ' . current($join['FROM']) . ' ON (' . $join['ON'] . ')'; -					} -				} - -				if (!empty($array['WHERE'])) -				{ -					$sql .= ' WHERE ' . $this->_sql_custom_build('WHERE', $array['WHERE']); -				} - -				if (!empty($array['GROUP_BY'])) -				{ -					$sql .= ' GROUP BY ' . $array['GROUP_BY']; -				} - -				if (!empty($array['ORDER_BY'])) -				{ -					$sql .= ' ORDER BY ' . $array['ORDER_BY']; -				} - -			break; -		} - -		return $sql; -	} - -	/** -	* display sql error page -	*/ -	function sql_error($sql = '') -	{ -		global $auth, $user, $config; - -		// Set var to retrieve errored status -		$this->sql_error_triggered = true; -		$this->sql_error_sql = $sql; - -		$this->sql_error_returned = $this->_sql_error(); - -		if (!$this->return_on_error) -		{ -			$message = 'SQL ERROR [ ' . $this->sql_layer . ' ]<br /><br />' . $this->sql_error_returned['message'] . ' [' . $this->sql_error_returned['code'] . ']'; - -			// Show complete SQL error and path to administrators only -			// Additionally show complete error on installation or if extended debug mode is enabled -			// The DEBUG constant is for development only! -			if ((isset($auth) && $auth->acl_get('a_')) || defined('IN_INSTALL') || defined('DEBUG')) -			{ -				$message .= ($sql) ? '<br /><br />SQL<br /><br />' . htmlspecialchars($sql) : ''; -			} -			else -			{ -				// If error occurs in initiating the session we need to use a pre-defined language string -				// This could happen if the connection could not be established for example (then we are not able to grab the default language) -				if (!isset($user->lang['SQL_ERROR_OCCURRED'])) -				{ -					$message .= '<br /><br />An sql error occurred while fetching this page. Please contact an administrator if this problem persists.'; -				} -				else -				{ -					if (!empty($config['board_contact'])) -					{ -						$message .= '<br /><br />' . sprintf($user->lang['SQL_ERROR_OCCURRED'], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>'); -					} -					else -					{ -						$message .= '<br /><br />' . sprintf($user->lang['SQL_ERROR_OCCURRED'], '', ''); -					} -				} -			} - -			if ($this->transaction) -			{ -				$this->sql_transaction('rollback'); -			} - -			if (strlen($message) > 1024) -			{ -				// We need to define $msg_long_text here to circumvent text stripping. -				global $msg_long_text; -				$msg_long_text = $message; - -				trigger_error(false, E_USER_ERROR); -			} - -			trigger_error($message, E_USER_ERROR); -		} - -		if ($this->transaction) -		{ -			$this->sql_transaction('rollback'); -		} - -		return $this->sql_error_returned; -	} - -	/** -	* Explain queries -	*/ -	function sql_report($mode, $query = '') -	{ -		global $cache, $starttime, $phpbb_root_path, $phpbb_admin_path, $user; -		global $request; - -		if (is_object($request) && !$request->variable('explain', false)) -		{ -			return false; -		} - -		if (!$query && $this->query_hold != '') -		{ -			$query = $this->query_hold; -		} - -		switch ($mode) -		{ -			case 'display': -				if (!empty($cache)) -				{ -					$cache->unload(); -				} -				$this->sql_close(); - -				$mtime = explode(' ', microtime()); -				$totaltime = $mtime[0] + $mtime[1] - $starttime; - -				echo '<!DOCTYPE html> -					<html dir="ltr"> -					<head> -						<meta charset="utf-8"> -						<title>SQL Report</title> -						<link href="' . htmlspecialchars($phpbb_admin_path) . 'style/admin.css" rel="stylesheet" type="text/css" media="screen" /> -					</head> -					<body id="errorpage"> -					<div id="wrap"> -						<div id="page-header"> -							<a href="' . build_url('explain') . '">Return to previous page</a> -						</div> -						<div id="page-body"> -							<div id="acp"> -							<div class="panel"> -								<span class="corners-top"><span></span></span> -								<div id="content"> -									<h1>SQL Report</h1> -									<br /> -									<p><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries['normal']} queries" . (($this->num_queries['cached']) ? " + {$this->num_queries['cached']} " . (($this->num_queries['cached'] == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></p> - -									<p>Time spent on ' . $this->sql_layer . ' queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></p> - -									<br /><br /> -									' . $this->sql_report . ' -								</div> -								<span class="corners-bottom"><span></span></span> -							</div> -							</div> -						</div> -						<div id="page-footer"> -							Powered by <a href="http://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group -						</div> -					</div> -					</body> -					</html>'; - -				exit_handler(); - -			break; - -			case 'stop': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$this->sql_report .= ' - -					<table cellspacing="1"> -					<thead> -					<tr> -						<th>Query #' . $this->num_queries['total'] . '</th> -					</tr> -					</thead> -					<tbody> -					<tr> -						<td class="row3"><textarea style="font-family:\'Courier New\',monospace;width:99%" rows="5" cols="10">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td> -					</tr> -					</tbody> -					</table> - -					' . $this->html_hold . ' - -					<p style="text-align: center;"> -				'; - -				if ($this->query_result) -				{ -					if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query)) -					{ -						$this->sql_report .= 'Affected rows: <b>' . $this->sql_affectedrows($this->query_result) . '</b> | '; -					} -					$this->sql_report .= 'Before: ' . sprintf('%.5f', $this->curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $this->curtime) . 's</b>'; -				} -				else -				{ -					$error = $this->sql_error(); -					$this->sql_report .= '<b style="color: red">FAILED</b> - ' . $this->sql_layer . ' Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']); -				} - -				$this->sql_report .= '</p><br /><br />'; - -				$this->sql_time += $endtime - $this->curtime; -			break; - -			case 'start': -				$this->query_hold = $query; -				$this->html_hold = ''; - -				$this->_sql_report($mode, $query); - -				$this->curtime = explode(' ', microtime()); -				$this->curtime = $this->curtime[0] + $this->curtime[1]; - -			break; - -			case 'add_select_row': - -				$html_table = func_get_arg(2); -				$row = func_get_arg(3); - -				if (!$html_table && sizeof($row)) -				{ -					$html_table = true; -					$this->html_hold .= '<table cellspacing="1"><tr>'; - -					foreach (array_keys($row) as $val) -					{ -						$this->html_hold .= '<th>' . (($val) ? ucwords(str_replace('_', ' ', $val)) : ' ') . '</th>'; -					} -					$this->html_hold .= '</tr>'; -				} -				$this->html_hold .= '<tr>'; - -				$class = 'row1'; -				foreach (array_values($row) as $val) -				{ -					$class = ($class == 'row1') ? 'row2' : 'row1'; -					$this->html_hold .= '<td class="' . $class . '">' . (($val) ? $val : ' ') . '</td>'; -				} -				$this->html_hold .= '</tr>'; - -				return $html_table; - -			break; - -			case 'fromcache': - -				$this->_sql_report($mode, $query); - -			break; - -			case 'record_fromcache': - -				$endtime = func_get_arg(2); -				$splittime = func_get_arg(3); - -				$time_cache = $endtime - $this->curtime; -				$time_db = $splittime - $endtime; -				$color = ($time_db > $time_cache) ? 'green' : 'red'; - -				$this->sql_report .= '<table cellspacing="1"><thead><tr><th>Query results obtained from the cache</th></tr></thead><tbody><tr>'; -				$this->sql_report .= '<td class="row3"><textarea style="font-family:\'Courier New\',monospace;width:99%" rows="5" cols="10">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></tbody></table>'; -				$this->sql_report .= '<p style="text-align: center;">'; -				$this->sql_report .= 'Before: ' . sprintf('%.5f', $this->curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p><br /><br />'; - -				// Pad the start time to not interfere with page timing -				$starttime += $time_db; - -			break; - -			default: - -				$this->_sql_report($mode, $query); - -			break; -		} - -		return true; -	} - -	/** -	* Gets the estimated number of rows in a specified table. -	* -	* @param string $table_name		Table name -	* -	* @return string				Number of rows in $table_name. -	*								Prefixed with ~ if estimated (otherwise exact). -	* -	* @access public -	*/ -	function get_estimated_row_count($table_name) -	{ -		return $this->get_row_count($table_name); -	} - -	/** -	* Gets the exact number of rows in a specified table. -	* -	* @param string $table_name		Table name -	* -	* @return string				Exact number of rows in $table_name. -	* -	* @access public -	*/ -	function get_row_count($table_name) -	{ -		$sql = 'SELECT COUNT(*) AS rows_total -			FROM ' . $this->sql_escape($table_name); -		$result = $this->sql_query($sql); -		$rows_total = $this->sql_fetchfield('rows_total'); -		$this->sql_freeresult($result); - -		return $rows_total; -	} -} | 
