mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-15 10:00:55 +01:00
(stable) Promote 2017 Week 40
This commit is contained in:
commit
58598e1963
36 changed files with 690 additions and 81 deletions
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_maniphest.maniphest_task_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.02.event.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.02.event.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_calendar.calendar_event_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_differential.differential_revision_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.04.fund.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.04.fund.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_fund.fund_initiative_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.05.owners.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.05.owners.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_owners.owners_package_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_passphrase.passphrase_credential_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.07.blog.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.07.blog.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phame.phame_blog_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.08.post.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.08.post.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phame.phame_post_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.09.pholio.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.09.pholio.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_pholio.pholio_mock_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phriction.phriction_document_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.11.project.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.11.project.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_project.project_project_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.12.user.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.12.user.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_user.user_user_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_repository.repository_repository_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
7
resources/sql/autopatches/20171002.cngram.14.commit.sql
Normal file
7
resources/sql/autopatches/20171002.cngram.14.commit.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_repository.repository_commit_fngrams_common (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
needsCollection BOOL NOT NULL,
|
||||||
|
UNIQUE KEY `key_ngram` (ngram),
|
||||||
|
KEY `key_collect` (needsCollection)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -3941,6 +3941,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSearchEngineAttachment' => 'applications/search/engineextension/PhabricatorSearchEngineAttachment.php',
|
'PhabricatorSearchEngineAttachment' => 'applications/search/engineextension/PhabricatorSearchEngineAttachment.php',
|
||||||
'PhabricatorSearchEngineExtension' => 'applications/search/engineextension/PhabricatorSearchEngineExtension.php',
|
'PhabricatorSearchEngineExtension' => 'applications/search/engineextension/PhabricatorSearchEngineExtension.php',
|
||||||
'PhabricatorSearchEngineExtensionModule' => 'applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php',
|
'PhabricatorSearchEngineExtensionModule' => 'applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php',
|
||||||
|
'PhabricatorSearchFerretNgramGarbageCollector' => 'applications/search/garbagecollector/PhabricatorSearchFerretNgramGarbageCollector.php',
|
||||||
'PhabricatorSearchField' => 'applications/search/field/PhabricatorSearchField.php',
|
'PhabricatorSearchField' => 'applications/search/field/PhabricatorSearchField.php',
|
||||||
'PhabricatorSearchHost' => 'infrastructure/cluster/search/PhabricatorSearchHost.php',
|
'PhabricatorSearchHost' => 'infrastructure/cluster/search/PhabricatorSearchHost.php',
|
||||||
'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php',
|
'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php',
|
||||||
|
@ -3948,6 +3949,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSearchIndexVersionDestructionEngineExtension' => 'applications/search/engineextension/PhabricatorSearchIndexVersionDestructionEngineExtension.php',
|
'PhabricatorSearchIndexVersionDestructionEngineExtension' => 'applications/search/engineextension/PhabricatorSearchIndexVersionDestructionEngineExtension.php',
|
||||||
'PhabricatorSearchManagementIndexWorkflow' => 'applications/search/management/PhabricatorSearchManagementIndexWorkflow.php',
|
'PhabricatorSearchManagementIndexWorkflow' => 'applications/search/management/PhabricatorSearchManagementIndexWorkflow.php',
|
||||||
'PhabricatorSearchManagementInitWorkflow' => 'applications/search/management/PhabricatorSearchManagementInitWorkflow.php',
|
'PhabricatorSearchManagementInitWorkflow' => 'applications/search/management/PhabricatorSearchManagementInitWorkflow.php',
|
||||||
|
'PhabricatorSearchManagementNgramsWorkflow' => 'applications/search/management/PhabricatorSearchManagementNgramsWorkflow.php',
|
||||||
|
'PhabricatorSearchManagementQueryWorkflow' => 'applications/search/management/PhabricatorSearchManagementQueryWorkflow.php',
|
||||||
'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
|
'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
|
||||||
'PhabricatorSearchNgrams' => 'applications/search/ngrams/PhabricatorSearchNgrams.php',
|
'PhabricatorSearchNgrams' => 'applications/search/ngrams/PhabricatorSearchNgrams.php',
|
||||||
'PhabricatorSearchNgramsDestructionEngineExtension' => 'applications/search/engineextension/PhabricatorSearchNgramsDestructionEngineExtension.php',
|
'PhabricatorSearchNgramsDestructionEngineExtension' => 'applications/search/engineextension/PhabricatorSearchNgramsDestructionEngineExtension.php',
|
||||||
|
@ -9521,6 +9524,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSearchEngineAttachment' => 'Phobject',
|
'PhabricatorSearchEngineAttachment' => 'Phobject',
|
||||||
'PhabricatorSearchEngineExtension' => 'Phobject',
|
'PhabricatorSearchEngineExtension' => 'Phobject',
|
||||||
'PhabricatorSearchEngineExtensionModule' => 'PhabricatorConfigModule',
|
'PhabricatorSearchEngineExtensionModule' => 'PhabricatorConfigModule',
|
||||||
|
'PhabricatorSearchFerretNgramGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
'PhabricatorSearchField' => 'Phobject',
|
'PhabricatorSearchField' => 'Phobject',
|
||||||
'PhabricatorSearchHost' => 'Phobject',
|
'PhabricatorSearchHost' => 'Phobject',
|
||||||
'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController',
|
'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController',
|
||||||
|
@ -9528,6 +9532,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSearchIndexVersionDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
'PhabricatorSearchIndexVersionDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
||||||
'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||||
'PhabricatorSearchManagementInitWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
'PhabricatorSearchManagementInitWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||||
|
'PhabricatorSearchManagementNgramsWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||||
|
'PhabricatorSearchManagementQueryWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||||
'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
'PhabricatorSearchNgrams' => 'PhabricatorSearchDAO',
|
'PhabricatorSearchNgrams' => 'PhabricatorSearchDAO',
|
||||||
'PhabricatorSearchNgramsDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
'PhabricatorSearchNgramsDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
||||||
|
|
|
@ -30,6 +30,9 @@ final class PhabricatorCacheSchemaSpec extends PhabricatorConfigSchemaSpec {
|
||||||
'key_ttl' => array(
|
'key_ttl' => array(
|
||||||
'columns' => array('cacheExpires'),
|
'columns' => array('cacheExpires'),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'persistence' => PhabricatorConfigTableSchema::PERSISTENCE_CACHE,
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,7 @@ final class PhabricatorConfigDatabaseStatusController
|
||||||
$this->renderAttr(
|
$this->renderAttr(
|
||||||
$table->getCollation(),
|
$table->getCollation(),
|
||||||
$table->hasIssue($collation_issue)),
|
$table->hasIssue($collation_issue)),
|
||||||
|
$table->getPersistenceTypeDisplayName(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,12 +271,14 @@ final class PhabricatorConfigDatabaseStatusController
|
||||||
null,
|
null,
|
||||||
pht('Table'),
|
pht('Table'),
|
||||||
pht('Collation'),
|
pht('Collation'),
|
||||||
|
pht('Persistence'),
|
||||||
))
|
))
|
||||||
->setColumnClasses(
|
->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
null,
|
null,
|
||||||
'wide pri',
|
'wide pri',
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
));
|
));
|
||||||
|
|
||||||
$title = $database_name;
|
$title = $database_name;
|
||||||
|
|
|
@ -338,6 +338,8 @@ final class PhabricatorConfigSchemaQuery extends Phobject {
|
||||||
$comp_table->addKey($comp_key);
|
$comp_table->addKey($comp_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$comp_table->setPersistenceType($expect_table->getPersistenceType());
|
||||||
|
|
||||||
$comp_database->addTable($comp_table);
|
$comp_database->addTable($comp_table);
|
||||||
}
|
}
|
||||||
$comp_server->addDatabase($comp_database);
|
$comp_server->addDatabase($comp_database);
|
||||||
|
|
|
@ -56,30 +56,52 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildFerretIndexSchema(PhabricatorFerretEngine $engine) {
|
protected function buildFerretIndexSchema(PhabricatorFerretEngine $engine) {
|
||||||
|
$index_options = array(
|
||||||
|
'persistence' => PhabricatorConfigTableSchema::PERSISTENCE_INDEX,
|
||||||
|
);
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
$engine->getApplicationName(),
|
$engine->getApplicationName(),
|
||||||
$engine->getDocumentTableName(),
|
$engine->getDocumentTableName(),
|
||||||
$engine->getDocumentSchemaColumns(),
|
$engine->getDocumentSchemaColumns(),
|
||||||
$engine->getDocumentSchemaKeys());
|
$engine->getDocumentSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
$engine->getApplicationName(),
|
$engine->getApplicationName(),
|
||||||
$engine->getFieldTableName(),
|
$engine->getFieldTableName(),
|
||||||
$engine->getFieldSchemaColumns(),
|
$engine->getFieldSchemaColumns(),
|
||||||
$engine->getFieldSchemaKeys());
|
$engine->getFieldSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
$engine->getApplicationName(),
|
$engine->getApplicationName(),
|
||||||
$engine->getNgramsTableName(),
|
$engine->getNgramsTableName(),
|
||||||
$engine->getNgramsSchemaColumns(),
|
$engine->getNgramsSchemaColumns(),
|
||||||
$engine->getNgramsSchemaKeys());
|
$engine->getNgramsSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
|
|
||||||
|
$this->buildRawSchema(
|
||||||
|
$engine->getApplicationName(),
|
||||||
|
$engine->getCommonNgramsTableName(),
|
||||||
|
$engine->getCommonNgramsSchemaColumns(),
|
||||||
|
$engine->getCommonNgramsSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildRawSchema(
|
protected function buildRawSchema(
|
||||||
$database_name,
|
$database_name,
|
||||||
$table_name,
|
$table_name,
|
||||||
array $columns,
|
array $columns,
|
||||||
array $keys) {
|
array $keys,
|
||||||
|
array $options = array()) {
|
||||||
|
|
||||||
|
PhutilTypeSpec::checkMap(
|
||||||
|
$options,
|
||||||
|
array(
|
||||||
|
'persistence' => 'optional string',
|
||||||
|
));
|
||||||
|
|
||||||
$database = $this->getDatabase($database_name);
|
$database = $this->getDatabase($database_name);
|
||||||
|
|
||||||
$table = $this->newTable($table_name);
|
$table = $this->newTable($table_name);
|
||||||
|
@ -138,6 +160,11 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
||||||
$table->addKey($key);
|
$table->addKey($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$persistence_type = idx($options, 'persistence');
|
||||||
|
if ($persistence_type !== null) {
|
||||||
|
$table->setPersistenceType($persistence_type);
|
||||||
|
}
|
||||||
|
|
||||||
$database->addTable($table);
|
$database->addTable($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,11 @@ final class PhabricatorConfigTableSchema
|
||||||
private $engine;
|
private $engine;
|
||||||
private $columns = array();
|
private $columns = array();
|
||||||
private $keys = array();
|
private $keys = array();
|
||||||
|
private $persistenceType = self::PERSISTENCE_DATA;
|
||||||
|
|
||||||
|
const PERSISTENCE_DATA = 'data';
|
||||||
|
const PERSISTENCE_CACHE = 'cache';
|
||||||
|
const PERSISTENCE_INDEX = 'index';
|
||||||
|
|
||||||
public function addColumn(PhabricatorConfigColumnSchema $column) {
|
public function addColumn(PhabricatorConfigColumnSchema $column) {
|
||||||
$key = $column->getName();
|
$key = $column->getName();
|
||||||
|
@ -45,6 +50,27 @@ final class PhabricatorConfigTableSchema
|
||||||
return idx($this->getKeys(), $key);
|
return idx($this->getKeys(), $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setPersistenceType($persistence_type) {
|
||||||
|
$this->persistenceType = $persistence_type;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPersistenceType() {
|
||||||
|
return $this->persistenceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPersistenceTypeDisplayName() {
|
||||||
|
$map = array(
|
||||||
|
self::PERSISTENCE_DATA => pht('Data'),
|
||||||
|
self::PERSISTENCE_CACHE => pht('Cache'),
|
||||||
|
self::PERSISTENCE_INDEX => pht('Index'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$type = $this->getPersistenceType();
|
||||||
|
|
||||||
|
return idx($map, $type, $type);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getSubschemata() {
|
protected function getSubschemata() {
|
||||||
// NOTE: Keys and columns may have the same name, so make sure we return
|
// NOTE: Keys and columns may have the same name, so make sure we return
|
||||||
// everything.
|
// everything.
|
||||||
|
|
|
@ -21,6 +21,9 @@ final class DifferentialSchemaSpec extends PhabricatorConfigSchemaSpec {
|
||||||
'dateCreated' => array(
|
'dateCreated' => array(
|
||||||
'columns' => array('dateCreated'),
|
'columns' => array('dateCreated'),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'persistence' => PhabricatorConfigTableSchema::PERSISTENCE_CACHE,
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
|
|
|
@ -69,10 +69,11 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
|
||||||
'branches/(?P<dblob>.*)' => 'DiffusionBranchTableController',
|
'branches/(?P<dblob>.*)' => 'DiffusionBranchTableController',
|
||||||
'refs/(?P<dblob>.*)' => 'DiffusionRefTableController',
|
'refs/(?P<dblob>.*)' => 'DiffusionRefTableController',
|
||||||
'lint/(?P<dblob>.*)' => 'DiffusionLintController',
|
'lint/(?P<dblob>.*)' => 'DiffusionLintController',
|
||||||
'commit/(?P<commit>[a-z0-9]+)/branches/'
|
'commit/(?P<commit>[a-z0-9]+)' => array(
|
||||||
=> 'DiffusionCommitBranchesController',
|
'/?' => 'DiffusionCommitController',
|
||||||
'commit/(?P<commit>[a-z0-9]+)/tags/'
|
'/branches/' => 'DiffusionCommitBranchesController',
|
||||||
=> 'DiffusionCommitTagsController',
|
'/tags/' => 'DiffusionCommitTagsController',
|
||||||
|
),
|
||||||
'compare/' => 'DiffusionCompareController',
|
'compare/' => 'DiffusionCompareController',
|
||||||
'manage/(?:(?P<panel>[^/]+)/)?'
|
'manage/(?:(?P<panel>[^/]+)/)?'
|
||||||
=> 'DiffusionRepositoryManagePanelsController',
|
=> 'DiffusionRepositoryManagePanelsController',
|
||||||
|
|
|
@ -115,6 +115,10 @@ final class DiffusionLastModifiedQueryConduitAPIMethod
|
||||||
$graph_cache = new PhabricatorRepositoryGraphCache();
|
$graph_cache = new PhabricatorRepositoryGraphCache();
|
||||||
|
|
||||||
$results = array();
|
$results = array();
|
||||||
|
|
||||||
|
// Spend no more than this many total seconds trying to satisfy queries
|
||||||
|
// via the graph cache.
|
||||||
|
$remaining_time = 10.0;
|
||||||
foreach ($map as $path => $commit) {
|
foreach ($map as $path => $commit) {
|
||||||
$path_id = idx($path_map, $path);
|
$path_id = idx($path_map, $path);
|
||||||
if (!$path_id) {
|
if (!$path_id) {
|
||||||
|
@ -125,13 +129,21 @@ final class DiffusionLastModifiedQueryConduitAPIMethod
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$t_start = microtime(true);
|
||||||
$cache_result = $graph_cache->loadLastModifiedCommitID(
|
$cache_result = $graph_cache->loadLastModifiedCommitID(
|
||||||
$commit_id,
|
$commit_id,
|
||||||
$path_id);
|
$path_id,
|
||||||
|
$remaining_time);
|
||||||
|
$t_end = microtime(true);
|
||||||
|
|
||||||
if ($cache_result !== false) {
|
if ($cache_result !== false) {
|
||||||
$results[$path] = $cache_result;
|
$results[$path] = $cache_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$remaining_time -= ($t_end - $t_start);
|
||||||
|
if ($remaining_time <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($results) {
|
if ($results) {
|
||||||
|
|
|
@ -22,17 +22,27 @@ final class DiffusionCommitController extends DiffusionController {
|
||||||
|
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
$viewer = $request->getUser();
|
$viewer = $request->getUser();
|
||||||
|
$repository = $drequest->getRepository();
|
||||||
|
$commit_identifier = $drequest->getCommit();
|
||||||
|
|
||||||
|
// If this page is being accessed via "/source/xyz/commit/...", redirect
|
||||||
|
// to the canonical URI.
|
||||||
|
$has_callsign = strlen($request->getURIData('repositoryCallsign'));
|
||||||
|
$has_id = strlen($request->getURIData('repositoryID'));
|
||||||
|
if (!$has_callsign && !$has_id) {
|
||||||
|
$canonical_uri = $repository->getCommitURI($commit_identifier);
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI($canonical_uri);
|
||||||
|
}
|
||||||
|
|
||||||
if ($request->getStr('diff')) {
|
if ($request->getStr('diff')) {
|
||||||
return $this->buildRawDiffResponse($drequest);
|
return $this->buildRawDiffResponse($drequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
$repository = $drequest->getRepository();
|
|
||||||
|
|
||||||
$commit = id(new DiffusionCommitQuery())
|
$commit = id(new DiffusionCommitQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withRepository($repository)
|
->withRepository($repository)
|
||||||
->withIdentifiers(array($drequest->getCommit()))
|
->withIdentifiers(array($commit_identifier))
|
||||||
->needCommitData(true)
|
->needCommitData(true)
|
||||||
->needAuditRequests(true)
|
->needAuditRequests(true)
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
|
|
@ -102,6 +102,10 @@ final class PhabricatorRepositoryGraphCache extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, the rebuild gave us the data, so we can keep going.
|
// Otherwise, the rebuild gave us the data, so we can keep going.
|
||||||
|
|
||||||
|
$did_fill = true;
|
||||||
|
} else {
|
||||||
|
$did_fill = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanity check so we can survive and recover from bad data.
|
// Sanity check so we can survive and recover from bad data.
|
||||||
|
@ -147,12 +151,17 @@ final class PhabricatorRepositoryGraphCache extends Phobject {
|
||||||
$commit_id = $parent_id;
|
$commit_id = $parent_id;
|
||||||
|
|
||||||
// Periodically check if we've spent too long looking for a result
|
// Periodically check if we've spent too long looking for a result
|
||||||
// in the cache, and return so we can fall back to a VCS operation. This
|
// in the cache, and return so we can fall back to a VCS operation.
|
||||||
// keeps us from having a degenerate worst case if, e.g., the cache
|
// This keeps us from having a degenerate worst case if, e.g., the
|
||||||
// is cold and we need to inspect a very large number of blocks
|
// cache is cold and we need to inspect a very large number of blocks
|
||||||
// to satisfy the query.
|
// to satisfy the query.
|
||||||
|
|
||||||
if (((++$iterations) % 64) === 0) {
|
++$iterations;
|
||||||
|
|
||||||
|
// If we performed a cache fill in this cycle, always check the time
|
||||||
|
// limit, since cache fills may take a significant amount of time.
|
||||||
|
|
||||||
|
if ($did_fill || ($iterations % 64 === 0)) {
|
||||||
$t_end = microtime(true);
|
$t_end = microtime(true);
|
||||||
if (($t_end - $t_start) > $time) {
|
if (($t_end - $t_start) > $time) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -165,21 +165,46 @@ final class PhabricatorFerretFulltextEngineExtension
|
||||||
$ferret_field['normalCorpus']);
|
$ferret_field['normalCorpus']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = array();
|
if ($ngrams) {
|
||||||
foreach ($ngrams as $ngram) {
|
$common = queryfx_all(
|
||||||
$sql[] = qsprintf(
|
|
||||||
$conn,
|
$conn,
|
||||||
'(%d, %s)',
|
'SELECT ngram FROM %T WHERE ngram IN (%Ls)',
|
||||||
$document_id,
|
$engine->getCommonNgramsTableName(),
|
||||||
$ngram);
|
$ngrams);
|
||||||
|
$common = ipull($common, 'ngram', 'ngram');
|
||||||
|
|
||||||
|
foreach ($ngrams as $key => $ngram) {
|
||||||
|
if (isset($common[$ngram])) {
|
||||||
|
unset($ngrams[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: MySQL discards trailing whitespace in CHAR(X) columns.
|
||||||
|
$trim_ngram = rtrim($ngram, ' ');
|
||||||
|
if (isset($common[$ngram])) {
|
||||||
|
unset($ngrams[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
|
if ($ngrams) {
|
||||||
queryfx(
|
$sql = array();
|
||||||
$conn,
|
foreach ($ngrams as $ngram) {
|
||||||
'INSERT INTO %T (documentID, ngram) VALUES %Q',
|
$sql[] = qsprintf(
|
||||||
$engine->getNgramsTableName(),
|
$conn,
|
||||||
$chunk);
|
'(%d, %s)',
|
||||||
|
$document_id,
|
||||||
|
$ngram);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'INSERT INTO %T (documentID, ngram) VALUES %Q',
|
||||||
|
$engine->getNgramsTableName(),
|
||||||
|
$chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
$object->killTransaction();
|
$object->killTransaction();
|
||||||
|
|
|
@ -295,4 +295,35 @@ abstract class PhabricatorFerretEngine extends Phobject {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCommonNgramsTableName() {
|
||||||
|
$application = $this->getApplicationName();
|
||||||
|
$scope = $this->getScopeName();
|
||||||
|
|
||||||
|
return "{$application}_{$scope}_fngrams_common";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommonNgramsSchemaColumns() {
|
||||||
|
return array(
|
||||||
|
'id' => 'auto',
|
||||||
|
'ngram' => 'char3',
|
||||||
|
'needsCollection' => 'bool',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommonNgramsSchemaKeys() {
|
||||||
|
return array(
|
||||||
|
'PRIMARY' => array(
|
||||||
|
'columns' => array('id'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
|
'key_ngram' => array(
|
||||||
|
'columns' => array('ngram'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
|
'key_collect' => array(
|
||||||
|
'columns' => array('needsCollection'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorSearchFerretNgramGarbageCollector
|
||||||
|
extends PhabricatorGarbageCollector {
|
||||||
|
|
||||||
|
const COLLECTORCONST = 'search.ferret.ngram';
|
||||||
|
|
||||||
|
public function getCollectorName() {
|
||||||
|
return pht('Ferret Engine Ngrams');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticPolicy() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function collectGarbage() {
|
||||||
|
$all_objects = id(new PhutilClassMapQuery())
|
||||||
|
->setAncestorClass('PhabricatorFerretInterface')
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$did_collect = false;
|
||||||
|
foreach ($all_objects as $object) {
|
||||||
|
$engine = $object->newFerretEngine();
|
||||||
|
$conn = $object->establishConnection('w');
|
||||||
|
|
||||||
|
$ngram_row = queryfx_one(
|
||||||
|
$conn,
|
||||||
|
'SELECT ngram FROM %T WHERE needsCollection = 1 LIMIT 1',
|
||||||
|
$engine->getCommonNgramsTableName());
|
||||||
|
if (!$ngram_row) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ngram = $ngram_row['ngram'];
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'DELETE FROM %T WHERE ngram = %s',
|
||||||
|
$engine->getNgramsTableName(),
|
||||||
|
$ngram);
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'UPDATE %T SET needsCollection = 0 WHERE ngram = %s',
|
||||||
|
$engine->getCommonNgramsTableName(),
|
||||||
|
$ngram);
|
||||||
|
|
||||||
|
$did_collect = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $did_collect;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorSearchManagementNgramsWorkflow
|
||||||
|
extends PhabricatorSearchManagementWorkflow {
|
||||||
|
|
||||||
|
protected function didConstruct() {
|
||||||
|
$this
|
||||||
|
->setName('ngrams')
|
||||||
|
->setSynopsis(
|
||||||
|
pht(
|
||||||
|
'Recompute common ngrams. This is an advanced workflow that '.
|
||||||
|
'can harm search quality if used improperly.'))
|
||||||
|
->setArguments(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'name' => 'reset',
|
||||||
|
'help' => pht('Reset all common ngram records.'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
$is_reset = $args->getArg('reset');
|
||||||
|
|
||||||
|
$all_objects = id(new PhutilClassMapQuery())
|
||||||
|
->setAncestorClass('PhabricatorFerretInterface')
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$min_documents = 4096;
|
||||||
|
$threshold = 0.15;
|
||||||
|
|
||||||
|
foreach ($all_objects as $object) {
|
||||||
|
$engine = $object->newFerretEngine();
|
||||||
|
$conn = $object->establishConnection('w');
|
||||||
|
$display_name = get_class($object);
|
||||||
|
|
||||||
|
if ($is_reset) {
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
'Resetting common ngrams for "%s".',
|
||||||
|
$display_name));
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'DELETE FROM %T',
|
||||||
|
$engine->getCommonNgramsTableName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$document_count = queryfx_one(
|
||||||
|
$conn,
|
||||||
|
'SELECT COUNT(*) N FROM %T',
|
||||||
|
$engine->getDocumentTableName());
|
||||||
|
$document_count = $document_count['N'];
|
||||||
|
|
||||||
|
if ($document_count < $min_documents) {
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
'Too few documents of type "%s" for any ngrams to be common.',
|
||||||
|
$display_name));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$min_frequency = (int)ceil($document_count * $threshold);
|
||||||
|
$common_ngrams = queryfx_all(
|
||||||
|
$conn,
|
||||||
|
'SELECT ngram, COUNT(*) N FROM %T
|
||||||
|
GROUP BY ngram
|
||||||
|
HAVING N >= %d',
|
||||||
|
$engine->getNgramsTableName(),
|
||||||
|
$min_frequency);
|
||||||
|
|
||||||
|
if (!$common_ngrams) {
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
'No new common ngrams exist for "%s".',
|
||||||
|
$display_name));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = array();
|
||||||
|
foreach ($common_ngrams as $ngram) {
|
||||||
|
$sql[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'(%s, 1)',
|
||||||
|
$ngram['ngram']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'INSERT IGNORE INTO %T (ngram, needsCollection)
|
||||||
|
VALUES %Q',
|
||||||
|
$engine->getCommonNgramsTableName(),
|
||||||
|
$chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
'Updated common ngrams for "%s".',
|
||||||
|
$display_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorSearchManagementQueryWorkflow
|
||||||
|
extends PhabricatorSearchManagementWorkflow {
|
||||||
|
|
||||||
|
protected function didConstruct() {
|
||||||
|
$this
|
||||||
|
->setName('query')
|
||||||
|
->setSynopsis(
|
||||||
|
pht('Run a search query. Intended for debugging and development.'))
|
||||||
|
->setArguments(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'name' => 'query',
|
||||||
|
'param' => 'query',
|
||||||
|
'help' => pht('Raw query to execute.'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$raw_query = $args->getArg('query');
|
||||||
|
if (!strlen($raw_query)) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht('Specify a query with --query.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorSearchApplicationSearchEngine())
|
||||||
|
->setViewer($viewer);
|
||||||
|
|
||||||
|
$saved = $engine->newSavedQuery();
|
||||||
|
$saved->setParameter('query', $raw_query);
|
||||||
|
|
||||||
|
$query = $engine->buildQueryFromSavedQuery($saved);
|
||||||
|
$pager = $engine->newPagerForSavedQuery($saved);
|
||||||
|
|
||||||
|
$results = $engine->executeQuery($query, $pager);
|
||||||
|
if ($results) {
|
||||||
|
foreach ($results as $result) {
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\t%s\n",
|
||||||
|
$result->getPHID(),
|
||||||
|
$result->getName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht('No results.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -138,9 +138,9 @@ final class PhabricatorEmailAddressesSettingsPanel
|
||||||
$editable,
|
$editable,
|
||||||
));
|
));
|
||||||
|
|
||||||
$button = null;
|
$buttons = array();
|
||||||
if ($editable) {
|
if ($editable) {
|
||||||
$button = id(new PHUIButtonView())
|
$buttons[] = id(new PHUIButtonView())
|
||||||
->setTag('a')
|
->setTag('a')
|
||||||
->setIcon('fa-plus')
|
->setIcon('fa-plus')
|
||||||
->setText(pht('Add New Address'))
|
->setText(pht('Add New Address'))
|
||||||
|
@ -149,7 +149,7 @@ final class PhabricatorEmailAddressesSettingsPanel
|
||||||
->setColor(PHUIButtonView::GREY);
|
->setColor(PHUIButtonView::GREY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->newBox(pht('Email Addresses'), $table, array($button));
|
return $this->newBox(pht('Email Addresses'), $table, $buttons);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function returnNewAddressResponse(
|
private function returnNewAddressResponse(
|
||||||
|
|
|
@ -14,7 +14,7 @@ are:
|
||||||
- performance and capacity may improve.
|
- performance and capacity may improve.
|
||||||
|
|
||||||
This configuration is relatively simple, but has a small impact on availability
|
This configuration is relatively simple, but has a small impact on availability
|
||||||
and does nothing to increase resitance to data loss.
|
and does nothing to increase resistance to data loss.
|
||||||
|
|
||||||
|
|
||||||
Clustering Design Goals
|
Clustering Design Goals
|
||||||
|
|
|
@ -145,6 +145,24 @@ present a risk. If you restrict access to the Phabricator host or database, you
|
||||||
should also restrict access to the backups.
|
should also restrict access to the backups.
|
||||||
|
|
||||||
|
|
||||||
|
Skipping Indexes
|
||||||
|
================
|
||||||
|
|
||||||
|
By default, `bin/storage dump` does not dump all of the data in the database:
|
||||||
|
it skips some caches which can be rebuilt automatically and do not need to be
|
||||||
|
backed up. Some of these caches are very large, so the size of the dump may
|
||||||
|
be significantly smaller than the size of the databases.
|
||||||
|
|
||||||
|
If you have a large amount of data, you can specify `--no-indexes` when taking
|
||||||
|
a database dump to skip additional tables which contain search indexes. This
|
||||||
|
will reduce the size (and increase the speed) of the backup. This is an
|
||||||
|
advanced option which most installs will not benefit from.
|
||||||
|
|
||||||
|
This index data can be rebuilt after a restore, but will not be rebuilt
|
||||||
|
automatically. If you choose to use this flag, you must manually rebuild
|
||||||
|
indexes after a restore (for details, see ((reindex))).
|
||||||
|
|
||||||
|
|
||||||
Next Steps
|
Next Steps
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ final class ManiphestTaskGraph
|
||||||
protected function newTableRow($phid, $object, $trace) {
|
protected function newTableRow($phid, $object, $trace) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
Javelin::initBehavior('phui-hovercards');
|
||||||
|
|
||||||
if ($object) {
|
if ($object) {
|
||||||
$status = $object->getStatus();
|
$status = $object->getStatus();
|
||||||
$priority = $object->getPriority();
|
$priority = $object->getPriority();
|
||||||
|
@ -51,15 +53,16 @@ final class ManiphestTaskGraph
|
||||||
$assigned = phutil_tag('em', array(), pht('None'));
|
$assigned = phutil_tag('em', array(), pht('None'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$full_title = $object->getTitle();
|
$link = javelin_tag(
|
||||||
|
|
||||||
$link = phutil_tag(
|
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
'href' => $object->getURI(),
|
'href' => $object->getURI(),
|
||||||
'title' => $full_title,
|
'sigil' => 'hovercard',
|
||||||
|
'meta' => array(
|
||||||
|
'hoverPHID' => $object->getPHID(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
$full_title);
|
$object->getTitle());
|
||||||
|
|
||||||
$link = array(
|
$link = array(
|
||||||
phutil_tag(
|
phutil_tag(
|
||||||
|
|
|
@ -1700,6 +1700,34 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove common ngrams, like "the", which occur too frequently in
|
||||||
|
// documents to be useful in constraining the query. The best ngrams
|
||||||
|
// are obscure sequences which occur in very few documents.
|
||||||
|
|
||||||
|
if ($flat) {
|
||||||
|
$common_ngrams = queryfx_all(
|
||||||
|
$conn,
|
||||||
|
'SELECT ngram FROM %T WHERE ngram IN (%Ls)',
|
||||||
|
$engine->getCommonNgramsTableName(),
|
||||||
|
ipull($flat, 'ngram'));
|
||||||
|
$common_ngrams = ipull($common_ngrams, 'ngram', 'ngram');
|
||||||
|
|
||||||
|
foreach ($flat as $key => $spec) {
|
||||||
|
$ngram = $spec['ngram'];
|
||||||
|
if (isset($common_ngrams[$ngram])) {
|
||||||
|
unset($flat[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: MySQL discards trailing whitespace in CHAR(X) columns.
|
||||||
|
$trim_ngram = rtrim($ngram, ' ');
|
||||||
|
if (isset($common_ngrams[$trim_ngram])) {
|
||||||
|
unset($flat[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MySQL only allows us to join a maximum of 61 tables per query. Each
|
// MySQL only allows us to join a maximum of 61 tables per query. Each
|
||||||
// ngram is going to cost us a join toward that limit, so if the user
|
// ngram is going to cost us a join toward that limit, so if the user
|
||||||
// specified a very long query string, just pick 16 of the ngrams
|
// specified a very long query string, just pick 16 of the ngrams
|
||||||
|
|
|
@ -30,6 +30,13 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
'With __--output__, write a compressed file to disk instead '.
|
'With __--output__, write a compressed file to disk instead '.
|
||||||
'of a plaintext file.'),
|
'of a plaintext file.'),
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'no-indexes',
|
||||||
|
'help' => pht(
|
||||||
|
'Do not dump data in rebuildable index tables. This means '.
|
||||||
|
'backups are smaller and faster, but you will need to manually '.
|
||||||
|
'rebuild indexes after performing a restore.'),
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'overwrite',
|
'name' => 'overwrite',
|
||||||
'help' => pht(
|
'help' => pht(
|
||||||
|
@ -49,6 +56,8 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
|
|
||||||
$console = PhutilConsole::getConsole();
|
$console = PhutilConsole::getConsole();
|
||||||
|
|
||||||
|
$with_indexes = !$args->getArg('no-indexes');
|
||||||
|
|
||||||
$applied = $api->getAppliedPatches();
|
$applied = $api->getAppliedPatches();
|
||||||
if ($applied === null) {
|
if ($applied === null) {
|
||||||
$namespace = $api->getNamespace();
|
$namespace = $api->getNamespace();
|
||||||
|
@ -62,7 +71,64 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$databases = $api->getDatabaseList($patches, true);
|
$ref = $api->getRef();
|
||||||
|
$ref_key = $ref->getRefKey();
|
||||||
|
|
||||||
|
$schemata_query = id(new PhabricatorConfigSchemaQuery())
|
||||||
|
->setAPIs(array($api))
|
||||||
|
->setRefs(array($ref));
|
||||||
|
|
||||||
|
$actual_map = $schemata_query->loadActualSchemata();
|
||||||
|
$expect_map = $schemata_query->loadExpectedSchemata();
|
||||||
|
|
||||||
|
$schemata = $actual_map[$ref_key];
|
||||||
|
$expect = $expect_map[$ref_key];
|
||||||
|
|
||||||
|
$targets = array();
|
||||||
|
foreach ($schemata->getDatabases() as $database_name => $database) {
|
||||||
|
$expect_database = $expect->getDatabase($database_name);
|
||||||
|
foreach ($database->getTables() as $table_name => $table) {
|
||||||
|
|
||||||
|
// NOTE: It's possible for us to find tables in these database which
|
||||||
|
// we don't expect to be there. For example, an older version of
|
||||||
|
// Phabricator may have had a table that was later dropped. We assume
|
||||||
|
// these are data tables and always dump them, erring on the side of
|
||||||
|
// caution.
|
||||||
|
|
||||||
|
$persistence = PhabricatorConfigTableSchema::PERSISTENCE_DATA;
|
||||||
|
if ($expect_database) {
|
||||||
|
$expect_table = $expect_database->getTable($table_name);
|
||||||
|
if ($expect_table) {
|
||||||
|
$persistence = $expect_table->getPersistenceType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($persistence) {
|
||||||
|
case PhabricatorConfigTableSchema::PERSISTENCE_CACHE:
|
||||||
|
// When dumping tables, leave the data in cache tables in the
|
||||||
|
// database. This will be automatically rebuild after the data
|
||||||
|
// is restored and does not need to be persisted in backups.
|
||||||
|
$with_data = false;
|
||||||
|
break;
|
||||||
|
case PhabricatorConfigTableSchema::PERSISTENCE_INDEX:
|
||||||
|
// When dumping tables, leave index data behind of the caller
|
||||||
|
// specified "--no-indexes". These tables can be rebuilt manually
|
||||||
|
// from other tables, but do not rebuild automatically.
|
||||||
|
$with_data = $with_indexes;
|
||||||
|
break;
|
||||||
|
case PhabricatorConfigTableSchema::PERSISTENCE_DATA:
|
||||||
|
default:
|
||||||
|
$with_data = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$targets[] = array(
|
||||||
|
'database' => $database_name,
|
||||||
|
'table' => $table_name,
|
||||||
|
'data' => $with_data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list($host, $port) = $this->getBareHostAndPort($api->getHost());
|
list($host, $port) = $this->getBareHostAndPort($api->getHost());
|
||||||
|
|
||||||
|
@ -126,35 +192,46 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
$argv[] = $port;
|
$argv[] = $port;
|
||||||
}
|
}
|
||||||
|
|
||||||
$argv[] = '--databases';
|
$commands = array();
|
||||||
foreach ($databases as $database) {
|
foreach ($targets as $target) {
|
||||||
$argv[] = $database;
|
$target_argv = $argv;
|
||||||
|
|
||||||
|
if (!$target['data']) {
|
||||||
|
$target_argv[] = '--no-data';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($has_password) {
|
||||||
|
$commands[] = csprintf(
|
||||||
|
'mysqldump -p%P %Ls -- %R %R',
|
||||||
|
$password,
|
||||||
|
$target_argv,
|
||||||
|
$target['database'],
|
||||||
|
$target['table']);
|
||||||
|
} else {
|
||||||
|
$command = csprintf(
|
||||||
|
'mysqldump %Ls -- %R %R',
|
||||||
|
$target_argv,
|
||||||
|
$target['database'],
|
||||||
|
$target['table']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$commands[] = $command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($has_password) {
|
|
||||||
$command = csprintf('mysqldump -p%P %Ls', $password, $argv);
|
|
||||||
} else {
|
|
||||||
$command = csprintf('mysqldump %Ls', $argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decrease the CPU priority of this process so it doesn't contend with
|
// Decrease the CPU priority of this process so it doesn't contend with
|
||||||
// other more important things.
|
// other more important things.
|
||||||
if (function_exists('proc_nice')) {
|
if (function_exists('proc_nice')) {
|
||||||
proc_nice(19);
|
proc_nice(19);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If we aren't writing to a file, just passthru the command.
|
|
||||||
if ($output_file === null) {
|
|
||||||
return phutil_passthru('%C', $command);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are writing to a file, stream the command output to disk. This
|
// If we are writing to a file, stream the command output to disk. This
|
||||||
// mode makes sure the whole command fails if there's an error (commonly,
|
// mode makes sure the whole command fails if there's an error (commonly,
|
||||||
// a full disk). See T6996 for discussion.
|
// a full disk). See T6996 for discussion.
|
||||||
|
|
||||||
if ($is_compress) {
|
if ($output_file === null) {
|
||||||
|
$file = null;
|
||||||
|
} else if ($is_compress) {
|
||||||
$file = gzopen($output_file, 'wb1');
|
$file = gzopen($output_file, 'wb1');
|
||||||
} else {
|
} else {
|
||||||
$file = fopen($output_file, 'wb');
|
$file = fopen($output_file, 'wb');
|
||||||
|
@ -167,41 +244,47 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
$file));
|
$file));
|
||||||
}
|
}
|
||||||
|
|
||||||
$future = new ExecFuture('%C', $command);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$iterator = id(new FutureIterator(array($future)))
|
foreach ($commands as $command) {
|
||||||
->setUpdateInterval(0.100);
|
$future = new ExecFuture('%C', $command);
|
||||||
foreach ($iterator as $ready) {
|
|
||||||
list($stdout, $stderr) = $future->read();
|
|
||||||
$future->discardBuffers();
|
|
||||||
|
|
||||||
if (strlen($stderr)) {
|
$iterator = id(new FutureIterator(array($future)))
|
||||||
fwrite(STDERR, $stderr);
|
->setUpdateInterval(0.100);
|
||||||
}
|
foreach ($iterator as $ready) {
|
||||||
|
list($stdout, $stderr) = $future->read();
|
||||||
|
$future->discardBuffers();
|
||||||
|
|
||||||
if (strlen($stdout)) {
|
if (strlen($stderr)) {
|
||||||
if ($is_compress) {
|
fwrite(STDERR, $stderr);
|
||||||
$ok = gzwrite($file, $stdout);
|
|
||||||
} else {
|
|
||||||
$ok = fwrite($file, $stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ok !== strlen($stdout)) {
|
if (strlen($stdout)) {
|
||||||
throw new Exception(
|
if (!$file) {
|
||||||
pht(
|
$ok = fwrite(STDOUT, $stdout);
|
||||||
'Failed to write %d byte(s) to file "%s".',
|
} else if ($is_compress) {
|
||||||
new PhutilNumber(strlen($stdout)),
|
$ok = gzwrite($file, $stdout);
|
||||||
$output_file));
|
} else {
|
||||||
}
|
$ok = fwrite($file, $stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ready !== null) {
|
if ($ok !== strlen($stdout)) {
|
||||||
$ready->resolvex();
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Failed to write %d byte(s) to file "%s".',
|
||||||
|
new PhutilNumber(strlen($stdout)),
|
||||||
|
$output_file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ready !== null) {
|
||||||
|
$ready->resolvex();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($is_compress) {
|
if (!$file) {
|
||||||
|
$ok = true;
|
||||||
|
} else if ($is_compress) {
|
||||||
$ok = gzclose($file);
|
$ok = gzclose($file);
|
||||||
} else {
|
} else {
|
||||||
$ok = fclose($file);
|
$ok = fclose($file);
|
||||||
|
@ -218,7 +301,9 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
// we don't leave any confusing artifacts laying around.
|
// we don't leave any confusing artifacts laying around.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Filesystem::remove($output_file);
|
if ($file !== null) {
|
||||||
|
Filesystem::remove($output_file);
|
||||||
|
}
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
// Ignore any errors we hit.
|
// Ignore any errors we hit.
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue