Page MenuHomestyx hydra

No OneTemporary

diff --git a/scripts/sql/manage_storage.php b/scripts/sql/manage_storage.php
index 040046e75f..81d90059a0 100755
--- a/scripts/sql/manage_storage.php
+++ b/scripts/sql/manage_storage.php
@@ -1,115 +1,115 @@
#!/usr/bin/env php
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline('manage Phabricator storage and schemata');
$args->setSynopsis(<<<EOHELP
**storage** __workflow__ [__options__]
Manage Phabricator database storage and schema versioning.
**storage** upgrade
Initialize or upgrade Phabricator storage.
**storage** upgrade --user __root__ --password __hunter2__
Use administrative credentials for schema changes.
EOHELP
);
$args->parseStandardArguments();
$conf = PhabricatorEnv::newObjectFromConfig(
'mysql.configuration-provider',
array($dao = null, 'w'));
$default_user = $conf->getUser();
$default_host = $conf->getHost();
$default_namespace = PhabricatorLiskDAO::getDefaultStorageNamespace();
try {
$args->parsePartial(
array(
array(
'name' => 'force',
'short' => 'f',
'help' => 'Do not prompt before performing dangerous operations.',
),
array(
'name' => 'user',
'short' => 'u',
'param' => 'username',
'default' => $default_user,
'help' => "Connect with __username__ instead of the configured ".
"default ('{$default_user}').",
),
array(
'name' => 'password',
'short' => 'p',
'param' => 'password',
'help' => 'Use __password__ instead of the configured default.',
),
array(
'name' => 'namespace',
'param' => 'name',
'default' => $default_namespace,
'help' => "Use namespace __namespace__ instead of the configured ".
"default ('{$default_namespace}'). This is an advanced ".
"feature used by unit tests; you should not normally ".
"use this flag.",
),
array(
'name' => 'dryrun',
'help' => 'Do not actually change anything, just show what would be '.
'changed.',
),
));
} catch (PhutilArgumentUsageException $ex) {
$args->printUsageException($ex);
exit(77);
}
if ($args->getArg('password') === null) {
// This is already a PhutilOpaqueEnvelope.
$password = $conf->getPassword();
} else {
// Put this in a PhutilOpaqueEnvelope.
$password = new PhutilOpaqueEnvelope($args->getArg('password'));
}
$api = new PhabricatorStorageManagementAPI();
$api->setUser($args->getArg('user'));
$api->setHost($default_host);
$api->setPassword($password);
$api->setNamespace($args->getArg('namespace'));
try {
queryfx(
- $api->getConn('meta_data', $select_database = false),
+ $api->getConn(null),
'SELECT 1');
} catch (AphrontQueryException $ex) {
echo phutil_console_format(
"**%s**: %s\n",
'Unable To Connect',
$ex->getMessage());
exit(1);
}
$workflows = array(
new PhabricatorStorageManagementDatabasesWorkflow(),
new PhabricatorStorageManagementDestroyWorkflow(),
new PhabricatorStorageManagementDumpWorkflow(),
new PhabricatorStorageManagementStatusWorkflow(),
new PhabricatorStorageManagementUpgradeWorkflow(),
);
$patches = PhabricatorSQLPatchList::buildAllPatches();
foreach ($workflows as $workflow) {
$workflow->setAPI($api);
$workflow->setPatches($patches);
}
$workflows[] = new PhutilHelpArgumentWorkflow();
$args->parseWorkflows($workflows);
diff --git a/src/infrastructure/storage/management/PhabricatorStorageManagementAPI.php b/src/infrastructure/storage/management/PhabricatorStorageManagementAPI.php
index 9c012993f8..2421d50a6e 100644
--- a/src/infrastructure/storage/management/PhabricatorStorageManagementAPI.php
+++ b/src/infrastructure/storage/management/PhabricatorStorageManagementAPI.php
@@ -1,179 +1,185 @@
<?php
final class PhabricatorStorageManagementAPI {
private $host;
private $user;
private $password;
private $namespace;
+ private $conns = array();
public function setNamespace($namespace) {
$this->namespace = $namespace;
PhabricatorLiskDAO::pushStorageNamespace($namespace);
return $this;
}
public function getNamespace() {
return $this->namespace;
}
public function setUser($user) {
$this->user = $user;
return $this;
}
public function getUser() {
return $this->user;
}
public function setPassword($password) {
$this->password = $password;
return $this;
}
public function getPassword() {
return $this->password;
}
public function setHost($host) {
$this->host = $host;
return $this;
}
public function getHost() {
return $this->host;
}
public function getDatabaseName($fragment) {
return $this->namespace.'_'.$fragment;
}
public function getDatabaseList(array $patches) {
assert_instances_of($patches, 'PhabricatorStoragePatch');
$list = array();
foreach ($patches as $patch) {
if ($patch->getType() == 'db') {
$list[] = $this->getDatabaseName($patch->getName());
}
}
return $list;
}
- public function getConn($fragment, $select_database = true) {
- return PhabricatorEnv::newObjectFromConfig(
+ public function getConn($fragment) {
+ $database = $this->getDatabaseName($fragment);
+ $return = &$this->conns[$this->host][$this->user][$database];
+ if (!$return) {
+ $return = PhabricatorEnv::newObjectFromConfig(
'mysql.implementation',
array(
array(
'user' => $this->user,
'pass' => $this->password,
'host' => $this->host,
- 'database' => $select_database
- ? $this->getDatabaseName($fragment)
+ 'database' => $fragment
+ ? $database
: null,
),
));
+ }
+ return $return;
}
public function getAppliedPatches() {
try {
$applied = queryfx_all(
$this->getConn('meta_data'),
'SELECT patch FROM patch_status');
return ipull($applied, 'patch');
} catch (AphrontQueryException $ex) {
return null;
}
}
public function createDatabase($fragment) {
queryfx(
- $this->getConn($fragment, $select_database = false),
+ $this->getConn(null),
'CREATE DATABASE IF NOT EXISTS %T COLLATE utf8_general_ci',
$this->getDatabaseName($fragment));
}
public function createTable($fragment, $table, array $cols) {
queryfx(
$this->getConn($fragment),
'CREATE TABLE IF NOT EXISTS %T.%T (%Q) '.
'ENGINE=InnoDB, COLLATE utf8_general_ci',
$this->getDatabaseName($fragment),
$table,
implode(', ', $cols));
}
public function getLegacyPatches(array $patches) {
assert_instances_of($patches, 'PhabricatorStoragePatch');
try {
$row = queryfx_one(
$this->getConn('meta_data'),
'SELECT version FROM %T',
'schema_version');
$version = $row['version'];
} catch (AphrontQueryException $ex) {
return array();
}
$legacy = array();
foreach ($patches as $key => $patch) {
if ($patch->getLegacy() !== false && $patch->getLegacy() <= $version) {
$legacy[] = $key;
}
}
return $legacy;
}
public function markPatchApplied($patch) {
queryfx(
$this->getConn('meta_data'),
'INSERT INTO %T (patch, applied) VALUES (%s, %d)',
'patch_status',
$patch,
time());
}
public function applyPatch(PhabricatorStoragePatch $patch) {
$type = $patch->getType();
$name = $patch->getName();
switch ($type) {
case 'db':
$this->createDatabase($name);
break;
case 'sql':
$this->applyPatchSQL($name);
break;
case 'php':
$this->applyPatchPHP($name);
break;
default:
throw new Exception("Unable to apply patch of type '{$type}'.");
}
}
public function applyPatchSQL($sql) {
$sql = Filesystem::readFile($sql);
$queries = preg_split('/;\s+/', $sql);
$queries = array_filter($queries);
- $conn = $this->getConn('meta_data', $select_database = false);
+ $conn = $this->getConn(null);
foreach ($queries as $query) {
$query = str_replace('{$NAMESPACE}', $this->namespace, $query);
queryfx(
$conn,
'%Q',
$query);
}
}
public function applyPatchPHP($script) {
- $schema_conn = $this->getConn('meta_data', $select_database = false);
+ $schema_conn = $this->getConn(null);
require_once $script;
}
}
diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php
index 4da1c88cd4..d26625e5c9 100644
--- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php
+++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php
@@ -1,80 +1,80 @@
<?php
final class PhabricatorStorageManagementDestroyWorkflow
extends PhabricatorStorageManagementWorkflow {
public function didConstruct() {
$this
->setName('destroy')
->setExamples('**destroy** [__options__]')
->setSynopsis('Permanently destroy all storage and data.')
->setArguments(
array(
array(
'name' => 'unittest-fixtures',
'help' => "Restrict **destroy** operations to databases created ".
"by PhabricatorTestCase test fixtures.",
)));
}
public function execute(PhutilArgumentParser $args) {
$is_dry = $args->getArg('dryrun');
$is_force = $args->getArg('force');
if (!$is_dry && !$is_force) {
echo phutil_console_wrap(
"Are you completely sure you really want to permanently destroy all ".
"storage for Phabricator data? This operation can not be undone and ".
"your data will not be recoverable if you proceed.");
if (!phutil_console_confirm('Permanently destroy all data?')) {
echo "Cancelled.\n";
exit(1);
}
if (!phutil_console_confirm('Really destroy all data forever?')) {
echo "Cancelled.\n";
exit(1);
}
}
$api = $this->getAPI();
$patches = $this->getPatches();
if ($args->getArg('unittest-fixtures')) {
- $conn = $api->getConn(null, false);
+ $conn = $api->getConn(null);
$databases = queryfx_all(
$conn,
'SELECT DISTINCT(TABLE_SCHEMA) AS db '.
'FROM INFORMATION_SCHEMA.TABLES '.
'WHERE TABLE_SCHEMA LIKE %>',
PhabricatorTestCase::NAMESPACE_PREFIX);
$databases = ipull($databases, 'db');
} else {
$databases = $api->getDatabaseList($patches);
$databases[] = $api->getDatabaseName('meta_data');
// These are legacy databases that were dropped long ago. See T2237.
$databases[] = $api->getDatabaseName('phid');
$databases[] = $api->getDatabaseName('directory');
}
foreach ($databases as $database) {
if ($is_dry) {
echo "DRYRUN: Would drop database '{$database}'.\n";
} else {
echo "Dropping database '{$database}'...\n";
queryfx(
- $api->getConn('meta_data', $select_database = false),
+ $api->getConn(null),
'DROP DATABASE IF EXISTS %T',
$database);
}
}
if (!$is_dry) {
echo "Storage was destroyed.\n";
}
return 0;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Dec 2, 3:56 PM (12 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
432185
Default Alt Text
(11 KB)

Event Timeline