mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
Allow bin/storage adjust
to make key changes
Summary: Ref T1191. These are a bit tricky because keys can interact with column changes, so basically we do three phases: 1. Nuke all bad keys. 2. Make all column (and database/table) changes. 3. Fix all nuked keys. Test Plan: Ran migration locally. See note for remaining issues. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T1191 Differential Revision: https://secure.phabricator.com/D10599
This commit is contained in:
parent
22ee8432d2
commit
a5ce56aa76
1 changed files with 135 additions and 42 deletions
|
@ -129,56 +129,99 @@ final class PhabricatorStorageManagementAdjustWorkflow
|
|||
|
||||
$failed = array();
|
||||
|
||||
// We make changes in three phases:
|
||||
//
|
||||
// Phase 0: Drop all keys which we're going to adjust. This prevents them
|
||||
// from interfering with column changes.
|
||||
//
|
||||
// Phase 1: Apply all database, table, and column changes.
|
||||
//
|
||||
// Phase 2: Restore adjusted keys.
|
||||
$phases = 3;
|
||||
|
||||
$bar = id(new PhutilConsoleProgressBar())
|
||||
->setTotal(count($adjustments));
|
||||
foreach ($adjustments as $adjust) {
|
||||
try {
|
||||
switch ($adjust['kind']) {
|
||||
case 'database':
|
||||
queryfx(
|
||||
$conn,
|
||||
'ALTER DATABASE %T CHARACTER SET = %s COLLATE = %s',
|
||||
$adjust['database'],
|
||||
$adjust['charset'],
|
||||
$adjust['collation']);
|
||||
break;
|
||||
case 'table':
|
||||
queryfx(
|
||||
$conn,
|
||||
'ALTER TABLE %T.%T COLLATE = %s',
|
||||
$adjust['database'],
|
||||
$adjust['table'],
|
||||
$adjust['collation']);
|
||||
break;
|
||||
case 'column':
|
||||
$parts = array();
|
||||
if ($adjust['charset']) {
|
||||
$parts[] = qsprintf(
|
||||
->setTotal(count($adjustments) * $phases);
|
||||
|
||||
for ($phase = 0; $phase < $phases; $phase++) {
|
||||
foreach ($adjustments as $adjust) {
|
||||
try {
|
||||
switch ($adjust['kind']) {
|
||||
case 'database':
|
||||
if ($phase != 1) {
|
||||
break;
|
||||
}
|
||||
queryfx(
|
||||
$conn,
|
||||
'CHARACTER SET %Q COLLATE %Q',
|
||||
'ALTER DATABASE %T CHARACTER SET = %s COLLATE = %s',
|
||||
$adjust['database'],
|
||||
$adjust['charset'],
|
||||
$adjust['collation']);
|
||||
}
|
||||
break;
|
||||
case 'table':
|
||||
if ($phase != 1) {
|
||||
break;
|
||||
}
|
||||
queryfx(
|
||||
$conn,
|
||||
'ALTER TABLE %T.%T COLLATE = %s',
|
||||
$adjust['database'],
|
||||
$adjust['table'],
|
||||
$adjust['collation']);
|
||||
break;
|
||||
case 'column':
|
||||
if ($phase != 1) {
|
||||
break;
|
||||
}
|
||||
$parts = array();
|
||||
if ($adjust['charset']) {
|
||||
$parts[] = qsprintf(
|
||||
$conn,
|
||||
'CHARACTER SET %Q COLLATE %Q',
|
||||
$adjust['charset'],
|
||||
$adjust['collation']);
|
||||
}
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'ALTER TABLE %T.%T MODIFY %T %Q %Q %Q',
|
||||
$adjust['database'],
|
||||
$adjust['table'],
|
||||
$adjust['name'],
|
||||
$adjust['type'],
|
||||
implode(' ', $parts),
|
||||
$adjust['nullable'] ? 'NULL' : 'NOT NULL');
|
||||
queryfx(
|
||||
$conn,
|
||||
'ALTER TABLE %T.%T MODIFY %T %Q %Q %Q',
|
||||
$adjust['database'],
|
||||
$adjust['table'],
|
||||
$adjust['name'],
|
||||
$adjust['type'],
|
||||
implode(' ', $parts),
|
||||
$adjust['nullable'] ? 'NULL' : 'NOT NULL');
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht('Unknown schema adjustment kind "%s"!', $adjust['kind']));
|
||||
break;
|
||||
case 'key':
|
||||
if (($phase == 0) && $adjust['exists']) {
|
||||
queryfx(
|
||||
$conn,
|
||||
'ALTER TABLE %T.%T DROP KEY %T',
|
||||
$adjust['database'],
|
||||
$adjust['table'],
|
||||
$adjust['name']);
|
||||
}
|
||||
|
||||
if (($phase == 2) && $adjust['keep']) {
|
||||
queryfx(
|
||||
$conn,
|
||||
'ALTER TABLE %T.%T ADD %Q KEY %T (%Q)',
|
||||
$adjust['database'],
|
||||
$adjust['table'],
|
||||
$adjust['unique'] ? 'UNIQUE' : '/* NONUNIQUE */',
|
||||
$adjust['name'],
|
||||
implode(', ', $adjust['columns']));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht('Unknown schema adjustment kind "%s"!', $adjust['kind']));
|
||||
}
|
||||
} catch (AphrontQueryException $ex) {
|
||||
$failed[] = array($adjust, $ex);
|
||||
}
|
||||
} catch (AphrontQueryException $ex) {
|
||||
$failed[] = array($adjust, $ex);
|
||||
$bar->update(1);
|
||||
}
|
||||
$bar->update(1);
|
||||
}
|
||||
$bar->done();
|
||||
|
||||
|
@ -222,6 +265,11 @@ final class PhabricatorStorageManagementAdjustWorkflow
|
|||
$issue_charset = PhabricatorConfigStorageSchema::ISSUE_CHARSET;
|
||||
$issue_collation = PhabricatorConfigStorageSchema::ISSUE_COLLATION;
|
||||
$issue_columntype = PhabricatorConfigStorageSchema::ISSUE_COLUMNTYPE;
|
||||
$issue_surpluskey = PhabricatorConfigStorageSchema::ISSUE_SURPLUSKEY;
|
||||
$issue_missingkey = PhabricatorConfigStorageSchema::ISSUE_MISSINGKEY;
|
||||
$issue_columns = PhabricatorConfigStorageSchema::ISSUE_KEYCOLUMNS;
|
||||
$issue_unique = PhabricatorConfigStorageSchema::ISSUE_UNIQUE;
|
||||
|
||||
|
||||
$adjustments = array();
|
||||
foreach ($comp->getDatabases() as $database_name => $database) {
|
||||
|
@ -321,6 +369,51 @@ final class PhabricatorStorageManagementAdjustWorkflow
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($table->getKeys() as $key_name => $key) {
|
||||
$expect_key = $expect_table->getKey($key_name);
|
||||
$actual_key = $actual_table->getKey($key_name);
|
||||
|
||||
$issues = array();
|
||||
$keep_key = true;
|
||||
if ($key->hasIssue($issue_surpluskey)) {
|
||||
$issues[] = $issue_surpluskey;
|
||||
$keep_key = false;
|
||||
}
|
||||
|
||||
if ($key->hasIssue($issue_missingkey)) {
|
||||
$issues[] = $issue_missingkey;
|
||||
}
|
||||
|
||||
if ($key->hasIssue($issue_columns)) {
|
||||
$issues[] = $issue_columns;
|
||||
}
|
||||
|
||||
if ($key->hasIssue($issue_unique)) {
|
||||
$issues[] = $issue_unique;
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
$adjustment = array(
|
||||
'kind' => 'key',
|
||||
'database' => $database_name,
|
||||
'table' => $table_name,
|
||||
'name' => $key_name,
|
||||
'issues' => $issues,
|
||||
'exists' => (bool)$actual_key,
|
||||
'keep' => $keep_key,
|
||||
);
|
||||
|
||||
if ($keep_key) {
|
||||
$adjustment += array(
|
||||
'columns' => $expect_key->getColumnNames(),
|
||||
'unique' => $expect_key->getUnique(),
|
||||
);
|
||||
}
|
||||
|
||||
$adjustments[] = $adjustment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue