forked from GNUsocial/gnu-social
some of the ensureTable stuff partially working
This commit is contained in:
parent
72cba88650
commit
621233e1ad
@ -234,7 +234,7 @@ class Schema
|
||||
*/
|
||||
function appendUniqueKeyDef(array &$sql, $name, array $def)
|
||||
{
|
||||
$sql[] = "UNIQUE $key " . $this->buildIndexList($def);
|
||||
$sql[] = "UNIQUE $name " . $this->buildIndexList($def);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -487,59 +487,81 @@ 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];
|
||||
|
||||
if (!$this->columnsEqual($curCol, $newCol)) {
|
||||
$tomod[] = $name;
|
||||
}
|
||||
}
|
||||
// @fixme check if not present
|
||||
$fields = $this->diffArrays($old['fields'], $def['fields'], array($this, 'columnsEqual'));
|
||||
$uniques = $this->diffArrays($old['unique keys'], $def['unique keys']);
|
||||
$indexes = $this->diffArrays($old['indexes'], $def['indexes']);
|
||||
|
||||
/*
|
||||
if (count($toadd) + count($todrop) + count($tomod) == 0) {
|
||||
// nothing to do
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
// For efficiency, we want this all in one
|
||||
// query, instead of using our methods.
|
||||
|
||||
$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);
|
||||
|
||||
$res = $this->conn->query($sql);
|
||||
|
||||
if (PEAR::isError($res)) {
|
||||
throw new Exception($res->getMessage());
|
||||
foreach ($uniques['mod'] + $uniques['add'] as $keyName) {
|
||||
$this->appendAlterAddUnique($phrase, $keyName, $def['unique keys'][$keyName]);
|
||||
}
|
||||
|
||||
return true;
|
||||
$sql = 'ALTER TABLE ' . $tableName . ' ' . implode(",\n", $phrase);
|
||||
|
||||
return array($sql);
|
||||
}
|
||||
|
||||
function diffArrays($old, $new, $compareCallback=null)
|
||||
{
|
||||
|
||||
$oldKeys = array_keys($old ? $old : array());
|
||||
$newKeys = array_keys($new ? $new : array());
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -587,6 +609,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.
|
||||
*
|
||||
|
@ -23,9 +23,15 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||
$helptext = <<<END_OF_CHECKSCHEMA_HELP
|
||||
Attempt to pull a schema definition for a given table.
|
||||
|
||||
--all run over all defined core tables
|
||||
--diff do a raw text diff between the expected and live table defs
|
||||
--update dump SQL that would be run to update or create this table
|
||||
--build dump SQL that would be run to create this table fresh
|
||||
|
||||
|
||||
END_OF_CHECKSCHEMA_HELP;
|
||||
|
||||
$longoptions = array('diff', 'all', 'build');
|
||||
$longoptions = array('diff', 'all', 'build', 'update');
|
||||
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||
|
||||
function indentOptions($indent)
|
||||
@ -121,6 +127,21 @@ function dumpBuildTable($tableName)
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function dumpEnsureTable($tableName)
|
||||
{
|
||||
echo "-- \n";
|
||||
echo "-- $tableName\n";
|
||||
echo "-- \n";
|
||||
|
||||
$schema = Schema::get();
|
||||
$def = getCoreSchema($tableName);
|
||||
$sql = $schema->buildEnsureTable($tableName, $def);
|
||||
$sql[] = '';
|
||||
|
||||
echo implode(";\n", $sql);
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function showDiff($a, $b)
|
||||
{
|
||||
$fnameA = tempnam(sys_get_temp_dir(), 'defined-diff-a');
|
||||
@ -156,6 +177,8 @@ if (count($args)) {
|
||||
showDiff($defined, $detected);
|
||||
} else if (have_option('build')) {
|
||||
dumpBuildTable($tableName);
|
||||
} else if (have_option('update')) {
|
||||
dumpEnsureTable($tableName);
|
||||
} else {
|
||||
dumpTable($tableName, true);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user