]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
MySQL schema: fix dropping unique indexes, add support for changing table properties...
authorBrion Vibber <brion@pobox.com>
Tue, 19 Oct 2010 00:44:41 +0000 (17:44 -0700)
committerBrion Vibber <brion@pobox.com>
Tue, 19 Oct 2010 00:44:41 +0000 (17:44 -0700)
lib/mysqlschema.php
lib/schema.php

index 9785deb6614b036e419251f300d85043dbd364e2..b21008518bfea250cb4ef9403b303a4248f7ebc9 100644 (file)
@@ -245,6 +245,9 @@ class MysqlSchema extends Schema
      * @param string $name
      * @param array $def
      * @return string;
+     *
+     * @fixme ENGINE may need to be set differently in some cases,
+     * such as to support fulltext index.
      */
     function endCreateTable($name, array $def)
     {
@@ -267,153 +270,36 @@ class MysqlSchema extends Schema
         return "{$tableName}_{$columnName}_idx";
     }
 
+
     /**
-     * Ensures that a table exists with the given
-     * name and the given column definitions.
-     *
-     * If the table does not yet exist, it will
-     * create the table. If it does exist, it will
-     * alter the table to match the column definitions.
-     *
-     * @param string $tableName name of the table
-     * @param array  $columns   array of ColumnDef
-     *                          objects for the table
+     * MySQL doesn't take 'DROP CONSTRAINT', need to treat unique keys as
+     * if they were indexes here.
      *
-     * @return boolean success flag
+     * @param array $phrase
+     * @param <type> $keyName MySQL
      */
-
-    public function oldensureTable($tableName, $columns)
+    function appendAlterDropUnique(array &$phrase, $keyName)
     {
-        // XXX: DB engine portability -> toilet
-
-        try {
-            $td = $this->getTableDef($tableName);
-        } catch (SchemaTableMissingException $e) {
-            return $this->createTable($tableName, $columns);
-        }
-
-        $cur = $this->_names($td->columns);
-        $new = $this->_names($columns);
-
-        $dropIndex  = array();
-        $toadd      = array_diff($new, $cur);
-        $todrop     = array_diff($cur, $new);
-        $same       = array_intersect($new, $cur);
-        $tomod      = array();
-        $addIndex   = array();
-        $tableProps = array();
-
-        foreach ($same as $m) {
-            $curCol = $this->_byName($td->columns, $m);
-            $newCol = $this->_byName($columns, $m);
-
-            if (!$newCol->equals($curCol)) {
-                $tomod[] = $newCol->name;
-                continue;
-            }
-
-            // Earlier versions may have accidentally left tables at default
-            // charsets which might be latin1 or other freakish things.
-            if ($this->_isString($curCol)) {
-                if ($curCol->charset != 'utf8') {
-                    $tomod[] = $newCol->name;
-                    continue;
-                }
-            }
-        }
-
-        // Find any indices we have to change...
-        $curIdx = $this->_indexList($td->columns);
-        $newIdx = $this->_indexList($columns);
-
-        if ($curIdx['primary'] != $newIdx['primary']) {
-            if ($curIdx['primary']) {
-                $dropIndex[] = 'drop primary key';
-            }
-            if ($newIdx['primary']) {
-                $keys = implode(',', $newIdx['primary']);
-                $addIndex[] = "add constraint primary key ($keys)";
-            }
-        }
-
-        $dropUnique = array_diff($curIdx['uniques'], $newIdx['uniques']);
-        $addUnique = array_diff($newIdx['uniques'], $curIdx['uniques']);
-        foreach ($dropUnique as $columnName) {
-            $dropIndex[] = 'drop key ' . $this->_uniqueKey($tableName, $columnName);
-        }
-        foreach ($addUnique as $columnName) {
-            $addIndex[] = 'add constraint unique key ' . $this->_uniqueKey($tableName, $columnName) . " ($columnName)";;
-        }
-
-        $dropMultiple = array_diff($curIdx['indices'], $newIdx['indices']);
-        $addMultiple = array_diff($newIdx['indices'], $curIdx['indices']);
-        foreach ($dropMultiple as $columnName) {
-            $dropIndex[] = 'drop key ' . $this->_key($tableName, $columnName);
-        }
-        foreach ($addMultiple as $columnName) {
-            $addIndex[] = 'add key ' . $this->_key($tableName, $columnName) . " ($columnName)";
-        }
+        $phrase[] = 'DROP INDEX ' . $keyName;
+    }
 
