mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-05 21:26:14 +01:00
(stable) Promote 2019 Week 35
This commit is contained in:
commit
4fca51c75c
16 changed files with 291 additions and 35 deletions
|
@ -4470,6 +4470,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryIdentityTransaction' => 'applications/repository/storage/PhabricatorRepositoryIdentityTransaction.php',
|
'PhabricatorRepositoryIdentityTransaction' => 'applications/repository/storage/PhabricatorRepositoryIdentityTransaction.php',
|
||||||
'PhabricatorRepositoryIdentityTransactionQuery' => 'applications/repository/query/PhabricatorRepositoryIdentityTransactionQuery.php',
|
'PhabricatorRepositoryIdentityTransactionQuery' => 'applications/repository/query/PhabricatorRepositoryIdentityTransactionQuery.php',
|
||||||
'PhabricatorRepositoryIdentityTransactionType' => 'applications/repository/xaction/PhabricatorRepositoryIdentityTransactionType.php',
|
'PhabricatorRepositoryIdentityTransactionType' => 'applications/repository/xaction/PhabricatorRepositoryIdentityTransactionType.php',
|
||||||
|
'PhabricatorRepositoryMaintenanceTransaction' => 'applications/repository/xaction/PhabricatorRepositoryMaintenanceTransaction.php',
|
||||||
'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php',
|
'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementClusterizeWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php',
|
'PhabricatorRepositoryManagementClusterizeWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
|
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
|
||||||
|
@ -4478,6 +4479,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryManagementListPathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListPathsWorkflow.php',
|
'PhabricatorRepositoryManagementListPathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListPathsWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
|
'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
|
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
|
||||||
|
'PhabricatorRepositoryManagementMaintenanceWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMaintenanceWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
|
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkReachableWorkflow.php',
|
'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkReachableWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php',
|
'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php',
|
||||||
|
@ -10911,6 +10913,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryIdentityTransaction' => 'PhabricatorModularTransaction',
|
'PhabricatorRepositoryIdentityTransaction' => 'PhabricatorModularTransaction',
|
||||||
'PhabricatorRepositoryIdentityTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
'PhabricatorRepositoryIdentityTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'PhabricatorRepositoryIdentityTransactionType' => 'PhabricatorModularTransactionType',
|
'PhabricatorRepositoryIdentityTransactionType' => 'PhabricatorModularTransactionType',
|
||||||
|
'PhabricatorRepositoryMaintenanceTransaction' => 'PhabricatorRepositoryTransactionType',
|
||||||
'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementClusterizeWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementClusterizeWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
|
@ -10919,6 +10922,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryManagementListPathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementListPathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
|
'PhabricatorRepositoryManagementMaintenanceWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
|
|
|
@ -30,4 +30,8 @@ final class PhabricatorMarkupCache extends PhabricatorCacheDAO {
|
||||||
) + parent::getConfiguration();
|
) + parent::getConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSchemaPersistence() {
|
||||||
|
return PhabricatorConfigTableSchema::PERSISTENCE_CACHE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,11 +48,19 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
||||||
abstract public function buildSchemata();
|
abstract public function buildSchemata();
|
||||||
|
|
||||||
protected function buildLiskObjectSchema(PhabricatorLiskDAO $object) {
|
protected function buildLiskObjectSchema(PhabricatorLiskDAO $object) {
|
||||||
|
$index_options = array();
|
||||||
|
|
||||||
|
$persistence = $object->getSchemaPersistence();
|
||||||
|
if ($persistence !== null) {
|
||||||
|
$index_options['persistence'] = $persistence;
|
||||||
|
}
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
$object->getApplicationName(),
|
$object->getApplicationName(),
|
||||||
$object->getTableName(),
|
$object->getTableName(),
|
||||||
$object->getSchemaColumns(),
|
$object->getSchemaColumns(),
|
||||||
$object->getSchemaKeys());
|
$object->getSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildFerretIndexSchema(PhabricatorFerretEngine $engine) {
|
protected function buildFerretIndexSchema(PhabricatorFerretEngine $engine) {
|
||||||
|
|
|
@ -145,9 +145,22 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
->setRight(array($this->branchButton, $actions_button, $clone_button))
|
->setRight(array($this->branchButton, $actions_button, $clone_button))
|
||||||
->addClass('diffusion-action-bar');
|
->addClass('diffusion-action-bar');
|
||||||
|
|
||||||
|
$status_view = null;
|
||||||
|
if ($repository->isReadOnly()) {
|
||||||
|
$status_view = id(new PHUIInfoView())
|
||||||
|
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||||
|
->setErrors(
|
||||||
|
array(
|
||||||
|
phutil_escape_html_newlines(
|
||||||
|
$repository->getReadOnlyMessageForDisplay()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
$view = id(new PHUITwoColumnView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->setFooter(array(
|
->setFooter(
|
||||||
|
array(
|
||||||
|
$status_view,
|
||||||
$bar,
|
$bar,
|
||||||
$description,
|
$description,
|
||||||
$content,
|
$content,
|
||||||
|
@ -327,6 +340,8 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
|
|
||||||
if (!$repository->isTracked()) {
|
if (!$repository->isTracked()) {
|
||||||
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
|
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
|
||||||
|
} else if ($repository->isReadOnly()) {
|
||||||
|
$header->setStatus('fa-wrench', 'indigo', pht('Under Maintenance'));
|
||||||
} else if ($repository->isImporting()) {
|
} else if ($repository->isImporting()) {
|
||||||
$ratio = $repository->loadImportProgress();
|
$ratio = $repository->loadImportProgress();
|
||||||
$percentage = sprintf('%.2f%%', 100 * $ratio);
|
$percentage = sprintf('%.2f%%', 100 * $ratio);
|
||||||
|
|
|
@ -302,6 +302,12 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($is_push) {
|
if ($is_push) {
|
||||||
|
if ($repository->isReadOnly()) {
|
||||||
|
return new PhabricatorVCSResponse(
|
||||||
|
503,
|
||||||
|
$repository->getReadOnlyMessageForDisplay());
|
||||||
|
}
|
||||||
|
|
||||||
$can_write =
|
$can_write =
|
||||||
$repository->canServeProtocol($proto_https, true) ||
|
$repository->canServeProtocol($proto_https, true) ||
|
||||||
$repository->canServeProtocol($proto_http, true);
|
$repository->canServeProtocol($proto_http, true);
|
||||||
|
|
|
@ -255,6 +255,10 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
'user account.'));
|
'user account.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($repository->isReadOnly()) {
|
||||||
|
throw new Exception($repository->getReadOnlyMessageForDisplay());
|
||||||
|
}
|
||||||
|
|
||||||
$protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH;
|
$protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH;
|
||||||
if ($repository->canServeProtocol($protocol, true)) {
|
if ($repository->canServeProtocol($protocol, true)) {
|
||||||
$can_push = PhabricatorPolicyFilter::hasCapability(
|
$can_push = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
|
|
@ -59,7 +59,6 @@ final class PhabricatorUser
|
||||||
private $rawCacheData = array();
|
private $rawCacheData = array();
|
||||||
private $usableCacheData = array();
|
private $usableCacheData = array();
|
||||||
|
|
||||||
private $authorities = array();
|
|
||||||
private $handlePool;
|
private $handlePool;
|
||||||
private $csrfSalt;
|
private $csrfSalt;
|
||||||
|
|
||||||
|
@ -705,23 +704,6 @@ final class PhabricatorUser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Grant a user a source of authority, to let them bypass policy checks they
|
|
||||||
* could not otherwise.
|
|
||||||
*/
|
|
||||||
public function grantAuthority($authority) {
|
|
||||||
$this->authorities[] = $authority;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get authorities granted to the user.
|
|
||||||
*/
|
|
||||||
public function getAuthorities() {
|
|
||||||
return $this->authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasConduitClusterToken() {
|
public function hasConduitClusterToken() {
|
||||||
return ($this->conduitClusterToken !== self::ATTACHABLE);
|
return ($this->conduitClusterToken !== self::ATTACHABLE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,13 @@ final class PhabricatorRepositoryPullEngine
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||||
|
|
||||||
|
if ($repository->isReadOnly()) {
|
||||||
|
$this->skipPull(
|
||||||
|
pht(
|
||||||
|
"Skipping pull on read-only repository.\n\n%s",
|
||||||
|
$repository->getReadOnlyMessageForDisplay()));
|
||||||
|
}
|
||||||
|
|
||||||
$is_hg = false;
|
$is_hg = false;
|
||||||
$is_git = false;
|
$is_git = false;
|
||||||
$is_svn = false;
|
$is_svn = false;
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorRepositoryManagementMaintenanceWorkflow
|
||||||
|
extends PhabricatorRepositoryManagementWorkflow {
|
||||||
|
|
||||||
|
protected function didConstruct() {
|
||||||
|
$this
|
||||||
|
->setName('maintenance')
|
||||||
|
->setExamples(
|
||||||
|
"**maintenance** --start __message__ __repository__ ...\n".
|
||||||
|
"**maintenance** --stop __repository__")
|
||||||
|
->setSynopsis(
|
||||||
|
pht('Set or clear read-only mode for repository maintenance.'))
|
||||||
|
->setArguments(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'name' => 'start',
|
||||||
|
'param' => 'message',
|
||||||
|
'help' => pht(
|
||||||
|
'Put repositories into maintenance mode.'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'stop',
|
||||||
|
'help' => pht(
|
||||||
|
'Take repositories out of maintenance mode, returning them '.
|
||||||
|
'to normal serice.'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'repositories',
|
||||||
|
'wildcard' => true,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$repositories = $this->loadRepositories($args, 'repositories');
|
||||||
|
if (!$repositories) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht('Specify one or more repositories to act on.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = $args->getArg('start');
|
||||||
|
$is_start = (bool)strlen($message);
|
||||||
|
$is_stop = $args->getArg('stop');
|
||||||
|
|
||||||
|
if (!$is_start && !$is_stop) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'Use "--start <message>" to put repositories into maintenance '.
|
||||||
|
'mode, or "--stop" to take them out of maintenance mode.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_start && $is_stop) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'Specify either "--start" or "--stop", but not both.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$content_source = $this->newContentSource();
|
||||||
|
$diffusion_phid = id(new PhabricatorDiffusionApplication())->getPHID();
|
||||||
|
|
||||||
|
if ($is_start) {
|
||||||
|
$new_value = $message;
|
||||||
|
} else {
|
||||||
|
$new_value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($repositories as $repository) {
|
||||||
|
$xactions = array();
|
||||||
|
|
||||||
|
$xactions[] = $repository->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorRepositoryMaintenanceTransaction::TRANSACTIONTYPE)
|
||||||
|
->setNewValue($new_value);
|
||||||
|
|
||||||
|
$repository->getApplicationTransactionEditor()
|
||||||
|
->setActor($viewer)
|
||||||
|
->setActingAsPHID($diffusion_phid)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContinueOnMissingFields(true)
|
||||||
|
->applyTransactions($repository, $xactions);
|
||||||
|
|
||||||
|
if ($is_start) {
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
'Put repository "%s" into maintenance mode.',
|
||||||
|
$repository->getDisplayName()));
|
||||||
|
} else {
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
'Took repository "%s" out of maintenance mode.',
|
||||||
|
$repository->getDisplayName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1410,6 +1410,12 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($write) {
|
||||||
|
if ($this->isReadOnly()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2266,6 +2272,35 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
return $this->isGit();
|
return $this->isGit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isReadOnly() {
|
||||||
|
return (bool)$this->getDetail('read-only');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setReadOnly($read_only) {
|
||||||
|
return $this->setDetail('read-only', $read_only);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReadOnlyMessage() {
|
||||||
|
return $this->getDetail('read-only-message');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setReadOnlyMessage($message) {
|
||||||
|
return $this->setDetail('read-only-message', $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReadOnlyMessageForDisplay() {
|
||||||
|
$parts = array();
|
||||||
|
$parts[] = pht(
|
||||||
|
'This repository is currently in read-only maintenance mode.');
|
||||||
|
|
||||||
|
$message = $this->getReadOnlyMessage();
|
||||||
|
if ($message !== null) {
|
||||||
|
$parts[] = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode("\n\n", $parts);
|
||||||
|
}
|
||||||
|
|
||||||
/* -( Repository URIs )---------------------------------------------------- */
|
/* -( Repository URIs )---------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorRepositoryMaintenanceTransaction
|
||||||
|
extends PhabricatorRepositoryTransactionType {
|
||||||
|
|
||||||
|
const TRANSACTIONTYPE = 'maintenance';
|
||||||
|
|
||||||
|
public function generateOldValue($object) {
|
||||||
|
return $object->getReadOnlyMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyInternalEffects($object, $value) {
|
||||||
|
if ($value === null) {
|
||||||
|
$object
|
||||||
|
->setReadOnly(false)
|
||||||
|
->setReadOnlyMessage(null);
|
||||||
|
} else {
|
||||||
|
$object
|
||||||
|
->setReadOnly(true)
|
||||||
|
->setReadOnlyMessage($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
$new = $this->getNewValue();
|
||||||
|
|
||||||
|
if (strlen($old) && !strlen($new)) {
|
||||||
|
return pht(
|
||||||
|
'%s took this repository out of maintenance mode.',
|
||||||
|
$this->renderAuthor());
|
||||||
|
} else if (!strlen($old) && strlen($new)) {
|
||||||
|
return pht(
|
||||||
|
'%s put this repository into maintenance mode.',
|
||||||
|
$this->renderAuthor());
|
||||||
|
} else {
|
||||||
|
return pht(
|
||||||
|
'%s updated the maintenance message for this repository.',
|
||||||
|
$this->renderAuthor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,11 +25,30 @@ final class PhabricatorEditEngineSubtypeTransaction
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateTransactions($object, array $xactions) {
|
public function validateTransactions($object, array $xactions) {
|
||||||
$map = $object->getEngine()
|
$errors = array();
|
||||||
|
|
||||||
|
if (!$xactions) {
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
$engine = $object->getEngine();
|
||||||
|
|
||||||
|
if (!$engine->supportsSubtypes()) {
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$errors[] = $this->newInvalidError(
|
||||||
|
pht(
|
||||||
|
'Edit engine (of class "%s") does not support subtypes, so '.
|
||||||
|
'subtype transactions can not be applied to it.',
|
||||||
|
get_class($engine)),
|
||||||
|
$xaction);
|
||||||
|
}
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
$map = $engine
|
||||||
->setViewer($this->getActor())
|
->setViewer($this->getActor())
|
||||||
->newSubtypeMap();
|
->newSubtypeMap();
|
||||||
|
|
||||||
$errors = array();
|
|
||||||
foreach ($xactions as $xaction) {
|
foreach ($xactions as $xaction) {
|
||||||
$new = $xaction->getNewValue();
|
$new = $xaction->getNewValue();
|
||||||
|
|
||||||
|
|
|
@ -1881,6 +1881,10 @@ abstract class LiskDAO extends Phobject
|
||||||
->getMaximumByteLengthForDataType($data_type);
|
->getMaximumByteLengthForDataType($data_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSchemaPersistence() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( AphrontDatabaseTableRefInterface )----------------------------------- */
|
/* -( AphrontDatabaseTableRefInterface )----------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -298,6 +298,14 @@ final class PhabricatorStorageManagementAPI extends Phobject {
|
||||||
return self::isCharacterSetAvailableOnConnection($character_set, $conn);
|
return self::isCharacterSetAvailableOnConnection($character_set, $conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getClientCharset() {
|
||||||
|
if ($this->isCharacterSetAvailable('utf8mb4')) {
|
||||||
|
return 'utf8mb4';
|
||||||
|
} else {
|
||||||
|
return 'utf8';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static function isCharacterSetAvailableOnConnection(
|
public static function isCharacterSetAvailableOnConnection(
|
||||||
$character_set,
|
$character_set,
|
||||||
AphrontDatabaseConnection $conn) {
|
AphrontDatabaseConnection $conn) {
|
||||||
|
|
|
@ -14,7 +14,8 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
'name' => 'for-replica',
|
'name' => 'for-replica',
|
||||||
'help' => pht(
|
'help' => pht(
|
||||||
'Add __--master-data__ to the __mysqldump__ command, '.
|
'Add __--master-data__ to the __mysqldump__ command, '.
|
||||||
'generating a CHANGE MASTER statement in the output.'),
|
'generating a CHANGE MASTER statement in the output. This '.
|
||||||
|
'option also dumps all data, including caches.'),
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'output',
|
'name' => 'output',
|
||||||
|
@ -54,6 +55,8 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
$output_file = $args->getArg('output');
|
$output_file = $args->getArg('output');
|
||||||
$is_compress = $args->getArg('compress');
|
$is_compress = $args->getArg('compress');
|
||||||
$is_overwrite = $args->getArg('overwrite');
|
$is_overwrite = $args->getArg('overwrite');
|
||||||
|
$is_noindex = $args->getArg('no-indexes');
|
||||||
|
$is_replica = $args->getArg('for-replica');
|
||||||
|
|
||||||
if ($is_compress) {
|
if ($is_compress) {
|
||||||
if ($output_file === null) {
|
if ($output_file === null) {
|
||||||
|
@ -79,6 +82,14 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($is_replica && $is_noindex) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'The "--for-replica" flag can not be used with the '.
|
||||||
|
'"--no-indexes" flag. Replication dumps must contain a complete '.
|
||||||
|
'representation of database state.'));
|
||||||
|
}
|
||||||
|
|
||||||
if ($output_file !== null) {
|
if ($output_file !== null) {
|
||||||
if (Filesystem::pathExists($output_file)) {
|
if (Filesystem::pathExists($output_file)) {
|
||||||
if (!$is_overwrite) {
|
if (!$is_overwrite) {
|
||||||
|
@ -94,8 +105,6 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
$api = $this->getSingleAPI();
|
$api = $this->getSingleAPI();
|
||||||
$patches = $this->getPatches();
|
$patches = $this->getPatches();
|
||||||
|
|
||||||
$with_indexes = !$args->getArg('no-indexes');
|
|
||||||
|
|
||||||
$applied = $api->getAppliedPatches();
|
$applied = $api->getAppliedPatches();
|
||||||
if ($applied === null) {
|
if ($applied === null) {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
|
@ -119,6 +128,9 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
$schemata = $actual_map[$ref_key];
|
$schemata = $actual_map[$ref_key];
|
||||||
$expect = $expect_map[$ref_key];
|
$expect = $expect_map[$ref_key];
|
||||||
|
|
||||||
|
$with_caches = $is_replica;
|
||||||
|
$with_indexes = !$is_noindex;
|
||||||
|
|
||||||
$targets = array();
|
$targets = array();
|
||||||
foreach ($schemata->getDatabases() as $database_name => $database) {
|
foreach ($schemata->getDatabases() as $database_name => $database) {
|
||||||
$expect_database = $expect->getDatabase($database_name);
|
$expect_database = $expect->getDatabase($database_name);
|
||||||
|
@ -143,7 +155,7 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
// When dumping tables, leave the data in cache tables in the
|
// When dumping tables, leave the data in cache tables in the
|
||||||
// database. This will be automatically rebuild after the data
|
// database. This will be automatically rebuild after the data
|
||||||
// is restored and does not need to be persisted in backups.
|
// is restored and does not need to be persisted in backups.
|
||||||
$with_data = false;
|
$with_data = $with_caches;
|
||||||
break;
|
break;
|
||||||
case PhabricatorConfigTableSchema::PERSISTENCE_INDEX:
|
case PhabricatorConfigTableSchema::PERSISTENCE_INDEX:
|
||||||
// When dumping tables, leave index data behind of the caller
|
// When dumping tables, leave index data behind of the caller
|
||||||
|
@ -179,9 +191,11 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
$argv = array();
|
$argv = array();
|
||||||
$argv[] = '--hex-blob';
|
$argv[] = '--hex-blob';
|
||||||
$argv[] = '--single-transaction';
|
$argv[] = '--single-transaction';
|
||||||
$argv[] = '--default-character-set=utf8';
|
|
||||||
|
|
||||||
if ($args->getArg('for-replica')) {
|
$argv[] = '--default-character-set';
|
||||||
|
$argv[] = $api->getClientCharset();
|
||||||
|
|
||||||
|
if ($is_replica) {
|
||||||
$argv[] = '--master-data';
|
$argv[] = '--master-data';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +354,6 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function writeData($data, $file, $is_compress, $output_file) {
|
private function writeData($data, $file, $is_compress, $output_file) {
|
||||||
if (!strlen($data)) {
|
if (!strlen($data)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -31,8 +31,8 @@ final class PhabricatorStorageManagementShellWorkflow
|
||||||
}
|
}
|
||||||
|
|
||||||
return phutil_passthru(
|
return phutil_passthru(
|
||||||
'mysql --protocol=TCP --default-character-set=utf8mb4 '.
|
'mysql --protocol=TCP --default-character-set %R -u %s %C -h %s %C',
|
||||||
'-u %s %C -h %s %C',
|
$api->getClientCharset(),
|
||||||
$api->getUser(),
|
$api->getUser(),
|
||||||
$flag_password,
|
$flag_password,
|
||||||
$host,
|
$host,
|
||||||
|
|
Loading…
Reference in a new issue