Page MenuHomePhabricator

D16410.id39461.diff
No OneTemporary

D16410.id39461.diff

diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementRenamespaceWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementRenamespaceWorkflow.php
--- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementRenamespaceWorkflow.php
+++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementRenamespaceWorkflow.php
@@ -8,16 +8,21 @@
->setName('renamespace')
->setExamples(
'**renamespace** [__options__] '.
- '--in __dump.sql__ --from __old__ --to __new__ > __out.sql__')
+ '--input __dump.sql__ --from __old__ --to __new__ > __out.sql__')
->setSynopsis(pht('Change the database namespace of a .sql dump file.'))
->setArguments(
array(
array(
- 'name' => 'in',
+ 'name' => 'input',
'param' => 'file',
'help' => pht('SQL dumpfile to process.'),
),
array(
+ 'name' => 'live',
+ 'help' => pht(
+ 'Generate a live dump instead of processing a file on disk.'),
+ ),
+ array(
'name' => 'from',
'param' => 'namespace',
'help' => pht('Current database namespace used by dumpfile.'),
@@ -27,6 +32,21 @@
'param' => 'namespace',
'help' => pht('Desired database namespace for output.'),
),
+ array(
+ 'name' => 'output',
+ 'param' => 'file',
+ 'help' => pht('Write output directly to a file on disk.'),
+ ),
+ array(
+ 'name' => 'compress',
+ 'help' => pht('Emit gzipped output instead of plain text.'),
+ ),
+ array(
+ 'name' => 'overwrite',
+ 'help' => pht(
+ 'With __--output__, write to disk even if the file already '.
+ 'exists.'),
+ ),
));
}
@@ -37,12 +57,13 @@
public function didExecute(PhutilArgumentParser $args) {
$console = PhutilConsole::getConsole();
- $in = $args->getArg('in');
- if (!strlen($in)) {
+ $input = $args->getArg('input');
+ $is_live = $args->getArg('live');
+ if (!strlen($input) && !$is_live) {
throw new PhutilArgumentUsageException(
pht(
- 'Specify the dumpfile to read with %s.',
- '--in'));
+ 'Specify the dumpfile to read with "--in", or use "--live" to '.
+ 'generate one automatically.'));
}
$from = $args->getArg('from');
@@ -61,6 +82,62 @@
'--to'));
}
+
+ $output_file = $args->getArg('output');
+ $is_overwrite = $args->getArg('overwrite');
+ $is_compress = $args->getArg('compress');
+
+ if ($is_overwrite) {
+ if ($output_file === null) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'The "--overwrite" flag can only be used alongside "--output".'));
+ }
+ }
+
+ if ($output_file !== null) {
+ if (Filesystem::pathExists($output_file)) {
+ if (!$is_overwrite) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Output file "%s" already exists. Use "--overwrite" '.
+ 'to overwrite.',
+ $output_file));
+ }
+ }
+ }
+
+ if ($is_live) {
+ $root = dirname(phutil_get_library_root('phabricator'));
+
+ $future = new ExecFuture(
+ '%R dump',
+ $root.'/bin/storage');
+
+ $lines = new LinesOfALargeExecFuture($future);
+ } else {
+ $lines = new LinesOfALargeFile($input);
+ }
+
+ if ($output_file === null) {
+ $file = fopen('php://stdout', 'wb');
+ $output_name = pht('stdout');
+ } else {
+ if ($is_compress) {
+ $file = gzopen($output_file, 'wb');
+ } else {
+ $file = fopen($output_file, 'wb');
+ }
+ $output_name = $output_file;
+ }
+
+ if (!$file) {
+ throw new Exception(
+ pht(
+ 'Failed to open output file "%s" for writing.',
+ $output_name));
+ }
+
$patterns = array(
'use' => '@^(USE `)([^_]+)(_.*)$@',
'create' => '@^(CREATE DATABASE /\*.*?\*/ `)([^_]+)(_.*)$@',
@@ -68,27 +145,66 @@
$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));
+ try {
+ $matches = null;
+ foreach ($lines 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]++;
}
+ }
- $line = $matches[1].$to.$matches[3];
- $found[$key]++;
+ $data = $line."\n";
+
+ if ($is_compress) {
+ $bytes = gzwrite($file, $data);
+ } else {
+ $bytes = fwrite($file, $data);
+ }
+
+ if ($bytes !== strlen($data)) {
+ throw new Exception(
+ pht(
+ 'Failed to write %d byte(s) to "%s".',
+ new PhutilNumber(strlen($data)),
+ $output_name));
+ }
+ }
+
+ if ($is_compress) {
+ $ok = gzclose($file);
+ } else {
+ $ok = fclose($file);
+ }
+
+ if ($ok !== true) {
+ throw new Exception(
+ pht(
+ 'Failed to close file "%s".',
+ $output_file));
+ }
+ } catch (Exception $ex) {
+ try {
+ if ($output_file !== null) {
+ Filesystem::remove($output_file);
}
+ } catch (Exception $ex) {
+ // Ignore any exception.
}
- echo $line."\n";
+ throw $ex;
}
// Give the user a chance to catch things if the results are crazy.

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 4, 5:04 PM (2 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7722276
Default Alt Text
D16410.id39461.diff (6 KB)

Event Timeline