Abstract tableName() by adding new function isQuotedIdentifier() to databases.
authorPlatonides <platonides@users.mediawiki.org>
Tue, 12 Apr 2011 16:34:12 +0000 (16:34 +0000)
committerPlatonides <platonides@users.mediawiki.org>
Tue, 12 Apr 2011 16:34:12 +0000 (16:34 +0000)
This fixes bug in DatabaseOracle.php tableName() on line 671 and allows it to call
the parent implementation instead of copying it with different quotes.
Adapt Mssql addIdentifierQuotes(). Replace its addIdentifierQuotes calls with addQuotes
as it's what it really is. The serialize() is probably unneeded, since I don't think it will
ever be called with objects but I kept it anyway.

includes/db/Database.php
includes/db/DatabaseMssql.php
includes/db/DatabaseMysql.php
includes/db/DatabaseOracle.php
includes/db/DatabaseSqlite.php

index f6f9bb3..3a5da57 100644 (file)
@@ -1521,7 +1521,7 @@ abstract class DatabaseBase implements DatabaseType {
                # 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 ) == '`' ) {
+               if ( $this->isQuotedIdentifier( $name ) ) {
                        return $name;
                }
 
@@ -1550,14 +1550,14 @@ abstract class DatabaseBase implements DatabaseType {
                # 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}`" );
+                       $table = ( $this->isQuotedIdentifier( $table ) ? $table : $this->addIdentifierQuotes( $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`'
+                && !$this->isQuotedIdentifier( $table ) # Paranoia check to prevent shared tables listing '`table`'
                 && isset( $wgSharedTables )
                 && is_array( $wgSharedTables )
                 && in_array( $table, $wgSharedTables ) ) { # A shared table is selected
@@ -1567,9 +1567,9 @@ abstract class DatabaseBase implements DatabaseType {
 
                # Quote the $database and $table and apply the prefix if not quoted.
                if ( isset( $database ) ) {
-                       $database = ( $database[0] == '`' ? $database : "`{$database}`" );
+                       $database = ( $this->isQuotedIdentifier( $database ) ? $database : $this->addIdentifierQuotes( $database ) );
                }
-               $table = ( $table[0] == '`' ? $table : "`{$prefix}{$table}`" );
+               $table = ( $this->isQuotedIdentifier( $table ) ? $table : $this->addIdentifierQuotes( "{$prefix}{$table}" ) );
 
                # Merge our database and table into our final table name.
                $tableName = ( isset( $database ) ? "{$database}.{$table}" : "{$table}" );
@@ -1746,6 +1746,15 @@ abstract class DatabaseBase implements DatabaseType {
                return '"' . str_replace( '"', '""', $s ) . '"';
        }
 
+       /**
+        * Returns if the given identifier looks quoted or not according to 
+        * the database convention for quoting identifiers .
+        * @return boolean
+        */
+       public function isQuotedIdentifier( $name ) {
+               return $name[0] == '"' && substr( $name, -1, 1 ) == '"';
+       }
+
        /**
         * Backwards compatibility, identifier quoting originated in DatabasePostgres
         * which used quote_ident which does not follow our naming conventions
index 015f5a0..e1f265b 100644 (file)
@@ -452,14 +452,14 @@ class DatabaseMssql extends DatabaseBase {
                                        $sql .= ',';
                                }
                                if ( is_string( $value ) ) {
-                                       $sql .= $this->addIdentifierQuotes( $value );
+                                       $sql .= $this->addQuotes( $value );
                                } elseif ( is_null( $value ) ) {
                                        $sql .= 'null';
                                } elseif ( is_array( $value ) || is_object( $value ) ) {
                                        if ( is_object( $value ) && strtolower( get_class( $value ) ) == 'blob' ) {
-                                               $sql .= $this->addIdentifierQuotes( $value->fetch() );
+                                               $sql .= $this->addQuotes( $value );
                                        }  else {
-                                               $sql .= $this->addIdentifierQuotes( serialize( $value ) );
+                                               $sql .= $this->addQuotes( serialize( $value ) );
                                        }
                                } else {
                                        $sql .= $value;
@@ -989,6 +989,15 @@ class DatabaseMssql extends DatabaseBase {
                }
        }
 
+       public function addIdentifierQuotes( $s ) {
+               // http://msdn.microsoft.com/en-us/library/aa223962.aspx
+               return '[' . $s . ']';
+       }
+
+       public function isQuotedIdentifier( $name ) {
+               return $name[0] == '[' && substr( $name, -1, 1 ) == ']';
+       }
+
        function selectDB( $db ) {
                return ( $this->query( "SET DATABASE $db" ) !== false );
        }
index 25c360d..1289e88 100644 (file)
@@ -329,6 +329,10 @@ class DatabaseMysql extends DatabaseBase {
                return "`" . $this->strencode( $s ) . "`";
        }
 
+       public function isQuotedIdentifier( $name ) {
+               return $name[0] == '`' && substr( $name, -1, 1 ) == '`';
+       }
+
        function ping() {
                $ping = mysql_ping( $this->mConn );
                if ( $ping ) {
index 41faf19..7113d1b 100644 (file)
@@ -648,46 +648,7 @@ class DatabaseOracle extends DatabaseBase {
                                break;
                }
 
-               /*
-                       The rest of procedure is equal to generic Databse class
-                       except for the quoting style
-               */
-               if ( $name[0] == '"' && substr( $name, - 1, 1 ) == '"' ) {
-                       return $name;
-               }
-               if ( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) {
-                       return $name;
-               }
-               $dbDetails = array_reverse( explode( '.', $name, 2 ) );
-               if ( isset( $dbDetails[1] ) ) {
-                       @list( $table, $database ) = $dbDetails;
-               } else {
-                       @list( $table ) = $dbDetails;
-               }
-
-               $prefix = $this->mTablePrefix;
-
-               if ( isset( $database ) ) {
-                       $table = ( $table[0] == '`' ? $table : "`{$table}`" );
-               }
-
-               if ( !isset( $database ) && isset( $wgSharedDB ) && $table[0] != '"'
-                       && isset( $wgSharedTables )
-                       && is_array( $wgSharedTables )
-                       && in_array( $table, $wgSharedTables )
-               ) {
-                       $database = $wgSharedDB;
-                       $prefix   = isset( $wgSharedPrefix ) ? $wgSharedPrefix : $prefix;
-               }
-
-               if ( isset( $database ) ) {
-                       $database = ( $database[0] == '"' ? $database : "\"{$database}\"" );
-               }
-               $table = ( $table[0] == '"') ? $table : "\"{$prefix}{$table}\"" ;
-
-               $tableName = ( isset( $database ) ? "{$database}.{$table}" : "{$table}" );
-
-               return strtoupper( $tableName );
+               return parent::tableName( strtoupper( $name ) );
        }
 
        /**
index e7bc31e..654376a 100644 (file)
@@ -257,7 +257,7 @@ class DatabaseSqlite extends DatabaseBase {
        function tableName( $name ) {
                // table names starting with sqlite_ are reserved
                if ( strpos( $name, 'sqlite_' ) === 0 ) return $name;
-               return str_replace( '`', '', parent::tableName( $name ) );
+               return str_replace( '"', '', parent::tableName( $name ) );
        }
 
        /**