Change the duplicateTableStructure() to use the original names.
authorPlatonides <platonides@users.mediawiki.org>
Tue, 12 Apr 2011 18:54:51 +0000 (18:54 +0000)
committerPlatonides <platonides@users.mediawiki.org>
Tue, 12 Apr 2011 18:54:51 +0000 (18:54 +0000)
It is now duplicateTableStructure() duty to addIdentifierQuotes() them.
Fixed bug for mysql < 4.1 where the new name would be quoted twice.

Always quote identifier in Oracle, doing otherwise seems a bug (can someone confirm?)

includes/db/CloneDatabase.php
includes/db/DatabaseMysql.php
includes/db/DatabaseOracle.php
includes/db/DatabasePostgres.php
includes/db/DatabaseSqlite.php

index b3015f6..d5da296 100644 (file)
@@ -92,14 +92,14 @@ class CloneDatabase {
                        # fix back and forth so tableName() works right.
                        
                        self::changePrefix( $this->oldTablePrefix );
-                       $oldTableName = $this->db->tableName( $tbl );
+                       $oldTableName = $this->db->tableName( $tbl, false );
                        
                        self::changePrefix( $this->newTablePrefix );
-                       $newTableName = $this->db->tableName( $tbl );
+                       $newTableName = $this->db->tableName( $tbl, false );
                        
                        if( $this->dropCurrentTables && !in_array( $this->db->getType(), array( 'postgres' ) ) ) {
                                $this->db->dropTable( $tbl, __METHOD__ );
-                               wfDebug( __METHOD__." dropping {$this->newTablePrefix}{$oldTableName}\n", true);
+                               wfDebug( __METHOD__." dropping {$newTableName}\n", true);
                                //Dropping the oldTable because the prefix was changed
                        }
 
index 1289e88..07e1e4f 100644 (file)
@@ -516,16 +516,18 @@ class DatabaseMysql extends DatabaseBase {
                        # Note that we don't bother changing around the prefixes here be-
                        # cause we know we're using MySQL anyway.
 
-                       $res = $this->query( "SHOW CREATE TABLE $oldName" );
+                       $res = $this->query( 'SHOW CREATE TABLE ' . $this->addIdentifierQuotes( $oldName ) );
                        $row = $this->fetchRow( $res );
                        $oldQuery = $row[1];
                        $query = preg_replace( '/CREATE TABLE `(.*?)`/',
-                               "CREATE $tmp TABLE `$newName`", $oldQuery );
+                               "CREATE $tmp TABLE " . $this->addIdentifierQuotes( $newName ), $oldQuery );
                        if ($oldQuery === $query) {
                                # Couldn't do replacement
                                throw new MWException( "could not create temporary table $newName" );
                        }
                } else {
+                       $newName = $this->addIdentifierQuotes( $newName );
+                       $oldName = $this->addIdentifierQuotes( $oldName );
                        $query = "CREATE $tmp TABLE $newName (LIKE $oldName)";
                }
                $this->query( $query, $fname );
index 7113d1b..a1dc46f 100644 (file)
@@ -783,16 +783,19 @@ class DatabaseOracle extends DatabaseBase {
 
        function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = 'DatabaseOracle::duplicateTableStructure' ) {
                global $wgDBprefix;
+               $this->setFlag( DBO_DDLMODE );
                
                $temporary = $temporary ? 'TRUE' : 'FALSE';
 
-               $newName = trim( strtoupper( $newName ), '"');
-               $oldName = trim( strtoupper( $oldName ), '"');
+               $newName = strtoupper( $newName );
+               $oldName = strtoupper( $oldName );
 
-               $tabName = substr( $newName, strlen( $wgDBprefix ) );
-               $oldPrefix = substr( $oldName, 0, strlen( $oldName ) - strlen( $tabName ) );
+               $tabName = $this->addIdentifierQuotes( substr( $newName, strlen( $wgDBprefix ) ) );
+               $oldPrefix = $this->addIdentifierQuotes( substr( $oldName, 0, strlen( $oldName ) - strlen( $tabName ) ) );
+               $newPrefix = $this->addIdentifierQuotes( $wgDBprefix );
 
-               return $this->doQuery( 'BEGIN DUPLICATE_TABLE(\'' . $tabName . '\', \'' . $oldPrefix . '\', \'' . strtoupper( $wgDBprefix ) . '\', ' . $temporary . '); END;' );
+               $this->clearFlag( DBO_DDLMODE );
+               return $this->doQuery( "BEGIN DUPLICATE_TABLE( $tabName, $oldPrefix, $newPrefix, $temporary ); END;" );
        }
 
        function listTables( $prefix = null, $fname = 'DatabaseOracle::listTables' ) {
@@ -1075,6 +1078,12 @@ class DatabaseOracle extends DatabaseBase {
        }
 
        public function addIdentifierQuotes( $s ) {
+               return parent::addIdentifierQuotes( $s );
+               
+               /* Does this old code make any sense?
+                * We could always use quoted identifier.
+                * See http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements008.htm
+                */
                if ( !$this->mFlags & DBO_DDLMODE ) {
                        $s = '"' . str_replace( '"', '""', $s ) . '"';
                }
index 41e5f57..a1c1d14 100644 (file)
@@ -748,6 +748,8 @@ class DatabasePostgres extends DatabaseBase {
        }
 
        function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = 'DatabasePostgres::duplicateTableStructure' ) {
+               $newName = $this->addIdentifierQuotes( $newName );
+               $oldName = $this->addIdentifierQuotes( $oldName );
                return $this->query( 'CREATE ' . ( $temporary ? 'TEMPORARY ' : '' ) . " TABLE $newName (LIKE $oldName INCLUDING DEFAULTS)", $fname );
        }
 
index 654376a..6861a63 100644 (file)
@@ -254,10 +254,10 @@ class DatabaseSqlite extends DatabaseBase {
        /**
         * Use MySQL's naming (accounts for prefix etc) but remove surrounding backticks
         */
-       function tableName( $name ) {
+       function tableName( $name, $quoted = true ) {
                // 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, $quoted ) );
        }
 
        /**
@@ -596,14 +596,13 @@ class DatabaseSqlite extends DatabaseBase {
        }
 
        function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = 'DatabaseSqlite::duplicateTableStructure' ) {
-       
-               $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name='$oldName' AND type='table'", $fname );
+               $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name=" . $this->addQuotes( $oldName ) . " AND type='table'", $fname );
                $obj = $this->fetchObject( $res );
                if ( !$obj ) {
                        throw new MWException( "Couldn't retrieve structure for table $oldName" );
                }
                $sql = $obj->sql;
-               $sql = preg_replace( '/\b' . preg_quote( $oldName ) . '\b/', $newName, $sql, 1 );
+               $sql = preg_replace( '/(?<=\W)"?' . preg_quote( trim( $this->addIdentifierQuotes( $oldName ), '"' ) ) . '"?(?=\W)/', $this->addIdentifierQuotes( $newName ), $sql, 1 );
                if ( $temporary ) {
                        if ( preg_match( '/^\\s*CREATE\\s+VIRTUAL\\s+TABLE\b/i', $sql ) ) {
                                wfDebug( "Table $oldName is virtual, can't create a temporary duplicate.\n" );