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)
|
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']);
|
// @fixme check if not present
|
||||||
$new = array_keys($def['fields']);
|
$fields = $this->diffArrays($old['fields'], $def['fields'], array($this, 'columnsEqual'));
|
||||||
|
$uniques = $this->diffArrays($old['unique keys'], $def['unique keys']);
|
||||||
$toadd = array_diff($new, $cur);
|
$indexes = $this->diffArrays($old['indexes'], $def['indexes']);
|
||||||
$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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
if (count($toadd) + count($todrop) + count($tomod) == 0) {
|
if (count($toadd) + count($todrop) + count($tomod) == 0) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// For efficiency, we want this all in one
|
// For efficiency, we want this all in one
|
||||||
// query, instead of using our methods.
|
// query, instead of using our methods.
|
||||||
|
|
||||||
$phrase = array();
|
$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,
|
$this->appendAlterAddColumn($phrase, $columnName,
|
||||||
$def['fields'][$columnName]);
|
$def['fields'][$columnName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($todrop as $columnName) {
|
foreach ($fields['mod'] as $columnName) {
|
||||||
$this->appendAlterModifyColumn($phrase, $columnName,
|
$this->appendAlterModifyColumn($phrase, $columnName,
|
||||||
$old['fields'][$columnName],
|
$old['fields'][$columnName],
|
||||||
$def['fields'][$columnName]);
|
$def['fields'][$columnName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($tomod as $columnName) {
|
foreach ($fields['del'] as $columnName) {
|
||||||
$this->appendAlterDropColumn($phrase, $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);
|
|
||||||
|
|
||||||
if (PEAR::isError($res)) {
|
|
||||||
throw new Exception($res->getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
$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.
|
* Quote a db/table/column identifier if necessary.
|
||||||
*
|
*
|
||||||
|
@ -23,9 +23,15 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
|||||||
$helptext = <<<END_OF_CHECKSCHEMA_HELP
|
$helptext = <<<END_OF_CHECKSCHEMA_HELP
|
||||||
Attempt to pull a schema definition for a given table.
|
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;
|
END_OF_CHECKSCHEMA_HELP;
|
||||||
|
|
||||||
$longoptions = array('diff', 'all', 'build');
|
$longoptions = array('diff', 'all', 'build', 'update');
|
||||||
require_once INSTALLDIR.'/scripts/commandline.inc';
|
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||||
|
|
||||||
function indentOptions($indent)
|
function indentOptions($indent)
|
||||||
@ -121,6 +127,21 @@ function dumpBuildTable($tableName)
|
|||||||
echo "\n";
|
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)
|
function showDiff($a, $b)
|
||||||
{
|
{
|
||||||
$fnameA = tempnam(sys_get_temp_dir(), 'defined-diff-a');
|
$fnameA = tempnam(sys_get_temp_dir(), 'defined-diff-a');
|
||||||
@ -156,6 +177,8 @@ if (count($args)) {
|
|||||||
showDiff($defined, $detected);
|
showDiff($defined, $detected);
|
||||||
} else if (have_option('build')) {
|
} else if (have_option('build')) {
|
||||||
dumpBuildTable($tableName);
|
dumpBuildTable($tableName);
|
||||||
|
} else if (have_option('update')) {
|
||||||
|
dumpEnsureTable($tableName);
|
||||||
} else {
|
} else {
|
||||||
dumpTable($tableName, true);
|
dumpTable($tableName, true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user