diff options
Diffstat (limited to 'phpBB/includes/db')
| -rw-r--r-- | phpBB/includes/db/db_tools.php | 199 | ||||
| -rw-r--r-- | phpBB/includes/db/dbal.php | 2 | ||||
| -rw-r--r-- | phpBB/includes/db/mssqlnative.php | 2 | ||||
| -rw-r--r-- | phpBB/includes/db/mysqli.php | 35 | 
4 files changed, 152 insertions, 86 deletions
| diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index 50e308dea2..2cba11133a 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -348,6 +348,66 @@ class phpbb_db_tools  	}  	/** +	* 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  	*  	* @@ -649,6 +709,23 @@ class phpbb_db_tools  			$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']))  		{ @@ -994,34 +1071,21 @@ class phpbb_db_tools  	}  	/** -	* Check if a specified column exist +	* Gets a list of columns of a table.  	* -	* @param string	$table			Table to check the column at -	* @param string	$column_name	The column to check +	* @param string $table		Table name  	* -	* @return bool True if column exists, else false +	* @return array				Array of column names (all lower case)  	*/ -	function sql_column_exists($table, $column_name) +	function sql_list_columns($table)  	{ +		$columns = array(); +  		switch ($this->sql_layer)  		{  			case 'mysql_40':  			case 'mysql_41': -  				$sql = "SHOW COLUMNS FROM $table"; -				$result = $this->db->sql_query($sql); - -				while ($row = $this->db->sql_fetchrow($result)) -				{ -					// lower case just in case -					if (strtolower($row['Field']) == $column_name) -					{ -						$this->db->sql_freeresult($result); -						return true; -					} -				} -				$this->db->sql_freeresult($result); -				return false;  			break;  			// PostgreSQL has a way of doing this in a much simpler way but would @@ -1032,19 +1096,6 @@ class phpbb_db_tools  					WHERE c.relname = '{$table}'  						AND a.attnum > 0  						AND a.attrelid = c.oid"; -				$result = $this->db->sql_query($sql); -				while ($row = $this->db->sql_fetchrow($result)) -				{ -					// lower case just in case -					if (strtolower($row['attname']) == $column_name) -					{ -						$this->db->sql_freeresult($result); -						return true; -					} -				} -				$this->db->sql_freeresult($result); - -				return false;  			break;  			// same deal with PostgreSQL, we must perform more complex operations than @@ -1055,62 +1106,26 @@ class phpbb_db_tools  					FROM syscolumns c  					LEFT JOIN sysobjects o ON c.id = o.id  					WHERE o.name = '{$table}'"; -				$result = $this->db->sql_query($sql); -				while ($row = $this->db->sql_fetchrow($result)) -				{ -					// lower case just in case -					if (strtolower($row['name']) == $column_name) -					{ -						$this->db->sql_freeresult($result); -						return true; -					} -				} -				$this->db->sql_freeresult($result); -				return false;  			break;  			case 'oracle':  				$sql = "SELECT column_name  					FROM user_tab_columns  					WHERE LOWER(table_name) = '" . strtolower($table) . "'"; -				$result = $this->db->sql_query($sql); -				while ($row = $this->db->sql_fetchrow($result)) -				{ -					// lower case just in case -					if (strtolower($row['column_name']) == $column_name) -					{ -						$this->db->sql_freeresult($result); -						return true; -					} -				} -				$this->db->sql_freeresult($result); -				return false;  			break;  			case 'firebird':  				$sql = "SELECT RDB\$FIELD_NAME as FNAME  					FROM RDB\$RELATION_FIELDS  					WHERE RDB\$RELATION_NAME = '" . strtoupper($table) . "'"; -				$result = $this->db->sql_query($sql); -				while ($row = $this->db->sql_fetchrow($result)) -				{ -					// lower case just in case -					if (strtolower($row['fname']) == $column_name) -					{ -						$this->db->sql_freeresult($result); -						return true; -					} -				} -				$this->db->sql_freeresult($result); -				return false;  			break; -			// ugh, SQLite  			case 'sqlite':  				$sql = "SELECT sql  					FROM sqlite_master  					WHERE type = 'table'  						AND name = '{$table}'"; +  				$result = $this->db->sql_query($sql);  				if (!$result) @@ -1134,14 +1149,39 @@ class phpbb_db_tools  						continue;  					} -					if (strtolower($entities[0]) == $column_name) -					{ -						return true; -					} +					$column = strtolower($entities[0]); +					$columns[$column] = $column;  				} -				return false; + +				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]);  	}  	/** @@ -1788,7 +1828,7 @@ class phpbb_db_tools  			break;  			case 'oracle': -				$statements[] = 'ALTER TABLE ' . $table_name . ' DROP ' . $column_name; +				$statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;  			break;  			case 'postgres': @@ -1939,6 +1979,7 @@ class phpbb_db_tools  					$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... @@ -2059,7 +2100,7 @@ class phpbb_db_tools  		$table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config)  		if (strlen($table_name . $index_name) - strlen($table_prefix) > 24)  		{ -			$max_length = $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);  		} @@ -2074,7 +2115,7 @@ class phpbb_db_tools  			case 'mysql_40':  			case 'mysql_41': -				$statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; +				$statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX (' . implode(', ', $column) . ')';  			break;  			case 'mssql': @@ -2096,7 +2137,7 @@ class phpbb_db_tools  		$table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config)  		if (strlen($table_name . $index_name) - strlen($table_prefix) > 24)  		{ -			$max_length = $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);  		} @@ -2127,7 +2168,7 @@ class phpbb_db_tools  				}  			// no break  			case 'mysql_41': -				$statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; +				$statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . '(' . implode(', ', $column) . ')';  			break;  			case 'mssql': diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 9b45c085a2..b4c1a72e1c 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -609,7 +609,7 @@ class dbal  					}  				} -				$sql .= $this->_sql_custom_build('FROM', implode(', ', $table_array)); +				$sql .= $this->_sql_custom_build('FROM', implode(' CROSS JOIN ', $table_array));  				if (!empty($array['LEFT_JOIN']))  				{ diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 6810562d17..7fbc374e77 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -396,7 +396,7 @@ class dbal_mssqlnative extends dbal  	*/  	function sql_affectedrows()  	{ -		return ($this->db_connect_id) ? @sqlsrv_rows_affected($this->db_connect_id) : false; +		return (!empty($this->query_result)) ? @sqlsrv_rows_affected($this->query_result) : false;  	}  	/** diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php index 862d62f4ba..456ce906d0 100644 --- a/phpBB/includes/db/mysqli.php +++ b/phpBB/includes/db/mysqli.php @@ -33,14 +33,33 @@ class dbal_mysqli extends dbal  	*/  	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false , $new_link = false)  	{ -		$this->persistency = $persistency; +		// Mysqli extension supports persistent connection since PHP 5.3.0 +		$this->persistency = (version_compare(PHP_VERSION, '5.3.0', '>=')) ? $persistency : false;  		$this->user = $sqluser; -		$this->server = $sqlserver; + +		// 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; -		// Persistant connections not supported by the mysqli extension? -		$this->db_connect_id = @mysqli_connect($this->server, $this->user, $sqlpassword, $this->dbname, $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 != '')  		{ @@ -230,7 +249,13 @@ class dbal_mysqli extends dbal  			return $cache->sql_fetchrow($query_id);  		} -		return ($query_id !== false) ? @mysqli_fetch_assoc($query_id) : false; +		if ($query_id !== false) +		{ +			$result = @mysqli_fetch_assoc($query_id); +			return $result !== null ? $result : false; +		} + +		return false;  	}  	/** | 
