1
0
Fork 0
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:
epriestley 2014-09-19 11:46:44 -07:00
parent 7dabc21154
commit 84568eba84
16 changed files with 207 additions and 7 deletions

View file

@ -0,0 +1 @@
DROP TABLE {$NAMESPACE}_maniphest.maniphest_taskauxiliarystorage;

View file

@ -0,0 +1 @@
DROP TABLE {$NAMESPACE}_maniphest.maniphest_taskproject;

View file

@ -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',

View file

@ -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)),

View file

@ -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) {

View file

@ -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) {

View file

@ -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);

View file

@ -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)';

View file

@ -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();
}

View 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(),
));
}
}

View file

@ -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();
}

View file

@ -113,6 +113,11 @@ abstract class PhabricatorApplicationTransaction
'contentSource' => 'text',
'transactionType' => 'text32',
),
self::CONFIG_KEY_SCHEMA => array(
'key_object' => array(
'columns' => array('objectPHID'),
),
),
) + parent::getConfiguration();
}

View file

@ -38,6 +38,7 @@ abstract class PhabricatorApplicationTransactionComment
self::CONFIG_KEY_SCHEMA => array(
'key_version' => array(
'columns' => array('transactionPHID', 'commentVersion'),
'unique' => true,
),
),
) + parent::getConfiguration();

View file

@ -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,

View file

@ -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();
}

View file

@ -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,