@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make `bin/storage dump` insert CREATE DATABASE and USE statements

Summary:
Ref T13000. The new approach for dumping database-by-database means that we don't get CREATE DATABASE or USE statements, which makes importing the dump again inconvenient.

Manually stitch these into the dump.

Test Plan:
- Used `bin/storage dump --namespace ...` to dump a smaller local instance.
- Used `bin/storage destroy --namespace ...`, to destroy the namespace, then inported the dump cleanly.
- Verified that each CREATE DATABASE statement appears only once.
- Verified that `bin/storage renamespace --live` can correctly process this file.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13000

Differential Revision: https://secure.phabricator.com/D18707

+47 -20
+47 -20
src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php
··· 215 215 $target['table']); 216 216 } 217 217 218 - $commands[] = $command; 218 + $commands[] = array( 219 + 'command' => $command, 220 + 'database' => $target['database'], 221 + ); 219 222 } 220 223 221 224 ··· 244 247 $file)); 245 248 } 246 249 250 + $created = array(); 251 + 247 252 try { 248 - foreach ($commands as $command) { 249 - $future = new ExecFuture('%C', $command); 253 + foreach ($commands as $spec) { 254 + // Because we're dumping database-by-database, we need to generate our 255 + // own CREATE DATABASE and USE statements. 256 + 257 + $database = $spec['database']; 258 + $preamble = array(); 259 + if (!isset($created[$database])) { 260 + $preamble[] = 261 + "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$database}` ". 262 + "/*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin */;\n"; 263 + $created[$database] = true; 264 + } 265 + $preamble[] = "USE `{$database}`;\n"; 266 + $preamble = implode('', $preamble); 267 + $this->writeData($preamble, $file, $is_compress, $output_file); 268 + 269 + $future = new ExecFuture('%C', $spec['command']); 250 270 251 271 $iterator = id(new FutureIterator(array($future))) 252 272 ->setUpdateInterval(0.100); ··· 258 278 fwrite(STDERR, $stderr); 259 279 } 260 280 261 - if (strlen($stdout)) { 262 - if (!$file) { 263 - $ok = fwrite(STDOUT, $stdout); 264 - } else if ($is_compress) { 265 - $ok = gzwrite($file, $stdout); 266 - } else { 267 - $ok = fwrite($file, $stdout); 268 - } 269 - 270 - if ($ok !== strlen($stdout)) { 271 - throw new Exception( 272 - pht( 273 - 'Failed to write %d byte(s) to file "%s".', 274 - new PhutilNumber(strlen($stdout)), 275 - $output_file)); 276 - } 277 - } 281 + $this->writeData($stdout, $file, $is_compress, $output_file); 278 282 279 283 if ($ready !== null) { 280 284 $ready->resolvex(); ··· 312 316 } 313 317 314 318 return 0; 319 + } 320 + 321 + 322 + private function writeData($data, $file, $is_compress, $output_file) { 323 + if (!strlen($data)) { 324 + return; 325 + } 326 + 327 + if (!$file) { 328 + $ok = fwrite(STDOUT, $data); 329 + } else if ($is_compress) { 330 + $ok = gzwrite($file, $data); 331 + } else { 332 + $ok = fwrite($file, $data); 333 + } 334 + 335 + if ($ok !== strlen($data)) { 336 + throw new Exception( 337 + pht( 338 + 'Failed to write %d byte(s) to file "%s".', 339 + new PhutilNumber(strlen($data)), 340 + $output_file)); 341 + } 315 342 } 316 343 317 344 }