Page MenuHomePhabricator

D10599.id25472.diff
No OneTemporary

D10599.id25472.diff

diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php
--- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php
+++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php
@@ -129,56 +129,99 @@
$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']);
- }
-
- 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 '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');
+
+ 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 @@
$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 @@
);
}
}
+
+ 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;
+ }
+ }
}
}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 4, 1:11 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6723995
Default Alt Text
D10599.id25472.diff (6 KB)

Event Timeline