New config variables. $wgSharedPrefix and $wgSharedTables.
authorDaniel Friesen <dantman@users.mediawiki.org>
Wed, 7 May 2008 04:44:04 +0000 (04:44 +0000)
committerDaniel Friesen <dantman@users.mediawiki.org>
Wed, 7 May 2008 04:44:04 +0000 (04:44 +0000)
This is a complete rewrite of Database::tableName.
The new tableName also has no PHP errors, and outputs a cleanly quoted table name 100% of the time.
This should solve bug 2396

RELEASE-NOTES
includes/Database.php
includes/DefaultSettings.php

index 8fe6912..a00c721 100644 (file)
@@ -33,6 +33,11 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * Removed the emailconfirmed implicit group by default. To re-add it, use:
     $wgAutopromote['emailconfirmed'] = APCOND_EMAILCONFIRMED;
   in your LocalSettings.php.
+* (bug 2396) New shared database configuration variables. $wgSharedPrefix allows
+  you to use a shared database with a different prefix. Or you can now use a local
+  database and use prefixes to separate wiki and the shared tables. And the new
+  $wgSharedTables variable allows you to specify a list of tables to share.
+  
 
 === New features in 1.13 ===
 
index 1f19226..9b79ad6 100644 (file)
@@ -1355,30 +1355,55 @@ class Database {
        /**
         * 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;
+               
+               # Split database and table into proper variables.
+               # We reverse the explode so that database.table and table both output
+               # the correct table.
+               @list( $table, $database ) = array_reverse( explode( '.', $name, 2 ) );
+               $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 23c9f5c..32e9906 100644 (file)
@@ -579,12 +579,20 @@ $wgCheckDBSchema = true;
 
 
 /**
- * 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 = $wgDBprefix;
+$wgSharedTables = array( 'user' );
 
 /**
  * Database load balancer