Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15484140
D16410.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D16410.id.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 10, 4:33 PM (1 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7722276
Default Alt Text
D16410.id.diff (6 KB)
Attached To
Mode
D16410: Provide "--output" flags for "bin/storage renamespace"
Attached
Detach File
Event Timeline
Log In to Comment