summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrion Vibber <brion@pobox.com>2010-10-18 17:44:41 -0700
committerBrion Vibber <brion@pobox.com>2010-10-18 17:44:41 -0700
commit4aa6c4e49f9c4a41fa72d841370886a8f49c06f4 (patch)
tree7600d013c5bdca7ee986470effb19341304dd01b
parenta923ef971912e7d095cd4cae335abb9095930ecb (diff)
MySQL schema: fix dropping unique indexes, add support for changing table properties back from old code.
-rw-r--r--lib/mysqlschema.php154
-rw-r--r--lib/schema.php18
2 files changed, 32 insertions, 140 deletions
diff --git a/lib/mysqlschema.php b/lib/mysqlschema.php
index 9785deb66..b21008518 100644
--- a/lib/mysqlschema.php
+++ b/lib/mysqlschema.php
@@ -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;
}
/**
diff --git a/lib/schema.php b/lib/schema.php
index 9f2899ba8..4feb11a87 100644
--- a/lib/schema.php
+++ b/lib/schema.php
@@ -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.
*