1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-20 04:20:55 +01:00

Add a storage renamespace for mangling SQL dumpfiles into a new namespace

Summary:
Ref T7149. When users give us dumpfiles for import, they will almost inevitably use the `phabricator` namespace. They need to be renamed to use an instance namespace.

We can do this either by:

  - importing the data first, then renaming; or
  - renaming first, then importing.

This implements the second one, basically `storage renamespace --in dump.sql --from phabricator --to instancename > instance.sql`.

Renaming first is a little hackier since we have to `preg_match()` a SQL dump file, but I think it's better overall:

  - With only one database, it lets you dump/import without downtime.
  - If you have development stuff in a development environment in the `phabricator` namespace, you don't have to move it aside to do an import.
  - No possibility that two people doing an import at the same time on the same box will collide with each other.
  - You can do the rename once and then repeat the import process with the renamed dump more easily.
  - No tricky stuff with modern Phabricator running against an old dump and the database names not matching up.

None of this is super important, but it just makes large dumps a bit easier to work with, and the dumpfile format is regular enough that this seems unlikely to ever really not work.

Test Plan: Renamespaced a dump, did a `diff -u`, saw all the relevant parts changed (and only those parts changed).

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7149

Differential Revision: https://secure.phabricator.com/D12105
This commit is contained in:
epriestley 2015-03-17 18:29:01 -07:00
parent 85de4419a5
commit 924b135d31
2 changed files with 96 additions and 0 deletions

View file

@ -2511,6 +2511,7 @@ phutil_register_library_map(array(
'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php',
'PhabricatorStorageManagementProbeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementProbeWorkflow.php',
'PhabricatorStorageManagementQuickstartWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementQuickstartWorkflow.php',
'PhabricatorStorageManagementRenamespaceWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementRenamespaceWorkflow.php',
'PhabricatorStorageManagementShellWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementShellWorkflow.php',
'PhabricatorStorageManagementStatusWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementStatusWorkflow.php',
'PhabricatorStorageManagementUpgradeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementUpgradeWorkflow.php',
@ -5870,6 +5871,7 @@ phutil_register_library_map(array(
'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementProbeWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementQuickstartWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementRenamespaceWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementShellWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow',

View file

@ -0,0 +1,94 @@
<?php
final class PhabricatorStorageManagementRenamespaceWorkflow
extends PhabricatorStorageManagementWorkflow {
protected function didConstruct() {
$this
->setName('renamespace')
->setExamples(
'**renamespace** [__options__] '.
'--in __dump.sql__ --from __old__ --to __new__ > __out.sql__')
->setSynopsis(pht('Change the database namespace of a .sql dump file.'))
->setArguments(
array(
array(
'name' => 'in',
'param' => 'file',
'help' => pht('SQL dumpfile to process.'),
),
array(
'name' => 'from',
'param' => 'namespace',
'help' => pht('Current database namespace used by dumpfile.'),
),
array(
'name' => 'to',
'param' => 'namespace',
'help' => pht('Desired database namespace for output.'),
),
));
}
public function execute(PhutilArgumentParser $args) {
$console = PhutilConsole::getConsole();
$in = $args->getArg('in');
if (!strlen($in)) {
throw new PhutilArgumentUsageException(
pht('Specify the dumpfile to read with --in.'));
}
$from = $args->getArg('from');
if (!strlen($from)) {
throw new PhutilArgumentUsageException(
pht('Specify namespace to rename from with --from.'));
}
$to = $args->getArg('to');
if (!strlen($to)) {
throw new PhutilArgumentUsageException(
pht('Specify namespace to rename to with --to.'));
}
$patterns = array(
'use' => '@^(USE `)([^_]+)(_.*)$@',
'create' => '@^(CREATE DATABASE /\*.*?\*/ `)([^_]+)(_.*)$@',
);
$found = array_fill_keys(array_keys($patterns), 0);
$matches = null;
foreach (new LinesOfALargeFile($in) as $line) {
foreach ($patterns as $key => $pattern) {
if (preg_match($pattern, $line, $matches)) {
$namespace = $matches[2];
if ($namespace != $from) {
throw new Exception(
pht(
'Expected namespace "%s", found "%s": %s.',
$from,
$namespace,
$line));
}
$line = $matches[1].$to.$matches[3];
$found[$key]++;
}
}
echo $line."\n";
}
// Give the user a chance to catch things if the results are crazy.
$console->writeErr(
pht(
'Adjusted **%s** create statements and **%s** use statements.',
new PhutilNumber($found['create']),
new PhutilNumber($found['use']))."\n");
return 0;
}
}