Load all keys, support unique keys, and provide an "all issues" view

Summary:
Ref T1191. Three parts:

  - The old way of getting key information only got primary / unique / foreign keys, not all keys. Use `SHOW INDEXES` to get all keys instead.
  - Track key uniqueness and raise warnings about it.
  - Add a new "all issues" view to show an expanded, flat view of all issues. This is just an easier way to get a list so you don't have to dig around in the hierarchical view.

Test Plan:
{F206351}

{F206352}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T1191

Differential Revision: https://secure.phabricator.com/D10525
This commit is contained in:
epriestley
2014-09-19 11:46:30 -07:00
parent 6bfe8b5984
commit 7dabc21154
11 changed files with 958 additions and 734 deletions

View File

@@ -0,0 +1,167 @@
<?php
final class PhabricatorConfigDatabaseIssueController
extends PhabricatorConfigDatabaseController {
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$query = $this->buildSchemaQuery();
$actual = $query->loadActualSchema();
$expect = $query->loadExpectedSchema();
$comp = $query->buildComparisonSchema($expect, $actual);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Database Issues'));
// Collect all open issues.
$issues = array();
foreach ($comp->getDatabases() as $database_name => $database) {
foreach ($database->getLocalIssues() as $issue) {
$issues[] = array(
$database_name,
null,
null,
null,
$issue);
}
foreach ($database->getTables() as $table_name => $table) {
foreach ($table->getLocalIssues() as $issue) {
$issues[] = array(
$database_name,
$table_name,
null,
null,
$issue);
}
foreach ($table->getColumns() as $column_name => $column) {
foreach ($column->getLocalIssues() as $issue) {
$issues[] = array(
$database_name,
$table_name,
'column',
$column_name,
$issue);
}
}
foreach ($table->getKeys() as $key_name => $key) {
foreach ($key->getLocalIssues() as $issue) {
$issues[] = array(
$database_name,
$table_name,
'key',
$key_name,
$issue);
}
}
}
}
// Sort all open issues so that the most severe issues appear first.
$order = array();
$counts = array();
foreach ($issues as $key => $issue) {
$const = $issue[4];
$status = PhabricatorConfigStorageSchema::getIssueStatus($const);
$severity = PhabricatorConfigStorageSchema::getStatusSeverity($status);
$order[$key] = sprintf(
'~%d~%s%s%s',
9 - $severity,
$issue[0],
$issue[1],
$issue[3]);
if (empty($counts[$status])) {
$counts[$status] = 0;
}
$counts[$status]++;
}
asort($order);
$issues = array_select_keys($issues, array_keys($order));
// Render the issues.
$rows = array();
foreach ($issues as $issue) {
$const = $issue[4];
$rows[] = array(
$this->renderIcon(
PhabricatorConfigStorageSchema::getIssueStatus($const)),
$issue[0],
$issue[1],
$issue[2],
$issue[3],
PhabricatorConfigStorageSchema::getIssueDescription($const),
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
null,
pht('Database'),
pht('Table'),
pht('Type'),
pht('Column/Key'),
pht('Issue'),
))
->setColumnClasses(
array(
null,
null,
null,
null,
null,
'wide',
));
$errors = array();
$errors[] = pht(
'IMPORTANT: This feature is in development and the information below '.
'is not accurate! Ignore it for now. See T1191.');
if (isset($counts[PhabricatorConfigStorageSchema::STATUS_FAIL])) {
$errors[] = pht(
'Detected %s serious issue(s) with the schemata.',
new PhutilNumber($counts[PhabricatorConfigStorageSchema::STATUS_FAIL]));
}
if (isset($counts[PhabricatorConfigStorageSchema::STATUS_WARN])) {
$errors[] = pht(
'Detected %s warning(s) with the schemata.',
new PhutilNumber($counts[PhabricatorConfigStorageSchema::STATUS_WARN]));
}
if (isset($counts[PhabricatorConfigStorageSchema::STATUS_NOTE])) {
$errors[] = pht(
'Detected %s minor issue(s) with the scheamata.',
new PhutilNumber($counts[PhabricatorConfigStorageSchema::STATUS_NOTE]));
}
$table_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Database Issues'))
->setFormErrors($errors)
->appendChild($table);
$nav = $this->buildSideNavView();
$nav->selectFilter('dbissue/');
$nav->appendChild(
array(
$crumbs,
$table_box,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => 'all',
));
}
}