Refactor table cloning code into its own class so it can maybe be used by things...
authorChad Horohoe <demon@users.mediawiki.org>
Tue, 28 Dec 2010 00:44:16 +0000 (00:44 +0000)
committerChad Horohoe <demon@users.mediawiki.org>
Tue, 28 Dec 2010 00:44:16 +0000 (00:44 +0000)
includes/AutoLoader.php
includes/db/CloneDatabase.php [new file with mode: 0644]
tests/parser/parserTest.inc

index 9f273f8..122b5ed 100644 (file)
@@ -367,6 +367,7 @@ $wgAutoloadLocalClasses = array(
        # includes/db
        'Blob' => 'includes/db/Database.php',
        'ChronologyProtector' => 'includes/db/LBFactory.php',
+       'CloneDatabase' => 'includes/db/CloneDatabase.php',
        'Database' => 'includes/db/DatabaseMysql.php',
        'DatabaseBase' => 'includes/db/Database.php',
        'DatabaseMssql' => 'includes/db/DatabaseMssql.php',
diff --git a/includes/db/CloneDatabase.php b/includes/db/CloneDatabase.php
new file mode 100644 (file)
index 0000000..c0fcebc
--- /dev/null
@@ -0,0 +1,131 @@
+<?php
+/**
+ * Helper class for making a copy of the database, mostly for unit testing.
+ *
+ * Copyright © 2010 Chad Horohoe <chad@anyonecanedit.org>
+ * http://www.mediawiki.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @ingroup Database
+ */
+
+class CloneDatabase {
+
+       /**
+        * Table prefix for cloning
+        * @var String
+        */
+       private $newTablePrefix = '';
+
+       /**
+        * Current table prefix
+        * @var String
+        */
+       private $oldTablePrefix = '';
+
+       /**
+        * List of tables to be cloned
+        * @var Array
+        */
+       private $tablesToClone = array();
+
+       /**
+        * Should we DROP tables containing the new names?
+        * @var Bool
+        */
+       private $dropCurrentTables = true;
+
+       /**
+        * Whether to use temporary tables or not
+        * @var Bool
+        */
+       private $useTemporaryTables = true;
+
+       /**
+        * Constructor
+        *
+        * @param $db DatabaseBase A database subclass
+        * @param $tablesToClone Array An array of tables to clone, unprefixed
+        * @param $newTablePrefix String Prefix to assign to the tables
+        * @param $oldTablePrefix String Prefix on current tables, if not $wgDBprefix
+        */
+       public function __construct( DatabaseBase $db, Array $tablesToClone, 
+               $newTablePrefix = 'parsertest', $oldTablePrefix = '', $dropCurrentTables = true )
+       {
+               $this->db = $db;
+               $this->tablesToClone = $tablesToClone;
+               $this->newTablePrefix = $newTablePrefix;
+               $this->oldTablePrefix = $oldTablePrefix ? $oldTablePrefix : $this->db->tablePrefix();
+               $this->dropCurrentTables = $dropCurrentTables;
+       }
+
+       /**
+        * Set whether to use temporary tables or not
+        * @param $u Bool Use temporary tables when cloning the structure
+        */
+       public function useTemporaryTables( $u = true ) {
+               $this->useTemporaryTables = false;
+       }
+
+       /**
+        * Clone the table structure
+        */
+       public function cloneTableStructure() {
+               foreach( $this->tablesToClone as $tbl ) {
+                       # Clean up from previous aborted run.  So that table escaping
+                       # works correctly across DB engines, we need to change the pre-
+                       # fix back and forth so tableName() works right.
+                       $this->changePrefix( $this->oldTablePrefix );
+                       $oldTableName = $this->db->tableName( $tbl );
+                       $this->changePrefix( $this->newTablePrefix );
+                       $newTableName = $this->db->tableName( $tbl );
+
+                       if( $this->dropCurrentTables ) {
+                               if ( $this->db->getType() == 'mysql' && $this->db->tableExists( $tbl ) ) {
+                                       $this->db->query( "DROP TABLE IF EXISTS $newTableName" );
+                               } elseif ( in_array( $this->db->getType(), array( 'postgres', 'oracle' ) ) ) {
+                                       /* DROPs wouldn't work due to Foreign Key Constraints (bug 14990, r58669)
+                                        * Use "DROP TABLE IF EXISTS $newTableName CASCADE" for postgres? That
+                                        * syntax would also work for mysql.
+                                        */
+                               } elseif ( $this->db->tableExists( $tbl ) ) {
+                                       $this->db->query( "DROP TABLE $newTableName" );
+                               }
+                       }
+
+                       # Create new table
+                       $this->db->duplicateTableStructure( $oldTableName, $newTableName, $this->useTemporaryTables );
+               }
+       }
+
+       /**
+        * Change the table prefix on all open DB connections/
+        */
+       protected function changePrefix( $prefix ) {
+               global $wgDBprefix;
+               wfGetLBFactory()->forEachLB( array( $this, 'changeLBPrefix' ), array( $prefix ) );
+               $wgDBprefix = $prefix;
+       }
+
+       public function changeLBPrefix( $lb, $prefix ) {
+               $lb->forEachOpenConnection( array( $this, 'changeDBPrefix' ), array( $prefix ) );
+       }
+
+       public function changeDBPrefix( $db, $prefix ) {
+               $db->tablePrefix( $prefix );
+       }
+}
index 9b4255b..a97f2c5 100644 (file)
@@ -751,36 +751,15 @@ class ParserTest {
 
                $temporary = $this->useTemporaryTables || $dbType == 'postgres';
                $tables = $this->listTables();
+               $prefix = $dbType != 'oracle' ? 'parsertest_' : 'pt_';
 
-               foreach ( $tables as $tbl ) {
-                       # Clean up from previous aborted run.  So that table escaping
-                       # works correctly across DB engines, we need to change the pre-
-                       # fix back and forth so tableName() works right.
-                       $this->changePrefix( $this->oldTablePrefix );
-                       $oldTableName = $this->db->tableName( $tbl );
-                       $this->changePrefix( $dbType != 'oracle' ? 'parsertest_' : 'pt_' );
-                       $newTableName = $this->db->tableName( $tbl );
-
-                       if ( $dbType == 'mysql' ) {
-                               $this->db->query( "DROP TABLE IF EXISTS $newTableName" );
-                       } elseif ( in_array( $dbType, array( 'postgres', 'oracle' ) ) ) {
-                               /* DROPs wouldn't work due to Foreign Key Constraints (bug 14990, r58669)
-                                * Use "DROP TABLE IF EXISTS $newTableName CASCADE" for postgres? That
-                                * syntax would also work for mysql.
-                                */
-                       } elseif ( $this->db->tableExists( $tbl ) ) {
-                               $this->db->query( "DROP TABLE $newTableName" );
-                       }
-
-                       # Create new table
-                       $this->db->duplicateTableStructure( $oldTableName, $newTableName, $temporary );
-               }
+               $this->dbClone = new CloneDatabase( $this->db, $this->listTables(), $prefix );
+               $this->dbClone->useTemporaryTables( $temporary );
+               $this->dbClone->cloneTableStructure();
 
                if ( $dbType == 'oracle' )
                        $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' );
 
-               $this->changePrefix( $dbType != 'oracle' ? 'parsertest_' : 'pt_' );
-
                if ( $dbType == 'oracle' ) {
                        # Insert 0 user to prevent FK violations
 
@@ -866,23 +845,6 @@ class ParserTest {
                        ), $this->db->timestamp( '20010115123500' ), $user );
        }
 
-       /**
-        * Change the table prefix on all open DB connections/
-        */
-       protected function changePrefix( $prefix ) {
-               global $wgDBprefix;
-               wfGetLBFactory()->forEachLB( array( $this, 'changeLBPrefix' ), array( $prefix ) );
-               $wgDBprefix = $prefix;
-       }
-
-       public function changeLBPrefix( $lb, $prefix ) {
-               $lb->forEachOpenConnection( array( $this, 'changeDBPrefix' ), array( $prefix ) );
-       }
-
-       public function changeDBPrefix( $db, $prefix ) {
-               $db->tablePrefix( $prefix );
-       }
-
        public function teardownDatabase() {
                if ( !$this->databaseSetupDone ) {
                        $this->teardownGlobals();
@@ -890,7 +852,7 @@ class ParserTest {
                }
                $this->teardownUploadDir( $this->uploadDir );
 
-               $this->changePrefix( $this->oldTablePrefix );
+               $this->db->tablePrefix( $this->oldTablePrefix );
                $this->databaseSetupDone = false;
 
                if ( $this->useTemporaryTables ) {