diff options
Diffstat (limited to 'phpBB/includes/db')
| -rw-r--r-- | phpBB/includes/db/db_tools.php | 2525 | ||||
| -rw-r--r-- | phpBB/includes/db/dbal.php | 1000 | ||||
| -rw-r--r-- | phpBB/includes/db/firebird.php | 526 | ||||
| -rw-r--r-- | phpBB/includes/db/index.htm | 10 | ||||
| -rw-r--r-- | phpBB/includes/db/mssql.php | 476 | ||||
| -rw-r--r-- | phpBB/includes/db/mssql_odbc.php | 422 | ||||
| -rw-r--r-- | phpBB/includes/db/mssqlnative.php | 652 | ||||
| -rw-r--r-- | phpBB/includes/db/mysql.php | 591 | ||||
| -rw-r--r-- | phpBB/includes/db/mysqli.php | 581 | ||||
| -rw-r--r-- | phpBB/includes/db/oracle.php | 808 | ||||
| -rw-r--r-- | phpBB/includes/db/postgres.php | 485 | ||||
| -rw-r--r-- | phpBB/includes/db/sqlite.php | 370 | 
12 files changed, 0 insertions, 8446 deletions
| diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php deleted file mode 100644 index 6913960185..0000000000 --- a/phpBB/includes/db/db_tools.php +++ /dev/null @@ -1,2525 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2007 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -/** -* Database Tools for handling cross-db actions such as altering columns, etc. -* Currently not supported is returning SQL for creating tables. -* -* @package dbal -* @note currently not used within phpBB3, but may be utilized later. -*/ -class phpbb_db_tools -{ -	/** -	* Current sql layer -	*/ -	var $sql_layer = ''; - -	/** -	* @var object DB object -	*/ -	var $db = NULL; - -	/** -	* The Column types for every database we support -	* @var array -	*/ -	var $dbms_type_map = array( -		'mysql_41'	=> array( -			'INT:'		=> 'int(%d)', -			'BINT'		=> 'bigint(20)', -			'UINT'		=> 'mediumint(8) UNSIGNED', -			'UINT:'		=> 'int(%d) UNSIGNED', -			'TINT:'		=> 'tinyint(%d)', -			'USINT'		=> 'smallint(4) UNSIGNED', -			'BOOL'		=> 'tinyint(1) UNSIGNED', -			'VCHAR'		=> 'varchar(255)', -			'VCHAR:'	=> 'varchar(%d)', -			'CHAR:'		=> 'char(%d)', -			'XSTEXT'	=> 'text', -			'XSTEXT_UNI'=> 'varchar(100)', -			'STEXT'		=> 'text', -			'STEXT_UNI'	=> 'varchar(255)', -			'TEXT'		=> 'text', -			'TEXT_UNI'	=> 'text', -			'MTEXT'		=> 'mediumtext', -			'MTEXT_UNI'	=> 'mediumtext', -			'TIMESTAMP'	=> 'int(11) UNSIGNED', -			'DECIMAL'	=> 'decimal(5,2)', -			'DECIMAL:'	=> 'decimal(%d,2)', -			'PDECIMAL'	=> 'decimal(6,3)', -			'PDECIMAL:'	=> 'decimal(%d,3)', -			'VCHAR_UNI'	=> 'varchar(255)', -			'VCHAR_UNI:'=> 'varchar(%d)', -			'VCHAR_CI'	=> 'varchar(255)', -			'VARBINARY'	=> 'varbinary(255)', -		), - -		'mysql_40'	=> array( -			'INT:'		=> 'int(%d)', -			'BINT'		=> 'bigint(20)', -			'UINT'		=> 'mediumint(8) UNSIGNED', -			'UINT:'		=> 'int(%d) UNSIGNED', -			'TINT:'		=> 'tinyint(%d)', -			'USINT'		=> 'smallint(4) UNSIGNED', -			'BOOL'		=> 'tinyint(1) UNSIGNED', -			'VCHAR'		=> 'varbinary(255)', -			'VCHAR:'	=> 'varbinary(%d)', -			'CHAR:'		=> 'binary(%d)', -			'XSTEXT'	=> 'blob', -			'XSTEXT_UNI'=> 'blob', -			'STEXT'		=> 'blob', -			'STEXT_UNI'	=> 'blob', -			'TEXT'		=> 'blob', -			'TEXT_UNI'	=> 'blob', -			'MTEXT'		=> 'mediumblob', -			'MTEXT_UNI'	=> 'mediumblob', -			'TIMESTAMP'	=> 'int(11) UNSIGNED', -			'DECIMAL'	=> 'decimal(5,2)', -			'DECIMAL:'	=> 'decimal(%d,2)', -			'PDECIMAL'	=> 'decimal(6,3)', -			'PDECIMAL:'	=> 'decimal(%d,3)', -			'VCHAR_UNI'	=> 'blob', -			'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')), -			'VCHAR_CI'	=> 'blob', -			'VARBINARY'	=> 'varbinary(255)', -		), - -		'firebird'	=> array( -			'INT:'		=> 'INTEGER', -			'BINT'		=> 'DOUBLE PRECISION', -			'UINT'		=> 'INTEGER', -			'UINT:'		=> 'INTEGER', -			'TINT:'		=> 'INTEGER', -			'USINT'		=> 'INTEGER', -			'BOOL'		=> 'INTEGER', -			'VCHAR'		=> 'VARCHAR(255) CHARACTER SET NONE', -			'VCHAR:'	=> 'VARCHAR(%d) CHARACTER SET NONE', -			'CHAR:'		=> 'CHAR(%d) CHARACTER SET NONE', -			'XSTEXT'	=> 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', -			'STEXT'		=> 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', -			'TEXT'		=> 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', -			'MTEXT'		=> 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', -			'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8', -			'STEXT_UNI'	=> 'VARCHAR(255) CHARACTER SET UTF8', -			'TEXT_UNI'	=> 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', -			'MTEXT_UNI'	=> 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', -			'TIMESTAMP'	=> 'INTEGER', -			'DECIMAL'	=> 'DOUBLE PRECISION', -			'DECIMAL:'	=> 'DOUBLE PRECISION', -			'PDECIMAL'	=> 'DOUBLE PRECISION', -			'PDECIMAL:'	=> 'DOUBLE PRECISION', -			'VCHAR_UNI'	=> 'VARCHAR(255) CHARACTER SET UTF8', -			'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8', -			'VCHAR_CI'	=> 'VARCHAR(255) CHARACTER SET UTF8', -			'VARBINARY'	=> 'CHAR(255) CHARACTER SET NONE', -		), - -		'mssql'		=> array( -			'INT:'		=> '[int]', -			'BINT'		=> '[float]', -			'UINT'		=> '[int]', -			'UINT:'		=> '[int]', -			'TINT:'		=> '[int]', -			'USINT'		=> '[int]', -			'BOOL'		=> '[int]', -			'VCHAR'		=> '[varchar] (255)', -			'VCHAR:'	=> '[varchar] (%d)', -			'CHAR:'		=> '[char] (%d)', -			'XSTEXT'	=> '[varchar] (1000)', -			'STEXT'		=> '[varchar] (3000)', -			'TEXT'		=> '[varchar] (8000)', -			'MTEXT'		=> '[text]', -			'XSTEXT_UNI'=> '[varchar] (100)', -			'STEXT_UNI'	=> '[varchar] (255)', -			'TEXT_UNI'	=> '[varchar] (4000)', -			'MTEXT_UNI'	=> '[text]', -			'TIMESTAMP'	=> '[int]', -			'DECIMAL'	=> '[float]', -			'DECIMAL:'	=> '[float]', -			'PDECIMAL'	=> '[float]', -			'PDECIMAL:'	=> '[float]', -			'VCHAR_UNI'	=> '[varchar] (255)', -			'VCHAR_UNI:'=> '[varchar] (%d)', -			'VCHAR_CI'	=> '[varchar] (255)', -			'VARBINARY'	=> '[varchar] (255)', -		), - -		'mssqlnative'	=> array( -			'INT:'		=> '[int]', -			'BINT'		=> '[float]', -			'UINT'		=> '[int]', -			'UINT:'		=> '[int]', -			'TINT:'		=> '[int]', -			'USINT'		=> '[int]', -			'BOOL'		=> '[int]', -			'VCHAR'		=> '[varchar] (255)', -			'VCHAR:'	=> '[varchar] (%d)', -			'CHAR:'		=> '[char] (%d)', -			'XSTEXT'	=> '[varchar] (1000)', -			'STEXT'		=> '[varchar] (3000)', -			'TEXT'		=> '[varchar] (8000)', -			'MTEXT'		=> '[text]', -			'XSTEXT_UNI'=> '[varchar] (100)', -			'STEXT_UNI'	=> '[varchar] (255)', -			'TEXT_UNI'	=> '[varchar] (4000)', -			'MTEXT_UNI'	=> '[text]', -			'TIMESTAMP'	=> '[int]', -			'DECIMAL'	=> '[float]', -			'DECIMAL:'	=> '[float]', -			'PDECIMAL'	=> '[float]', -			'PDECIMAL:'	=> '[float]', -			'VCHAR_UNI'	=> '[varchar] (255)', -			'VCHAR_UNI:'=> '[varchar] (%d)', -			'VCHAR_CI'	=> '[varchar] (255)', -			'VARBINARY'	=> '[varchar] (255)', -		), - -		'oracle'	=> array( -			'INT:'		=> 'number(%d)', -			'BINT'		=> 'number(20)', -			'UINT'		=> 'number(8)', -			'UINT:'		=> 'number(%d)', -			'TINT:'		=> 'number(%d)', -			'USINT'		=> 'number(4)', -			'BOOL'		=> 'number(1)', -			'VCHAR'		=> 'varchar2(255)', -			'VCHAR:'	=> 'varchar2(%d)', -			'CHAR:'		=> 'char(%d)', -			'XSTEXT'	=> 'varchar2(1000)', -			'STEXT'		=> 'varchar2(3000)', -			'TEXT'		=> 'clob', -			'MTEXT'		=> 'clob', -			'XSTEXT_UNI'=> 'varchar2(300)', -			'STEXT_UNI'	=> 'varchar2(765)', -			'TEXT_UNI'	=> 'clob', -			'MTEXT_UNI'	=> 'clob', -			'TIMESTAMP'	=> 'number(11)', -			'DECIMAL'	=> 'number(5, 2)', -			'DECIMAL:'	=> 'number(%d, 2)', -			'PDECIMAL'	=> 'number(6, 3)', -			'PDECIMAL:'	=> 'number(%d, 3)', -			'VCHAR_UNI'	=> 'varchar2(765)', -			'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')), -			'VCHAR_CI'	=> 'varchar2(255)', -			'VARBINARY'	=> 'raw(255)', -		), - -		'sqlite'	=> array( -			'INT:'		=> 'int(%d)', -			'BINT'		=> 'bigint(20)', -			'UINT'		=> 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', -			'UINT:'		=> 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', -			'TINT:'		=> 'tinyint(%d)', -			'USINT'		=> 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', -			'BOOL'		=> 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', -			'VCHAR'		=> 'varchar(255)', -			'VCHAR:'	=> 'varchar(%d)', -			'CHAR:'		=> 'char(%d)', -			'XSTEXT'	=> 'text(65535)', -			'STEXT'		=> 'text(65535)', -			'TEXT'		=> 'text(65535)', -			'MTEXT'		=> 'mediumtext(16777215)', -			'XSTEXT_UNI'=> 'text(65535)', -			'STEXT_UNI'	=> 'text(65535)', -			'TEXT_UNI'	=> 'text(65535)', -			'MTEXT_UNI'	=> 'mediumtext(16777215)', -			'TIMESTAMP'	=> 'INTEGER UNSIGNED', //'int(11) UNSIGNED', -			'DECIMAL'	=> 'decimal(5,2)', -			'DECIMAL:'	=> 'decimal(%d,2)', -			'PDECIMAL'	=> 'decimal(6,3)', -			'PDECIMAL:'	=> 'decimal(%d,3)', -			'VCHAR_UNI'	=> 'varchar(255)', -			'VCHAR_UNI:'=> 'varchar(%d)', -			'VCHAR_CI'	=> 'varchar(255)', -			'VARBINARY'	=> 'blob', -		), - -		'postgres'	=> array( -			'INT:'		=> 'INT4', -			'BINT'		=> 'INT8', -			'UINT'		=> 'INT4', // unsigned -			'UINT:'		=> 'INT4', // unsigned -			'USINT'		=> 'INT2', // unsigned -			'BOOL'		=> 'INT2', // unsigned -			'TINT:'		=> 'INT2', -			'VCHAR'		=> 'varchar(255)', -			'VCHAR:'	=> 'varchar(%d)', -			'CHAR:'		=> 'char(%d)', -			'XSTEXT'	=> 'varchar(1000)', -			'STEXT'		=> 'varchar(3000)', -			'TEXT'		=> 'varchar(8000)', -			'MTEXT'		=> 'TEXT', -			'XSTEXT_UNI'=> 'varchar(100)', -			'STEXT_UNI'	=> 'varchar(255)', -			'TEXT_UNI'	=> 'varchar(4000)', -			'MTEXT_UNI'	=> 'TEXT', -			'TIMESTAMP'	=> 'INT4', // unsigned -			'DECIMAL'	=> 'decimal(5,2)', -			'DECIMAL:'	=> 'decimal(%d,2)', -			'PDECIMAL'	=> 'decimal(6,3)', -			'PDECIMAL:'	=> 'decimal(%d,3)', -			'VCHAR_UNI'	=> 'varchar(255)', -			'VCHAR_UNI:'=> 'varchar(%d)', -			'VCHAR_CI'	=> 'varchar_ci', -			'VARBINARY'	=> 'bytea', -		), -	); - -	/** -	* A list of types being unsigned for better reference in some db's -	* @var array -	*/ -	var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); - -	/** -	* A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. -	* @var array -	*/ -	var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); - -	/** -	* This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). -	* This mode has no effect on some methods (inserting of data for example). This is expressed within the methods command. -	*/ -	var $return_statements = false; - -	/** -	* Constructor. Set DB Object and set {@link $return_statements return_statements}. -	* -	* @param phpbb_dbal	$db					DBAL object -	* @param bool		$return_statements	True if only statements should be returned and no SQL being executed -	*/ -	function phpbb_db_tools(&$db, $return_statements = false) -	{ -		$this->db = $db; -		$this->return_statements = $return_statements; - -		// Determine mapping database type -		switch ($this->db->sql_layer) -		{ -			case 'mysql': -				$this->sql_layer = 'mysql_40'; -			break; - -			case 'mysql4': -				if (version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) -				{ -					$this->sql_layer = 'mysql_41'; -				} -				else -				{ -					$this->sql_layer = 'mysql_40'; -				} -			break; - -			case 'mysqli': -				$this->sql_layer = 'mysql_41'; -			break; - -			case 'mssql': -			case 'mssql_odbc': -				$this->sql_layer = 'mssql'; -			break; - -			case 'mssqlnative': -				$this->sql_layer = 'mssqlnative'; -			break; - -			default: -				$this->sql_layer = $this->db->sql_layer; -			break; -		} -	} - -	/** -	* Gets a list of tables in the database. -	* -	* @return array		Array of table names  (all lower case) -	*/ -	function sql_list_tables() -	{ -		switch ($this->db->sql_layer) -		{ -			case 'mysql': -			case 'mysql4': -			case 'mysqli': -				$sql = 'SHOW TABLES'; -			break; - -			case 'sqlite': -				$sql = 'SELECT name -					FROM sqlite_master -					WHERE type = "table"'; -			break; - -			case 'mssql': -			case 'mssql_odbc': -			case 'mssqlnative': -				$sql = "SELECT name -					FROM sysobjects -					WHERE type='U'"; -			break; - -			case 'postgres': -				$sql = 'SELECT relname -					FROM pg_stat_user_tables'; -			break; - -			case 'firebird': -				$sql = 'SELECT rdb$relation_name -					FROM rdb$relations -					WHERE rdb$view_source is null -						AND rdb$system_flag = 0'; -			break; - -			case 'oracle': -				$sql = 'SELECT table_name -					FROM USER_TABLES'; -			break; -		} - -		$result = $this->db->sql_query($sql); - -		$tables = array(); -		while ($row = $this->db->sql_fetchrow($result)) -		{ -			$name = current($row); -			$tables[$name] = $name; -		} -		$this->db->sql_freeresult($result); - -		return $tables; -	} - -	/** -	* Check if table exists -	* -	* -	* @param string	$table_name	The table name to check for -	* @return bool true if table exists, else false -	*/ -	function sql_table_exists($table_name) -	{ -		$this->db->sql_return_on_error(true); -		$result = $this->db->sql_query_limit('SELECT * FROM ' . $table_name, 1); -		$this->db->sql_return_on_error(false); - -		if ($result) -		{ -			$this->db->sql_freeresult($result); -			return true; -		} - -		return false; -	} - -	/** -	* Create SQL Table -	* -	* @param string	$table_name	The table name to create -	* @param array	$table_data	Array containing table data. -	* @return array	Statements if $return_statements is true. -	*/ -	function sql_create_table($table_name, $table_data) -	{ -		// holds the DDL for a column -		$columns = $statements = array(); - -		if ($this->sql_table_exists($table_name)) -		{ -			return $this->_sql_run_sql($statements); -		} - -		// Begin transaction -		$statements[] = 'begin'; - -		// Determine if we have created a PRIMARY KEY in the earliest -		$primary_key_gen = false; - -		// Determine if the table requires a sequence -		$create_sequence = false; - -		// Begin table sql statement -		switch ($this->sql_layer) -		{ -			case 'mssql': -			case 'mssqlnative': -				$table_sql = 'CREATE TABLE [' . $table_name . '] (' . "\n"; -			break; - -			default: -				$table_sql = 'CREATE TABLE ' . $table_name . ' (' . "\n"; -			break; -		} - -		if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') -		{ -			if (!isset($table_data['PRIMARY_KEY'])) -			{ -				$table_data['COLUMNS']['mssqlindex'] = array('UINT', null, 'auto_increment'); -				$table_data['PRIMARY_KEY'] = 'mssqlindex'; -			} -		} - -		// Iterate through the columns to create a table -		foreach ($table_data['COLUMNS'] as $column_name => $column_data) -		{ -			// here lies an array, filled with information compiled on the column's data -			$prepared_column = $this->sql_prepare_column_data($table_name, $column_name, $column_data); - -			if (isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'] && strlen($column_name) > 26) // "${column_name}_gen" -			{ -				trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum auto increment column length is 26 characters.", E_USER_ERROR); -			} - -			// here we add the definition of the new column to the list of columns -			switch ($this->sql_layer) -			{ -				case 'mssql': -				case 'mssqlnative': -					$columns[] = "\t [{$column_name}] " . $prepared_column['column_type_sql_default']; -				break; - -				default: -					$columns[] = "\t {$column_name} " . $prepared_column['column_type_sql']; -				break; -			} - -			// see if we have found a primary key set due to a column definition if we have found it, we can stop looking -			if (!$primary_key_gen) -			{ -				$primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; -			} - -			// create sequence DDL based off of the existance of auto incrementing columns -			if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) -			{ -				$create_sequence = $column_name; -			} -		} - -		// this makes up all the columns in the create table statement -		$table_sql .= implode(",\n", $columns); - -		// Close the table for two DBMS and add to the statements -		switch ($this->sql_layer) -		{ -			case 'firebird': -			case 'mssql': -			case 'mssqlnative': -				$table_sql .= "\n);"; -				$statements[] = $table_sql; -			break; -		} - -		// we have yet to create a primary key for this table, -		// this means that we can add the one we really wanted instead -		if (!$primary_key_gen) -		{ -			// Write primary key -			if (isset($table_data['PRIMARY_KEY'])) -			{ -				if (!is_array($table_data['PRIMARY_KEY'])) -				{ -					$table_data['PRIMARY_KEY'] = array($table_data['PRIMARY_KEY']); -				} - -				switch ($this->sql_layer) -				{ -					case 'mysql_40': -					case 'mysql_41': -					case 'postgres': -					case 'sqlite': -						$table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; -					break; - -					case 'firebird': -					case 'mssql': -					case 'mssqlnative': -						// We need the data here -						$old_return_statements = $this->return_statements; -						$this->return_statements = true; - -						$primary_key_stmts = $this->sql_create_primary_key($table_name, $table_data['PRIMARY_KEY']); -						foreach ($primary_key_stmts as $pk_stmt) -						{ -							$statements[] = $pk_stmt; -						} - -						$this->return_statements = $old_return_statements; -					break; - -					case 'oracle': -						$table_sql .= ",\n\t CONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; -					break; -				} -			} -		} - -		// close the table -		switch ($this->sql_layer) -		{ -			case 'mysql_41': -				// make sure the table is in UTF-8 mode -				$table_sql .= "\n) CHARACTER SET `utf8` COLLATE `utf8_bin`;"; -				$statements[] = $table_sql; -			break; - -			case 'mysql_40': -			case 'sqlite': -				$table_sql .= "\n);"; -				$statements[] = $table_sql; -			break; - -			case 'postgres': -				// do we need to add a sequence for auto incrementing columns? -				if ($create_sequence) -				{ -					$statements[] = "CREATE SEQUENCE {$table_name}_seq;"; -				} - -				$table_sql .= "\n);"; -				$statements[] = $table_sql; -			break; - -			case 'oracle': -				$table_sql .= "\n)"; -				$statements[] = $table_sql; - -				// do we need to add a sequence and a tigger for auto incrementing columns? -				if ($create_sequence) -				{ -					// create the actual sequence -					$statements[] = "CREATE SEQUENCE {$table_name}_seq"; - -					// the trigger is the mechanism by which we increment the counter -					$trigger = "CREATE OR REPLACE TRIGGER t_{$table_name}\n"; -					$trigger .= "BEFORE INSERT ON {$table_name}\n"; -					$trigger .= "FOR EACH ROW WHEN (\n"; -					$trigger .= "\tnew.{$create_sequence} IS NULL OR new.{$create_sequence} = 0\n"; -					$trigger .= ")\n"; -					$trigger .= "BEGIN\n"; -					$trigger .= "\tSELECT {$table_name}_seq.nextval\n"; -					$trigger .= "\tINTO :new.{$create_sequence}\n"; -					$trigger .= "\tFROM dual;\n"; -					$trigger .= "END;"; - -					$statements[] = $trigger; -				} -			break; - -			case 'firebird': -				if ($create_sequence) -				{ -					$statements[] = "CREATE GENERATOR {$table_name}_gen;"; -					$statements[] = "SET GENERATOR {$table_name}_gen TO 0;"; - -					$trigger = "CREATE TRIGGER t_$table_name FOR $table_name\n"; -					$trigger .= "BEFORE INSERT\nAS\nBEGIN\n"; -					$trigger .= "\tNEW.{$create_sequence} = GEN_ID({$table_name}_gen, 1);\nEND;"; -					$statements[] = $trigger; -				} -			break; -		} - -		// Write Keys -		if (isset($table_data['KEYS'])) -		{ -			foreach ($table_data['KEYS'] as $key_name => $key_data) -			{ -				if (!is_array($key_data[1])) -				{ -					$key_data[1] = array($key_data[1]); -				} - -				$old_return_statements = $this->return_statements; -				$this->return_statements = true; - -				$key_stmts = ($key_data[0] == 'UNIQUE') ? $this->sql_create_unique_index($table_name, $key_name, $key_data[1]) : $this->sql_create_index($table_name, $key_name, $key_data[1]); - -				foreach ($key_stmts as $key_stmt) -				{ -					$statements[] = $key_stmt; -				} - -				$this->return_statements = $old_return_statements; -			} -		} - -		// Commit Transaction -		$statements[] = 'commit'; - -		return $this->_sql_run_sql($statements); -	} - -	/** -	* Handle passed database update array. -	* Expected structure... -	* Key being one of the following -	*	change_columns: Column changes (only type, not name) -	*	add_columns: Add columns to a table -	*	drop_keys: Dropping keys -	*	drop_columns: Removing/Dropping columns -	*	add_primary_keys: adding primary keys -	*	add_unique_index: adding an unique index -	*	add_index: adding an index (can be column:index_size if you need to provide size) -	* -	* The values are in this format: -	*		{TABLE NAME}		=> array( -	*			{COLUMN NAME}		=> array({COLUMN TYPE}, {DEFAULT VALUE}, {OPTIONAL VARIABLES}), -	*			{KEY/INDEX NAME}	=> array({COLUMN NAMES}), -	*		) -	* -	* For more information have a look at /develop/create_schema_files.php (only available through SVN) -	*/ -	function perform_schema_changes($schema_changes) -	{ -		if (empty($schema_changes)) -		{ -			return; -		} - -		$statements = array(); -		$sqlite = false; - -		// For SQLite we need to perform the schema changes in a much more different way -		if ($this->db->sql_layer == 'sqlite' && $this->return_statements) -		{ -			$sqlite_data = array(); -			$sqlite = true; -		} - -		// Drop tables? -		if (!empty($schema_changes['drop_tables'])) -		{ -			foreach ($schema_changes['drop_tables'] as $table) -			{ -				// only drop table if it exists -				if ($this->sql_table_exists($table)) -				{ -					$result = $this->sql_table_drop($table); -					if ($this->return_statements) -					{ -						$statements = array_merge($statements, $result); -					} -				} -			} -		} - -		// Add tables? -		if (!empty($schema_changes['add_tables'])) -		{ -			foreach ($schema_changes['add_tables'] as $table => $table_data) -			{ -				$result = $this->sql_create_table($table, $table_data); -				if ($this->return_statements) -				{ -					$statements = array_merge($statements, $result); -				} -			} -		} - -		// Change columns? -		if (!empty($schema_changes['change_columns'])) -		{ -			foreach ($schema_changes['change_columns'] as $table => $columns) -			{ -				foreach ($columns as $column_name => $column_data) -				{ -					// If the column exists we change it, else we add it ;) -					if ($column_exists = $this->sql_column_exists($table, $column_name)) -					{ -						$result = $this->sql_column_change($table, $column_name, $column_data, true); -					} -					else -					{ -						$result = $this->sql_column_add($table, $column_name, $column_data, true); -					} - -					if ($sqlite) -					{ -						if ($column_exists) -						{ -							$sqlite_data[$table]['change_columns'][] = $result; -						} -						else -						{ -							$sqlite_data[$table]['add_columns'][] = $result; -						} -					} -					else if ($this->return_statements) -					{ -						$statements = array_merge($statements, $result); -					} -				} -			} -		} - -		// Add columns? -		if (!empty($schema_changes['add_columns'])) -		{ -			foreach ($schema_changes['add_columns'] as $table => $columns) -			{ -				foreach ($columns as $column_name => $column_data) -				{ -					// Only add the column if it does not exist yet -					if ($column_exists = $this->sql_column_exists($table, $column_name)) -					{ -						continue; -						// This is commented out here because it can take tremendous time on updates -//						$result = $this->sql_column_change($table, $column_name, $column_data, true); -					} -					else -					{ -						$result = $this->sql_column_add($table, $column_name, $column_data, true); -					} - -					if ($sqlite) -					{ -						if ($column_exists) -						{ -							continue; -//							$sqlite_data[$table]['change_columns'][] = $result; -						} -						else -						{ -							$sqlite_data[$table]['add_columns'][] = $result; -						} -					} -					else if ($this->return_statements) -					{ -						$statements = array_merge($statements, $result); -					} -				} -			} -		} - -		// Remove keys? -		if (!empty($schema_changes['drop_keys'])) -		{ -			foreach ($schema_changes['drop_keys'] as $table => $indexes) -			{ -				foreach ($indexes as $index_name) -				{ -					if (!$this->sql_index_exists($table, $index_name)) -					{ -						continue; -					} - -					$result = $this->sql_index_drop($table, $index_name); - -					if ($this->return_statements) -					{ -						$statements = array_merge($statements, $result); -					} -				} -			} -		} - -		// Drop columns? -		if (!empty($schema_changes['drop_columns'])) -		{ -			foreach ($schema_changes['drop_columns'] as $table => $columns) -			{ -				foreach ($columns as $column) -				{ -					// Only remove the column if it exists... -					if ($this->sql_column_exists($table, $column)) -					{ -						$result = $this->sql_column_remove($table, $column, true); - -						if ($sqlite) -						{ -							$sqlite_data[$table]['drop_columns'][] = $result; -						} -						else if ($this->return_statements) -						{ -							$statements = array_merge($statements, $result); -						} -					} -				} -			} -		} - -		// Add primary keys? -		if (!empty($schema_changes['add_primary_keys'])) -		{ -			foreach ($schema_changes['add_primary_keys'] as $table => $columns) -			{ -				$result = $this->sql_create_primary_key($table, $columns, true); - -				if ($sqlite) -				{ -					$sqlite_data[$table]['primary_key'] = $result; -				} -				else if ($this->return_statements) -				{ -					$statements = array_merge($statements, $result); -				} -			} -		} - -		// Add unique indexes? -		if (!empty($schema_changes['add_unique_index'])) -		{ -			foreach ($schema_changes['add_unique_index'] as $table => $index_array) -			{ -				foreach ($index_array as $index_name => $column) -				{ -					if ($this->sql_unique_index_exists($table, $index_name)) -					{ -						continue; -					} - -					$result = $this->sql_create_unique_index($table, $index_name, $column); - -					if ($this->return_statements) -					{ -						$statements = array_merge($statements, $result); -					} -				} -			} -		} - -		// Add indexes? -		if (!empty($schema_changes['add_index'])) -		{ -			foreach ($schema_changes['add_index'] as $table => $index_array) -			{ -				foreach ($index_array as $index_name => $column) -				{ -					if ($this->sql_index_exists($table, $index_name)) -					{ -						continue; -					} - -					$result = $this->sql_create_index($table, $index_name, $column); - -					if ($this->return_statements) -					{ -						$statements = array_merge($statements, $result); -					} -				} -			} -		} - -		if ($sqlite) -		{ -			foreach ($sqlite_data as $table_name => $sql_schema_changes) -			{ -				// Create temporary table with original data -				$statements[] = 'begin'; - -				$sql = "SELECT sql -					FROM sqlite_master -					WHERE type = 'table' -						AND name = '{$table_name}' -					ORDER BY type DESC, name;"; -				$result = $this->db->sql_query($sql); - -				if (!$result) -				{ -					continue; -				} - -				$row = $this->db->sql_fetchrow($result); -				$this->db->sql_freeresult($result); - -				// Create a backup table and populate it, destroy the existing one -				$statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); -				$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; -				$statements[] = 'DROP TABLE ' . $table_name; - -				// Get the columns... -				preg_match('#\((.*)\)#s', $row['sql'], $matches); - -				$plain_table_cols = trim($matches[1]); -				$new_table_cols = preg_split('/,(?![\s\w]+\))/m', $plain_table_cols); -				$column_list = array(); - -				foreach ($new_table_cols as $declaration) -				{ -					$entities = preg_split('#\s+#', trim($declaration)); -					if ($entities[0] == 'PRIMARY') -					{ -						continue; -					} -					$column_list[] = $entities[0]; -				} - -				// note down the primary key notation because sqlite only supports adding it to the end for the new table -				$primary_key = false; -				$_new_cols = array(); - -				foreach ($new_table_cols as $key => $declaration) -				{ -					$entities = preg_split('#\s+#', trim($declaration)); -					if ($entities[0] == 'PRIMARY') -					{ -						$primary_key = $declaration; -						continue; -					} -					$_new_cols[] = $declaration; -				} - -				$new_table_cols = $_new_cols; - -				// First of all... change columns -				if (!empty($sql_schema_changes['change_columns'])) -				{ -					foreach ($sql_schema_changes['change_columns'] as $column_sql) -					{ -						foreach ($new_table_cols as $key => $declaration) -						{ -							$entities = preg_split('#\s+#', trim($declaration)); -							if (strpos($column_sql, $entities[0] . ' ') === 0) -							{ -								$new_table_cols[$key] = $column_sql; -							} -						} -					} -				} - -				if (!empty($sql_schema_changes['add_columns'])) -				{ -					foreach ($sql_schema_changes['add_columns'] as $column_sql) -					{ -						$new_table_cols[] = $column_sql; -					} -				} - -				// Now drop them... -				if (!empty($sql_schema_changes['drop_columns'])) -				{ -					foreach ($sql_schema_changes['drop_columns'] as $column_name) -					{ -						// Remove from column list... -						$new_column_list = array(); -						foreach ($column_list as $key => $value) -						{ -							if ($value === $column_name) -							{ -								continue; -							} - -							$new_column_list[] = $value; -						} - -						$column_list = $new_column_list; - -						// Remove from table... -						$_new_cols = array(); -						foreach ($new_table_cols as $key => $declaration) -						{ -							$entities = preg_split('#\s+#', trim($declaration)); -							if (strpos($column_name . ' ', $entities[0] . ' ') === 0) -							{ -								continue; -							} -							$_new_cols[] = $declaration; -						} -						$new_table_cols = $_new_cols; -					} -				} - -				// Primary key... -				if (!empty($sql_schema_changes['primary_key'])) -				{ -					$new_table_cols[] = 'PRIMARY KEY (' . implode(', ', $sql_schema_changes['primary_key']) . ')'; -				} -				// Add a new one or the old primary key -				else if ($primary_key !== false) -				{ -					$new_table_cols[] = $primary_key; -				} - -				$columns = implode(',', $column_list); - -				// create a new table and fill it up. destroy the temp one -				$statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $new_table_cols) . ');'; -				$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; -				$statements[] = 'DROP TABLE ' . $table_name . '_temp'; - -				$statements[] = 'commit'; -			} -		} - -		if ($this->return_statements) -		{ -			return $statements; -		} -	} - -	/** -	* Gets a list of columns of a table. -	* -	* @param string $table		Table name -	* -	* @return array				Array of column names (all lower case) -	*/ -	function sql_list_columns($table) -	{ -		$columns = array(); - -		switch ($this->sql_layer) -		{ -			case 'mysql_40': -			case 'mysql_41': -				$sql = "SHOW COLUMNS FROM $table"; -			break; - -			// PostgreSQL has a way of doing this in a much simpler way but would -			// not allow us to support all versions of PostgreSQL -			case 'postgres': -				$sql = "SELECT a.attname -					FROM pg_class c, pg_attribute a -					WHERE c.relname = '{$table}' -						AND a.attnum > 0 -						AND a.attrelid = c.oid"; -			break; - -			// same deal with PostgreSQL, we must perform more complex operations than -			// we technically could -			case 'mssql': -			case 'mssqlnative': -				$sql = "SELECT c.name -					FROM syscolumns c -					LEFT JOIN sysobjects o ON c.id = o.id -					WHERE o.name = '{$table}'"; -			break; - -			case 'oracle': -				$sql = "SELECT column_name -					FROM user_tab_columns -					WHERE LOWER(table_name) = '" . strtolower($table) . "'"; -			break; - -			case 'firebird': -				$sql = "SELECT RDB\$FIELD_NAME as FNAME -					FROM RDB\$RELATION_FIELDS -					WHERE RDB\$RELATION_NAME = '" . strtoupper($table) . "'"; -			break; - -			case 'sqlite': -				$sql = "SELECT sql -					FROM sqlite_master -					WHERE type = 'table' -						AND name = '{$table}'"; - -				$result = $this->db->sql_query($sql); - -				if (!$result) -				{ -					return false; -				} - -				$row = $this->db->sql_fetchrow($result); -				$this->db->sql_freeresult($result); - -				preg_match('#\((.*)\)#s', $row['sql'], $matches); - -				$cols = trim($matches[1]); -				$col_array = preg_split('/,(?![\s\w]+\))/m', $cols); - -				foreach ($col_array as $declaration) -				{ -					$entities = preg_split('#\s+#', trim($declaration)); -					if ($entities[0] == 'PRIMARY') -					{ -						continue; -					} - -					$column = strtolower($entities[0]); -					$columns[$column] = $column; -				} - -				return $columns; -			break; -		} - -		$result = $this->db->sql_query($sql); - -		while ($row = $this->db->sql_fetchrow($result)) -		{ -			$column = strtolower(current($row)); -			$columns[$column] = $column; -		} -		$this->db->sql_freeresult($result); - -		return $columns; -	} - -	/** -	* Check whether a specified column exist in a table -	* -	* @param string	$table			Table to check -	* @param string	$column_name	Column to check -	* -	* @return bool		True if column exists, false otherwise -	*/ -	function sql_column_exists($table, $column_name) -	{ -		$columns = $this->sql_list_columns($table); - -		return isset($columns[$column_name]); -	} - -	/** -	* Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. -	* -	* @param string	$table_name		Table to check the index at -	* @param string	$index_name		The index name to check -	* -	* @return bool True if index exists, else false -	*/ -	function sql_index_exists($table_name, $index_name) -	{ -		if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') -		{ -			$sql = "EXEC sp_statistics '$table_name'"; -			$result = $this->db->sql_query($sql); - -			while ($row = $this->db->sql_fetchrow($result)) -			{ -				if ($row['TYPE'] == 3) -				{ -					if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) -					{ -						$this->db->sql_freeresult($result); -						return true; -					} -				} -			} -			$this->db->sql_freeresult($result); - -			return false; -		} - -		switch ($this->sql_layer) -		{ -			case 'firebird': -				$sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name -					FROM RDB\$INDICES -					WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "' -						AND RDB\$UNIQUE_FLAG IS NULL -						AND RDB\$FOREIGN_KEY IS NULL"; -				$col = 'index_name'; -			break; - -			case 'postgres': -				$sql = "SELECT ic.relname as index_name -					FROM pg_class bc, pg_class ic, pg_index i -					WHERE (bc.oid = i.indrelid) -						AND (ic.oid = i.indexrelid) -						AND (bc.relname = '" . $table_name . "') -						AND (i.indisunique != 't') -						AND (i.indisprimary != 't')"; -				$col = 'index_name'; -			break; - -			case 'mysql_40': -			case 'mysql_41': -				$sql = 'SHOW KEYS -					FROM ' . $table_name; -				$col = 'Key_name'; -			break; - -			case 'oracle': -				$sql = "SELECT index_name -					FROM user_indexes -					WHERE table_name = '" . strtoupper($table_name) . "' -						AND generated = 'N' -						AND uniqueness = 'NONUNIQUE'"; -				$col = 'index_name'; -			break; - -			case 'sqlite': -				$sql = "PRAGMA index_list('" . $table_name . "');"; -				$col = 'name'; -			break; -		} - -		$result = $this->db->sql_query($sql); -		while ($row = $this->db->sql_fetchrow($result)) -		{ -			if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) -			{ -				continue; -			} - -			// These DBMS prefix index name with the table name -			switch ($this->sql_layer) -			{ -				case 'firebird': -				case 'oracle': -				case 'postgres': -				case 'sqlite': -					$row[$col] = substr($row[$col], strlen($table_name) + 1); -				break; -			} - -			if (strtolower($row[$col]) == strtolower($index_name)) -			{ -				$this->db->sql_freeresult($result); -				return true; -			} -		} -		$this->db->sql_freeresult($result); - -		return false; -	} - -	/** -	* Check if a specified index exists in table. Does not return PRIMARY KEY indexes. -	* -	* @param string	$table_name		Table to check the index at -	* @param string	$index_name		The index name to check -	* -	* @return bool True if index exists, else false -	*/ -	function sql_unique_index_exists($table_name, $index_name) -	{ -		if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') -		{ -			$sql = "EXEC sp_statistics '$table_name'"; -			$result = $this->db->sql_query($sql); - -			while ($row = $this->db->sql_fetchrow($result)) -			{ -				// Usually NON_UNIQUE is the column we want to check, but we allow for both -				if ($row['TYPE'] == 3) -				{ -					if (strtolower($row['INDEX_NAME']) == strtolower($index_name)) -					{ -						$this->db->sql_freeresult($result); -						return true; -					} -				} -			} -			$this->db->sql_freeresult($result); -			return false; -		} - -		switch ($this->sql_layer) -		{ -			case 'firebird': -				$sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name -					FROM RDB\$INDICES -					WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "' -						AND RDB\$UNIQUE_FLAG IS NOT NULL -						AND RDB\$FOREIGN_KEY IS NULL"; -				$col = 'index_name'; -			break; - -			case 'postgres': -				$sql = "SELECT ic.relname as index_name, i.indisunique -					FROM pg_class bc, pg_class ic, pg_index i -					WHERE (bc.oid = i.indrelid) -						AND (ic.oid = i.indexrelid) -						AND (bc.relname = '" . $table_name . "') -						AND (i.indisprimary != 't')"; -				$col = 'index_name'; -			break; - -			case 'mysql_40': -			case 'mysql_41': -				$sql = 'SHOW KEYS -					FROM ' . $table_name; -				$col = 'Key_name'; -			break; - -			case 'oracle': -				$sql = "SELECT index_name, table_owner -					FROM user_indexes -					WHERE table_name = '" . strtoupper($table_name) . "' -						AND generated = 'N' -						AND uniqueness = 'UNIQUE'"; -				$col = 'index_name'; -			break; - -			case 'sqlite': -				$sql = "PRAGMA index_list('" . $table_name . "');"; -				$col = 'name'; -			break; -		} - -		$result = $this->db->sql_query($sql); -		while ($row = $this->db->sql_fetchrow($result)) -		{ -			if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && ($row['Non_unique'] || $row[$col] == 'PRIMARY')) -			{ -				continue; -			} - -			if ($this->sql_layer == 'sqlite' && !$row['unique']) -			{ -				continue; -			} - -			if ($this->sql_layer == 'postgres' && $row['indisunique'] != 't') -			{ -				continue; -			} - -			// These DBMS prefix index name with the table name -			switch ($this->sql_layer) -			{ -				case 'oracle': -					// Two cases here... prefixed with U_[table_owner] and not prefixed with table_name -					if (strpos($row[$col], 'U_') === 0) -					{ -						$row[$col] = substr($row[$col], strlen('U_' . $row['table_owner']) + 1); -					} -					else if (strpos($row[$col], strtoupper($table_name)) === 0) -					{ -						$row[$col] = substr($row[$col], strlen($table_name) + 1); -					} -				break; - -				case 'firebird': -				case 'postgres': -				case 'sqlite': -					$row[$col] = substr($row[$col], strlen($table_name) + 1); -				break; -			} - -			if (strtolower($row[$col]) == strtolower($index_name)) -			{ -				$this->db->sql_freeresult($result); -				return true; -			} -		} -		$this->db->sql_freeresult($result); - -		return false; -	} - -	/** -	* Private method for performing sql statements (either execute them or return them) -	* @access private -	*/ -	function _sql_run_sql($statements) -	{ -		if ($this->return_statements) -		{ -			return $statements; -		} - -		// We could add error handling here... -		foreach ($statements as $sql) -		{ -			if ($sql === 'begin') -			{ -				$this->db->sql_transaction('begin'); -			} -			else if ($sql === 'commit') -			{ -				$this->db->sql_transaction('commit'); -			} -			else -			{ -				$this->db->sql_query($sql); -			} -		} - -		return true; -	} - -	/** -	* Function to prepare some column information for better usage -	* @access private -	*/ -	function sql_prepare_column_data($table_name, $column_name, $column_data) -	{ -		if (strlen($column_name) > 30) -		{ -			trigger_error("Column name '$column_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); -		} - -		// Get type -		if (strpos($column_data[0], ':') !== false) -		{ -			list($orig_column_type, $column_length) = explode(':', $column_data[0]); -			if (!is_array($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'])) -			{ -				$column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length); -			} -			else -			{ -				if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'])) -				{ -					switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][0]) -					{ -						case 'div': -							$column_length /= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][1]; -							$column_length = ceil($column_length); -							$column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); -						break; -					} -				} - -				if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'])) -				{ -					switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][0]) -					{ -						case 'mult': -							$column_length *= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][1]; -							if ($column_length > $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][2]) -							{ -								$column_type = $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][3]; -							} -							else -							{ -								$column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); -							} -						break; -					} -				} -			} -			$orig_column_type .= ':'; -		} -		else -		{ -			$orig_column_type = $column_data[0]; -			$column_type = $this->dbms_type_map[$this->sql_layer][$column_data[0]]; -		} - -		// Adjust default value if db-dependant specified -		if (is_array($column_data[1])) -		{ -			$column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default']; -		} - -		$sql = ''; - -		$return_array = array(); - -		switch ($this->sql_layer) -		{ -			case 'firebird': -				$sql .= " {$column_type} "; -				$return_array['column_type_sql_type'] = " {$column_type} "; - -				if (!is_null($column_data[1])) -				{ -					$sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; -					$return_array['column_type_sql_default'] = ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; -				} - -				$sql .= 'NOT NULL'; - -				// This is a UNICODE column and thus should be given it's fair share -				if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0])) -				{ -					$sql .= ' COLLATE UNICODE'; -				} - -				$return_array['auto_increment'] = false; -				if (isset($column_data[2]) && $column_data[2] == 'auto_increment') -				{ -					$return_array['auto_increment'] = true; -				} - -			break; - -			case 'mssql': -			case 'mssqlnative': -				$sql .= " {$column_type} "; -				$sql_default = " {$column_type} "; - -				// For adding columns we need the default definition -				if (!is_null($column_data[1])) -				{ -					// For hexadecimal values do not use single quotes -					if (strpos($column_data[1], '0x') === 0) -					{ -						$return_array['default'] = 'DEFAULT (' . $column_data[1] . ') '; -						$sql_default .= $return_array['default']; -					} -					else -					{ -						$return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; -						$sql_default .= $return_array['default']; -					} -				} - -				if (isset($column_data[2]) && $column_data[2] == 'auto_increment') -				{ -//					$sql .= 'IDENTITY (1, 1) '; -					$sql_default .= 'IDENTITY (1, 1) '; -				} - -				$return_array['textimage'] = $column_type === '[text]'; - -				$sql .= 'NOT NULL'; -				$sql_default .= 'NOT NULL'; - -				$return_array['column_type_sql_default'] = $sql_default; - -			break; - -			case 'mysql_40': -			case 'mysql_41': -				$sql .= " {$column_type} "; - -				// For hexadecimal values do not use single quotes -				if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob') -				{ -					$sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; -				} -				$sql .= 'NOT NULL'; - -				if (isset($column_data[2])) -				{ -					if ($column_data[2] == 'auto_increment') -					{ -						$sql .= ' auto_increment'; -					} -					else if ($this->sql_layer === 'mysql_41' && $column_data[2] == 'true_sort') -					{ -						$sql .= ' COLLATE utf8_unicode_ci'; -					} -				} - -			break; - -			case 'oracle': -				$sql .= " {$column_type} "; -				$sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; - -				// In Oracle empty strings ('') are treated as NULL. -				// Therefore in oracle we allow NULL's for all DEFAULT '' entries -				// Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields) -				if (!preg_match('/number/i', $column_type)) -				{ -					$sql .= ($column_data[1] === '') ? '' : 'NOT NULL'; -				} - -				$return_array['auto_increment'] = false; -				if (isset($column_data[2]) && $column_data[2] == 'auto_increment') -				{ -					$return_array['auto_increment'] = true; -				} - -			break; - -			case 'postgres': -				$return_array['column_type'] = $column_type; - -				$sql .= " {$column_type} "; - -				$return_array['auto_increment'] = false; -				if (isset($column_data[2]) && $column_data[2] == 'auto_increment') -				{ -					$default_val = "nextval('{$table_name}_seq')"; -					$return_array['auto_increment'] = true; -				} -				else if (!is_null($column_data[1])) -				{ -					$default_val = "'" . $column_data[1] . "'"; -					$return_array['null'] = 'NOT NULL'; -					$sql .= 'NOT NULL '; -				} - -				$return_array['default'] = $default_val; - -				$sql .= "DEFAULT {$default_val}"; - -				// Unsigned? Then add a CHECK contraint -				if (in_array($orig_column_type, $this->unsigned_types)) -				{ -					$return_array['constraint'] = "CHECK ({$column_name} >= 0)"; -					$sql .= " CHECK ({$column_name} >= 0)"; -				} - -			break; - -			case 'sqlite': -				$return_array['primary_key_set'] = false; -				if (isset($column_data[2]) && $column_data[2] == 'auto_increment') -				{ -					$sql .= ' INTEGER PRIMARY KEY'; -					$return_array['primary_key_set'] = true; -				} -				else -				{ -					$sql .= ' ' . $column_type; -				} - -				$sql .= ' NOT NULL '; -				$sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; - -			break; -		} - -		$return_array['column_type_sql'] = $sql; - -		return $return_array; -	} - -	/** -	* Add new column -	*/ -	function sql_column_add($table_name, $column_name, $column_data, $inline = false) -	{ -		$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); -		$statements = array(); - -		switch ($this->sql_layer) -		{ -			case 'firebird': -				// Does not support AFTER statement, only POSITION (and there you need the column position) -				$statements[] = 'ALTER TABLE ' . $table_name . ' ADD "' . strtoupper($column_name) . '" ' . $column_data['column_type_sql']; -			break; - -			case 'mssql': -			case 'mssqlnative': -				// Does not support AFTER, only through temporary table -				$statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default']; -			break; - -			case 'mysql_40': -			case 'mysql_41': -				$after = (!empty($column_data['after'])) ? ' AFTER ' . $column_data['after'] : ''; -				$statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'] . $after; -			break; - -			case 'oracle': -				// Does not support AFTER, only through temporary table -				$statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; -			break; - -			case 'postgres': -				// Does not support AFTER, only through temporary table -				if (version_compare($this->db->sql_server_info(true), '8.0', '>=')) -				{ -					$statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; -				} -				else -				{ -					// old versions cannot add columns with default and null information -					$statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type'] . ' ' . $column_data['constraint']; - -					if (isset($column_data['null'])) -					{ -						if ($column_data['null'] == 'NOT NULL') -						{ -							$statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET NOT NULL'; -						} -					} - -					if (isset($column_data['default'])) -					{ -						$statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; -					} -				} - -			break; - -			case 'sqlite': - -				if ($inline && $this->return_statements) -				{ -					return $column_name . ' ' . $column_data['column_type_sql']; -				} - -				if (version_compare(sqlite_libversion(), '3.0') == -1) -				{ -					$sql = "SELECT sql -						FROM sqlite_master -						WHERE type = 'table' -							AND name = '{$table_name}' -						ORDER BY type DESC, name;"; -					$result = $this->db->sql_query($sql); - -					if (!$result) -					{ -						break; -					} - -					$row = $this->db->sql_fetchrow($result); -					$this->db->sql_freeresult($result); - -					$statements[] = 'begin'; - -					// Create a backup table and populate it, destroy the existing one -					$statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); -					$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; -					$statements[] = 'DROP TABLE ' . $table_name; - -					preg_match('#\((.*)\)#s', $row['sql'], $matches); - -					$new_table_cols = trim($matches[1]); -					$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); -					$column_list = array(); - -					foreach ($old_table_cols as $declaration) -					{ -						$entities = preg_split('#\s+#', trim($declaration)); -						if ($entities[0] == 'PRIMARY') -						{ -							continue; -						} -						$column_list[] = $entities[0]; -					} - -					$columns = implode(',', $column_list); - -					$new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols; - -					// create a new table and fill it up. destroy the temp one -					$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; -					$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; -					$statements[] = 'DROP TABLE ' . $table_name . '_temp'; - -					$statements[] = 'commit'; -				} -				else -				{ -					$statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']'; -				} -			break; -		} - -		return $this->_sql_run_sql($statements); -	} - -	/** -	* Drop column -	*/ -	function sql_column_remove($table_name, $column_name, $inline = false) -	{ -		$statements = array(); - -		switch ($this->sql_layer) -		{ -			case 'firebird': -				$statements[] = 'ALTER TABLE ' . $table_name . ' DROP "' . strtoupper($column_name) . '"'; -			break; - -			case 'mssql': -			case 'mssqlnative': -				$sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; -				$result = $this->db->sql_query($sql); -				$row = $this->db->sql_fetchrow($result); -				$this->db->sql_freeresult($result); - -				// Remove default constraints -				if ($row['mssql_version'][0] == '8')	// SQL Server 2000 -				{ -					// http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx -					// Deprecated in SQL Server 2005 -					$statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) -						SET @drop_default_name = -							(SELECT so.name FROM sysobjects so -							JOIN sysconstraints sc ON so.id = sc.constid -							WHERE object_name(so.parent_obj) = '{$table_name}' -								AND so.xtype = 'D' -								AND sc.colid = (SELECT colid FROM syscolumns -									WHERE id = object_id('{$table_name}') -										AND name = '{$column_name}')) -						IF @drop_default_name <> '' -						BEGIN -							SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' -							EXEC(@cmd) -						END"; -				} -				else -				{ -					$sql = "SELECT dobj.name AS def_name -					FROM sys.columns col  -						LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') -					WHERE col.object_id = object_id('{$table_name}')  -					AND col.name = '{$column_name}' -					AND dobj.name IS NOT NULL"; -					$result = $this->db->sql_query($sql); -					$row = $this->db->sql_fetchrow($result); -					$this->db->sql_freeresult($result); - -					if ($row) -					{ -						$statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']'; -					} -				} - -				$statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; -			break; - -			case 'mysql_40': -			case 'mysql_41': -				$statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`'; -			break; - -			case 'oracle': -				$statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; -			break; - -			case 'postgres': -				$statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"'; -			break; - -			case 'sqlite': - -				if ($inline && $this->return_statements) -				{ -					return $column_name; -				} - -				if (version_compare(sqlite_libversion(), '3.0') == -1) -				{ -					$sql = "SELECT sql -						FROM sqlite_master -						WHERE type = 'table' -							AND name = '{$table_name}' -						ORDER BY type DESC, name;"; -					$result = $this->db->sql_query($sql); - -					if (!$result) -					{ -						break; -					} - -					$row = $this->db->sql_fetchrow($result); -					$this->db->sql_freeresult($result); - -					$statements[] = 'begin'; - -					// Create a backup table and populate it, destroy the existing one -					$statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); -					$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; -					$statements[] = 'DROP TABLE ' . $table_name; - -					preg_match('#\((.*)\)#s', $row['sql'], $matches); - -					$new_table_cols = trim($matches[1]); -					$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); -					$column_list = array(); - -					foreach ($old_table_cols as $declaration) -					{ -						$entities = preg_split('#\s+#', trim($declaration)); -						if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name) -						{ -							continue; -						} -						$column_list[] = $entities[0]; -					} - -					$columns = implode(',', $column_list); - -					$new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols); - -					// create a new table and fill it up. destroy the temp one -					$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; -					$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; -					$statements[] = 'DROP TABLE ' . $table_name . '_temp'; - -					$statements[] = 'commit'; -				} -				else -				{ -					$statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; -				} -			break; -		} - -		return $this->_sql_run_sql($statements); -	} - -	/** -	* Drop Index -	*/ -	function sql_index_drop($table_name, $index_name) -	{ -		$statements = array(); - -		switch ($this->sql_layer) -		{ -			case 'mssql': -			case 'mssqlnative': -				$statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; -			break; - -			case 'mysql_40': -			case 'mysql_41': -				$statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; -			break; - -			case 'firebird': -			case 'oracle': -			case 'postgres': -			case 'sqlite': -				$statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; -			break; -		} - -		return $this->_sql_run_sql($statements); -	} - -	/** -	* Drop Table -	*/ -	function sql_table_drop($table_name) -	{ -		$statements = array(); - -		if (!$this->sql_table_exists($table_name)) -		{ -			return $this->_sql_run_sql($statements); -		} - -		// the most basic operation, get rid of the table -		$statements[] = 'DROP TABLE ' . $table_name; - -		switch ($this->sql_layer) -		{ -			case 'firebird': -				$sql = 'SELECT RDB$GENERATOR_NAME as gen -					FROM RDB$GENERATORS -					WHERE RDB$SYSTEM_FLAG = 0 -						AND RDB$GENERATOR_NAME = \'' . strtoupper($table_name) . "_GEN'"; -				$result = $this->db->sql_query($sql); - -				// does a generator exist? -				if ($row = $this->db->sql_fetchrow($result)) -				{ -					$statements[] = "DROP GENERATOR {$row['gen']};"; -				} -				$this->db->sql_freeresult($result); -			break; - -			case 'oracle': -				$sql = 'SELECT A.REFERENCED_NAME -					FROM USER_DEPENDENCIES A, USER_TRIGGERS B -					WHERE A.REFERENCED_TYPE = \'SEQUENCE\' -						AND A.NAME = B.TRIGGER_NAME -						AND B.TABLE_NAME = \'' . strtoupper($table_name) . "'"; -				$result = $this->db->sql_query($sql); - -				// any sequences ref'd to this table's triggers? -				while ($row = $this->db->sql_fetchrow($result)) -				{ -					$statements[] = "DROP SEQUENCE {$row['referenced_name']}"; -				} -				$this->db->sql_freeresult($result); -			break; - -			case 'postgres': -				// PGSQL does not "tightly" bind sequences and tables, we must guess... -				$sql = "SELECT relname -					FROM pg_class -					WHERE relkind = 'S' -						AND relname = '{$table_name}_seq'"; -				$result = $this->db->sql_query($sql); - -				// We don't even care about storing the results. We already know the answer if we get rows back. -				if ($this->db->sql_fetchrow($result)) -				{ -					$statements[] =  "DROP SEQUENCE {$table_name}_seq;\n"; -				} -				$this->db->sql_freeresult($result); -			break; -		} - -		return $this->_sql_run_sql($statements); -	} - -	/** -	* Add primary key -	*/ -	function sql_create_primary_key($table_name, $column, $inline = false) -	{ -		$statements = array(); - -		switch ($this->sql_layer) -		{ -			case 'firebird': -			case 'postgres': -			case 'mysql_40': -			case 'mysql_41': -				$statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; -			break; - -			case 'mssql': -			case 'mssqlnative': -				$sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; -				$sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY  CLUSTERED ("; -				$sql .= '[' . implode("],\n\t\t[", $column) . ']'; -				$sql .= ')'; - -				$statements[] = $sql; -			break; - -			case 'oracle': -				$statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; -			break; - -			case 'sqlite': - -				if ($inline && $this->return_statements) -				{ -					return $column; -				} - -				$sql = "SELECT sql -					FROM sqlite_master -					WHERE type = 'table' -						AND name = '{$table_name}' -					ORDER BY type DESC, name;"; -				$result = $this->db->sql_query($sql); - -				if (!$result) -				{ -					break; -				} - -				$row = $this->db->sql_fetchrow($result); -				$this->db->sql_freeresult($result); - -				$statements[] = 'begin'; - -				// Create a backup table and populate it, destroy the existing one -				$statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); -				$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; -				$statements[] = 'DROP TABLE ' . $table_name; - -				preg_match('#\((.*)\)#s', $row['sql'], $matches); - -				$new_table_cols = trim($matches[1]); -				$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); -				$column_list = array(); - -				foreach ($old_table_cols as $declaration) -				{ -					$entities = preg_split('#\s+#', trim($declaration)); -					if ($entities[0] == 'PRIMARY') -					{ -						continue; -					} -					$column_list[] = $entities[0]; -				} - -				$columns = implode(',', $column_list); - -				// create a new table and fill it up. destroy the temp one -				$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));'; -				$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; -				$statements[] = 'DROP TABLE ' . $table_name . '_temp'; - -				$statements[] = 'commit'; -			break; -		} - -		return $this->_sql_run_sql($statements); -	} - -	/** -	* Add unique index -	*/ -	function sql_create_unique_index($table_name, $index_name, $column) -	{ -		$statements = array(); - -		$table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) -		if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) -		{ -			$max_length = strlen($table_prefix) + 24; -			trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); -		} - -		switch ($this->sql_layer) -		{ -			case 'firebird': -			case 'postgres': -			case 'oracle': -			case 'sqlite': -				$statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; -			break; - -			case 'mysql_40': -			case 'mysql_41': -				$statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; -			break; - -			case 'mssql': -			case 'mssqlnative': -				$statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; -			break; -		} - -		return $this->_sql_run_sql($statements); -	} - -	/** -	* Add index -	*/ -	function sql_create_index($table_name, $index_name, $column) -	{ -		$statements = array(); - -		$table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config) -		if (strlen($table_name . $index_name) - strlen($table_prefix) > 24) -		{ -			$max_length = strlen($table_prefix) + 24; -			trigger_error("Index name '{$table_name}_$index_name' on table '$table_name' is too long. The maximum is $max_length characters.", E_USER_ERROR); -		} - -		// remove index length unless MySQL4 -		if ('mysql_40' != $this->sql_layer) -		{ -			$column = preg_replace('#:.*$#', '', $column); -		} - -		switch ($this->sql_layer) -		{ -			case 'firebird': -			case 'postgres': -			case 'oracle': -			case 'sqlite': -				$statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; -			break; - -			case 'mysql_40': -				// add index size to definition as required by MySQL4 -				foreach ($column as $i => $col) -				{ -					if (false !== strpos($col, ':')) -					{ -						list($col, $index_size) = explode(':', $col); -						$column[$i] = "$col($index_size)"; -					} -				} -			// no break -			case 'mysql_41': -				$statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; -			break; - -			case 'mssql': -			case 'mssqlnative': -				$statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; -			break; -		} - -		return $this->_sql_run_sql($statements); -	} - -	/** -	* List all of the indices that belong to a table, -	* does not count: -	* * UNIQUE indices -	* * PRIMARY keys -	*/ -	function sql_list_index($table_name) -	{ -		$index_array = array(); - -		if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') -		{ -			$sql = "EXEC sp_statistics '$table_name'"; -			$result = $this->db->sql_query($sql); -			while ($row = $this->db->sql_fetchrow($result)) -			{ -				if ($row['TYPE'] == 3) -				{ -					$index_array[] = $row['INDEX_NAME']; -				} -			} -			$this->db->sql_freeresult($result); -		} -		else -		{ -			switch ($this->sql_layer) -			{ -				case 'firebird': -					$sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name -						FROM RDB\$INDICES -						WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "' -							AND RDB\$UNIQUE_FLAG IS NULL -							AND RDB\$FOREIGN_KEY IS NULL"; -					$col = 'index_name'; -				break; - -				case 'postgres': -					$sql = "SELECT ic.relname as index_name -						FROM pg_class bc, pg_class ic, pg_index i -						WHERE (bc.oid = i.indrelid) -							AND (ic.oid = i.indexrelid) -							AND (bc.relname = '" . $table_name . "') -							AND (i.indisunique != 't') -							AND (i.indisprimary != 't')"; -					$col = 'index_name'; -				break; - -				case 'mysql_40': -				case 'mysql_41': -					$sql = 'SHOW KEYS -						FROM ' . $table_name; -					$col = 'Key_name'; -				break; - -				case 'oracle': -					$sql = "SELECT index_name -						FROM user_indexes -						WHERE table_name = '" . strtoupper($table_name) . "' -							AND generated = 'N' -							AND uniqueness = 'NONUNIQUE'"; -					$col = 'index_name'; -				break; - -				case 'sqlite': -					$sql = "PRAGMA index_info('" . $table_name . "');"; -					$col = 'name'; -				break; -			} - -			$result = $this->db->sql_query($sql); -			while ($row = $this->db->sql_fetchrow($result)) -			{ -				if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) -				{ -					continue; -				} - -				switch ($this->sql_layer) -				{ -					case 'firebird': -					case 'oracle': -					case 'postgres': -					case 'sqlite': -						$row[$col] = substr($row[$col], strlen($table_name) + 1); -					break; -				} - -				$index_array[] = $row[$col]; -			} -			$this->db->sql_freeresult($result); -		} - -		return array_map('strtolower', $index_array); -	} - -	/** -	* Change column type (not name!) -	*/ -	function sql_column_change($table_name, $column_name, $column_data, $inline = false) -	{ -		$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); -		$statements = array(); - -		switch ($this->sql_layer) -		{ -			case 'firebird': -				// Change type... -				if (!empty($column_data['column_type_sql_default'])) -				{ -					$statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type']; -					$statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" SET DEFAULT ' . ' ' . $column_data['column_type_sql_default']; -				} -				else -				{ -					// TODO: try to change pkey without removing trigger, generator or constraints. ATM this query may fail. -					$statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type']; -				} -			break; - -			case 'mssql': -			case 'mssqlnative': -				$statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; - -				if (!empty($column_data['default'])) -				{ -					$sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; -					$result = $this->db->sql_query($sql); -					$row = $this->db->sql_fetchrow($result); -					$this->db->sql_freeresult($result); - -					// Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage -					if ($row['mssql_version'][0] == '8')	// SQL Server 2000 -					{ -						$statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) -							SET @drop_default_name = -								(SELECT so.name FROM sysobjects so -								JOIN sysconstraints sc ON so.id = sc.constid -								WHERE object_name(so.parent_obj) = '{$table_name}' -									AND so.xtype = 'D' -									AND sc.colid = (SELECT colid FROM syscolumns -										WHERE id = object_id('{$table_name}') -											AND name = '{$column_name}')) -							IF @drop_default_name <> '' -							BEGIN -								SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' -								EXEC(@cmd) -							END -							SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]' -							EXEC(@cmd)"; -					} -					else -					{ -						$statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) -							SET @drop_default_name = -								(SELECT dobj.name FROM sys.columns col  -									LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') -								WHERE col.object_id = object_id('{$table_name}')  -								AND col.name = '{$column_name}' -								AND dobj.name IS NOT NULL) -							IF @drop_default_name <> '' -							BEGIN -								SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' -								EXEC(@cmd) -							END -							SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]' -							EXEC(@cmd)"; -					} -				} -			break; - -			case 'mysql_40': -			case 'mysql_41': -				$statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql']; -			break; - -			case 'oracle': -				$statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql']; -			break; - -			case 'postgres': -				$sql = 'ALTER TABLE ' . $table_name . ' '; - -				$sql_array = array(); -				$sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type']; - -				if (isset($column_data['null'])) -				{ -					if ($column_data['null'] == 'NOT NULL') -					{ -						$sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL'; -					} -					else if ($column_data['null'] == 'NULL') -					{ -						$sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL'; -					} -				} - -				if (isset($column_data['default'])) -				{ -					$sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; -				} - -				// we don't want to double up on constraints if we change different number data types -				if (isset($column_data['constraint'])) -				{ -					$constraint_sql = "SELECT consrc as constraint_data -								FROM pg_constraint, pg_class bc -								WHERE conrelid = bc.oid -									AND bc.relname = '{$table_name}' -									AND NOT EXISTS ( -										SELECT * -											FROM pg_constraint as c, pg_inherits as i -											WHERE i.inhrelid = pg_constraint.conrelid -												AND c.conname = pg_constraint.conname -												AND c.consrc = pg_constraint.consrc -												AND c.conrelid = i.inhparent -									)"; - -					$constraint_exists = false; - -					$result = $this->db->sql_query($constraint_sql); -					while ($row = $this->db->sql_fetchrow($result)) -					{ -						if (trim($row['constraint_data']) == trim($column_data['constraint'])) -						{ -							$constraint_exists = true; -							break; -						} -					} -					$this->db->sql_freeresult($result); - -					if (!$constraint_exists) -					{ -						$sql_array[] = 'ADD ' . $column_data['constraint']; -					} -				} - -				$sql .= implode(', ', $sql_array); - -				$statements[] = $sql; -			break; - -			case 'sqlite': - -				if ($inline && $this->return_statements) -				{ -					return $column_name . ' ' . $column_data['column_type_sql']; -				} - -				$sql = "SELECT sql -					FROM sqlite_master -					WHERE type = 'table' -						AND name = '{$table_name}' -					ORDER BY type DESC, name;"; -				$result = $this->db->sql_query($sql); - -				if (!$result) -				{ -					break; -				} - -				$row = $this->db->sql_fetchrow($result); -				$this->db->sql_freeresult($result); - -				$statements[] = 'begin'; - -				// Create a temp table and populate it, destroy the existing one -				$statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); -				$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; -				$statements[] = 'DROP TABLE ' . $table_name; - -				preg_match('#\((.*)\)#s', $row['sql'], $matches); - -				$new_table_cols = trim($matches[1]); -				$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); -				$column_list = array(); - -				foreach ($old_table_cols as $key => $declaration) -				{ -					$entities = preg_split('#\s+#', trim($declaration)); -					$column_list[] = $entities[0]; -					if ($entities[0] == $column_name) -					{ -						$old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql']; -					} -				} - -				$columns = implode(',', $column_list); - -				// create a new table and fill it up. destroy the temp one -				$statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');'; -				$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; -				$statements[] = 'DROP TABLE ' . $table_name . '_temp'; - -				$statements[] = 'commit'; - -			break; -		} - -		return $this->_sql_run_sql($statements); -	} -} - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php deleted file mode 100644 index 30d2870938..0000000000 --- a/phpBB/includes/db/dbal.php +++ /dev/null @@ -1,1000 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -/** -* Database Abstraction Layer -* @package dbal -*/ -class dbal -{ -	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 dbal() -	{ -		$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), 5); - -		// 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 (isset($cache->sql_rowset[$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 (!is_object($query_id) && isset($cache->sql_rowset[$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) . '\''); -	} - -	/** -	* 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 : ''); -	} - -	/** -	* 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_EXTRA constant is for development only! -			if ((isset($auth) && $auth->acl_get('a_')) || defined('IN_INSTALL') || defined('DEBUG_EXTRA')) -			{ -				$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, $user; - -		if (empty($_REQUEST['explain'])) -		{ -			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 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -					<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> -					<head> -						<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> -						<meta http-equiv="Content-Style-Type" content="text/css" /> -						<meta http-equiv="imagetoolbar" content="no" /> -						<title>SQL Report</title> -						<link href="' . $phpbb_root_path . 'adm/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="https://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; -	} -} - -/** -* This variable holds the class name to use later -*/ -$sql_db = (!empty($dbms)) ? 'dbal_' . basename($dbms) : 'dbal'; - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/firebird.php b/phpBB/includes/db/firebird.php deleted file mode 100644 index 7072c58ac0..0000000000 --- a/phpBB/includes/db/firebird.php +++ /dev/null @@ -1,526 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -/** -* Firebird/Interbase Database Abstraction Layer -* Minimum Requirement is Firebird 2.1 -* @package dbal -*/ -class dbal_firebird extends dbal -{ -	var $last_query_text = ''; -	var $service_handle = false; -	var $affected_rows = 0; -	var $connect_error = ''; - -	/** -	* Connect to server -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) -	{ -		$this->persistency = $persistency; -		$this->user = $sqluser; -		$this->server = $sqlserver . (($port) ? ':' . $port : ''); -		$this->dbname = str_replace('\\', '/', $database); - -		// There are three possibilities to connect to an interbase db -		if (!$this->server) -		{ -			$use_database = $this->dbname; -		} -		else if (strpos($this->server, '//') === 0) -		{ -			$use_database = $this->server . $this->dbname; -		} -		else -		{ -			$use_database = $this->server . ':' . $this->dbname; -		} - -		if ($this->persistency) -		{ -			if (!function_exists('ibase_pconnect')) -			{ -				$this->connect_error = 'ibase_pconnect function does not exist, is interbase extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @ibase_pconnect($use_database, $this->user, $sqlpassword, false, false, 3); -		} -		else -		{ -			if (!function_exists('ibase_connect')) -			{ -				$this->connect_error = 'ibase_connect function does not exist, is interbase extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @ibase_connect($use_database, $this->user, $sqlpassword, false, false, 3); -		} - -		// Do not call ibase_service_attach if connection failed, -		// otherwise error message from ibase_(p)connect call will be clobbered. -		if ($this->db_connect_id && function_exists('ibase_service_attach') && $this->server) -		{ -			$this->service_handle = @ibase_service_attach($this->server, $this->user, $sqlpassword); -		} -		else -		{ -			$this->service_handle = false; -		} - -		return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error(''); -	} - -	/** -	* Version information about used database -	* @param bool $raw if true, only return the fetched sql_server_version -	* @param bool $use_cache forced to false for Interbase -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		/** -		* force $use_cache false.  I didn't research why the caching code there is no caching code -		* but I assume its because the IB extension provides a direct method to access it -		* without a query. -		*/ - -		$use_cache = false; - -		if ($this->service_handle !== false && function_exists('ibase_server_info')) -		{ -			return @ibase_server_info($this->service_handle, IBASE_SVC_SERVER_VERSION); -		} - -		return ($raw) ? '2.1' : 'Firebird/Interbase'; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return true; -			break; - -			case 'commit': -				return @ibase_commit(); -			break; - -			case 'rollback': -				return @ibase_rollback(); -			break; -		} - -		return true; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->last_query_text = $query; -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				$array = array(); -				// We overcome Firebird's 32767 char limit by binding vars -				if (strlen($query) > 32767) -				{ -					if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/s', $query, $regs)) -					{ -						if (strlen($regs[3]) > 32767) -						{ -							preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER); - -							$inserts = $vals[0]; -							unset($vals); - -							foreach ($inserts as $key => $value) -							{ -								if (!empty($value) && $value[0] === "'" && strlen($value) > 32769) // check to see if this thing is greater than the max + 'x2 -								{ -									$inserts[$key] = '?'; -									$array[] = str_replace("''", "'", substr($value, 1, -1)); -								} -							} - -							$query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')'; -						} -					} -					else if (preg_match('/^(UPDATE ([\\w_]++)\\s+SET )([\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|\\d+)(?:,\\s*[\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+)\\s+(WHERE.*)$/s', $query, $data)) -					{ -						if (strlen($data[3]) > 32767) -						{ -							$update = $data[1]; -							$where = $data[4]; -							preg_match_all('/(\\w++)\\s*=\\s*(\'(?:[^\']++|\'\')*+\'|[\d-.]++)/', $data[3], $temp, PREG_SET_ORDER); -							unset($data); - -							$cols = array(); -							foreach ($temp as $value) -							{ -								if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 32769) // check to see if this thing is greater than the max + 'x2 -								{ -									$array[] = str_replace("''", "'", substr($value[2], 1, -1)); -									$cols[] = $value[1] . '=?'; -								} -								else -								{ -									$cols[] = $value[1] . '=' . $value[2]; -								} -							} - -							$query = $update . implode(', ', $cols) . ' ' . $where; -							unset($cols); -						} -					} -				} - -				if (!function_exists('ibase_affected_rows') && (preg_match('/^UPDATE ([\w_]++)\s+SET [\w_]++\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+)(?:,\s*[\w_]++\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+\s+(WHERE.*)?$/s', $query, $regs) || preg_match('/^DELETE FROM ([\w_]++)\s*(WHERE\s*.*)?$/s', $query, $regs))) -				{ -					$affected_sql = 'SELECT COUNT(*) as num_rows_affected FROM ' . $regs[1]; -					if (!empty($regs[2])) -					{ -						$affected_sql .= ' ' . $regs[2]; -					} - -					if (!($temp_q_id = @ibase_query($this->db_connect_id, $affected_sql))) -					{ -						return false; -					} - -					$temp_result = @ibase_fetch_assoc($temp_q_id); -					@ibase_free_result($temp_q_id); - -					$this->affected_rows = ($temp_result) ? $temp_result['NUM_ROWS_AFFECTED'] : false; -				} - -				if (sizeof($array)) -				{ -					$p_query = @ibase_prepare($this->db_connect_id, $query); -					array_unshift($array, $p_query); -					$this->query_result = call_user_func_array('ibase_execute', $array); -					unset($array); - -					if ($this->query_result === false) -					{ -						$this->sql_error($query); -					} -				} -				else if (($this->query_result = @ibase_query($this->db_connect_id, $query)) === false) -				{ -					$this->sql_error($query); -				} - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if (!$this->transaction) -				{ -					if (function_exists('ibase_commit_ret')) -					{ -						@ibase_commit_ret(); -					} -					else -					{ -						// way cooler than ibase_commit_ret :D -						@ibase_query('COMMIT RETAIN;'); -					} -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -				else if (strpos($query, 'SELECT') === 0 && $this->query_result) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} - -		return $this->query_result; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		$query = 'SELECT FIRST ' . $total . ((!empty($offset)) ? ' SKIP ' . $offset : '') . substr($query, 6); - -		return $this->sql_query($query, $cache_ttl); -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		// PHP 5+ function -		if (function_exists('ibase_affected_rows')) -		{ -			return ($this->db_connect_id) ? @ibase_affected_rows($this->db_connect_id) : false; -		} -		else -		{ -			return $this->affected_rows; -		} -	} - -	/** -	* Fetch current row -	*/ -	function sql_fetchrow($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		if ($query_id === false) -		{ -			return false; -		} - -		$row = array(); -		$cur_row = @ibase_fetch_object($query_id, IBASE_TEXT); - -		if (!$cur_row) -		{ -			return false; -		} - -		foreach (get_object_vars($cur_row) as $key => $value) -		{ -			$row[strtolower($key)] = (is_string($value)) ? trim(str_replace(array("\\0", "\\n"), array("\0", "\n"), $value)) : $value; -		} - -		return (sizeof($row)) ? $row : false; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		$query_id = $this->query_result; - -		if ($query_id !== false && $this->last_query_text != '') -		{ -			if ($this->query_result && preg_match('#^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)#i', $this->last_query_text, $tablename)) -			{ -				$sql = 'SELECT GEN_ID(' . $tablename[1] . '_gen, 0) AS new_id FROM RDB$DATABASE'; - -				if (!($temp_q_id = @ibase_query($this->db_connect_id, $sql))) -				{ -					return false; -				} - -				$temp_result = @ibase_fetch_assoc($temp_q_id); -				@ibase_free_result($temp_q_id); - -				return ($temp_result) ? $temp_result['NEW_ID'] : false; -			} -		} - -		return false; -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		if (isset($this->open_queries[(int) $query_id])) -		{ -			unset($this->open_queries[(int) $query_id]); -			return @ibase_free_result($query_id); -		} - -		return false; -	} - -	/** -	* Escape string used in sql query -	*/ -	function sql_escape($msg) -	{ -		return str_replace(array("'", "\0"), array("''", ''), $msg); -	} - -	/** -	* Build LIKE expression -	* @access private -	*/ -	function _sql_like_expression($expression) -	{ -		return $expression . " ESCAPE '\\'"; -	} - -	/** -	* Build db-specific query data -	* @access private -	*/ -	function _sql_custom_build($stage, $data) -	{ -		return $data; -	} - -	function _sql_bit_and($column_name, $bit, $compare = '') -	{ -		return 'BIN_AND(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : ''); -	} - -	function _sql_bit_or($column_name, $bit, $compare = '') -	{ -		return 'BIN_OR(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : ''); -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		// Need special handling here because ibase_errmsg returns -		// connection errors, however if the interbase extension -		// is not installed then ibase_errmsg does not exist and -		// we cannot call it. -		if (function_exists('ibase_errmsg')) -		{ -			$msg = @ibase_errmsg(); -			if (!$msg) -			{ -				$msg = $this->connect_error; -			} -		} -		else -		{ -			$msg = $this->connect_error; -		} -		return array( -			'message'	=> $msg, -			'code'		=> (@function_exists('ibase_errcode') ? @ibase_errcode() : '') -		); -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		if ($this->service_handle !== false) -		{ -			@ibase_service_detach($this->service_handle); -		} - -		return @ibase_close($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		switch ($mode) -		{ -			case 'start': -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @ibase_query($this->db_connect_id, $query); -				while ($void = @ibase_fetch_object($result, IBASE_TEXT)) -				{ -					// Take the time spent on parsing rows into account -				} -				@ibase_free_result($result); - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} -} - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/index.htm b/phpBB/includes/db/index.htm deleted file mode 100644 index ee1f723a7d..0000000000 --- a/phpBB/includes/db/index.htm +++ /dev/null @@ -1,10 +0,0 @@ -<html> -<head> -<title></title> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -</head> - -<body bgcolor="#FFFFFF" text="#000000"> - -</body> -</html> diff --git a/phpBB/includes/db/mssql.php b/phpBB/includes/db/mssql.php deleted file mode 100644 index 2dd95c2508..0000000000 --- a/phpBB/includes/db/mssql.php +++ /dev/null @@ -1,476 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -/** -* MSSQL Database Abstraction Layer -* Minimum Requirement is MSSQL 2000+ -* @package dbal -*/ -class dbal_mssql extends dbal -{ -	var $connect_error = ''; - -	/** -	* Connect to server -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) -	{ -		if (!function_exists('mssql_connect')) -		{ -			$this->connect_error = 'mssql_connect function does not exist, is mssql extension installed?'; -			return $this->sql_error(''); -		} - -		$this->persistency = $persistency; -		$this->user = $sqluser; -		$this->dbname = $database; - -		$port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':'; -		$this->server = $sqlserver . (($port) ? $port_delimiter . $port : ''); - -		@ini_set('mssql.charset', 'UTF-8'); -		@ini_set('mssql.textlimit', 2147483647); -		@ini_set('mssql.textsize', 2147483647); - -		if (version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.1', '>='))) -		{ -			$this->db_connect_id = ($this->persistency) ? @mssql_pconnect($this->server, $this->user, $sqlpassword, $new_link) : @mssql_connect($this->server, $this->user, $sqlpassword, $new_link); -		} -		else -		{ -			$this->db_connect_id = ($this->persistency) ? @mssql_pconnect($this->server, $this->user, $sqlpassword) : @mssql_connect($this->server, $this->user, $sqlpassword); -		} - -		if ($this->db_connect_id && $this->dbname != '') -		{ -			if (!@mssql_select_db($this->dbname, $this->db_connect_id)) -			{ -				@mssql_close($this->db_connect_id); -				return false; -			} -		} - -		return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error(''); -	} - -	/** -	* Version information about used database -	* @param bool $raw if true, only return the fetched sql_server_version -	* @param bool $use_cache If true, it is safe to retrieve the value from the cache -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		global $cache; - -		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mssql_version')) === false) -		{ -			$result_id = @mssql_query("SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY('productlevel'), SERVERPROPERTY('edition')", $this->db_connect_id); - -			$row = false; -			if ($result_id) -			{ -				$row = @mssql_fetch_assoc($result_id); -				@mssql_free_result($result_id); -			} - -			$this->sql_server_version = ($row) ? trim(implode(' ', $row)) : 0; - -			if (!empty($cache) && $use_cache) -			{ -				$cache->put('mssql_version', $this->sql_server_version); -			} -		} - -		if ($raw) -		{ -			return $this->sql_server_version; -		} - -		return ($this->sql_server_version) ? 'MSSQL<br />' . $this->sql_server_version : 'MSSQL'; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return @mssql_query('BEGIN TRANSACTION', $this->db_connect_id); -			break; - -			case 'commit': -				return @mssql_query('COMMIT TRANSACTION', $this->db_connect_id); -			break; - -			case 'rollback': -				return @mssql_query('ROLLBACK TRANSACTION', $this->db_connect_id); -			break; -		} - -		return true; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				if (($this->query_result = @mssql_query($query, $this->db_connect_id)) === false) -				{ -					$this->sql_error($query); -				} - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -				else if (strpos($query, 'SELECT') === 0 && $this->query_result) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} - -		return $this->query_result; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		// Since TOP is only returning a set number of rows we won't need it if total is set to 0 (return all rows) -		if ($total) -		{ -			// We need to grab the total number of rows + the offset number of rows to get the correct result -			if (strpos($query, 'SELECT DISTINCT') === 0) -			{ -				$query = 'SELECT DISTINCT TOP ' . ($total + $offset) . ' ' . substr($query, 15); -			} -			else -			{ -				$query = 'SELECT TOP ' . ($total + $offset) . ' ' . substr($query, 6); -			} -		} - -		$result = $this->sql_query($query, $cache_ttl); - -		// Seek by $offset rows -		if ($offset) -		{ -			$this->sql_rowseek($offset, $result); -		} - -		return $result; -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		return ($this->db_connect_id) ? @mssql_rows_affected($this->db_connect_id) : false; -	} - -	/** -	* Fetch current row -	*/ -	function sql_fetchrow($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		if ($query_id === false) -		{ -			return false; -		} - -		$row = @mssql_fetch_assoc($query_id); - -		// I hope i am able to remove this later... hopefully only a PHP or MSSQL bug -		if ($row) -		{ -			foreach ($row as $key => $value) -			{ -				$row[$key] = ($value === ' ' || $value === NULL) ? '' : $value; -			} -		} - -		return $row; -	} - -	/** -	* 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 (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_rowseek($rownum, $query_id); -		} - -		return ($query_id !== false) ? @mssql_data_seek($query_id, $rownum) : false; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		$result_id = @mssql_query('SELECT SCOPE_IDENTITY()', $this->db_connect_id); -		if ($result_id) -		{ -			if ($row = @mssql_fetch_assoc($result_id)) -			{ -				@mssql_free_result($result_id); -				return $row['computed']; -			} -			@mssql_free_result($result_id); -		} - -		return false; -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		if (isset($this->open_queries[$query_id])) -		{ -			unset($this->open_queries[$query_id]); -			return @mssql_free_result($query_id); -		} - -		return false; -	} - -	/** -	* Escape string used in sql query -	*/ -	function sql_escape($msg) -	{ -		return str_replace(array("'", "\0"), array("''", ''), $msg); -	} - -	/** -	* {@inheritDoc} -	*/ -	function sql_lower_text($column_name) -	{ -		return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; -	} - -	/** -	* Build LIKE expression -	* @access private -	*/ -	function _sql_like_expression($expression) -	{ -		return $expression . " ESCAPE '\\'"; -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		if (function_exists('mssql_get_last_message')) -		{ -			$error = array( -				'message'	=> @mssql_get_last_message(), -				'code'		=> '', -			); - -			// Get error code number -			$result_id = @mssql_query('SELECT @@ERROR as code', $this->db_connect_id); -			if ($result_id) -			{ -				$row = @mssql_fetch_assoc($result_id); -				$error['code'] = $row['code']; -				@mssql_free_result($result_id); -			} - -			// Get full error message if possible -			$sql = 'SELECT CAST(description as varchar(255)) as message -				FROM master.dbo.sysmessages -				WHERE error = ' . $error['code']; -			$result_id = @mssql_query($sql); - -			if ($result_id) -			{ -				$row = @mssql_fetch_assoc($result_id); -				if (!empty($row['message'])) -				{ -					$error['message'] .= '<br />' . $row['message']; -				} -				@mssql_free_result($result_id); -			} -		} -		else -		{ -			$error = array( -				'message'	=> $this->connect_error, -				'code'		=> '', -			); -		} - -		return $error; -	} - -	/** -	* Build db-specific query data -	* @access private -	*/ -	function _sql_custom_build($stage, $data) -	{ -		return $data; -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		return @mssql_close($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		switch ($mode) -		{ -			case 'start': -				$html_table = false; -				@mssql_query('SET SHOWPLAN_TEXT ON;', $this->db_connect_id); -				if ($result = @mssql_query($query, $this->db_connect_id)) -				{ -					@mssql_next_result($result); -					while ($row = @mssql_fetch_row($result)) -					{ -						$html_table = $this->sql_report('add_select_row', $query, $html_table, $row); -					} -				} -				@mssql_query('SET SHOWPLAN_TEXT OFF;', $this->db_connect_id); -				@mssql_free_result($result); - -				if ($html_table) -				{ -					$this->html_hold .= '</table>'; -				} -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @mssql_query($query, $this->db_connect_id); -				while ($void = @mssql_fetch_assoc($result)) -				{ -					// Take the time spent on parsing rows into account -				} -				@mssql_free_result($result); - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} -} - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php deleted file mode 100644 index 04501cce8b..0000000000 --- a/phpBB/includes/db/mssql_odbc.php +++ /dev/null @@ -1,422 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -/** -* Unified ODBC functions -* Unified ODBC functions support any database having ODBC driver, for example Adabas D, IBM DB2, iODBC, Solid, Sybase SQL Anywhere... -* Here we only support MSSQL Server 2000+ because of the provided schema -* -* @note number of bytes returned for returning data depends on odbc.defaultlrl php.ini setting. -* If it is limited to 4K for example only 4K of data is returned max, resulting in incomplete theme data for example. -* @note odbc.defaultbinmode may affect UTF8 characters -* -* @package dbal -*/ -class dbal_mssql_odbc extends dbal -{ -	var $last_query_text = ''; -	var $connect_error = ''; - -	/** -	* Connect to server -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) -	{ -		$this->persistency = $persistency; -		$this->user = $sqluser; -		$this->dbname = $database; - -		$port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':'; -		$this->server = $sqlserver . (($port) ? $port_delimiter . $port : ''); - -		$max_size = @ini_get('odbc.defaultlrl'); -		if (!empty($max_size)) -		{ -			$unit = strtolower(substr($max_size, -1, 1)); -			$max_size = (int) $max_size; - -			if ($unit == 'k') -			{ -				$max_size = floor($max_size / 1024); -			} -			else if ($unit == 'g') -			{ -				$max_size *= 1024; -			} -			else if (is_numeric($unit)) -			{ -				$max_size = floor((int) ($max_size . $unit) / 1048576); -			} -			$max_size = max(8, $max_size) . 'M'; - -			@ini_set('odbc.defaultlrl', $max_size); -		} - -		if ($this->persistency) -		{ -			if (!function_exists('odbc_pconnect')) -			{ -				$this->connect_error = 'odbc_pconnect function does not exist, is odbc extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @odbc_pconnect($this->server, $this->user, $sqlpassword); -		} -		else -		{ -			if (!function_exists('odbc_connect')) -			{ -				$this->connect_error = 'odbc_connect function does not exist, is odbc extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @odbc_connect($this->server, $this->user, $sqlpassword); -		} - -		return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error(''); -	} - -	/** -	* Version information about used database -	* @param bool $raw if true, only return the fetched sql_server_version -	* @param bool $use_cache If true, it is safe to retrieve the value from the cache -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		global $cache; - -		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mssqlodbc_version')) === false) -		{ -			$result_id = @odbc_exec($this->db_connect_id, "SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY('productlevel'), SERVERPROPERTY('edition')"); - -			$row = false; -			if ($result_id) -			{ -				$row = @odbc_fetch_array($result_id); -				@odbc_free_result($result_id); -			} - -			$this->sql_server_version = ($row) ? trim(implode(' ', $row)) : 0; - -			if (!empty($cache) && $use_cache) -			{ -				$cache->put('mssqlodbc_version', $this->sql_server_version); -			} -		} - -		if ($raw) -		{ -			return $this->sql_server_version; -		} - -		return ($this->sql_server_version) ? 'MSSQL (ODBC)<br />' . $this->sql_server_version : 'MSSQL (ODBC)'; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return @odbc_exec($this->db_connect_id, 'BEGIN TRANSACTION'); -			break; - -			case 'commit': -				return @odbc_exec($this->db_connect_id, 'COMMIT TRANSACTION'); -			break; - -			case 'rollback': -				return @odbc_exec($this->db_connect_id, 'ROLLBACK TRANSACTION'); -			break; -		} - -		return true; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->last_query_text = $query; -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				if (($this->query_result = @odbc_exec($this->db_connect_id, $query)) === false) -				{ -					$this->sql_error($query); -				} - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -				else if (strpos($query, 'SELECT') === 0 && $this->query_result) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} - -		return $this->query_result; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		// Since TOP is only returning a set number of rows we won't need it if total is set to 0 (return all rows) -		if ($total) -		{ -			// We need to grab the total number of rows + the offset number of rows to get the correct result -			if (strpos($query, 'SELECT DISTINCT') === 0) -			{ -				$query = 'SELECT DISTINCT TOP ' . ($total + $offset) . ' ' . substr($query, 15); -			} -			else -			{ -				$query = 'SELECT TOP ' . ($total + $offset) . ' ' . substr($query, 6); -			} -		} - -		$result = $this->sql_query($query, $cache_ttl); - -		// Seek by $offset rows -		if ($offset) -		{ -			$this->sql_rowseek($offset, $result); -		} - -		return $result; -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		return ($this->db_connect_id) ? @odbc_num_rows($this->query_result) : false; -	} - -	/** -	* Fetch current row -	* @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max. -	*/ -	function sql_fetchrow($query_id = false, $debug = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		return ($query_id !== false) ? @odbc_fetch_array($query_id) : false; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		$result_id = @odbc_exec($this->db_connect_id, 'SELECT @@IDENTITY'); - -		if ($result_id) -		{ -			if (@odbc_fetch_array($result_id)) -			{ -				$id = @odbc_result($result_id, 1); -				@odbc_free_result($result_id); -				return $id; -			} -			@odbc_free_result($result_id); -		} - -		return false; -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		if (isset($this->open_queries[(int) $query_id])) -		{ -			unset($this->open_queries[(int) $query_id]); -			return @odbc_free_result($query_id); -		} - -		return false; -	} - -	/** -	* Escape string used in sql query -	*/ -	function sql_escape($msg) -	{ -		return str_replace(array("'", "\0"), array("''", ''), $msg); -	} - -	/** -	* {@inheritDoc} -	*/ -	function sql_lower_text($column_name) -	{ -		return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; -	} - -	/** -	* Build LIKE expression -	* @access private -	*/ -	function _sql_like_expression($expression) -	{ -		return $expression . " ESCAPE '\\'"; -	} - -	/** -	* Build db-specific query data -	* @access private -	*/ -	function _sql_custom_build($stage, $data) -	{ -		return $data; -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		if (function_exists('odbc_errormsg')) -		{ -			$error = array( -				'message'	=> @odbc_errormsg(), -				'code'		=> @odbc_error(), -			); -		} -		else -		{ -			$error = array( -				'message'	=> $this->connect_error, -				'code'		=> '', -			); -		} - -		return $error; -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		return @odbc_close($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		switch ($mode) -		{ -			case 'start': -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @odbc_exec($this->db_connect_id, $query); -				while ($void = @odbc_fetch_array($result)) -				{ -					// Take the time spent on parsing rows into account -				} -				@odbc_free_result($result); - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} -} - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php deleted file mode 100644 index b91372ac61..0000000000 --- a/phpBB/includes/db/mssqlnative.php +++ /dev/null @@ -1,652 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2010 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -* This is the MS SQL Server Native database abstraction layer. -* PHP mssql native driver required. -* @author Chris Pucci -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -/** - * Prior to version 1.1 the SQL Server Native PHP driver didn't support sqlsrv_num_rows, or cursor based seeking so we recall all rows into an array - * and maintain our own cursor index into that array. - */ -class result_mssqlnative -{ -	public function result_mssqlnative($queryresult = false) -	{ -		$this->m_cursor = 0; -		$this->m_rows = array(); -		$this->m_num_fields = sqlsrv_num_fields($queryresult); -		$this->m_field_meta = sqlsrv_field_metadata($queryresult); - -		while ($row = sqlsrv_fetch_array($queryresult, SQLSRV_FETCH_ASSOC)) -		{ -			if ($row !== null) -			{ -				foreach($row as $k => $v) -				{ -					if (is_object($v) && method_exists($v, 'format')) -					{ -						$row[$k] = $v->format("Y-m-d\TH:i:s\Z"); -					} -				} -				$this->m_rows[] = $row;//read results into memory, cursors are not supported -			} -		} - -		$this->m_row_count = sizeof($this->m_rows); -	} - -	private function array_to_obj($array, &$obj) -	{ -		foreach ($array as $key => $value) -		{ -			if (is_array($value)) -			{ -				$obj->$key = new stdClass(); -				array_to_obj($value, $obj->$key); -			} -			else -			{ -				$obj->$key = $value; -			} -		} -		return $obj; -	} - -	public function fetch($mode = SQLSRV_FETCH_BOTH, $object_class = 'stdClass') -	{ -		if ($this->m_cursor >= $this->m_row_count || $this->m_row_count == 0) -		{ -			return false; -		} - -		$ret = false; -		$arr_num = array(); - -		if ($mode == SQLSRV_FETCH_NUMERIC || $mode == SQLSRV_FETCH_BOTH) -		{ -			foreach($this->m_rows[$this->m_cursor] as $key => $value) -			{ -				$arr_num[] = $value; -			} -		} - -		switch ($mode) -		{ -			case SQLSRV_FETCH_ASSOC: -				$ret = $this->m_rows[$this->m_cursor]; -			break; -			case SQLSRV_FETCH_NUMERIC: -				$ret = $arr_num; -			break; -			case 'OBJECT': -				$ret = $this->array_to_obj($this->m_rows[$this->m_cursor], $o = new $object_class); -			break; -			case SQLSRV_FETCH_BOTH: -			default: -				$ret = $this->m_rows[$this->m_cursor] + $arr_num; -			break; -		} -		$this->m_cursor++; -		return $ret; -	} - -	public function get($pos, $fld) -	{ -		return $this->m_rows[$pos][$fld]; -	} - -	public function num_rows() -	{ -		return $this->m_row_count; -	} - -	public function seek($iRow) -	{ -		$this->m_cursor = min($iRow, $this->m_row_count); -	} - -	public function num_fields() -	{ -		return $this->m_num_fields; -	} - -	public function field_name($nr) -	{ -		$arr_keys = array_keys($this->m_rows[0]); -		return $arr_keys[$nr]; -	} - -	public function field_type($nr) -	{ -		$i = 0; -		$int_type = -1; -		$str_type = ''; - -		foreach ($this->m_field_meta as $meta) -		{ -			if ($nr == $i) -			{ -				$int_type = $meta['Type']; -				break; -			} -			$i++; -		} - -		//http://msdn.microsoft.com/en-us/library/cc296183.aspx contains type table -		switch ($int_type) -		{ -			case SQLSRV_SQLTYPE_BIGINT: 		$str_type = 'bigint'; break; -			case SQLSRV_SQLTYPE_BINARY: 		$str_type = 'binary'; break; -			case SQLSRV_SQLTYPE_BIT: 			$str_type = 'bit'; break; -			case SQLSRV_SQLTYPE_CHAR: 			$str_type = 'char'; break; -			case SQLSRV_SQLTYPE_DATETIME: 		$str_type = 'datetime'; break; -			case SQLSRV_SQLTYPE_DECIMAL/*($precision, $scale)*/: $str_type = 'decimal'; break; -			case SQLSRV_SQLTYPE_FLOAT: 			$str_type = 'float'; break; -			case SQLSRV_SQLTYPE_IMAGE: 			$str_type = 'image'; break; -			case SQLSRV_SQLTYPE_INT: 			$str_type = 'int'; break; -			case SQLSRV_SQLTYPE_MONEY: 			$str_type = 'money'; break; -			case SQLSRV_SQLTYPE_NCHAR/*($charCount)*/: $str_type = 'nchar'; break; -			case SQLSRV_SQLTYPE_NUMERIC/*($precision, $scale)*/: $str_type = 'numeric'; break; -			case SQLSRV_SQLTYPE_NVARCHAR/*($charCount)*/: $str_type = 'nvarchar'; break; -			case SQLSRV_SQLTYPE_NTEXT: 			$str_type = 'ntext'; break; -			case SQLSRV_SQLTYPE_REAL: 			$str_type = 'real'; break; -			case SQLSRV_SQLTYPE_SMALLDATETIME: 	$str_type = 'smalldatetime'; break; -			case SQLSRV_SQLTYPE_SMALLINT: 		$str_type = 'smallint'; break; -			case SQLSRV_SQLTYPE_SMALLMONEY: 	$str_type = 'smallmoney'; break; -			case SQLSRV_SQLTYPE_TEXT: 			$str_type = 'text'; break; -			case SQLSRV_SQLTYPE_TIMESTAMP: 		$str_type = 'timestamp'; break; -			case SQLSRV_SQLTYPE_TINYINT: 		$str_type = 'tinyint'; break; -			case SQLSRV_SQLTYPE_UNIQUEIDENTIFIER: $str_type = 'uniqueidentifier'; break; -			case SQLSRV_SQLTYPE_UDT: 			$str_type = 'UDT'; break; -			case SQLSRV_SQLTYPE_VARBINARY/*($byteCount)*/: $str_type = 'varbinary'; break; -			case SQLSRV_SQLTYPE_VARCHAR/*($charCount)*/: $str_type = 'varchar'; break; -			case SQLSRV_SQLTYPE_XML: 			$str_type = 'xml'; break; -			default: $str_type = $int_type; -		} -		return $str_type; -	} - -	public function free() -	{ -		unset($this->m_rows); -		return; -	} -} - -/** -* @package dbal -*/ -class dbal_mssqlnative extends dbal -{ -	var $m_insert_id = NULL; -	var $last_query_text = ''; -	var $query_options = array(); -	var $connect_error = ''; - -	/** -	* Connect to server -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) -	{ -		// Test for driver support, to avoid suppressed fatal error -		if (!function_exists('sqlsrv_connect')) -		{ -			$this->connect_error = 'Native MS SQL Server driver for PHP is missing or needs to be updated. Version 1.1 or later is required to install phpBB3. You can download the driver from: http://www.microsoft.com/sqlserver/2005/en/us/PHP-Driver.aspx'; -			return $this->sql_error(''); -		} - -		//set up connection variables -		$this->persistency = $persistency; -		$this->user = $sqluser; -		$this->dbname = $database; -		$port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':'; -		$this->server = $sqlserver . (($port) ? $port_delimiter . $port : ''); - -		//connect to database -		$this->db_connect_id = sqlsrv_connect($this->server, array( -			'Database' => $this->dbname, -			'UID' => $this->user, -			'PWD' => $sqlpassword -		)); - -		return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error(''); -	} - -	/** -	* Version information about used database -	* @param bool $raw if true, only return the fetched sql_server_version -	* @param bool $use_cache If true, it is safe to retrieve the value from the cache -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		global $cache; - -		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mssql_version')) === false) -		{ -			$arr_server_info = sqlsrv_server_info($this->db_connect_id); -			$this->sql_server_version = $arr_server_info['SQLServerVersion']; - -			if (!empty($cache) && $use_cache) -			{ -				$cache->put('mssql_version', $this->sql_server_version); -			} -		} - -		if ($raw) -		{ -			return $this->sql_server_version; -		} - -		return ($this->sql_server_version) ? 'MSSQL<br />' . $this->sql_server_version : 'MSSQL'; -	} - -	/** -	* {@inheritDoc} -	*/ -	function sql_buffer_nested_transactions() -	{ -		return true; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return sqlsrv_begin_transaction($this->db_connect_id); -			break; - -			case 'commit': -				return sqlsrv_commit($this->db_connect_id); -			break; - -			case 'rollback': -				return sqlsrv_rollback($this->db_connect_id); -			break; -		} -		return true; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->last_query_text = $query; -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				if (($this->query_result = @sqlsrv_query($this->db_connect_id, $query, array(), $this->query_options)) === false) -				{ -					$this->sql_error($query); -				} -				// reset options for next query -				$this->query_options = array(); - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -				else if (strpos($query, 'SELECT') === 0 && $this->query_result) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} -		return $this->query_result; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		// total == 0 means all results - not zero results -		if ($offset == 0 && $total !== 0) -		{ -			if (strpos($query, "SELECT") === false) -			{ -				$query = "TOP {$total} " . $query; -			} -			else -			{ -				$query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query); -			} -		} -		else if ($offset > 0) -		{ -			$query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query); -			$query = 'SELECT * -					FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 -					FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3'; - -			if ($total > 0) -			{ -				$query .= ' WHERE line3 BETWEEN ' . ($offset+1) . ' AND ' . ($offset + $total); -			} -			else -			{ -				$query .= ' WHERE line3 > ' . $offset; -			} -		} - -		$result = $this->sql_query($query, $cache_ttl); - -		return $result; -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		return (!empty($this->query_result)) ? @sqlsrv_rows_affected($this->query_result) : false; -	} - -	/** -	* Fetch current row -	*/ -	function sql_fetchrow($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		if ($query_id === false) -		{ -			return false; -		} - -		$row = @sqlsrv_fetch_array($query_id, SQLSRV_FETCH_ASSOC); - -		if ($row) -		{ -			foreach ($row as $key => $value) -			{ -				$row[$key] = ($value === ' ' || $value === NULL) ? '' : $value; -			} - -			// remove helper values from LIMIT queries -			if (isset($row['line2'])) -			{ -				unset($row['line2'], $row['line3']); -			} -		} -		return (sizeof($row)) ? $row : false; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		$result_id = @sqlsrv_query($this->db_connect_id, 'SELECT @@IDENTITY'); - -		if ($result_id !== false) -		{ -			$row = @sqlsrv_fetch_array($result_id); -			$id = $row[0]; -			@sqlsrv_free_stmt($result_id); -			return $id; -		} -		else -		{ -			return false; -		} -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		if (isset($this->open_queries[$query_id])) -		{ -			unset($this->open_queries[$query_id]); -			return @sqlsrv_free_stmt($query_id); -		} -		return false; -	} - -	/** -	* Escape string used in sql query -	*/ -	function sql_escape($msg) -	{ -		return str_replace(array("'", "\0"), array("''", ''), $msg); -	} - -	/** -	* {@inheritDoc} -	*/ -	function sql_lower_text($column_name) -	{ -		return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; -	} - -	/** -	* Build LIKE expression -	* @access private -	*/ -	function _sql_like_expression($expression) -	{ -		return $expression . " ESCAPE '\\'"; -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		if (function_exists('sqlsrv_errors')) -		{ -			$errors = @sqlsrv_errors(SQLSRV_ERR_ERRORS); -			$error_message = ''; -			$code = 0; - -			if ($errors != null) -			{ -				foreach ($errors as $error) -				{ -					$error_message .= "SQLSTATE: " . $error[ 'SQLSTATE'] . "\n"; -					$error_message .= "code: " . $error[ 'code'] . "\n"; -					$code = $error['code']; -					$error_message .= "message: " . $error[ 'message'] . "\n"; -				} -				$this->last_error_result = $error_message; -				$error = $this->last_error_result; -			} -			else -			{ -				$error = (isset($this->last_error_result) && $this->last_error_result) ? $this->last_error_result : array(); -			} - -			$error = array( -				'message'	=> $error, -				'code'		=> $code, -			); -		} -		else -		{ -			$error = array( -				'message'	=> $this->connect_error, -				'code'		=> '', -			); -		} - -		return $error; -	} - -	/** -	* Build db-specific query data -	* @access private -	*/ -	function _sql_custom_build($stage, $data) -	{ -		return $data; -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		return @sqlsrv_close($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		switch ($mode) -		{ -			case 'start': -				$html_table = false; -				@sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT ON;'); -				if ($result = @sqlsrv_query($this->db_connect_id, $query)) -				{ -					@sqlsrv_next_result($result); -					while ($row = @sqlsrv_fetch_array($result)) -					{ -						$html_table = $this->sql_report('add_select_row', $query, $html_table, $row); -					} -				} -				@sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT OFF;'); -				@sqlsrv_free_stmt($result); - -				if ($html_table) -				{ -					$this->html_hold .= '</table>'; -				} -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @sqlsrv_query($this->db_connect_id, $query); -				while ($void = @sqlsrv_fetch_array($result)) -				{ -					// Take the time spent on parsing rows into account -				} -				@sqlsrv_free_stmt($result); - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} - -	/** -	* Utility method used to retrieve number of rows -	* Emulates mysql_num_rows -	* Used in acp_database.php -> write_data_mssqlnative() -	* Requires a static or keyset cursor to be definde via -	* mssqlnative_set_query_options() -	*/ -	function mssqlnative_num_rows($res) -	{ -		if ($res !== false) -		{ -			return sqlsrv_num_rows($res); -		} -		else -		{ -			return false; -		} -	} - -	/** -	* Allows setting mssqlnative specific query options passed to sqlsrv_query as 4th parameter. -	*/ -	function mssqlnative_set_query_options($options) -	{ -		$this->query_options = $options; -	} -} - -?> diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php deleted file mode 100644 index 252cb20bd4..0000000000 --- a/phpBB/includes/db/mysql.php +++ /dev/null @@ -1,591 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -/** -* MySQL4 Database Abstraction Layer -* Compatible with: -* MySQL 3.23+ -* MySQL 4.0+ -* MySQL 4.1+ -* MySQL 5.0+ -* @package dbal -*/ -class dbal_mysql extends dbal -{ -	var $multi_insert = true; -	var $connect_error = ''; - -	/** -	* Connect to server -	* @access public -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) -	{ -		$this->persistency = $persistency; -		$this->user = $sqluser; -		$this->server = $sqlserver . (($port) ? ':' . $port : ''); -		$this->dbname = $database; - -		$this->sql_layer = 'mysql4'; - -		if ($this->persistency) -		{ -			if (!function_exists('mysql_pconnect')) -			{ -				$this->connect_error = 'mysql_pconnect function does not exist, is mysql extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @mysql_pconnect($this->server, $this->user, $sqlpassword); -		} -		else -		{ -			if (!function_exists('mysql_connect')) -			{ -				$this->connect_error = 'mysql_connect function does not exist, is mysql extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @mysql_connect($this->server, $this->user, $sqlpassword, $new_link); -		} - -		if ($this->db_connect_id && $this->dbname != '') -		{ -			if (@mysql_select_db($this->dbname, $this->db_connect_id)) -			{ -				// Determine what version we are using and if it natively supports UNICODE -				if (version_compare($this->sql_server_info(true), '4.1.0', '>=')) -				{ -					@mysql_query("SET NAMES 'utf8'", $this->db_connect_id); - -					// enforce strict mode on databases that support it -					if (version_compare($this->sql_server_info(true), '5.0.2', '>=')) -					{ -						$result = @mysql_query('SELECT @@session.sql_mode AS sql_mode', $this->db_connect_id); -						$row = @mysql_fetch_assoc($result); -						@mysql_free_result($result); -						$modes = array_map('trim', explode(',', $row['sql_mode'])); - -						// TRADITIONAL includes STRICT_ALL_TABLES and STRICT_TRANS_TABLES -						if (!in_array('TRADITIONAL', $modes)) -						{ -							if (!in_array('STRICT_ALL_TABLES', $modes)) -							{ -								$modes[] = 'STRICT_ALL_TABLES'; -							} - -							if (!in_array('STRICT_TRANS_TABLES', $modes)) -							{ -								$modes[] = 'STRICT_TRANS_TABLES'; -							} -						} - -						$mode = implode(',', $modes); -						@mysql_query("SET SESSION sql_mode='{$mode}'", $this->db_connect_id); -					} -				} -				else if (version_compare($this->sql_server_info(true), '4.0.0', '<')) -				{ -					$this->sql_layer = 'mysql'; -				} - -				return $this->db_connect_id; -			} -		} - -		return $this->sql_error(''); -	} - -	/** -	* Version information about used database -	* @param bool $raw if true, only return the fetched sql_server_version -	* @param bool $use_cache If true, it is safe to retrieve the value from the cache -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		global $cache; - -		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysql_version')) === false) -		{ -			$result = @mysql_query('SELECT VERSION() AS version', $this->db_connect_id); -			$row = @mysql_fetch_assoc($result); -			@mysql_free_result($result); - -			$this->sql_server_version = $row['version']; - -			if (!empty($cache) && $use_cache) -			{ -				$cache->put('mysql_version', $this->sql_server_version); -			} -		} - -		return ($raw) ? $this->sql_server_version : 'MySQL ' . $this->sql_server_version; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return @mysql_query('BEGIN', $this->db_connect_id); -			break; - -			case 'commit': -				return @mysql_query('COMMIT', $this->db_connect_id); -			break; - -			case 'rollback': -				return @mysql_query('ROLLBACK', $this->db_connect_id); -			break; -		} - -		return true; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				if (($this->query_result = @mysql_query($query, $this->db_connect_id)) === false) -				{ -					$this->sql_error($query); -				} - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -				else if (strpos($query, 'SELECT') === 0 && $this->query_result) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} - -		return $this->query_result; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		// if $total is set to 0 we do not want to limit the number of rows -		if ($total == 0) -		{ -			// Having a value of -1 was always a bug -			$total = '18446744073709551615'; -		} - -		$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); - -		return $this->sql_query($query, $cache_ttl); -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		return ($this->db_connect_id) ? @mysql_affected_rows($this->db_connect_id) : false; -	} - -	/** -	* Fetch current row -	*/ -	function sql_fetchrow($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		return ($query_id !== false) ? @mysql_fetch_assoc($query_id) : 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 (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_rowseek($rownum, $query_id); -		} - -		return ($query_id !== false) ? @mysql_data_seek($query_id, $rownum) : false; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		return ($this->db_connect_id) ? @mysql_insert_id($this->db_connect_id) : false; -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		if (isset($this->open_queries[(int) $query_id])) -		{ -			unset($this->open_queries[(int) $query_id]); -			return @mysql_free_result($query_id); -		} - -		return false; -	} - -	/** -	* Escape string used in sql query -	*/ -	function sql_escape($msg) -	{ -		if (!$this->db_connect_id) -		{ -			return @mysql_real_escape_string($msg); -		} - -		return @mysql_real_escape_string($msg, $this->db_connect_id); -	} - -	/** -	* 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) -	{ -		$table_status = $this->get_table_status($table_name); - -		if (isset($table_status['Engine'])) -		{ -			if ($table_status['Engine'] === 'MyISAM') -			{ -				return $table_status['Rows']; -			} -			else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000) -			{ -				return '~' . $table_status['Rows']; -			} -		} - -		return parent::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) -	{ -		$table_status = $this->get_table_status($table_name); - -		if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM') -		{ -			return $table_status['Rows']; -		} - -		return parent::get_row_count($table_name); -	} - -	/** -	* Gets some information about the specified table. -	* -	* @param string $table_name		Table name -	* -	* @return array -	* -	* @access protected -	*/ -	function get_table_status($table_name) -	{ -		$sql = "SHOW TABLE STATUS -			LIKE '" . $this->sql_escape($table_name) . "'"; -		$result = $this->sql_query($sql); -		$table_status = $this->sql_fetchrow($result); -		$this->sql_freeresult($result); - -		return $table_status; -	} - -	/** -	* Build LIKE expression -	* @access private -	*/ -	function _sql_like_expression($expression) -	{ -		return $expression; -	} - -	/** -	* Build db-specific query data -	* @access private -	*/ -	function _sql_custom_build($stage, $data) -	{ -		switch ($stage) -		{ -			case 'FROM': -				$data = '(' . $data . ')'; -			break; -		} - -		return $data; -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		if ($this->db_connect_id) -		{ -			$error = array( -				'message'	=> @mysql_error($this->db_connect_id), -				'code'		=> @mysql_errno($this->db_connect_id), -			); -		} -		else if (function_exists('mysql_error')) -		{ -			$error = array( -				'message'	=> @mysql_error(), -				'code'		=> @mysql_errno(), -			); -		} -		else -		{ -			$error = array( -				'message'	=> $this->connect_error, -				'code'		=> '', -			); -		} - -		return $error; -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		return @mysql_close($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		static $test_prof; - -		// current detection method, might just switch to see the existance of INFORMATION_SCHEMA.PROFILING -		if ($test_prof === null) -		{ -			$test_prof = false; -			if (version_compare($this->sql_server_info(true), '5.0.37', '>=') && version_compare($this->sql_server_info(true), '5.1', '<')) -			{ -				$test_prof = true; -			} -		} - -		switch ($mode) -		{ -			case 'start': - -				$explain_query = $query; -				if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m)) -				{ -					$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2]; -				} -				else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m)) -				{ -					$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2]; -				} - -				if (preg_match('/^SELECT/', $explain_query)) -				{ -					$html_table = false; - -					// begin profiling -					if ($test_prof) -					{ -						@mysql_query('SET profiling = 1;', $this->db_connect_id); -					} - -					if ($result = @mysql_query("EXPLAIN $explain_query", $this->db_connect_id)) -					{ -						while ($row = @mysql_fetch_assoc($result)) -						{ -							$html_table = $this->sql_report('add_select_row', $query, $html_table, $row); -						} -					} -					@mysql_free_result($result); - -					if ($html_table) -					{ -						$this->html_hold .= '</table>'; -					} - -					if ($test_prof) -					{ -						$html_table = false; - -						// get the last profile -						if ($result = @mysql_query('SHOW PROFILE ALL;', $this->db_connect_id)) -						{ -							$this->html_hold .= '<br />'; -							while ($row = @mysql_fetch_assoc($result)) -							{ -								// make <unknown> HTML safe -								if (!empty($row['Source_function'])) -								{ -									$row['Source_function'] = str_replace(array('<', '>'), array('<', '>'), $row['Source_function']); -								} - -								// remove unsupported features -								foreach ($row as $key => $val) -								{ -									if ($val === null) -									{ -										unset($row[$key]); -									} -								} -								$html_table = $this->sql_report('add_select_row', $query, $html_table, $row); -							} -						} -						@mysql_free_result($result); - -						if ($html_table) -						{ -							$this->html_hold .= '</table>'; -						} - -						@mysql_query('SET profiling = 0;', $this->db_connect_id); -					} -				} - -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @mysql_query($query, $this->db_connect_id); -				while ($void = @mysql_fetch_assoc($result)) -				{ -					// Take the time spent on parsing rows into account -				} -				@mysql_free_result($result); - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} -} - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php deleted file mode 100644 index 69f1d26a40..0000000000 --- a/phpBB/includes/db/mysqli.php +++ /dev/null @@ -1,581 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -/** -* MySQLi Database Abstraction Layer -* mysqli-extension has to be compiled with: -* MySQL 4.1+ or MySQL 5.0+ -* @package dbal -*/ -class dbal_mysqli extends dbal -{ -	var $multi_insert = true; -	var $connect_error = ''; - -	/** -	* Connect to server -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false , $new_link = false) -	{ -		if (!function_exists('mysqli_connect')) -		{ -			$this->connect_error = 'mysqli_connect function does not exist, is mysqli extension installed?'; -			return $this->sql_error(''); -		} - -		// Mysqli extension supports persistent connection since PHP 5.3.0 -		$this->persistency = (version_compare(PHP_VERSION, '5.3.0', '>=')) ? $persistency : false; -		$this->user = $sqluser; - -		// If persistent connection, set dbhost to localhost when empty and prepend it with 'p:' prefix -		$this->server = ($this->persistency) ? 'p:' . (($sqlserver) ? $sqlserver : 'localhost') : $sqlserver; - -		$this->dbname = $database; -		$port = (!$port) ? NULL : $port; - -		// If port is set and it is not numeric, most likely mysqli socket is set. -		// Try to map it to the $socket parameter. -		$socket = NULL; -		if ($port) -		{ -			if (is_numeric($port)) -			{ -				$port = (int) $port; -			} -			else -			{ -				$socket = $port; -				$port = NULL; -			} -		} - -		$this->db_connect_id = @mysqli_connect($this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket); - -		if ($this->db_connect_id && $this->dbname != '') -		{ -			@mysqli_query($this->db_connect_id, "SET NAMES 'utf8'"); - -			// enforce strict mode on databases that support it -			if (version_compare($this->sql_server_info(true), '5.0.2', '>=')) -			{ -				$result = @mysqli_query($this->db_connect_id, 'SELECT @@session.sql_mode AS sql_mode'); -				$row = @mysqli_fetch_assoc($result); -				@mysqli_free_result($result); - -				$modes = array_map('trim', explode(',', $row['sql_mode'])); - -				// TRADITIONAL includes STRICT_ALL_TABLES and STRICT_TRANS_TABLES -				if (!in_array('TRADITIONAL', $modes)) -				{ -					if (!in_array('STRICT_ALL_TABLES', $modes)) -					{ -						$modes[] = 'STRICT_ALL_TABLES'; -					} - -					if (!in_array('STRICT_TRANS_TABLES', $modes)) -					{ -						$modes[] = 'STRICT_TRANS_TABLES'; -					} -				} - -				$mode = implode(',', $modes); -				@mysqli_query($this->db_connect_id, "SET SESSION sql_mode='{$mode}'"); -			} -			return $this->db_connect_id; -		} - -		return $this->sql_error(''); -	} - -	/** -	* Version information about used database -	* @param bool $use_cache If true, it is safe to retrieve the value from the cache -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		global $cache; - -		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysqli_version')) === false) -		{ -			$result = @mysqli_query($this->db_connect_id, 'SELECT VERSION() AS version'); -			$row = @mysqli_fetch_assoc($result); -			@mysqli_free_result($result); - -			$this->sql_server_version = $row['version']; - -			if (!empty($cache) && $use_cache) -			{ -				$cache->put('mysqli_version', $this->sql_server_version); -			} -		} - -		return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return @mysqli_autocommit($this->db_connect_id, false); -			break; - -			case 'commit': -				$result = @mysqli_commit($this->db_connect_id); -				@mysqli_autocommit($this->db_connect_id, true); -				return $result; -			break; - -			case 'rollback': -				$result = @mysqli_rollback($this->db_connect_id); -				@mysqli_autocommit($this->db_connect_id, true); -				return $result; -			break; -		} - -		return true; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				if (($this->query_result = @mysqli_query($this->db_connect_id, $query)) === false) -				{ -					$this->sql_error($query); -				} - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} - -		return $this->query_result; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		// if $total is set to 0 we do not want to limit the number of rows -		if ($total == 0) -		{ -			// MySQL 4.1+ no longer supports -1 in limit queries -			$total = '18446744073709551615'; -		} - -		$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); - -		return $this->sql_query($query, $cache_ttl); -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		return ($this->db_connect_id) ? @mysqli_affected_rows($this->db_connect_id) : false; -	} - -	/** -	* Fetch current row -	*/ -	function sql_fetchrow($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (!is_object($query_id) && isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		if ($query_id !== false) -		{ -			$result = @mysqli_fetch_assoc($query_id); -			return $result !== null ? $result : false; -		} - -		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 (!is_object($query_id) && isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_rowseek($rownum, $query_id); -		} - -		return ($query_id !== false) ? @mysqli_data_seek($query_id, $rownum) : false; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		return ($this->db_connect_id) ? @mysqli_insert_id($this->db_connect_id) : false; -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (!is_object($query_id) && isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		return @mysqli_free_result($query_id); -	} - -	/** -	* Escape string used in sql query -	*/ -	function sql_escape($msg) -	{ -		return @mysqli_real_escape_string($this->db_connect_id, $msg); -	} - -	/** -	* 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) -	{ -		$table_status = $this->get_table_status($table_name); - -		if (isset($table_status['Engine'])) -		{ -			if ($table_status['Engine'] === 'MyISAM') -			{ -				return $table_status['Rows']; -			} -			else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000) -			{ -				return '~' . $table_status['Rows']; -			} -		} - -		return parent::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) -	{ -		$table_status = $this->get_table_status($table_name); - -		if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM') -		{ -			return $table_status['Rows']; -		} - -		return parent::get_row_count($table_name); -	} - -	/** -	* Gets some information about the specified table. -	* -	* @param string $table_name		Table name -	* -	* @return array -	* -	* @access protected -	*/ -	function get_table_status($table_name) -	{ -		$sql = "SHOW TABLE STATUS -			LIKE '" . $this->sql_escape($table_name) . "'"; -		$result = $this->sql_query($sql); -		$table_status = $this->sql_fetchrow($result); -		$this->sql_freeresult($result); - -		return $table_status; -	} - -	/** -	* Build LIKE expression -	* @access private -	*/ -	function _sql_like_expression($expression) -	{ -		return $expression; -	} - -	/** -	* Build db-specific query data -	* @access private -	*/ -	function _sql_custom_build($stage, $data) -	{ -		switch ($stage) -		{ -			case 'FROM': -				$data = '(' . $data . ')'; -			break; -		} - -		return $data; -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		if ($this->db_connect_id) -		{ -			$error = array( -				'message'	=> @mysqli_error($this->db_connect_id), -				'code'		=> @mysqli_errno($this->db_connect_id) -			); -		} -		else if (function_exists('mysqli_connect_error')) -		{ -			$error = array( -				'message'	=> @mysqli_connect_error(), -				'code'		=> @mysqli_connect_errno(), -			); -		} -		else -		{ -			$error = array( -				'message'	=> $this->connect_error, -				'code'		=> '', -			); -		} - -		return $error; -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		return @mysqli_close($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		static $test_prof; - -		// current detection method, might just switch to see the existance of INFORMATION_SCHEMA.PROFILING -		if ($test_prof === null) -		{ -			$test_prof = false; -			if (strpos(mysqli_get_server_info($this->db_connect_id), 'community') !== false) -			{ -				$ver = mysqli_get_server_version($this->db_connect_id); -				if ($ver >= 50037 && $ver < 50100) -				{ -					$test_prof = true; -				} -			} -		} - -		switch ($mode) -		{ -			case 'start': - -				$explain_query = $query; -				if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m)) -				{ -					$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2]; -				} -				else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m)) -				{ -					$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2]; -				} - -				if (preg_match('/^SELECT/', $explain_query)) -				{ -					$html_table = false; - -					// begin profiling -					if ($test_prof) -					{ -						@mysqli_query($this->db_connect_id, 'SET profiling = 1;'); -					} - -					if ($result = @mysqli_query($this->db_connect_id, "EXPLAIN $explain_query")) -					{ -						while ($row = @mysqli_fetch_assoc($result)) -						{ -							$html_table = $this->sql_report('add_select_row', $query, $html_table, $row); -						} -					} -					@mysqli_free_result($result); - -					if ($html_table) -					{ -						$this->html_hold .= '</table>'; -					} - -					if ($test_prof) -					{ -						$html_table = false; - -						// get the last profile -						if ($result = @mysqli_query($this->db_connect_id, 'SHOW PROFILE ALL;')) -						{ -							$this->html_hold .= '<br />'; -							while ($row = @mysqli_fetch_assoc($result)) -							{ -								// make <unknown> HTML safe -								if (!empty($row['Source_function'])) -								{ -									$row['Source_function'] = str_replace(array('<', '>'), array('<', '>'), $row['Source_function']); -								} - -								// remove unsupported features -								foreach ($row as $key => $val) -								{ -									if ($val === null) -									{ -										unset($row[$key]); -									} -								} -								$html_table = $this->sql_report('add_select_row', $query, $html_table, $row); -							} -						} -						@mysqli_free_result($result); - -						if ($html_table) -						{ -							$this->html_hold .= '</table>'; -						} - -						@mysqli_query($this->db_connect_id, 'SET profiling = 0;'); -					} -				} - -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @mysqli_query($this->db_connect_id, $query); -				while ($void = @mysqli_fetch_assoc($result)) -				{ -					// Take the time spent on parsing rows into account -				} -				@mysqli_free_result($result); - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} -} - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/oracle.php b/phpBB/includes/db/oracle.php deleted file mode 100644 index 4a7a4ecc8c..0000000000 --- a/phpBB/includes/db/oracle.php +++ /dev/null @@ -1,808 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -/** -* Oracle Database Abstraction Layer -* @package dbal -*/ -class dbal_oracle extends dbal -{ -	var $last_query_text = ''; -	var $connect_error = ''; - -	/** -	* Connect to server -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) -	{ -		$this->persistency = $persistency; -		$this->user = $sqluser; -		$this->server = $sqlserver . (($port) ? ':' . $port : ''); -		$this->dbname = $database; - -		$connect = $database; - -		// support for "easy connect naming" -		if ($sqlserver !== '' && $sqlserver !== '/') -		{ -			if (substr($sqlserver, -1, 1) == '/') -			{ -				$sqlserver == substr($sqlserver, 0, -1); -			} -			$connect = $sqlserver . (($port) ? ':' . $port : '') . '/' . $database; -		} - -		if ($new_link) -		{ -			if (!function_exists('ocinlogon')) -			{ -				$this->connect_error = 'ocinlogon function does not exist, is oci extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @ocinlogon($this->user, $sqlpassword, $connect, 'UTF8'); -		} -		else if ($this->persistency) -		{ -			if (!function_exists('ociplogon')) -			{ -				$this->connect_error = 'ociplogon function does not exist, is oci extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @ociplogon($this->user, $sqlpassword, $connect, 'UTF8'); -		} -		else -		{ -			if (!function_exists('ocilogon')) -			{ -				$this->connect_error = 'ocilogon function does not exist, is oci extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @ocilogon($this->user, $sqlpassword, $connect, 'UTF8'); -		} - -		return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error(''); -	} - -	/** -	* Version information about used database -	* @param bool $raw if true, only return the fetched sql_server_version -	* @param bool $use_cache forced to false for Oracle -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		/** -		* force $use_cache false.  I didn't research why the caching code below is commented out -		* but I assume its because the Oracle extension provides a direct method to access it -		* without a query. -		*/ - -		$use_cache = false; -/* -		global $cache; - -		if (empty($cache) || ($this->sql_server_version = $cache->get('oracle_version')) === false) -		{ -			$result = @ociparse($this->db_connect_id, 'SELECT * FROM v$version WHERE banner LIKE \'Oracle%\''); -			@ociexecute($result, OCI_DEFAULT); -			@ocicommit($this->db_connect_id); - -			$row = array(); -			@ocifetchinto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS); -			@ocifreestatement($result); -			$this->sql_server_version = trim($row['BANNER']); - -			$cache->put('oracle_version', $this->sql_server_version); -		} -*/ -		$this->sql_server_version = @ociserverversion($this->db_connect_id); - -		return $this->sql_server_version; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return true; -			break; - -			case 'commit': -				return @ocicommit($this->db_connect_id); -			break; - -			case 'rollback': -				return @ocirollback($this->db_connect_id); -			break; -		} - -		return true; -	} - -	/** -	* Oracle specific code to handle the fact that it does not compare columns properly -	* @access private -	*/ -	function _rewrite_col_compare($args) -	{ -		if (sizeof($args) == 4) -		{ -			if ($args[2] == '=') -			{ -				return '(' . $args[0] . ' OR (' . $args[1] . ' is NULL AND ' . $args[3] . ' is NULL))'; -			} -			else if ($args[2] == '<>') -			{ -				// really just a fancy way of saying foo <> bar or (foo is NULL XOR bar is NULL) but SQL has no XOR :P -				return '(' . $args[0] . ' OR ((' . $args[1] . ' is NULL AND ' . $args[3] . ' is NOT NULL) OR (' . $args[1] . ' is NOT NULL AND ' . $args[3] . ' is NULL)))'; -			} -		} -		else -		{ -			return $this->_rewrite_where($args[0]); -		} -	} - -	/** -	* Oracle specific code to handle it's lack of sanity -	* @access private -	*/ -	function _rewrite_where($where_clause) -	{ -		preg_match_all('/\s*(AND|OR)?\s*([\w_.()]++)\s*(?:(=|<[=>]?|>=?|LIKE)\s*((?>\'(?>[^\']++|\'\')*+\'|[\d-.()]+))|((NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]+,? ?)*+\)))/', $where_clause, $result, PREG_SET_ORDER); -		$out = ''; -		foreach ($result as $val) -		{ -			if (!isset($val[5])) -			{ -				if ($val[4] !== "''") -				{ -					$out .= $val[0]; -				} -				else -				{ -					$out .= ' ' . $val[1] . ' ' . $val[2]; -					if ($val[3] == '=') -					{ -						$out .= ' is NULL'; -					} -					else if ($val[3] == '<>') -					{ -						$out .= ' is NOT NULL'; -					} -				} -			} -			else -			{ -				$in_clause = array(); -				$sub_exp = substr($val[5], strpos($val[5], '(') + 1, -1); -				$extra = false; -				preg_match_all('/\'(?>[^\']++|\'\')*+\'|[\d-.]++/', $sub_exp, $sub_vals, PREG_PATTERN_ORDER); -				$i = 0; -				foreach ($sub_vals[0] as $sub_val) -				{ -					// two things: -					// 1) This determines if an empty string was in the IN clausing, making us turn it into a NULL comparison -					// 2) This fixes the 1000 list limit that Oracle has (ORA-01795) -					if ($sub_val !== "''") -					{ -						$in_clause[(int) $i++/1000][] = $sub_val; -					} -					else -					{ -						$extra = true; -					} -				} -				if (!$extra && $i < 1000) -				{ -					$out .= $val[0]; -				} -				else -				{ -					$out .= ' ' . $val[1] . '('; -					$in_array = array(); - -					// constuct each IN() clause -					foreach ($in_clause as $in_values) -					{ -						$in_array[] = $val[2] . ' ' . (isset($val[6]) ? $val[6] : '') . 'IN(' . implode(', ', $in_values) . ')'; -					} - -					// Join the IN() clauses against a few ORs (IN is just a nicer OR anyway) -					$out .= implode(' OR ', $in_array); - -					// handle the empty string case -					if ($extra) -					{ -						$out .= ' OR ' . $val[2] . ' is ' . (isset($val[6]) ? $val[6] : '') . 'NULL'; -					} -					$out .= ')'; - -					unset($in_array, $in_clause); -				} -			} -		} - -		return $out; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->last_query_text = $query; -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				$in_transaction = false; -				if (!$this->transaction) -				{ -					$this->sql_transaction('begin'); -				} -				else -				{ -					$in_transaction = true; -				} - -				$array = array(); - -				// We overcome Oracle's 4000 char limit by binding vars -				if (strlen($query) > 4000) -				{ -					if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/sU', $query, $regs)) -					{ -						if (strlen($regs[3]) > 4000) -						{ -							$cols = explode(', ', $regs[2]); - -							preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER); - -/*						The code inside this comment block breaks clob handling, but does allow the -						database restore script to work.  If you want to allow no posts longer than 4KB -						and/or need the db restore script, uncomment this. - - -							if (sizeof($cols) !== sizeof($vals)) -							{ -								// Try to replace some common data we know is from our restore script or from other sources -								$regs[3] = str_replace("'||chr(47)||'", '/', $regs[3]); -								$_vals = explode(', ', $regs[3]); - -								$vals = array(); -								$is_in_val = false; -								$i = 0; -								$string = ''; - -								foreach ($_vals as $value) -								{ -									if (strpos($value, "'") === false && !$is_in_val) -									{ -										$vals[$i++] = $value; -										continue; -									} - -									if (substr($value, -1) === "'") -									{ -										$vals[$i] = $string . (($is_in_val) ? ', ' : '') . $value; -										$string = ''; -										$is_in_val = false; - -										if ($vals[$i][0] !== "'") -										{ -											$vals[$i] = "''" . $vals[$i]; -										} -										$i++; -										continue; -									} -									else -									{ -										$string .= (($is_in_val) ? ', ' : '') . $value; -										$is_in_val = true; -									} -								} - -								if ($string) -								{ -									// New value if cols != value -									$vals[(sizeof($cols) !== sizeof($vals)) ? $i : $i - 1] .= $string; -								} - -								$vals = array(0 => $vals); -							} -*/ - -							$inserts = $vals[0]; -							unset($vals); - -							foreach ($inserts as $key => $value) -							{ -								if (!empty($value) && $value[0] === "'" && strlen($value) > 4002) // check to see if this thing is greater than the max + 'x2 -								{ -									$inserts[$key] = ':' . strtoupper($cols[$key]); -									$array[$inserts[$key]] = str_replace("''", "'", substr($value, 1, -1)); -								} -							} - -							$query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')'; -						} -					} -					else if (preg_match_all('/^(UPDATE [\\w_]++\\s+SET )([\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+)(?:,\\s*[\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+)\\s+(WHERE.*)$/s', $query, $data, PREG_SET_ORDER)) -					{ -						if (strlen($data[0][2]) > 4000) -						{ -							$update = $data[0][1]; -							$where = $data[0][3]; -							preg_match_all('/([\\w_]++)\\s*=\\s*(\'(?:[^\']++|\'\')*+\'|[\d-.]++)/', $data[0][2], $temp, PREG_SET_ORDER); -							unset($data); - -							$cols = array(); -							foreach ($temp as $value) -							{ -								if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 4002) // check to see if this thing is greater than the max + 'x2 -								{ -									$cols[] = $value[1] . '=:' . strtoupper($value[1]); -									$array[$value[1]] = str_replace("''", "'", substr($value[2], 1, -1)); -								} -								else -								{ -									$cols[] = $value[1] . '=' . $value[2]; -								} -							} - -							$query = $update . implode(', ', $cols) . ' ' . $where; -							unset($cols); -						} -					} -				} - -				switch (substr($query, 0, 6)) -				{ -					case 'DELETE': -						if (preg_match('/^(DELETE FROM [\w_]++ WHERE)((?:\s*(?:AND|OR)?\s*[\w_]+\s*(?:(?:=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d-.]+)|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]+,? ?)*+\)))*+)$/', $query, $regs)) -						{ -							$query = $regs[1] . $this->_rewrite_where($regs[2]); -							unset($regs); -						} -					break; - -					case 'UPDATE': -						if (preg_match('/^(UPDATE [\\w_]++\\s+SET [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]++|:\w++)(?:, [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]++|:\w++))*+\\s+WHERE)(.*)$/s',  $query, $regs)) -						{ -							$query = $regs[1] . $this->_rewrite_where($regs[2]); -							unset($regs); -						} -					break; - -					case 'SELECT': -						$query = preg_replace_callback('/([\w_.]++)\s*(?:(=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d-.]++|([\w_.]++))|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]++,? ?)*+\))/', array($this, '_rewrite_col_compare'), $query); -					break; -				} - -				$this->query_result = @ociparse($this->db_connect_id, $query); - -				foreach ($array as $key => $value) -				{ -					@ocibindbyname($this->query_result, $key, $array[$key], -1); -				} - -				$success = @ociexecute($this->query_result, OCI_DEFAULT); - -				if (!$success) -				{ -					$this->sql_error($query); -					$this->query_result = false; -				} -				else -				{ -					if (!$in_transaction) -					{ -						$this->sql_transaction('commit'); -					} -				} - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -				else if (strpos($query, 'SELECT') === 0 && $this->query_result) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} - -		return $this->query_result; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		$query = 'SELECT * FROM (SELECT /*+ FIRST_ROWS */ rownum AS xrownum, a.* FROM (' . $query . ') a WHERE rownum <= ' . ($offset + $total) . ') WHERE xrownum >= ' . $offset; - -		return $this->sql_query($query, $cache_ttl); -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		return ($this->query_result) ? @ocirowcount($this->query_result) : false; -	} - -	/** -	* Fetch current row -	*/ -	function sql_fetchrow($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		if ($query_id !== false) -		{ -			$row = array(); -			$result = @ocifetchinto($query_id, $row, OCI_ASSOC + OCI_RETURN_NULLS); - -			if (!$result || !$row) -			{ -				return false; -			} - -			$result_row = array(); -			foreach ($row as $key => $value) -			{ -				// Oracle treats empty strings as null -				if (is_null($value)) -				{ -					$value = ''; -				} - -				// OCI->CLOB? -				if (is_object($value)) -				{ -					$value = $value->load(); -				} - -				$result_row[strtolower($key)] = $value; -			} - -			return $result_row; -		} - -		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 (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_rowseek($rownum, $query_id); -		} - -		if ($query_id === false) -		{ -			return false; -		} - -		// Reset internal pointer -		@ociexecute($query_id, OCI_DEFAULT); - -		// 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; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		$query_id = $this->query_result; - -		if ($query_id !== false && $this->last_query_text != '') -		{ -			if (preg_match('#^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)#is', $this->last_query_text, $tablename)) -			{ -				$query = 'SELECT ' . $tablename[1] . '_seq.currval FROM DUAL'; -				$stmt = @ociparse($this->db_connect_id, $query); -				@ociexecute($stmt, OCI_DEFAULT); - -				$temp_result = @ocifetchinto($stmt, $temp_array, OCI_ASSOC + OCI_RETURN_NULLS); -				@ocifreestatement($stmt); - -				if ($temp_result) -				{ -					return $temp_array['CURRVAL']; -				} -				else -				{ -					return false; -				} -			} -		} - -		return false; -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		if (isset($this->open_queries[(int) $query_id])) -		{ -			unset($this->open_queries[(int) $query_id]); -			return @ocifreestatement($query_id); -		} - -		return false; -	} - -	/** -	* Escape string used in sql query -	*/ -	function sql_escape($msg) -	{ -		return str_replace(array("'", "\0"), array("''", ''), $msg); -	} - -	/** -	* Build LIKE expression -	* @access private -	*/ -	function _sql_like_expression($expression) -	{ -		return $expression . " ESCAPE '\\'"; -	} - -	function _sql_custom_build($stage, $data) -	{ -		return $data; -	} - -	function _sql_bit_and($column_name, $bit, $compare = '') -	{ -		return 'BITAND(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : ''); -	} - -	function _sql_bit_or($column_name, $bit, $compare = '') -	{ -		return 'BITOR(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : ''); -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		if (function_exists('ocierror')) -		{ -			$error = @ocierror(); -			$error = (!$error) ? @ocierror($this->query_result) : $error; -			$error = (!$error) ? @ocierror($this->db_connect_id) : $error; - -			if ($error) -			{ -				$this->last_error_result = $error; -			} -			else -			{ -				$error = (isset($this->last_error_result) && $this->last_error_result) ? $this->last_error_result : array(); -			} -		} -		else -		{ -			$error = array( -				'message'	=> $this->connect_error, -				'code'		=> '', -			); -		} - -		return $error; -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		return @ocilogoff($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		switch ($mode) -		{ -			case 'start': - -				$html_table = false; - -				// Grab a plan table, any will do -				$sql = "SELECT table_name -					FROM USER_TABLES -					WHERE table_name LIKE '%PLAN_TABLE%'"; -				$stmt = ociparse($this->db_connect_id, $sql); -				ociexecute($stmt); -				$result = array(); - -				if (ocifetchinto($stmt, $result, OCI_ASSOC + OCI_RETURN_NULLS)) -				{ -					$table = $result['TABLE_NAME']; - -					// This is the statement_id that will allow us to track the plan -					$statement_id = substr(md5($query), 0, 30); - -					// Remove any stale plans -					$stmt2 = ociparse($this->db_connect_id, "DELETE FROM $table WHERE statement_id='$statement_id'"); -					ociexecute($stmt2); -					ocifreestatement($stmt2); - -					// Explain the plan -					$sql = "EXPLAIN PLAN -						SET STATEMENT_ID = '$statement_id' -						FOR $query"; -					$stmt2 = ociparse($this->db_connect_id, $sql); -					ociexecute($stmt2); -					ocifreestatement($stmt2); - -					// Get the data from the plan -					$sql = "SELECT operation, options, object_name, object_type, cardinality, cost -						FROM plan_table -						START WITH id = 0 AND statement_id = '$statement_id' -						CONNECT BY PRIOR id = parent_id -							AND statement_id = '$statement_id'"; -					$stmt2 = ociparse($this->db_connect_id, $sql); -					ociexecute($stmt2); - -					$row = array(); -					while (ocifetchinto($stmt2, $row, OCI_ASSOC + OCI_RETURN_NULLS)) -					{ -						$html_table = $this->sql_report('add_select_row', $query, $html_table, $row); -					} - -					ocifreestatement($stmt2); - -					// Remove the plan we just made, we delete them on request anyway -					$stmt2 = ociparse($this->db_connect_id, "DELETE FROM $table WHERE statement_id='$statement_id'"); -					ociexecute($stmt2); -					ocifreestatement($stmt2); -				} - -				ocifreestatement($stmt); - -				if ($html_table) -				{ -					$this->html_hold .= '</table>'; -				} - -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @ociparse($this->db_connect_id, $query); -				$success = @ociexecute($result, OCI_DEFAULT); -				$row = array(); - -				while (@ocifetchinto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS)) -				{ -					// Take the time spent on parsing rows into account -				} -				@ocifreestatement($result); - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} -} - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/postgres.php b/phpBB/includes/db/postgres.php deleted file mode 100644 index bb116e0763..0000000000 --- a/phpBB/includes/db/postgres.php +++ /dev/null @@ -1,485 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -if (!class_exists('phpbb_error_collector')) -{ -	include($phpbb_root_path . 'includes/error_collector.' . $phpEx); -} - -/** -* PostgreSQL Database Abstraction Layer -* Minimum Requirement is Version 7.3+ -* @package dbal -*/ -class dbal_postgres extends dbal -{ -	var $last_query_text = ''; -	var $connect_error = ''; - -	/** -	* Connect to server -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) -	{ -		$connect_string = ''; - -		if ($sqluser) -		{ -			$connect_string .= "user=$sqluser "; -		} - -		if ($sqlpassword) -		{ -			$connect_string .= "password=$sqlpassword "; -		} - -		if ($sqlserver) -		{ -			// $sqlserver can carry a port separated by : for compatibility reasons -			// If $sqlserver has more than one : it's probably an IPv6 address. -			// In this case we only allow passing a port via the $port variable. -			if (substr_count($sqlserver, ':') === 1) -			{ -				list($sqlserver, $port) = explode(':', $sqlserver); -			} - -			if ($sqlserver !== 'localhost') -			{ -				$connect_string .= "host=$sqlserver "; -			} - -			if ($port) -			{ -				$connect_string .= "port=$port "; -			} -		} - -		$schema = ''; - -		if ($database) -		{ -			$this->dbname = $database; -			if (strpos($database, '.') !== false) -			{ -				list($database, $schema) = explode('.', $database); -			} -			$connect_string .= "dbname=$database"; -		} - -		$this->persistency = $persistency; - -		if ($this->persistency) -		{ -			if (!function_exists('pg_pconnect')) -			{ -				$this->connect_error = 'pg_pconnect function does not exist, is pgsql extension installed?'; -				return $this->sql_error(''); -			} -			$collector = new phpbb_error_collector; -			$collector->install(); -			$this->db_connect_id = (!$new_link) ? @pg_pconnect($connect_string) : @pg_pconnect($connect_string, PGSQL_CONNECT_FORCE_NEW); -		} -		else -		{ -			if (!function_exists('pg_connect')) -			{ -				$this->connect_error = 'pg_connect function does not exist, is pgsql extension installed?'; -				return $this->sql_error(''); -			} -			$collector = new phpbb_error_collector; -			$collector->install(); -			$this->db_connect_id = (!$new_link) ? @pg_connect($connect_string) : @pg_connect($connect_string, PGSQL_CONNECT_FORCE_NEW); -		} - -		$collector->uninstall(); - -		if ($this->db_connect_id) -		{ -			if (version_compare($this->sql_server_info(true), '8.2', '>=')) -			{ -				$this->multi_insert = true; -			} - -			if ($schema !== '') -			{ -				@pg_query($this->db_connect_id, 'SET search_path TO ' . $schema); -			} -			return $this->db_connect_id; -		} - -		$this->connect_error = $collector->format_errors(); -		return $this->sql_error(''); -	} - -	/** -	* Version information about used database -	* @param bool $raw if true, only return the fetched sql_server_version -	* @param bool $use_cache If true, it is safe to retrieve the value from the cache -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		global $cache; - -		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('pgsql_version')) === false) -		{ -			$query_id = @pg_query($this->db_connect_id, 'SELECT VERSION() AS version'); -			$row = @pg_fetch_assoc($query_id, null); -			@pg_free_result($query_id); - -			$this->sql_server_version = (!empty($row['version'])) ? trim(substr($row['version'], 10)) : 0; - -			if (!empty($cache) && $use_cache) -			{ -				$cache->put('pgsql_version', $this->sql_server_version); -			} -		} - -		return ($raw) ? $this->sql_server_version : 'PostgreSQL ' . $this->sql_server_version; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return @pg_query($this->db_connect_id, 'BEGIN'); -			break; - -			case 'commit': -				return @pg_query($this->db_connect_id, 'COMMIT'); -			break; - -			case 'rollback': -				return @pg_query($this->db_connect_id, 'ROLLBACK'); -			break; -		} - -		return true; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->last_query_text = $query; -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				if (($this->query_result = @pg_query($this->db_connect_id, $query)) === false) -				{ -					$this->sql_error($query); -				} - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -				else if (strpos($query, 'SELECT') === 0 && $this->query_result) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} - -		return $this->query_result; -	} - -	/** -	* Build db-specific query data -	* @access private -	*/ -	function _sql_custom_build($stage, $data) -	{ -		return $data; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		// if $total is set to 0 we do not want to limit the number of rows -		if ($total == 0) -		{ -			$total = 'ALL'; -		} - -		$query .= "\n LIMIT $total OFFSET $offset"; - -		return $this->sql_query($query, $cache_ttl); -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		return ($this->query_result) ? @pg_affected_rows($this->query_result) : false; -	} - -	/** -	* Fetch current row -	*/ -	function sql_fetchrow($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		return ($query_id !== false) ? @pg_fetch_assoc($query_id, null) : 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 (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_rowseek($rownum, $query_id); -		} - -		return ($query_id !== false) ? @pg_result_seek($query_id, $rownum) : false; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		$query_id = $this->query_result; - -		if ($query_id !== false && $this->last_query_text != '') -		{ -			if (preg_match("/^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)/is", $this->last_query_text, $tablename)) -			{ -				$query = "SELECT currval('" . $tablename[1] . "_seq') AS last_value"; -				$temp_q_id = @pg_query($this->db_connect_id, $query); - -				if (!$temp_q_id) -				{ -					return false; -				} - -				$temp_result = @pg_fetch_assoc($temp_q_id, NULL); -				@pg_free_result($query_id); - -				return ($temp_result) ? $temp_result['last_value'] : false; -			} -		} - -		return false; -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		if (isset($this->open_queries[(int) $query_id])) -		{ -			unset($this->open_queries[(int) $query_id]); -			return @pg_free_result($query_id); -		} - -		return false; -	} - -	/** -	* Escape string used in sql query -	* Note: Do not use for bytea values if we may use them at a later stage -	*/ -	function sql_escape($msg) -	{ -		return @pg_escape_string($msg); -	} - -	/** -	* Build LIKE expression -	* @access private -	*/ -	function _sql_like_expression($expression) -	{ -		return $expression; -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		// pg_last_error only works when there is an established connection. -		// Connection errors have to be tracked by us manually. -		if ($this->db_connect_id) -		{ -			$message = @pg_last_error($this->db_connect_id); -		} -		else -		{ -			$message = $this->connect_error; -		} - -		return array( -			'message'	=> $message, -			'code'		=> '' -		); -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		return @pg_close($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		switch ($mode) -		{ -			case 'start': - -				$explain_query = $query; -				if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m)) -				{ -					$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2]; -				} -				else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m)) -				{ -					$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2]; -				} - -				if (preg_match('/^SELECT/', $explain_query)) -				{ -					$html_table = false; - -					if ($result = @pg_query($this->db_connect_id, "EXPLAIN $explain_query")) -					{ -						while ($row = @pg_fetch_assoc($result, NULL)) -						{ -							$html_table = $this->sql_report('add_select_row', $query, $html_table, $row); -						} -					} -					@pg_free_result($result); - -					if ($html_table) -					{ -						$this->html_hold .= '</table>'; -					} -				} - -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @pg_query($this->db_connect_id, $query); -				while ($void = @pg_fetch_assoc($result, NULL)) -				{ -					// Take the time spent on parsing rows into account -				} -				@pg_free_result($result); - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} -} - -?>
\ No newline at end of file diff --git a/phpBB/includes/db/sqlite.php b/phpBB/includes/db/sqlite.php deleted file mode 100644 index 557b057cce..0000000000 --- a/phpBB/includes/db/sqlite.php +++ /dev/null @@ -1,370 +0,0 @@ -<?php -/** -* -* @package dbal -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ -	exit; -} - -include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); - -/** -* Sqlite Database Abstraction Layer -* Minimum Requirement: 2.8.2+ -* @package dbal -*/ -class dbal_sqlite extends dbal -{ -	var $connect_error = ''; - -	/** -	* Connect to server -	*/ -	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) -	{ -		$this->persistency = $persistency; -		$this->user = $sqluser; -		$this->server = $sqlserver . (($port) ? ':' . $port : ''); -		$this->dbname = $database; - -		$error = ''; -		if ($this->persistency) -		{ -			if (!function_exists('sqlite_popen')) -			{ -				$this->connect_error = 'sqlite_popen function does not exist, is sqlite extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @sqlite_popen($this->server, 0666, $error); -		} -		else -		{ -			if (!function_exists('sqlite_open')) -			{ -				$this->connect_error = 'sqlite_open function does not exist, is sqlite extension installed?'; -				return $this->sql_error(''); -			} -			$this->db_connect_id = @sqlite_open($this->server, 0666, $error); -		} - -		if ($this->db_connect_id) -		{ -			@sqlite_query('PRAGMA short_column_names = 1', $this->db_connect_id); -//			@sqlite_query('PRAGMA encoding = "UTF-8"', $this->db_connect_id); -		} - -		return ($this->db_connect_id) ? true : array('message' => $error); -	} - -	/** -	* Version information about used database -	* @param bool $raw if true, only return the fetched sql_server_version -	* @param bool $use_cache if true, it is safe to retrieve the stored value from the cache -	* @return string sql server version -	*/ -	function sql_server_info($raw = false, $use_cache = true) -	{ -		global $cache; - -		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false) -		{ -			$result = @sqlite_query('SELECT sqlite_version() AS version', $this->db_connect_id); -			$row = @sqlite_fetch_array($result, SQLITE_ASSOC); - -			$this->sql_server_version = (!empty($row['version'])) ? $row['version'] : 0; - -			if (!empty($cache) && $use_cache) -			{ -				$cache->put('sqlite_version', $this->sql_server_version); -			} -		} - -		return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version; -	} - -	/** -	* SQL Transaction -	* @access private -	*/ -	function _sql_transaction($status = 'begin') -	{ -		switch ($status) -		{ -			case 'begin': -				return @sqlite_query('BEGIN', $this->db_connect_id); -			break; - -			case 'commit': -				return @sqlite_query('COMMIT', $this->db_connect_id); -			break; - -			case 'rollback': -				return @sqlite_query('ROLLBACK', $this->db_connect_id); -			break; -		} - -		return true; -	} - -	/** -	* Base query method -	* -	* @param	string	$query		Contains the SQL query which shall be executed -	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache -	* @return	mixed				When casted to bool the returned value returns true on success and false on failure -	* -	* @access	public -	*/ -	function sql_query($query = '', $cache_ttl = 0) -	{ -		if ($query != '') -		{ -			global $cache; - -			// EXPLAIN only in extra debug mode -			if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('start', $query); -			} - -			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false; -			$this->sql_add_num_queries($this->query_result); - -			if ($this->query_result === false) -			{ -				if (($this->query_result = @sqlite_query($query, $this->db_connect_id)) === false) -				{ -					$this->sql_error($query); -				} - -				if (defined('DEBUG_EXTRA')) -				{ -					$this->sql_report('stop', $query); -				} - -				if ($cache_ttl && method_exists($cache, 'sql_save')) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -					$cache->sql_save($query, $this->query_result, $cache_ttl); -				} -				else if (strpos($query, 'SELECT') === 0 && $this->query_result) -				{ -					$this->open_queries[(int) $this->query_result] = $this->query_result; -				} -			} -			else if (defined('DEBUG_EXTRA')) -			{ -				$this->sql_report('fromcache', $query); -			} -		} -		else -		{ -			return false; -		} - -		return $this->query_result; -	} - -	/** -	* Build LIMIT query -	*/ -	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) -	{ -		$this->query_result = false; - -		// if $total is set to 0 we do not want to limit the number of rows -		if ($total == 0) -		{ -			$total = -1; -		} - -		$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); - -		return $this->sql_query($query, $cache_ttl); -	} - -	/** -	* Return number of affected rows -	*/ -	function sql_affectedrows() -	{ -		return ($this->db_connect_id) ? @sqlite_changes($this->db_connect_id) : false; -	} - -	/** -	* Fetch current row -	*/ -	function sql_fetchrow($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_fetchrow($query_id); -		} - -		return ($query_id !== false) ? @sqlite_fetch_array($query_id, SQLITE_ASSOC) : 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 (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_rowseek($rownum, $query_id); -		} - -		return ($query_id !== false) ? @sqlite_seek($query_id, $rownum) : false; -	} - -	/** -	* Get last inserted id after insert statement -	*/ -	function sql_nextid() -	{ -		return ($this->db_connect_id) ? @sqlite_last_insert_rowid($this->db_connect_id) : false; -	} - -	/** -	* Free sql result -	*/ -	function sql_freeresult($query_id = false) -	{ -		global $cache; - -		if ($query_id === false) -		{ -			$query_id = $this->query_result; -		} - -		if (isset($cache->sql_rowset[$query_id])) -		{ -			return $cache->sql_freeresult($query_id); -		} - -		return true; -	} - -	/** -	* Escape string used in sql query -	*/ -	function sql_escape($msg) -	{ -		return @sqlite_escape_string($msg); -	} - -	/** -	* Correctly adjust LIKE expression for special characters -	* For SQLite an underscore is a not-known character... this may change with SQLite3 -	*/ -	function sql_like_expression($expression) -	{ -		// Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it! -		// We only catch * and ? here, not the character map possible on file globbing. -		$expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression); - -		$expression = str_replace(array('?', '*'), array("\?", "\*"), $expression); -		$expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression); - -		return 'GLOB \'' . $this->sql_escape($expression) . '\''; -	} - -	/** -	* return sql error array -	* @access private -	*/ -	function _sql_error() -	{ -		if (function_exists('sqlite_error_string')) -		{ -			$error = array( -				'message'	=> @sqlite_error_string(@sqlite_last_error($this->db_connect_id)), -				'code'		=> @sqlite_last_error($this->db_connect_id), -			); -		} -		else -		{ -			$error = array( -				'message'	=> $this->connect_error, -				'code'		=> '', -			); -		} - -		return $error; -	} - -	/** -	* Build db-specific query data -	* @access private -	*/ -	function _sql_custom_build($stage, $data) -	{ -		return $data; -	} - -	/** -	* Close sql connection -	* @access private -	*/ -	function _sql_close() -	{ -		return @sqlite_close($this->db_connect_id); -	} - -	/** -	* Build db-specific report -	* @access private -	*/ -	function _sql_report($mode, $query = '') -	{ -		switch ($mode) -		{ -			case 'start': -			break; - -			case 'fromcache': -				$endtime = explode(' ', microtime()); -				$endtime = $endtime[0] + $endtime[1]; - -				$result = @sqlite_query($query, $this->db_connect_id); -				while ($void = @sqlite_fetch_array($result, SQLITE_ASSOC)) -				{ -					// Take the time spent on parsing rows into account -				} - -				$splittime = explode(' ', microtime()); -				$splittime = $splittime[0] + $splittime[1]; - -				$this->sql_report('record_fromcache', $query, $endtime, $splittime); - -			break; -		} -	} -} - -?>
\ No newline at end of file | 