+    /**
+     * Throw some table metadata onto the ALTER TABLE if we have a mismatch
+     * in expected type, collation.
+     */
+    function appendAlterExtras(array &$phrase, $tableName)
+    {
         // Check for table properties: make sure we're using a sane
         // engine type and charset/collation.
         // @fixme make the default engine configurable?
         $oldProps = $this->getTableProperties($tableName, array('ENGINE', 'TABLE_COLLATION'));
         if (strtolower($oldProps['ENGINE']) != 'innodb') {
-            $tableProps['ENGINE'] = 'InnoDB';
+            $phrase[] = 'ENGINE=InnoDB';
         }
         if (strtolower($oldProps['TABLE_COLLATION']) != 'utf8_bin') {
-            $tableProps['DEFAULT CHARSET'] = 'utf8';
-            $tableProps['COLLATE'] = 'utf8_bin';
-        }
-
-        if (count($dropIndex) + count($toadd) + count($todrop) + count($tomod) + count($addIndex) + count($tableProps) == 0) {
-            // nothing to do
-            return true;
-        }
-
-        // For efficiency, we want this all in one
-        // query, instead of using our methods.
-
-        $phrase = array();
-
-        foreach ($dropIndex as $indexSql) {
-            $phrase[] = $indexSql;
+            $phrase[] = 'DEFAULT CHARSET=utf8';
+            $phrase[] = 'COLLATE=utf8_bin';
         }
-
-        foreach ($toadd as $columnName) {
-            $cd = $this->_byName($columns, $columnName);
-
-            $phrase[] = 'ADD COLUMN ' . $this->_columnSql($cd);
-        }
-
-        foreach ($todrop as $columnName) {
-            $phrase[] = 'DROP COLUMN ' . $columnName;
-        }
-
-        foreach ($tomod as $columnName) {
-            $cd = $this->_byName($columns, $columnName);
-
-            $phrase[] = 'MODIFY COLUMN ' . $this->_columnSql($cd);
-        }
-
-        foreach ($addIndex as $indexSql) {
-            $phrase[] = $indexSql;
-        }
-
-        foreach ($tableProps as $key => $val) {
-            $phrase[] = "$key=$val";
-        }
-
-        $sql = 'ALTER TABLE ' . $tableName . ' ' . implode(', ', $phrase);
-
-        common_log(LOG_DEBUG, __METHOD__ . ': ' . $sql);
-        $res = $this->conn->query($sql);
-
-        if (PEAR::isError($res)) {
-            throw new Exception($res->getMessage());
-        }
-
-        return true;
     }
 
     /**
index 9f2899ba8c62fa179bf978a1fddd7c8629838d76..4feb11a879416fb2a4a31c427c5d9b96323a495b 100644 (file)
@@ -493,12 +493,6 @@ class Schema
         $uniques = $this->diffArrays($old, $def, 'unique keys');
         $indexes = $this->diffArrays($old, $def, 'indexes');
 
-        $total = $fields['count'] + $uniques['count'] + $indexes['count'];
-        if ($total == 0) {
-            // nothing to do
-            return array();
-        }
-
         // For efficiency, we want this all in one
         // query, instead of using our methods.
 
@@ -527,6 +521,13 @@ class Schema
             $this->appendAlterAddUnique($phrase, $keyName, $def['unique keys'][$keyName]);
         }
 
+        $this->appendAlterExtras($phrase, $tableName);
+
+        if (count($phrase) == 0) {
+            // nothing to do
+            return array();
+        }
+
         $sql = 'ALTER TABLE ' . $tableName . ' ' . implode(",\n", $phrase);
 
         return array($sql);
@@ -625,6 +626,11 @@ class Schema
         $phrase[] = 'DROP CONSTRAINT ' . $keyName;
     }
 
+    function appendAlterExtras(array &$phrase, $tableName)
+    {
+        // no-op
+    }
+
     /**
      * Quote a db/table/column identifier if necessary.
      *