Implemented support for table conflicts
authorAlexander Ebert <ebert@woltlab.com>
Fri, 27 Jan 2012 17:42:38 +0000 (18:42 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 27 Jan 2012 17:42:38 +0000 (18:42 +0100)
@Burntime Could you add PostgreSQL support later?

See #178

wcfsetup/install/files/lib/system/WCFSetup.class.php
wcfsetup/install/files/lib/system/database/editor/DatabaseEditor.class.php
wcfsetup/install/files/lib/system/database/editor/MySQLDatabaseEditor.class.php
wcfsetup/install/files/lib/system/database/editor/PostgreSQLDatabaseEditor.class.php

index 579e37fed37dda1713403c2db8fe9b79edd5bf54..b3716bb7e510caeb9d92fd8e951d07e3092d363c 100644 (file)
@@ -555,6 +555,10 @@ class WCFSetup extends WCF {
                                
                                // check for table conflicts
                                $conflictedTables = $this->getConflictedTables($db, $dbNumber);
+                               if (!empty($conflictedTables) && ($overwriteTables || self::$developerMode)) {
+                                       // remove tables
+                                       $db->getEditor()->dropConflictedTables($conflictedTables);
+                               }
                                
                                // write config.inc
                                if (empty($conflictedTables) || $overwriteTables || self::$developerMode) {
index 7cd88bc5a0c585e41b63f262860187ce1ce4891a..afdc91ccae304ef9c6f62fc1a6266f0dff61d520 100644 (file)
@@ -128,4 +128,11 @@ abstract class DatabaseEditor {
         * @param       string          $indexName
         */
        public abstract function dropForeignKey($tableName, $indexName);
+       
+       /**
+        * Drops all given databases.
+        * 
+        * @param       array           $conflictedTables
+        */
+       public abstract function dropConflictedTables(array $conflictedTables);
 }
index 53fac0494fedfc8fd51366a8e626f9a2dc6a4816..b960268471ba90c5ee7c5eb81fe1f9e3c726178c 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\database\editor;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\database\Database;
 
 /**
@@ -228,4 +229,49 @@ class MySQLDatabaseEditor extends DatabaseEditor {
                
                return $definition;
        }
+       
+       /**
+        * @see wcf\system\database\editor\DatabaseEditor::dropConflictedTables()
+        */
+       public function dropConflictedTables(array $conflictedTables) {
+               $tables = array();
+               foreach ($conflictedTables as $tableName) {
+                       $tables[$tableName] = array();
+               }
+               
+               // get current database
+               $sql = "SELECT  DATABASE() AS currentDB";
+               $statement = $this->dbObj->prepareStatement($sql);
+               $statement->execute();
+               $row = $statement->fetchArray();
+               $currentDB = $row['currentDB'];
+               
+               // get constraints
+               $conditions = new PreparedStatementConditionBuilder();
+               $conditions->add("TABLE_SCHEMA = ?", array($currentDB));
+               $conditions->add("TABLE_NAME IN (?)", array($conflictedTables));
+               $conditions->add("REFERENCED_TABLE_NAME IS NOT NULL");
+               $conditions->add("CONSTRAINT_NAME LIKE ?", array('%_fk'));
+               
+               $sql = "SELECT  CONSTRAINT_NAME, TABLE_NAME
+                       FROM    information_schema.KEY_COLUMN_USAGE
+                       ".$conditions;
+               $statement = $this->dbObj->prepareStatement($sql);
+               $statement->execute($conditions->getParameters());
+               while ($row = $statement->fetchArray()) {
+                       $this->tables[$row['TABLE_NAME']][] = $row['CONSTRAINT_NAME'];
+               }
+               
+               // drop foreign keys
+               foreach ($this->tables as $tableName => $foreignKeys) {
+                       foreach ($foreignKeys as $fk) {
+                               $this->dropForeignKey($tableName, $fk);
+                       }
+               }
+               
+               // drop tables
+               foreach (array_keys($this->tables) as $tableName) {
+                       $this->dropTable($tableName);
+               }
+       }
 }
index aae7fcb63646704a77e6593aab3b5afd95d0d22c..3e3b67cc71845496516d12a118bba12b63a12037 100644 (file)
@@ -387,4 +387,11 @@ class PostgreSQLDatabaseEditor extends DatabaseEditor {
                
                throw new DatabaseException("Unknown / unsupported data type '".$mySQLType."'", $this->dbObj);
        }
+       
+       /**
+        * @see wcf\system\database\editor\DatabaseEditor::dropConflictedTables()
+        */
+       public function dropConflictedTables(array $conflictedTables) {
+               die('IMPLEMENT ME: PostgreSQLDatabaseEditor::dropConflictedTables');
+       }
 }