[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PhabricatorConfigDatabaseStatusController 4 extends PhabricatorConfigDatabaseController { 5 6 private $database; 7 private $table; 8 private $column; 9 private $key; 10 11 public function willProcessRequest(array $data) { 12 $this->database = idx($data, 'database'); 13 $this->table = idx($data, 'table'); 14 $this->column = idx($data, 'column'); 15 $this->key = idx($data, 'key'); 16 } 17 18 public function processRequest() { 19 $request = $this->getRequest(); 20 $viewer = $request->getUser(); 21 22 $query = $this->buildSchemaQuery(); 23 24 $actual = $query->loadActualSchema(); 25 $expect = $query->loadExpectedSchema(); 26 $comp = $query->buildComparisonSchema($expect, $actual); 27 28 if ($this->column) { 29 return $this->renderColumn( 30 $comp, 31 $expect, 32 $actual, 33 $this->database, 34 $this->table, 35 $this->column); 36 } else if ($this->key) { 37 return $this->renderKey( 38 $comp, 39 $expect, 40 $actual, 41 $this->database, 42 $this->table, 43 $this->key); 44 } else if ($this->table) { 45 return $this->renderTable( 46 $comp, 47 $expect, 48 $actual, 49 $this->database, 50 $this->table); 51 } else if ($this->database) { 52 return $this->renderDatabase( 53 $comp, 54 $expect, 55 $actual, 56 $this->database); 57 } else { 58 return $this->renderServer( 59 $comp, 60 $expect, 61 $actual); 62 } 63 } 64 65 private function buildResponse($title, $body) { 66 $nav = $this->buildSideNavView(); 67 $nav->selectFilter('database/'); 68 69 $crumbs = $this->buildApplicationCrumbs(); 70 if ($this->database) { 71 $crumbs->addTextCrumb( 72 pht('Database Status'), 73 $this->getApplicationURI('database/')); 74 if ($this->table) { 75 $crumbs->addTextCrumb( 76 $this->database, 77 $this->getApplicationURI('database/'.$this->database.'/')); 78 if ($this->column || $this->key) { 79 $crumbs->addTextCrumb( 80 $this->table, 81 $this->getApplicationURI( 82 'database/'.$this->database.'/'.$this->table.'/')); 83 if ($this->column) { 84 $crumbs->addTextCrumb($this->column); 85 } else { 86 $crumbs->addTextCrumb($this->key); 87 } 88 } else { 89 $crumbs->addTextCrumb($this->table); 90 } 91 } else { 92 $crumbs->addTextCrumb($this->database); 93 } 94 } else { 95 $crumbs->addTextCrumb(pht('Database Status')); 96 } 97 98 $nav->setCrumbs($crumbs); 99 $nav->appendChild($body); 100 101 return $this->buildApplicationPage( 102 $nav, 103 array( 104 'title' => $title, 105 )); 106 } 107 108 109 private function renderServer( 110 PhabricatorConfigServerSchema $comp, 111 PhabricatorConfigServerSchema $expect, 112 PhabricatorConfigServerSchema $actual) { 113 114 $charset_issue = PhabricatorConfigStorageSchema::ISSUE_CHARSET; 115 $collation_issue = PhabricatorConfigStorageSchema::ISSUE_COLLATION; 116 117 $rows = array(); 118 foreach ($comp->getDatabases() as $database_name => $database) { 119 $actual_database = $actual->getDatabase($database_name); 120 if ($actual_database) { 121 $charset = $actual_database->getCharacterSet(); 122 $collation = $actual_database->getCollation(); 123 } else { 124 $charset = null; 125 $collation = null; 126 } 127 128 $status = $database->getStatus(); 129 $issues = $database->getIssues(); 130 131 $rows[] = array( 132 $this->renderIcon($status), 133 phutil_tag( 134 'a', 135 array( 136 'href' => $this->getApplicationURI( 137 '/database/'.$database_name.'/'), 138 ), 139 $database_name), 140 $this->renderAttr($charset, $database->hasIssue($charset_issue)), 141 $this->renderAttr($collation, $database->hasIssue($collation_issue)), 142 ); 143 } 144 145 $table = id(new AphrontTableView($rows)) 146 ->setHeaders( 147 array( 148 null, 149 pht('Database'), 150 pht('Charset'), 151 pht('Collation'), 152 )) 153 ->setColumnClasses( 154 array( 155 null, 156 'wide pri', 157 null, 158 null, 159 )); 160 161 $title = pht('Database Status'); 162 163 $properties = $this->buildProperties( 164 array( 165 ), 166 $comp->getIssues()); 167 168 $box = id(new PHUIObjectBoxView()) 169 ->setHeader($this->buildHeaderWithDocumentationLink($title)) 170 ->addPropertyList($properties) 171 ->appendChild($table); 172 173 return $this->buildResponse($title, $box); 174 } 175 176 private function renderDatabase( 177 PhabricatorConfigServerSchema $comp, 178 PhabricatorConfigServerSchema $expect, 179 PhabricatorConfigServerSchema $actual, 180 $database_name) { 181 182 $collation_issue = PhabricatorConfigStorageSchema::ISSUE_COLLATION; 183 184 $database = $comp->getDatabase($database_name); 185 if (!$database) { 186 return new Aphront404Response(); 187 } 188 189 $rows = array(); 190 foreach ($database->getTables() as $table_name => $table) { 191 $status = $table->getStatus(); 192 193 $rows[] = array( 194 $this->renderIcon($status), 195 phutil_tag( 196 'a', 197 array( 198 'href' => $this->getApplicationURI( 199 '/database/'.$database_name.'/'.$table_name.'/'), 200 ), 201 $table_name), 202 $this->renderAttr( 203 $table->getCollation(), 204 $table->hasIssue($collation_issue)), 205 ); 206 } 207 208 $table = id(new AphrontTableView($rows)) 209 ->setHeaders( 210 array( 211 null, 212 pht('Table'), 213 pht('Collation'), 214 )) 215 ->setColumnClasses( 216 array( 217 null, 218 'wide pri', 219 null, 220 )); 221 222 $title = pht('Database Status: %s', $database_name); 223 224 $actual_database = $actual->getDatabase($database_name); 225 if ($actual_database) { 226 $actual_charset = $actual_database->getCharacterSet(); 227 $actual_collation = $actual_database->getCollation(); 228 } else { 229 $actual_charset = null; 230 $actual_collation = null; 231 } 232 233 $expect_database = $expect->getDatabase($database_name); 234 if ($expect_database) { 235 $expect_charset = $expect_database->getCharacterSet(); 236 $expect_collation = $expect_database->getCollation(); 237 } else { 238 $expect_charset = null; 239 $expect_collation = null; 240 } 241 242 $properties = $this->buildProperties( 243 array( 244 array( 245 pht('Character Set'), 246 $actual_charset, 247 ), 248 array( 249 pht('Expected Character Set'), 250 $expect_charset, 251 ), 252 array( 253 pht('Collation'), 254 $actual_collation, 255 ), 256 array( 257 pht('Expected Collation'), 258 $expect_collation, 259 ), 260 ), 261 $database->getIssues()); 262 263 $box = id(new PHUIObjectBoxView()) 264 ->setHeader($this->buildHeaderWithDocumentationLink($title)) 265 ->addPropertyList($properties) 266 ->appendChild($table); 267 268 return $this->buildResponse($title, $box); 269 } 270 271 private function renderTable( 272 PhabricatorConfigServerSchema $comp, 273 PhabricatorConfigServerSchema $expect, 274 PhabricatorConfigServerSchema $actual, 275 $database_name, 276 $table_name) { 277 278 $type_issue = PhabricatorConfigStorageSchema::ISSUE_COLUMNTYPE; 279 $charset_issue = PhabricatorConfigStorageSchema::ISSUE_CHARSET; 280 $collation_issue = PhabricatorConfigStorageSchema::ISSUE_COLLATION; 281 $nullable_issue = PhabricatorConfigStorageSchema::ISSUE_NULLABLE; 282 $unique_issue = PhabricatorConfigStorageSchema::ISSUE_UNIQUE; 283 $columns_issue = PhabricatorConfigStorageSchema::ISSUE_KEYCOLUMNS; 284 $longkey_issue = PhabricatorConfigStorageSchema::ISSUE_LONGKEY; 285 $auto_issue = PhabricatorConfigStorageSchema::ISSUE_AUTOINCREMENT; 286 287 $database = $comp->getDatabase($database_name); 288 if (!$database) { 289 return new Aphront404Response(); 290 } 291 292 $table = $database->getTable($table_name); 293 if (!$table) { 294 return new Aphront404Response(); 295 } 296 297 $actual_database = $actual->getDatabase($database_name); 298 $actual_table = null; 299 if ($actual_database) { 300 $actual_table = $actual_database->getTable($table_name); 301 } 302 303 $expect_database = $expect->getDatabase($database_name); 304 $expect_table = null; 305 if ($expect_database) { 306 $expect_table = $expect_database->getTable($table_name); 307 } 308 309 $rows = array(); 310 foreach ($table->getColumns() as $column_name => $column) { 311 $expect_column = null; 312 if ($expect_table) { 313 $expect_column = $expect_table->getColumn($column_name); 314 } 315 316 $status = $column->getStatus(); 317 318 $data_type = null; 319 if ($expect_column) { 320 $data_type = $expect_column->getDataType(); 321 } 322 323 $rows[] = array( 324 $this->renderIcon($status), 325 phutil_tag( 326 'a', 327 array( 328 'href' => $this->getApplicationURI( 329 'database/'. 330 $database_name.'/'. 331 $table_name.'/'. 332 'col/'. 333 $column_name.'/'), 334 ), 335 $column_name), 336 $data_type, 337 $this->renderAttr( 338 $column->getColumnType(), 339 $column->hasIssue($type_issue)), 340 $this->renderAttr( 341 $this->renderBoolean($column->getNullable()), 342 $column->hasIssue($nullable_issue)), 343 $this->renderAttr( 344 $this->renderBoolean($column->getAutoIncrement()), 345 $column->hasIssue($auto_issue)), 346 $this->renderAttr( 347 $column->getCharacterSet(), 348 $column->hasIssue($charset_issue)), 349 $this->renderAttr( 350 $column->getCollation(), 351 $column->hasIssue($collation_issue)), 352 ); 353 } 354 355 $table_view = id(new AphrontTableView($rows)) 356 ->setHeaders( 357 array( 358 null, 359 pht('Column'), 360 pht('Data Type'), 361 pht('Column Type'), 362 pht('Nullable'), 363 pht('Autoincrement'), 364 pht('Character Set'), 365 pht('Collation'), 366 )) 367 ->setColumnClasses( 368 array( 369 null, 370 'wide pri', 371 null, 372 null, 373 null, 374 null, 375 null, 376 )); 377 378 $key_rows = array(); 379 foreach ($table->getKeys() as $key_name => $key) { 380 $expect_key = null; 381 if ($expect_table) { 382 $expect_key = $expect_table->getKey($key_name); 383 } 384 385 $status = $key->getStatus(); 386 387 $size = 0; 388 foreach ($key->getColumnNames() as $column_spec) { 389 list($column_name, $prefix) = $key->getKeyColumnAndPrefix($column_spec); 390 $column = $table->getColumn($column_name); 391 if (!$column) { 392 $size = 0; 393 break; 394 } 395 $size += $column->getKeyByteLength($prefix); 396 } 397 398 $size_formatted = null; 399 if ($size) { 400 $size_formatted = $this->renderAttr( 401 $size, 402 $key->hasIssue($longkey_issue)); 403 } 404 405 $key_rows[] = array( 406 $this->renderIcon($status), 407 phutil_tag( 408 'a', 409 array( 410 'href' => $this->getApplicationURI( 411 'database/'. 412 $database_name.'/'. 413 $table_name.'/'. 414 'key/'. 415 $key_name.'/'), 416 ), 417 $key_name), 418 $this->renderAttr( 419 implode(', ', $key->getColumnNames()), 420 $key->hasIssue($columns_issue)), 421 $this->renderAttr( 422 $this->renderBoolean($key->getUnique()), 423 $key->hasIssue($unique_issue)), 424 $size_formatted, 425 ); 426 } 427 428 $keys_view = id(new AphrontTableView($key_rows)) 429 ->setHeaders( 430 array( 431 null, 432 pht('Key'), 433 pht('Columns'), 434 pht('Unique'), 435 pht('Size'), 436 )) 437 ->setColumnClasses( 438 array( 439 null, 440 'wide pri', 441 null, 442 null, 443 null, 444 )); 445 446 $title = pht('Database Status: %s.%s', $database_name, $table_name); 447 448 if ($actual_table) { 449 $actual_collation = $actual_table->getCollation(); 450 } else { 451 $actual_collation = null; 452 } 453 454 if ($expect_table) { 455 $expect_collation = $expect_table->getCollation(); 456 } else { 457 $expect_collation = null; 458 } 459 460 $properties = $this->buildProperties( 461 array( 462 array( 463 pht('Collation'), 464 $actual_collation, 465 ), 466 array( 467 pht('Expected Collation'), 468 $expect_collation, 469 ), 470 ), 471 $table->getIssues()); 472 473 $box = id(new PHUIObjectBoxView()) 474 ->setHeader($this->buildHeaderWithDocumentationLink($title)) 475 ->addPropertyList($properties) 476 ->appendChild($table_view) 477 ->appendChild($keys_view); 478 479 return $this->buildResponse($title, $box); 480 } 481 482 private function renderColumn( 483 PhabricatorConfigServerSchema $comp, 484 PhabricatorConfigServerSchema $expect, 485 PhabricatorConfigServerSchema $actual, 486 $database_name, 487 $table_name, 488 $column_name) { 489 490 $database = $comp->getDatabase($database_name); 491 if (!$database) { 492 return new Aphront404Response(); 493 } 494 495 $table = $database->getTable($table_name); 496 if (!$table) { 497 return new Aphront404Response(); 498 } 499 500 $column = $table->getColumn($column_name); 501 if (!$column) { 502 return new Aphront404Response(); 503 } 504 505 $actual_database = $actual->getDatabase($database_name); 506 $actual_table = null; 507 $actual_column = null; 508 if ($actual_database) { 509 $actual_table = $actual_database->getTable($table_name); 510 if ($actual_table) { 511 $actual_column = $actual_table->getColumn($column_name); 512 } 513 } 514 515 $expect_database = $expect->getDatabase($database_name); 516 $expect_table = null; 517 $expect_column = null; 518 if ($expect_database) { 519 $expect_table = $expect_database->getTable($table_name); 520 if ($expect_table) { 521 $expect_column = $expect_table->getColumn($column_name); 522 } 523 } 524 525 if ($actual_column) { 526 $actual_coltype = $actual_column->getColumnType(); 527 $actual_charset = $actual_column->getCharacterSet(); 528 $actual_collation = $actual_column->getCollation(); 529 $actual_nullable = $actual_column->getNullable(); 530 $actual_auto = $actual_column->getAutoIncrement(); 531 } else { 532 $actual_coltype = null; 533 $actual_charset = null; 534 $actual_collation = null; 535 $actual_nullable = null; 536 $actual_auto = null; 537 } 538 539 if ($expect_column) { 540 $data_type = $expect_column->getDataType(); 541 $expect_coltype = $expect_column->getColumnType(); 542 $expect_charset = $expect_column->getCharacterSet(); 543 $expect_collation = $expect_column->getCollation(); 544 $expect_nullable = $expect_column->getNullable(); 545 $expect_auto = $expect_column->getAutoIncrement(); 546 } else { 547 $data_type = null; 548 $expect_coltype = null; 549 $expect_charset = null; 550 $expect_collation = null; 551 $expect_nullable = null; 552 $expect_auto = null; 553 } 554 555 556 $title = pht( 557 'Database Status: %s.%s.%s', 558 $database_name, 559 $table_name, 560 $column_name); 561 562 $properties = $this->buildProperties( 563 array( 564 array( 565 pht('Data Type'), 566 $data_type, 567 ), 568 array( 569 pht('Column Type'), 570 $actual_coltype, 571 ), 572 array( 573 pht('Expected Column Type'), 574 $expect_coltype, 575 ), 576 array( 577 pht('Character Set'), 578 $actual_charset, 579 ), 580 array( 581 pht('Expected Character Set'), 582 $expect_charset, 583 ), 584 array( 585 pht('Collation'), 586 $actual_collation, 587 ), 588 array( 589 pht('Expected Collation'), 590 $expect_collation, 591 ), 592 array( 593 pht('Nullable'), 594 $this->renderBoolean($actual_nullable), 595 ), 596 array( 597 pht('Expected Nullable'), 598 $this->renderBoolean($expect_nullable), 599 ), 600 array( 601 pht('Autoincrement'), 602 $this->renderBoolean($actual_auto), 603 ), 604 array( 605 pht('Expected Autoincrement'), 606 $this->renderBoolean($expect_auto), 607 ), 608 ), 609 $column->getIssues()); 610 611 $box = id(new PHUIObjectBoxView()) 612 ->setHeader($this->buildHeaderWithDocumentationLink($title)) 613 ->addPropertyList($properties); 614 615 return $this->buildResponse($title, $box); 616 } 617 618 private function renderKey( 619 PhabricatorConfigServerSchema $comp, 620 PhabricatorConfigServerSchema $expect, 621 PhabricatorConfigServerSchema $actual, 622 $database_name, 623 $table_name, 624 $key_name) { 625 626 $database = $comp->getDatabase($database_name); 627 if (!$database) { 628 return new Aphront404Response(); 629 } 630 631 $table = $database->getTable($table_name); 632 if (!$table) { 633 return new Aphront404Response(); 634 } 635 636 $key = $table->getKey($key_name); 637 if (!$key) { 638 return new Aphront404Response(); 639 } 640 641 $actual_database = $actual->getDatabase($database_name); 642 $actual_table = null; 643 $actual_key = null; 644 if ($actual_database) { 645 $actual_table = $actual_database->getTable($table_name); 646 if ($actual_table) { 647 $actual_key = $actual_table->getKey($key_name); 648 } 649 } 650 651 $expect_database = $expect->getDatabase($database_name); 652 $expect_table = null; 653 $expect_key = null; 654 if ($expect_database) { 655 $expect_table = $expect_database->getTable($table_name); 656 if ($expect_table) { 657 $expect_key = $expect_table->getKey($key_name); 658 } 659 } 660 661 if ($actual_key) { 662 $actual_columns = $actual_key->getColumnNames(); 663 $actual_unique = $actual_key->getUnique(); 664 } else { 665 $actual_columns = array(); 666 $actual_unique = null; 667 } 668 669 if ($expect_key) { 670 $expect_columns = $expect_key->getColumnNames(); 671 $expect_unique = $expect_key->getUnique(); 672 } else { 673 $expect_columns = array(); 674 $expect_unique = null; 675 } 676 677 $title = pht( 678 'Database Status: %s.%s (%s)', 679 $database_name, 680 $table_name, 681 $key_name); 682 683 $properties = $this->buildProperties( 684 array( 685 array( 686 pht('Unique'), 687 $this->renderBoolean($actual_unique), 688 ), 689 array( 690 pht('Expected Unique'), 691 $this->renderBoolean($expect_unique), 692 ), 693 array( 694 pht('Columns'), 695 implode(', ', $actual_columns), 696 ), 697 array( 698 pht('Expected Columns'), 699 implode(', ', $expect_columns), 700 ), 701 ), 702 $key->getIssues()); 703 704 $box = id(new PHUIObjectBoxView()) 705 ->setHeader($this->buildHeaderWithDocumentationLink($title)) 706 ->addPropertyList($properties); 707 708 return $this->buildResponse($title, $box); 709 } 710 711 private function buildProperties(array $properties, array $issues) { 712 $view = id(new PHUIPropertyListView()) 713 ->setUser($this->getRequest()->getUser()); 714 715 foreach ($properties as $property) { 716 list($key, $value) = $property; 717 $view->addProperty($key, $value); 718 } 719 720 $status_view = new PHUIStatusListView(); 721 if (!$issues) { 722 $status_view->addItem( 723 id(new PHUIStatusItemView()) 724 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 725 ->setTarget(pht('No Schema Issues'))); 726 } else { 727 foreach ($issues as $issue) { 728 $note = PhabricatorConfigStorageSchema::getIssueDescription($issue); 729 730 $status = PhabricatorConfigStorageSchema::getIssueStatus($issue); 731 switch ($status) { 732 case PhabricatorConfigStorageSchema::STATUS_WARN: 733 $icon = PHUIStatusItemView::ICON_WARNING; 734 $color = 'yellow'; 735 break; 736 case PhabricatorConfigStorageSchema::STATUS_FAIL: 737 default: 738 $icon = PHUIStatusItemView::ICON_REJECT; 739 $color = 'red'; 740 break; 741 } 742 743 $item = id(new PHUIStatusItemView()) 744 ->setTarget(PhabricatorConfigStorageSchema::getIssueName($issue)) 745 ->setIcon($icon, $color) 746 ->setNote($note); 747 748 $status_view->addItem($item); 749 } 750 } 751 $view->addProperty(pht('Schema Status'), $status_view); 752 753 return $view; 754 } 755 756 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |