X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Fschema.php;h=2793906a461657c6b8815dab66257a87969484b1;hb=dcf0acd5035e41d573e1f74c6804781ebb174d44;hp=4eafb4df2415dc4c6880c70363d8b27b391116e1;hpb=9cb42c8e45b9adf33872a7c5b116795c768b3b49;p=quix0rs-gnu-social.git diff --git a/lib/schema.php b/lib/schema.php index 4eafb4df24..2793906a46 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -143,6 +143,7 @@ class Schema */ public function buildCreateTable($name, $def) { + $def = $this->filterDef($def); $sql = array(); foreach ($def['fields'] as $col => $colDef) { @@ -169,7 +170,7 @@ class Schema $this->endCreateTable($name, $def); if (!empty($def['indexes'])) { foreach ($def['indexes'] as $col => $colDef) { - $this->appendCreateIndex($statements, $table, $col, $colDef); + $this->appendCreateIndex($statements, $name, $col, $colDef); } } @@ -234,7 +235,7 @@ class Schema */ function appendUniqueKeyDef(array &$sql, $name, array $def) { - $sql[] = "UNIQUE $key " . $this->buildIndexList($def); + $sql[] = "UNIQUE $name " . $this->buildIndexList($def); } /** @@ -254,7 +255,16 @@ class Schema function buildIndexList(array $def) { // @fixme - return '(' . implode(',', array_map(array($this, 'quoteIdentifier'), $def)) . ')'; + return '(' . implode(',', array_map(array($this, 'buildIndexItem'), $def)) . ')'; + } + + function buildIndexItem($def) + { + if (is_array($def)) { + list($name, $size) = $def; + return $this->quoteIdentifier($name) . '(' . intval($size) . ')'; + } + return $this->quoteIdentifier($def); } /** @@ -478,28 +488,18 @@ class Schema } } - $cur = array_keys($old['fields']); - $new = array_keys($def['fields']); - - $toadd = array_diff($new, $cur); - $todrop = array_diff($cur, $new); - $same = array_intersect($new, $cur); - $tomod = array(); - - // Find which fields have actually changed definition - // in a way that we need to tweak them for this DB type. - foreach ($same as $name) { - $curCol = $old['fields'][$name]; - $newCol = $cur['fields'][$name]; + $old = $this->filterDef($old); + $def = $this->filterDef($def); - if (!$this->columnsEqual($curCol, $newCol)) { - $tomod[] = $name; - } - } + // @fixme check if not present + $fields = $this->diffArrays($old, $def, 'fields', array($this, 'columnsEqual')); + $uniques = $this->diffArrays($old, $def, 'unique keys'); + $indexes = $this->diffArrays($old, $def, 'indexes'); - if (count($toadd) + count($todrop) + count($tomod) == 0) { + $total = $fields['count'] + $uniques['count'] + $indexes['count']; + if ($total == 0) { // nothing to do - return true; + return array(); } // For efficiency, we want this all in one @@ -507,30 +507,67 @@ class Schema $phrase = array(); - foreach ($toadd as $columnName) { + foreach ($uniques['del'] + $uniques['mod'] as $keyName) { + $this->appendAlterDropUnique($phrase, $keyName); + } + + foreach ($fields['add'] as $columnName) { $this->appendAlterAddColumn($phrase, $columnName, $def['fields'][$columnName]); } - foreach ($todrop as $columnName) { + foreach ($fields['mod'] as $columnName) { $this->appendAlterModifyColumn($phrase, $columnName, $old['fields'][$columnName], $def['fields'][$columnName]); } - foreach ($tomod as $columnName) { + foreach ($fields['del'] as $columnName) { $this->appendAlterDropColumn($phrase, $columnName); } - $sql = 'ALTER TABLE ' . $tableName . ' ' . implode(', ', $phrase); + foreach ($uniques['mod'] + $uniques['add'] as $keyName) { + $this->appendAlterAddUnique($phrase, $keyName, $def['unique keys'][$keyName]); + } - $res = $this->conn->query($sql); + $sql = 'ALTER TABLE ' . $tableName . ' ' . implode(",\n", $phrase); - if (PEAR::isError($res)) { - throw new Exception($res->getMessage()); - } + return array($sql); + } - return true; + function diffArrays($oldDef, $newDef, $section, $compareCallback=null) + { + $old = isset($oldDef[$section]) ? $oldDef[$section] : array(); + $new = isset($newDef[$section]) ? $newDef[$section] : array(); + + $oldKeys = array_keys($old); + $newKeys = array_keys($new); + + $toadd = array_diff($newKeys, $oldKeys); + $todrop = array_diff($oldKeys, $newKeys); + $same = array_intersect($newKeys, $oldKeys); + $tomod = array(); + $tokeep = array(); + + // Find which fields have actually changed definition + // in a way that we need to tweak them for this DB type. + foreach ($same as $name) { + if ($compareCallback) { + $same = call_user_func($compareCallback, $old[$name], $new[$name]); + } else { + $same = ($old[$name] == $new[$name]); + } + if ($same) { + $tokeep[] = $name; + continue; + } + $tomod[] = $name; + } + return array('add' => $toadd, + 'del' => $todrop, + 'mod' => $tomod, + 'keep' => $tokeep, + 'count' => count($toadd) + count($todrop) + count($tomod)); } /** @@ -578,6 +615,19 @@ class Schema $phrase[] = 'DROP COLUMN ' . $this->quoteIdentifier($columnName); } + function appendAlterAddUnique(array &$phrase, $keyName, array $def) + { + $sql = array(); + $sql[] = 'ADD'; + $this->appendUniqueKeyDef($sql, $keyName, $def); + $phrase[] = implode(' ', $sql);'ADD CONSTRAINT ' . $keyName; + } + + function appendAlterDropUnique(array &$phrase, $keyName) + { + $phrase[] = 'DROP CONSTRAINT ' . $keyName; + } + /** * Quote a db/table/column identifier if necessary. * @@ -803,6 +853,20 @@ class Schema return $table; } + /** + * Filter the given table definition array to match features available + * in this database. + * + * This lets us strip out unsupported things like comments, foreign keys, + * or type variants that we wouldn't get back from getTableDef(). + * + * @param array $tableDef + */ + function filterDef(array $tableDef) + { + return $tableDef; + } + function isNumericType($type) { $type = strtolower($type);