Differential D10499 Diff 25269 src/applications/config/controller/PhabricatorConfigDatabaseController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/config/controller/PhabricatorConfigDatabaseController.php
<?php | <?php | ||||
final class PhabricatorConfigDatabaseController | final class PhabricatorConfigDatabaseController | ||||
extends PhabricatorConfigController { | extends PhabricatorConfigController { | ||||
const MAX_INNODB_KEY_LENGTH = 767; | |||||
private $database; | private $database; | ||||
private $table; | private $table; | ||||
private $column; | private $column; | ||||
private $key; | |||||
public function willProcessRequest(array $data) { | public function willProcessRequest(array $data) { | ||||
$this->database = idx($data, 'database'); | $this->database = idx($data, 'database'); | ||||
$this->table = idx($data, 'table'); | $this->table = idx($data, 'table'); | ||||
$this->column = idx($data, 'column'); | $this->column = idx($data, 'column'); | ||||
$this->key = idx($data, 'key'); | |||||
} | } | ||||
public function processRequest() { | public function processRequest() { | ||||
$request = $this->getRequest(); | $request = $this->getRequest(); | ||||
$viewer = $request->getUser(); | $viewer = $request->getUser(); | ||||
$conf = PhabricatorEnv::newObjectFromConfig( | $conf = PhabricatorEnv::newObjectFromConfig( | ||||
'mysql.configuration-provider', | 'mysql.configuration-provider', | ||||
Show All 16 Lines | public function processRequest() { | ||||
if ($this->column) { | if ($this->column) { | ||||
return $this->renderColumn( | return $this->renderColumn( | ||||
$comp, | $comp, | ||||
$expect, | $expect, | ||||
$actual, | $actual, | ||||
$this->database, | $this->database, | ||||
$this->table, | $this->table, | ||||
$this->column); | $this->column); | ||||
} else if ($this->key) { | |||||
return $this->renderKey( | |||||
$comp, | |||||
$expect, | |||||
$actual, | |||||
$this->database, | |||||
$this->table, | |||||
$this->key); | |||||
} else if ($this->table) { | } else if ($this->table) { | ||||
return $this->renderTable( | return $this->renderTable( | ||||
$comp, | $comp, | ||||
$expect, | $expect, | ||||
$actual, | $actual, | ||||
$this->database, | $this->database, | ||||
$this->table); | $this->table); | ||||
} else if ($this->database) { | } else if ($this->database) { | ||||
Show All 18 Lines | private function buildResponse($title, $body) { | ||||
if ($this->database) { | if ($this->database) { | ||||
$crumbs->addTextCrumb( | $crumbs->addTextCrumb( | ||||
pht('Database Status'), | pht('Database Status'), | ||||
$this->getApplicationURI('database/')); | $this->getApplicationURI('database/')); | ||||
if ($this->table) { | if ($this->table) { | ||||
$crumbs->addTextCrumb( | $crumbs->addTextCrumb( | ||||
$this->database, | $this->database, | ||||
$this->getApplicationURI('database/'.$this->database.'/')); | $this->getApplicationURI('database/'.$this->database.'/')); | ||||
if ($this->column) { | if ($this->column || $this->key) { | ||||
$crumbs->addTextCrumb( | $crumbs->addTextCrumb( | ||||
$this->table, | $this->table, | ||||
$this->getApplicationURI( | $this->getApplicationURI( | ||||
'database/'.$this->database.'/'.$this->table.'/')); | 'database/'.$this->database.'/'.$this->table.'/')); | ||||
if ($this->column) { | |||||
$crumbs->addTextCrumb($this->column); | $crumbs->addTextCrumb($this->column); | ||||
} else { | } else { | ||||
$crumbs->addTextCrumb($this->key); | |||||
} | |||||
} else { | |||||
$crumbs->addTextCrumb($this->table); | $crumbs->addTextCrumb($this->table); | ||||
} | } | ||||
} else { | } else { | ||||
$crumbs->addTextCrumb($this->database); | $crumbs->addTextCrumb($this->database); | ||||
} | } | ||||
} else { | } else { | ||||
$crumbs->addTextCrumb(pht('Database Status')); | $crumbs->addTextCrumb(pht('Database Status')); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 176 Lines • ▼ Show 20 Lines | private function renderTable( | ||||
PhabricatorConfigServerSchema $expect, | PhabricatorConfigServerSchema $expect, | ||||
PhabricatorConfigServerSchema $actual, | PhabricatorConfigServerSchema $actual, | ||||
$database_name, | $database_name, | ||||
$table_name) { | $table_name) { | ||||
$type_issue = PhabricatorConfigStorageSchema::ISSUE_COLUMNTYPE; | $type_issue = PhabricatorConfigStorageSchema::ISSUE_COLUMNTYPE; | ||||
$charset_issue = PhabricatorConfigStorageSchema::ISSUE_CHARSET; | $charset_issue = PhabricatorConfigStorageSchema::ISSUE_CHARSET; | ||||
$collation_issue = PhabricatorConfigStorageSchema::ISSUE_COLLATION; | $collation_issue = PhabricatorConfigStorageSchema::ISSUE_COLLATION; | ||||
$nullable_issue = PhabricatorConfigStorageSchema::ISSUE_NULLABLE; | |||||
$database = $comp->getDatabase($database_name); | $database = $comp->getDatabase($database_name); | ||||
if (!$database) { | if (!$database) { | ||||
return new Aphront404Response(); | return new Aphront404Response(); | ||||
} | } | ||||
$table = $database->getTable($table_name); | $table = $database->getTable($table_name); | ||||
if (!$table) { | if (!$table) { | ||||
Show All 30 Lines | foreach ($table->getColumns() as $column_name => $column) { | ||||
$this->renderIcon($status), | $this->renderIcon($status), | ||||
phutil_tag( | phutil_tag( | ||||
'a', | 'a', | ||||
array( | array( | ||||
'href' => $this->getApplicationURI( | 'href' => $this->getApplicationURI( | ||||
'database/'. | 'database/'. | ||||
$database_name.'/'. | $database_name.'/'. | ||||
$table_name.'/'. | $table_name.'/'. | ||||
'col/'. | |||||
$column_name.'/'), | $column_name.'/'), | ||||
), | ), | ||||
$column_name), | $column_name), | ||||
$data_type, | $data_type, | ||||
$this->renderAttr( | $this->renderAttr( | ||||
$column->getColumnType(), | $column->getColumnType(), | ||||
$column->hasIssue($type_issue)), | $column->hasIssue($type_issue)), | ||||
$this->renderAttr( | $this->renderAttr( | ||||
$column->getNullable() | |||||
? pht('Yes') | |||||
: pht('No'), | |||||
$column->hasIssue($nullable_issue)), | |||||
$this->renderAttr( | |||||
$column->getCharacterSet(), | $column->getCharacterSet(), | ||||
$column->hasIssue($charset_issue)), | $column->hasIssue($charset_issue)), | ||||
$this->renderAttr( | $this->renderAttr( | ||||
$column->getCollation(), | $column->getCollation(), | ||||
$column->hasIssue($collation_issue)), | $column->hasIssue($collation_issue)), | ||||
); | ); | ||||
} | } | ||||
$table_view = id(new AphrontTableView($rows)) | $table_view = id(new AphrontTableView($rows)) | ||||
->setHeaders( | ->setHeaders( | ||||
array( | array( | ||||
null, | null, | ||||
pht('Table'), | pht('Column'), | ||||
pht('Data Type'), | pht('Data Type'), | ||||
pht('Column Type'), | pht('Column Type'), | ||||
pht('Nullable'), | |||||
pht('Character Set'), | pht('Character Set'), | ||||
pht('Collation'), | pht('Collation'), | ||||
)) | )) | ||||
->setColumnClasses( | ->setColumnClasses( | ||||
array( | array( | ||||
null, | null, | ||||
'wide pri', | 'wide pri', | ||||
null, | null, | ||||
null, | null, | ||||
null, | null, | ||||
null | null | ||||
)); | )); | ||||
$key_rows = array(); | |||||
foreach ($table->getKeys() as $key_name => $key) { | |||||
$expect_key = null; | |||||
if ($expect_table) { | |||||
$expect_key = $expect_table->getKey($key_name); | |||||
} | |||||
$status = $key->getStatus(); | |||||
$size = 0; | |||||
foreach ($key->getColumnNames() as $column_name) { | |||||
$column = $table->getColumn($column_name); | |||||
if (!$column) { | |||||
$size = 0; | |||||
break; | |||||
} | |||||
$size += $column->getKeyByteLength(); | |||||
} | |||||
$size_formatted = null; | |||||
if ($size) { | |||||
$size_formatted = $this->renderAttr( | |||||
$size, | |||||
($size > self::MAX_INNODB_KEY_LENGTH)); | |||||
btrahan: 767 ==> self::MAX_INNODB_KEY_LENGTH or something? | |||||
} | |||||
$key_rows[] = array( | |||||
$this->renderIcon($status), | |||||
phutil_tag( | |||||
'a', | |||||
array( | |||||
'href' => $this->getApplicationURI( | |||||
'database/'. | |||||
$database_name.'/'. | |||||
$table_name.'/'. | |||||
'key/'. | |||||
$key_name.'/'), | |||||
), | |||||
$key_name), | |||||
implode(', ', $key->getColumnNames()), | |||||
$size_formatted, | |||||
); | |||||
} | |||||
$keys_view = id(new AphrontTableView($key_rows)) | |||||
->setHeaders( | |||||
array( | |||||
null, | |||||
pht('Key'), | |||||
pht('Columns'), | |||||
pht('Size'), | |||||
)) | |||||
->setColumnClasses( | |||||
array( | |||||
null, | |||||
'wide pri', | |||||
null, | |||||
null, | |||||
)); | |||||
$title = pht('Database Status: %s.%s', $database_name, $table_name); | $title = pht('Database Status: %s.%s', $database_name, $table_name); | ||||
if ($actual_table) { | if ($actual_table) { | ||||
$actual_collation = $actual_table->getCollation(); | $actual_collation = $actual_table->getCollation(); | ||||
} else { | } else { | ||||
$actual_collation = null; | $actual_collation = null; | ||||
} | } | ||||
Show All 14 Lines | $properties = $this->buildProperties( | ||||
$expect_collation, | $expect_collation, | ||||
), | ), | ||||
), | ), | ||||
$table->getIssues()); | $table->getIssues()); | ||||
$box = id(new PHUIObjectBoxView()) | $box = id(new PHUIObjectBoxView()) | ||||
->setHeaderText($title) | ->setHeaderText($title) | ||||
->addPropertyList($properties) | ->addPropertyList($properties) | ||||
->appendChild($table_view); | ->appendChild($table_view) | ||||
->appendChild($keys_view); | |||||
return $this->buildResponse($title, $box); | return $this->buildResponse($title, $box); | ||||
} | } | ||||
private function renderColumn( | private function renderColumn( | ||||
PhabricatorConfigServerSchema $comp, | PhabricatorConfigServerSchema $comp, | ||||
PhabricatorConfigServerSchema $expect, | PhabricatorConfigServerSchema $expect, | ||||
PhabricatorConfigServerSchema $actual, | PhabricatorConfigServerSchema $actual, | ||||
$database_name, | $database_name, | ||||
$table_name, | $table_name, | ||||
$column_name) { | $column_name) { | ||||
$database = $comp->getDatabase($database_name); | $database = $comp->getDatabase($database_name); | ||||
if (!$database) { | if (!$database) { | ||||
return new Aphront404Response(); | return new Aphront404Response(); | ||||
} | } | ||||
$table = $database->getTable($table_name); | $table = $database->getTable($table_name); | ||||
if (!$table) { | if (!$table) { | ||||
return new Aphront404Response(); | return new Aphront404Response(); | ||||
} | } | ||||
$column = $table->getColumn($column_name); | $column = $table->getColumn($column_name); | ||||
if (!$table) { | if (!$column) { | ||||
return new Aphront404Response(); | return new Aphront404Response(); | ||||
} | } | ||||
$actual_database = $actual->getDatabase($database_name); | $actual_database = $actual->getDatabase($database_name); | ||||
$actual_table = null; | $actual_table = null; | ||||
$actual_column = null; | $actual_column = null; | ||||
if ($actual_database) { | if ($actual_database) { | ||||
$actual_table = $actual_database->getTable($table_name); | $actual_table = $actual_database->getTable($table_name); | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | $properties = $this->buildProperties( | ||||
$column->getIssues()); | $column->getIssues()); | ||||
$box = id(new PHUIObjectBoxView()) | $box = id(new PHUIObjectBoxView()) | ||||
->setHeaderText($title) | ->setHeaderText($title) | ||||
->addPropertyList($properties); | ->addPropertyList($properties); | ||||
return $this->buildResponse($title, $box); | return $this->buildResponse($title, $box); | ||||
} | } | ||||
private function renderKey( | |||||
PhabricatorConfigServerSchema $comp, | |||||
PhabricatorConfigServerSchema $expect, | |||||
PhabricatorConfigServerSchema $actual, | |||||
$database_name, | |||||
$table_name, | |||||
$key_name) { | |||||
$database = $comp->getDatabase($database_name); | |||||
if (!$database) { | |||||
return new Aphront404Response(); | |||||
} | |||||
$table = $database->getTable($table_name); | |||||
if (!$table) { | |||||
return new Aphront404Response(); | |||||
} | |||||
$key = $table->getKey($key_name); | |||||
if (!$key) { | |||||
return new Aphront404Response(); | |||||
} | |||||
$actual_database = $actual->getDatabase($database_name); | |||||
$actual_table = null; | |||||
$actual_key = null; | |||||
if ($actual_database) { | |||||
$actual_table = $actual_database->getTable($table_name); | |||||
if ($actual_table) { | |||||
$actual_key = $actual_table->getKey($key_name); | |||||
} | |||||
} | |||||
$expect_database = $expect->getDatabase($database_name); | |||||
$expect_table = null; | |||||
$expect_key = null; | |||||
if ($expect_database) { | |||||
$expect_table = $expect_database->getTable($table_name); | |||||
if ($expect_table) { | |||||
$expect_key = $expect_table->getKey($key_name); | |||||
} | |||||
} | |||||
if ($actual_key) { | |||||
$actual_columns = $actual_key->getColumnNames(); | |||||
} else { | |||||
$actual_columns = array(); | |||||
} | |||||
if ($expect_key) { | |||||
$expect_columns = $expect_key->getColumnNames(); | |||||
} else { | |||||
$expect_columns = array(); | |||||
} | |||||
$title = pht( | |||||
'Database Status: %s.%s (%s)', | |||||
$database_name, | |||||
$table_name, | |||||
$key_name); | |||||
$properties = $this->buildProperties( | |||||
array( | |||||
array( | |||||
pht('Columns'), | |||||
implode(', ', $actual_columns), | |||||
), | |||||
array( | |||||
pht('Expected Columns'), | |||||
implode(', ', $expect_columns), | |||||
), | |||||
), | |||||
$key->getIssues()); | |||||
$box = id(new PHUIObjectBoxView()) | |||||
->setHeaderText($title) | |||||
->addPropertyList($properties); | |||||
return $this->buildResponse($title, $box); | |||||
} | |||||
private function renderIcon($status) { | private function renderIcon($status) { | ||||
switch ($status) { | switch ($status) { | ||||
case PhabricatorConfigStorageSchema::STATUS_OKAY: | case PhabricatorConfigStorageSchema::STATUS_OKAY: | ||||
$icon = 'fa-check-circle green'; | $icon = 'fa-check-circle green'; | ||||
break; | break; | ||||
case PhabricatorConfigStorageSchema::STATUS_WARN: | case PhabricatorConfigStorageSchema::STATUS_WARN: | ||||
$icon = 'fa-exclamation-circle yellow'; | $icon = 'fa-exclamation-circle yellow'; | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 69 Lines • Show Last 20 Lines |
767 ==> self::MAX_INNODB_KEY_LENGTH or something?