mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-19 18:28:39 +01:00
Generate expected schemata for Maniphest
Summary: Ref T1191. - Adds support for custom fields. - Adds support for partial indexes (indexes on a prefix of a column). - Drops old auxiliary storage table: this was moved to custom field storage about a year ago. - Drops old project table: this was moved to edges about two months ago. Test Plan: - Viewed web UI, saw fewer issues. - Used `grep` to verify no readers/writers for storage or project table. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T1191 Differential Revision: https://secure.phabricator.com/D10526
This commit is contained in:
parent
7dabc21154
commit
84568eba84
16 changed files with 207 additions and 7 deletions
1
resources/sql/autopatches/20140919.schema.03.dropaux.sql
Normal file
1
resources/sql/autopatches/20140919.schema.03.dropaux.sql
Normal file
|
@ -0,0 +1 @@
|
|||
DROP TABLE {$NAMESPACE}_maniphest.maniphest_taskauxiliarystorage;
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE {$NAMESPACE}_maniphest.maniphest_taskproject;
|
|
@ -918,6 +918,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestRemarkupRule' => 'applications/maniphest/remarkup/ManiphestRemarkupRule.php',
|
||||
'ManiphestReplyHandler' => 'applications/maniphest/mail/ManiphestReplyHandler.php',
|
||||
'ManiphestReportController' => 'applications/maniphest/controller/ManiphestReportController.php',
|
||||
'ManiphestSchemaSpec' => 'applications/maniphest/storage/ManiphestSchemaSpec.php',
|
||||
'ManiphestSearchIndexer' => 'applications/maniphest/search/ManiphestSearchIndexer.php',
|
||||
'ManiphestStatusConfigOptionType' => 'applications/maniphest/config/ManiphestStatusConfigOptionType.php',
|
||||
'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php',
|
||||
|
@ -3800,6 +3801,7 @@ phutil_register_library_map(array(
|
|||
'ManiphestRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||
'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler',
|
||||
'ManiphestReportController' => 'ManiphestController',
|
||||
'ManiphestSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'ManiphestSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
|
||||
'ManiphestStatusConfigOptionType' => 'PhabricatorConfigJSONOptionType',
|
||||
'ManiphestSubpriorityController' => 'ManiphestController',
|
||||
|
|
|
@ -280,6 +280,7 @@ final class PhabricatorConfigDatabaseStatusController
|
|||
$collation_issue = PhabricatorConfigStorageSchema::ISSUE_COLLATION;
|
||||
$nullable_issue = PhabricatorConfigStorageSchema::ISSUE_NULLABLE;
|
||||
$unique_issue = PhabricatorConfigStorageSchema::ISSUE_UNIQUE;
|
||||
$columns_issue = PhabricatorConfigStorageSchema::ISSUE_KEYCOLUMNS;
|
||||
|
||||
$database = $comp->getDatabase($database_name);
|
||||
if (!$database) {
|
||||
|
@ -377,13 +378,14 @@ final class PhabricatorConfigDatabaseStatusController
|
|||
$status = $key->getStatus();
|
||||
|
||||
$size = 0;
|
||||
foreach ($key->getColumnNames() as $column_name) {
|
||||
foreach ($key->getColumnNames() as $column_spec) {
|
||||
list($column_name, $prefix) = $key->getKeyColumnAndPrefix($column_spec);
|
||||
$column = $table->getColumn($column_name);
|
||||
if (!$column) {
|
||||
$size = 0;
|
||||
break;
|
||||
}
|
||||
$size += $column->getKeyByteLength();
|
||||
$size += $column->getKeyByteLength($prefix);
|
||||
}
|
||||
|
||||
$size_formatted = null;
|
||||
|
@ -406,7 +408,9 @@ final class PhabricatorConfigDatabaseStatusController
|
|||
$key_name.'/'),
|
||||
),
|
||||
$key_name),
|
||||
implode(', ', $key->getColumnNames()),
|
||||
$this->renderAttr(
|
||||
implode(', ', $key->getColumnNames()),
|
||||
$key->hasIssue($columns_issue)),
|
||||
$this->renderAttr(
|
||||
$this->renderBoolean($key->getUnique()),
|
||||
$key->hasIssue($unique_issue)),
|
||||
|
|
|
@ -58,20 +58,47 @@ final class PhabricatorConfigColumnSchema
|
|||
return $this->characterSet;
|
||||
}
|
||||
|
||||
public function getKeyByteLength() {
|
||||
public function getKeyByteLength($prefix = null) {
|
||||
$type = $this->getColumnType();
|
||||
|
||||
$matches = null;
|
||||
if (preg_match('/^varchar\((\d+)\)$/', $type, $matches)) {
|
||||
// For utf8mb4, each character requires 4 bytes.
|
||||
return ((int)$matches[1]) * 4;
|
||||
$size = (int)$matches[1];
|
||||
if ($prefix && $prefix < $size) {
|
||||
$size = $prefix;
|
||||
}
|
||||
return $size * 4;
|
||||
}
|
||||
|
||||
$matches = null;
|
||||
if (preg_match('/^char\((\d+)\)$/', $type, $matches)) {
|
||||
// We use char() only for fixed-length binary data, so its size
|
||||
// is always the column size.
|
||||
return ((int)$matches[1]);
|
||||
$size = (int)$matches[1];
|
||||
if ($prefix && $prefix < $size) {
|
||||
$size = $prefix;
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
|
||||
// The "long..." types are arbitrarily long, so just use a big number to
|
||||
// get the point across. In practice, these should always index only a
|
||||
// prefix.
|
||||
if ($type == 'longtext') {
|
||||
$size = (1 << 16);
|
||||
if ($prefix && $prefix < $size) {
|
||||
$size = $prefix;
|
||||
}
|
||||
return $size * 4;
|
||||
}
|
||||
|
||||
if ($type == 'longblob') {
|
||||
$size = (1 << 16);
|
||||
if ($prefix && $prefix < $size) {
|
||||
$size = $prefix;
|
||||
}
|
||||
return $size * 1;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
|
|
|
@ -28,6 +28,15 @@ final class PhabricatorConfigKeySchema
|
|||
return array();
|
||||
}
|
||||
|
||||
public function getKeyColumnAndPrefix($column_name) {
|
||||
$matches = null;
|
||||
if (preg_match('/^(.*)\((\d+)\)\z/', $column_name, $matches)) {
|
||||
return array($matches[1], (int)$matches[2]);
|
||||
} else {
|
||||
return array($column_name, null);
|
||||
}
|
||||
}
|
||||
|
||||
public function compareToSimilarSchema(
|
||||
PhabricatorConfigStorageSchema $expect) {
|
||||
|
||||
|
|
|
@ -115,9 +115,20 @@ final class PhabricatorConfigSchemaQuery extends Phobject {
|
|||
foreach ($keys as $key_name => $key_pieces) {
|
||||
$key_pieces = isort($key_pieces, 'Seq_in_index');
|
||||
$head = head($key_pieces);
|
||||
|
||||
// This handles string indexes which index only a prefix of a field.
|
||||
$column_names = array();
|
||||
foreach ($key_pieces as $piece) {
|
||||
$name = $piece['Column_name'];
|
||||
if ($piece['Sub_part']) {
|
||||
$name = $name.'('.$piece['Sub_part'].')';
|
||||
}
|
||||
$column_names[] = $name;
|
||||
}
|
||||
|
||||
$key_schema = id(new PhabricatorConfigKeySchema())
|
||||
->setName($key_name)
|
||||
->setColumnNames(ipull($key_pieces, 'Column_name'))
|
||||
->setColumnNames($column_names)
|
||||
->setUnique(!$head['Non_unique']);
|
||||
|
||||
$table_schema->addKey($key_schema);
|
||||
|
|
|
@ -56,6 +56,16 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
protected function buildCustomFieldSchemata(
|
||||
PhabricatorLiskDAO $storage,
|
||||
array $indexes) {
|
||||
|
||||
$this->buildLiskObjectSchema($storage);
|
||||
foreach ($indexes as $index) {
|
||||
$this->buildLiskObjectSchema($index);
|
||||
}
|
||||
}
|
||||
|
||||
private function buildLiskObjectSchema(PhabricatorLiskDAO $object) {
|
||||
$this->buildRawSchema(
|
||||
$object->getApplicationName(),
|
||||
|
@ -123,6 +133,10 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
|||
array(
|
||||
'PRIMARY' => array(
|
||||
'columns' => array('src', 'type', 'dst'),
|
||||
'unique' => true,
|
||||
),
|
||||
'src' => array(
|
||||
'columns' => array('src', 'type', 'dateCreated', 'seq'),
|
||||
),
|
||||
));
|
||||
|
||||
|
@ -136,6 +150,7 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
|||
array(
|
||||
'PRIMARY' => array(
|
||||
'columns' => array('id'),
|
||||
'unique' => true,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
@ -217,6 +232,9 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
|||
case 'uint64':
|
||||
$column_type = 'bigint(20) unsigned';
|
||||
break;
|
||||
case 'sint64':
|
||||
$column_type = 'bigint(20)';
|
||||
break;
|
||||
case 'phid':
|
||||
case 'policy';
|
||||
$column_type = 'varchar(64)';
|
||||
|
|
|
@ -12,6 +12,18 @@ final class ManiphestNameIndex extends ManiphestDAO {
|
|||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_TIMESTAMPS => false,
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'indexedObjectName' => 'text128',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_phid' => array(
|
||||
'columns' => array('indexedObjectPHID'),
|
||||
'unique' => true,
|
||||
),
|
||||
'key_name' => array(
|
||||
'columns' => array('indexedObjectName'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
|
|
22
src/applications/maniphest/storage/ManiphestSchemaSpec.php
Normal file
22
src/applications/maniphest/storage/ManiphestSchemaSpec.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
final class ManiphestSchemaSpec
|
||||
extends PhabricatorConfigSchemaSpec {
|
||||
|
||||
public function buildSchemata() {
|
||||
$this->buildLiskSchemata('ManiphestDAO');
|
||||
|
||||
$this->buildEdgeSchemata(new ManiphestTask());
|
||||
$this->buildTransactionSchema(
|
||||
new ManiphestTransaction(),
|
||||
new ManiphestTransactionComment());
|
||||
|
||||
$this->buildCustomFieldSchemata(
|
||||
new ManiphestCustomFieldStorage(),
|
||||
array(
|
||||
new ManiphestCustomFieldNumericIndex(),
|
||||
new ManiphestCustomFieldStringIndex(),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -67,6 +67,49 @@ final class ManiphestTask extends ManiphestDAO
|
|||
'attached' => self::SERIALIZATION_JSON,
|
||||
'projectPHIDs' => self::SERIALIZATION_JSON,
|
||||
),
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'ownerPHID' => 'phid?',
|
||||
'status' => 'text12',
|
||||
'priority' => 'uint32',
|
||||
'title' => 'text',
|
||||
'originalTitle' => 'text',
|
||||
'description' => 'text',
|
||||
'mailKey' => 'bytes20',
|
||||
'ownerOrdering' => 'text64?',
|
||||
'originalEmailSource' => 'text255?',
|
||||
'subpriority' => 'double',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_phid' => null,
|
||||
'phid' => array(
|
||||
'columns' => array('phid'),
|
||||
'unique' => true,
|
||||
),
|
||||
'priority' => array(
|
||||
'columns' => array('priority', 'status'),
|
||||
),
|
||||
'status' => array(
|
||||
'columns' => array('status'),
|
||||
),
|
||||
'ownerPHID' => array(
|
||||
'columns' => array('ownerPHID', 'status'),
|
||||
),
|
||||
'authorPHID' => array(
|
||||
'columns' => array('authorPHID', 'status'),
|
||||
),
|
||||
'ownerOrdering' => array(
|
||||
'columns' => array('ownerOrdering'),
|
||||
),
|
||||
'priority_2' => array(
|
||||
'columns' => array('priority', 'subpriority'),
|
||||
),
|
||||
'key_dateCreated' => array(
|
||||
'columns' => array('dateCreated'),
|
||||
),
|
||||
'key_dateModified' => array(
|
||||
'columns' => array('dateModified'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,11 @@ abstract class PhabricatorApplicationTransaction
|
|||
'contentSource' => 'text',
|
||||
'transactionType' => 'text32',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_object' => array(
|
||||
'columns' => array('objectPHID'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ abstract class PhabricatorApplicationTransactionComment
|
|||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_version' => array(
|
||||
'columns' => array('transactionPHID', 'commentVersion'),
|
||||
'unique' => true,
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
|
|
|
@ -3,6 +3,23 @@
|
|||
abstract class PhabricatorCustomFieldNumericIndexStorage
|
||||
extends PhabricatorCustomFieldIndexStorage {
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'indexKey' => 'bytes12',
|
||||
'indexValue' => 'sint64',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_join' => array(
|
||||
'columns' => array('objectPHID', 'indexKey', 'indexValue'),
|
||||
),
|
||||
'key_find' => array(
|
||||
'columns' => array('indexKey', 'indexValue'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function formatForInsert(AphrontDatabaseConnection $conn) {
|
||||
return qsprintf(
|
||||
$conn,
|
||||
|
|
|
@ -10,6 +10,16 @@ abstract class PhabricatorCustomFieldStorage
|
|||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_TIMESTAMPS => false,
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'fieldIndex' => 'bytes12',
|
||||
'fieldValue' => 'text',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'objectPHID' => array(
|
||||
'columns' => array('objectPHID', 'fieldIndex'),
|
||||
'unique' => true,
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,23 @@
|
|||
abstract class PhabricatorCustomFieldStringIndexStorage
|
||||
extends PhabricatorCustomFieldIndexStorage {
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'indexKey' => 'bytes12',
|
||||
'indexValue' => 'text',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_join' => array(
|
||||
'columns' => array('objectPHID', 'indexKey', 'indexValue(64)'),
|
||||
),
|
||||
'key_find' => array(
|
||||
'columns' => array('indexKey', 'indexValue(64)'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function formatForInsert(AphrontDatabaseConnection $conn) {
|
||||
return qsprintf(
|
||||
$conn,
|
||||
|
|
Loading…
Add table
Reference in a new issue