Shared Tables in 1.12

From Wiki-Tools

Jump to: navigation, search
edit infoboxShared Tables in 1.12
Author: Dantman
Description: Enables $wgSharedPrefix and $wgSharedTables in MediaWiki 1.12.
License: GPLv2+

As you can see in r34353 of MediaWiki there is are two new variables $wgSharedPrefix and $wgSharedTables for using a shared prefix, and specifying what tables are affected by $wgSharedDB.

This patch below can be used to add these variables to MediaWiki 1.12 if you need it to.

[edit] Patch

Index: includes/Database.php
===================================================================
--- includes/Database.php	(revision 36800)
+++ includes/Database.php	(working copy)
@@ -1605,30 +1605,66 @@
 	/**
 	 * Format a table name ready for use in constructing an SQL query
 	 *
-	 * This does two important things: it quotes table names which as necessary,
-	 * and it adds a table prefix if there is one.
+	 * This does two important things: it quotes the table names to clean them up,
+	 * and it adds a table prefix if only given a table name with no quotes.
 	 *
 	 * All functions of this object which require a table name call this function
 	 * themselves. Pass the canonical name to such functions. This is only needed
 	 * when calling query() directly.
 	 *
 	 * @param string $name database table name
+	 * @return string full database name
 	 */
 	function tableName( $name ) {
-		global $wgSharedDB;
-		# Skip quoted literals
-		if ( $name{0} != '`' ) {
-			if ( $this->mTablePrefix !== '' &&  strpos( $name, '.' ) === false ) {
-				$name = "{$this->mTablePrefix}$name";
-			}
-			if ( isset( $wgSharedDB ) && "{$this->mTablePrefix}user" == $name ) {
-				$name = "`$wgSharedDB`.`$name`";
-			} else {
-				# Standard quoting
-				$name = "`$name`";
-			}
+		global $wgSharedDB, $wgSharedPrefix, $wgSharedTables;
+		# Skip the entire process when we have a string quoted on both ends.
+		# Note that we check the end so that we will still quote any use of
+		# use of `database`.table. But won't break things if someone wants
+		# to query a database table with a dot in the name.
+		if ( $name[0] == '`' && substr( $name, -1, 1 ) == '`' ) return $name;
+		
+		# Lets test for any bits of text that should never show up in a table
+		# name. Basically anything like JOIN or ON which are actually part of
+		# SQL queries, but may end up inside of the table value to combine
+		# sql. Such as how the API is doing.
+		# Note that we use a whitespace test rather than a \b test to avoid
+		# any remote case where a word like on may be inside of a table name
+		# surrounded by symbols which may be considered word breaks.
+		if( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) return $name;
+		
+		# Split database and table into proper variables.
+		# We reverse the explode so that database.table and table both output
+		# the correct table.
+		$dbDetails = array_reverse( explode( '.', $name, 2 ) );
+		if( isset( $dbDetails[1] ) ) @list( $table, $database ) = $dbDetails;
+		else                         @list( $table ) = $dbDetails;
+		$prefix = $this->mTablePrefix; # Default prefix
+		
+		# A database name has been specified in input. Quote the table name
+		# because we don't want any prefixes added.
+		if( isset($database) ) $table = ( $table[0] == '`' ? $table : "`{$table}`" );
+		
+		# Note that we use the long format because php will complain in in_array if
+		# the input is not an array, and will complain in is_array if it is not set.
+		if( !isset( $database ) # Don't use shared database if pre selected.
+		 && isset( $wgSharedDB ) # We have a shared database
+		 && $table[0] != '`' # Paranoia check to prevent shared tables listing '`table`'
+		 && isset( $wgSharedTables )
+		 && is_array( $wgSharedTables )
+		 && in_array( $table, $wgSharedTables ) ) { # A shared table is selected
+			$database = $wgSharedDB;
+			$prefix   = isset( $wgSharedPrefix ) ? $wgSharedPrefix : $prefix;
 		}
-		return $name;
+		
+		# Quote the $database and $table and apply the prefix if not quoted.
+		if( isset($database) ) $database = ( $database[0] == '`' ? $database : "`{$database}`" );
+		$table = ( $table[0] == '`' ? $table : "`{$prefix}{$table}`" );
+		
+		# Merge our database and table into our final table name.
+		$tableName = ( isset($database) ? "{$database}.{$table}" : "{$table}" );
+		
+		# We're finished, return.
+		return $tableName;
 	}
 
 	/**
Index: includes/DefaultSettings.php
===================================================================
--- includes/DefaultSettings.php	(revision 36800)
+++ includes/DefaultSettings.php	(working copy)
@@ -578,12 +578,20 @@
 
 
 /**
- * Shared database for multiple wikis. Presently used for storing a user table
+ * Shared database for multiple wikis. Commonly used for storing a user table
  * for single sign-on. The server for this database must be the same as for the
  * main database.
+ * For backwards compatibility the shared prefix is set to the same as the local
+ * prefix, and the user table is listed in the default list of shared tables.
+ *
+ * $wgSharedTables may be customized with a list of tables to share in the shared
+ * datbase. However it is advised to limit what tables you do share as many of
+ * MediaWiki's tables may have side effects if you try to share them.
  * EXPERIMENTAL
  */
-$wgSharedDB = null;
+$wgSharedDB     = null;
+$wgSharedPrefix = false; # Defaults to $wgDBprefix
+$wgSharedTables = array( 'user' );
 
 # Database load balancer
 # This is a two-dimensional array, an array of server info structures
Index: includes/Setup.php
===================================================================
--- includes/Setup.php	(revision 36800)
+++ includes/Setup.php	(working copy)
@@ -187,10 +187,15 @@
 wfProfileOut( $fname.'-memcached' );
 wfProfileIn( $fname.'-SetupSession' );
 
-if ( $wgDBprefix ) {
+# Set default shared prefix
+if( $wgSharedPrefix === false ) $wgSharedPrefix = $wgDBprefix;
+
+if ( in_array('user', $wgSharedTables) && $wgSharedDB && $wgSharedPrefix ) {
+	$wgCookiePrefix = $wgSharedDB . '_' . $wgSharedPrefix;
+} elseif ( in_array('user', $wgSharedTables) && $wgSharedDB ) {
+	$wgCookiePrefix = $wgSharedDB;
+} elseif ( $wgDBprefix ) {
 	$wgCookiePrefix = $wgDBname . '_' . $wgDBprefix;
-} elseif ( $wgSharedDB ) {
-	$wgCookiePrefix = $wgSharedDB;
 } else {
 	$wgCookiePrefix = $wgDBname;
 }
Index: maintenance/updaters.inc
===================================================================
--- maintenance/updaters.inc	(revision 36800)
+++ maintenance/updaters.inc	(working copy)
@@ -979,11 +979,11 @@
 }
 
 function do_all_updates( $shared = false, $purge = true ) {
-	global $wgNewTables, $wgNewFields, $wgRenamedTables, $wgSharedDB, $wgDatabase, $wgDBtype, $IP;
+	global $wgNewTables, $wgNewFields, $wgRenamedTables, $wgSharedDB, $wgSharedTables, $wgDatabase, $wgDBtype, $IP;
 
 	wfRunHooks('LoadExtensionSchemaUpdates');
 
-	$doUser = !$wgSharedDB || $shared;
+	$doUser = $shared ? $wgSharedDB && in_array('user', $wgSharedTables) : !$wgSharedDB || !in_array('user', $wgSharedTables);
 
 	if ($wgDBtype === 'postgres') {
 		do_postgres_updates();
Personal tools
Nadir Point Network