@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve Drydock log search engine

Summary: Ref T2015. This allows searching based on blueprints, resources or leases when viewing the logs, which helps when searching for events that occured to a particular blueprint / resource / lease. Unlike the logs shown on the resource / lease pages, the search engine supports paging properly, which means it can be used to find entries in the past.

Test Plan: Used the Drydock log search page.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: joshuaspence, Korvin, epriestley

Maniphest Tasks: T2015

Differential Revision: https://secure.phabricator.com/D10874

+210 -9
+6
src/__phutil_library_map__.php
··· 798 798 'DrydockBlueprintCoreCustomField' => 'applications/drydock/customfield/DrydockBlueprintCoreCustomField.php', 799 799 'DrydockBlueprintCreateController' => 'applications/drydock/controller/DrydockBlueprintCreateController.php', 800 800 'DrydockBlueprintCustomField' => 'applications/drydock/customfield/DrydockBlueprintCustomField.php', 801 + 'DrydockBlueprintDatasource' => 'applications/drydock/typeahead/DrydockBlueprintDatasource.php', 801 802 'DrydockBlueprintEditController' => 'applications/drydock/controller/DrydockBlueprintEditController.php', 802 803 'DrydockBlueprintEditor' => 'applications/drydock/editor/DrydockBlueprintEditor.php', 803 804 'DrydockBlueprintImplementation' => 'applications/drydock/blueprint/DrydockBlueprintImplementation.php', ··· 822 823 'DrydockInterface' => 'applications/drydock/interface/DrydockInterface.php', 823 824 'DrydockLease' => 'applications/drydock/storage/DrydockLease.php', 824 825 'DrydockLeaseController' => 'applications/drydock/controller/DrydockLeaseController.php', 826 + 'DrydockLeaseDatasource' => 'applications/drydock/typeahead/DrydockLeaseDatasource.php', 825 827 'DrydockLeaseListController' => 'applications/drydock/controller/DrydockLeaseListController.php', 826 828 'DrydockLeaseListView' => 'applications/drydock/view/DrydockLeaseListView.php', 827 829 'DrydockLeasePHIDType' => 'applications/drydock/phid/DrydockLeasePHIDType.php', ··· 847 849 'DrydockResource' => 'applications/drydock/storage/DrydockResource.php', 848 850 'DrydockResourceCloseController' => 'applications/drydock/controller/DrydockResourceCloseController.php', 849 851 'DrydockResourceController' => 'applications/drydock/controller/DrydockResourceController.php', 852 + 'DrydockResourceDatasource' => 'applications/drydock/typeahead/DrydockResourceDatasource.php', 850 853 'DrydockResourceListController' => 'applications/drydock/controller/DrydockResourceListController.php', 851 854 'DrydockResourceListView' => 'applications/drydock/view/DrydockResourceListView.php', 852 855 'DrydockResourcePHIDType' => 'applications/drydock/phid/DrydockResourcePHIDType.php', ··· 4479 4482 ), 4480 4483 'DrydockBlueprintCreateController' => 'DrydockBlueprintController', 4481 4484 'DrydockBlueprintCustomField' => 'PhabricatorCustomField', 4485 + 'DrydockBlueprintDatasource' => 'PhabricatorTypeaheadDatasource', 4482 4486 'DrydockBlueprintEditController' => 'DrydockBlueprintController', 4483 4487 'DrydockBlueprintEditor' => 'PhabricatorApplicationTransactionEditor', 4484 4488 'DrydockBlueprintImplementation' => 'Phobject', ··· 4506 4510 'PhabricatorPolicyInterface', 4507 4511 ), 4508 4512 'DrydockLeaseController' => 'DrydockController', 4513 + 'DrydockLeaseDatasource' => 'PhabricatorTypeaheadDatasource', 4509 4514 'DrydockLeaseListController' => 'DrydockLeaseController', 4510 4515 'DrydockLeaseListView' => 'AphrontView', 4511 4516 'DrydockLeasePHIDType' => 'PhabricatorPHIDType', ··· 4537 4542 ), 4538 4543 'DrydockResourceCloseController' => 'DrydockResourceController', 4539 4544 'DrydockResourceController' => 'DrydockController', 4545 + 'DrydockResourceDatasource' => 'PhabricatorTypeaheadDatasource', 4540 4546 'DrydockResourceListController' => 'DrydockResourceController', 4541 4547 'DrydockResourceListView' => 'AphrontView', 4542 4548 'DrydockResourcePHIDType' => 'PhabricatorPHIDType',
+3
src/applications/drydock/phid/DrydockLeasePHIDType.php
··· 29 29 $lease = $objects[$phid]; 30 30 $id = $lease->getID(); 31 31 32 + $handle->setName(pht( 33 + 'Lease %d', 34 + $id)); 32 35 $handle->setURI("/drydock/lease/{$id}/"); 33 36 } 34 37 }
+1
src/applications/drydock/phid/DrydockResourcePHIDType.php
··· 29 29 $resource = $objects[$phid]; 30 30 $id = $resource->getID(); 31 31 32 + $handle->setName($resource->getName()); 32 33 $handle->setURI("/drydock/resource/{$id}/"); 33 34 } 34 35 }
+13
src/applications/drydock/query/DrydockBlueprintQuery.php
··· 4 4 5 5 private $ids; 6 6 private $phids; 7 + private $datasourceQuery; 7 8 8 9 public function withIDs(array $ids) { 9 10 $this->ids = $ids; ··· 12 13 13 14 public function withPHIDs(array $phids) { 14 15 $this->phids = $phids; 16 + return $this; 17 + } 18 + 19 + public function withDatasourceQuery($query) { 20 + $this->datasourceQuery = $query; 15 21 return $this; 16 22 } 17 23 ··· 57 63 $conn_r, 58 64 'phid IN (%Ls)', 59 65 $this->phids); 66 + } 67 + 68 + if ($this->datasourceQuery) { 69 + $where[] = qsprintf( 70 + $conn_r, 71 + 'blueprintName LIKE %>', 72 + $this->datasourceQuery); 60 73 } 61 74 62 75 return $this->formatWhereClause($where);
+17 -4
src/applications/drydock/query/DrydockLeaseQuery.php
··· 6 6 private $phids; 7 7 private $resourceIDs; 8 8 private $statuses; 9 + private $datasourceQuery; 9 10 10 11 public function withIDs(array $ids) { 11 12 $this->ids = $ids; ··· 29 30 30 31 public function newResultObject() { 31 32 return new DrydockLease(); 33 + } 34 + 35 + public function withDatasourceQuery($query) { 36 + $this->datasourceQuery = $query; 37 + return $this; 32 38 } 33 39 34 40 protected function loadPage() { ··· 65 71 protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 66 72 $where = parent::buildWhereClauseParts($conn); 67 73 68 - if ($this->resourceIDs !== null) { 74 + if ($this->resourceIDs) { 69 75 $where[] = qsprintf( 70 76 $conn, 71 77 'resourceID IN (%Ld)', 72 78 $this->resourceIDs); 73 79 } 74 80 75 - if ($this->ids !== null) { 81 + if ($this->ids) { 76 82 $where[] = qsprintf( 77 83 $conn, 78 84 'id IN (%Ld)', 79 85 $this->ids); 80 86 } 81 87 82 - if ($this->phids !== null) { 88 + if ($this->phids) { 83 89 $where[] = qsprintf( 84 90 $conn, 85 91 'phid IN (%Ls)', 86 92 $this->phids); 87 93 } 88 94 89 - if ($this->statuses !== null) { 95 + if ($this->statuses) { 90 96 $where[] = qsprintf( 91 97 $conn, 92 98 'status IN (%Ld)', 93 99 $this->statuses); 100 + } 101 + 102 + if ($this->datasourceQuery) { 103 + $where[] = qsprintf( 104 + $conn, 105 + 'id = %d', 106 + (int)$this->datasourceQuery); 94 107 } 95 108 96 109 return $where;
+42 -3
src/applications/drydock/query/DrydockLogSearchEngine.php
··· 11 11 } 12 12 13 13 public function buildSavedQueryFromRequest(AphrontRequest $request) { 14 - return new PhabricatorSavedQuery(); 14 + $query = new PhabricatorSavedQuery(); 15 + 16 + $query->setParameter( 17 + 'resourcePHIDs', 18 + $this->readListFromRequest($request, 'resources')); 19 + $query->setParameter( 20 + 'leasePHIDs', 21 + $this->readListFromRequest($request, 'leases')); 22 + 23 + return $query; 15 24 } 16 25 17 26 public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { 18 - return new DrydockLogQuery(); 27 + 28 + // TODO: Change logs to use PHIDs instead of IDs. 29 + $resource_ids = id(new DrydockResourceQuery()) 30 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 31 + ->withPHIDs($saved->getParameter('resourcePHIDs', array())) 32 + ->execute(); 33 + $resource_ids = mpull($resource_ids, 'getID'); 34 + $lease_ids = id(new DrydockLeaseQuery()) 35 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 36 + ->withPHIDs($saved->getParameter('leasePHIDs', array())) 37 + ->execute(); 38 + $lease_ids = mpull($lease_ids, 'getID'); 39 + 40 + return id(new DrydockLogQuery()) 41 + ->withResourceIDs($resource_ids) 42 + ->withLeaseIDs($lease_ids); 19 43 } 20 44 21 45 public function buildSearchForm( 22 46 AphrontFormView $form, 23 - PhabricatorSavedQuery $saved) {} 47 + PhabricatorSavedQuery $saved) { 48 + 49 + $form 50 + ->appendControl( 51 + id(new AphrontFormTokenizerControl()) 52 + ->setDatasource(new DrydockResourceDatasource()) 53 + ->setName('resources') 54 + ->setLabel(pht('Resources')) 55 + ->setValue($saved->getParameter('resourcePHIDs', array()))) 56 + ->appendControl( 57 + id(new AphrontFormTokenizerControl()) 58 + ->setDatasource(new DrydockLeaseDatasource()) 59 + ->setName('leases') 60 + ->setLabel(pht('Leases')) 61 + ->setValue($saved->getParameter('leasePHIDs', array()))); 62 + } 24 63 25 64 protected function getURI($path) { 26 65 return '/drydock/log/'.$path;
+13
src/applications/drydock/query/DrydockResourceQuery.php
··· 7 7 private $statuses; 8 8 private $types; 9 9 private $blueprintPHIDs; 10 + private $datasourceQuery; 10 11 11 12 public function withIDs(array $ids) { 12 13 $this->ids = $ids; ··· 30 31 31 32 public function withBlueprintPHIDs(array $blueprint_phids) { 32 33 $this->blueprintPHIDs = $blueprint_phids; 34 + return $this; 35 + } 36 + 37 + public function withDatasourceQuery($query) { 38 + $this->datasourceQuery = $query; 33 39 return $this; 34 40 } 35 41 ··· 86 92 $conn_r, 87 93 'blueprintPHID IN (%Ls)', 88 94 $this->blueprintPHIDs); 95 + } 96 + 97 + if ($this->datasourceQuery) { 98 + $where[] = qsprintf( 99 + $conn_r, 100 + 'name LIKE %>', 101 + $this->datasourceQuery); 89 102 } 90 103 91 104 $where[] = $this->buildPagingClause($conn_r);
+1 -1
src/applications/drydock/storage/DrydockBlueprint.php
··· 40 40 ), 41 41 self::CONFIG_COLUMN_SCHEMA => array( 42 42 'className' => 'text255', 43 - 'blueprintName' => 'text255', 43 + 'blueprintName' => 'sort255', 44 44 ), 45 45 ) + parent::getConfiguration(); 46 46 }
+36
src/applications/drydock/typeahead/DrydockBlueprintDatasource.php
··· 1 + <?php 2 + 3 + final class DrydockBlueprintDatasource 4 + extends PhabricatorTypeaheadDatasource { 5 + 6 + public function getPlaceholderText() { 7 + return pht('Type a blueprint name...'); 8 + } 9 + 10 + public function getDatasourceApplicationClass() { 11 + return 'PhabricatorDrydockApplication'; 12 + } 13 + 14 + public function loadResults() { 15 + $viewer = $this->getViewer(); 16 + $raw_query = $this->getRawQuery(); 17 + 18 + $blueprints = id(new DrydockBlueprintQuery()) 19 + ->setViewer($viewer) 20 + ->withDatasourceQuery($raw_query) 21 + ->execute(); 22 + 23 + $handles = id(new PhabricatorHandleQuery()) 24 + ->setViewer($viewer) 25 + ->withPHIDs(mpull($blueprints, 'getPHID')) 26 + ->execute(); 27 + 28 + $results = array(); 29 + foreach ($handles as $handle) { 30 + $results[] = id(new PhabricatorTypeaheadResult()) 31 + ->setName($handle->getName()) 32 + ->setPHID($handle->getPHID()); 33 + } 34 + return $results; 35 + } 36 + }
+36
src/applications/drydock/typeahead/DrydockLeaseDatasource.php
··· 1 + <?php 2 + 3 + final class DrydockLeaseDatasource 4 + extends PhabricatorTypeaheadDatasource { 5 + 6 + public function getPlaceholderText() { 7 + return pht('Type a lease ID (exact match)...'); 8 + } 9 + 10 + public function getDatasourceApplicationClass() { 11 + return 'PhabricatorDrydockApplication'; 12 + } 13 + 14 + public function loadResults() { 15 + $viewer = $this->getViewer(); 16 + $raw_query = $this->getRawQuery(); 17 + 18 + $leases = id(new DrydockLeaseQuery()) 19 + ->setViewer($viewer) 20 + ->withDatasourceQuery($raw_query) 21 + ->execute(); 22 + 23 + $handles = id(new PhabricatorHandleQuery()) 24 + ->setViewer($viewer) 25 + ->withPHIDs(mpull($leases, 'getPHID')) 26 + ->execute(); 27 + 28 + $results = array(); 29 + foreach ($handles as $handle) { 30 + $results[] = id(new PhabricatorTypeaheadResult()) 31 + ->setName($handle->getName()) 32 + ->setPHID($handle->getPHID()); 33 + } 34 + return $results; 35 + } 36 + }
+36
src/applications/drydock/typeahead/DrydockResourceDatasource.php
··· 1 + <?php 2 + 3 + final class DrydockResourceDatasource 4 + extends PhabricatorTypeaheadDatasource { 5 + 6 + public function getPlaceholderText() { 7 + return pht('Type a resource name...'); 8 + } 9 + 10 + public function getDatasourceApplicationClass() { 11 + return 'PhabricatorDrydockApplication'; 12 + } 13 + 14 + public function loadResults() { 15 + $viewer = $this->getViewer(); 16 + $raw_query = $this->getRawQuery(); 17 + 18 + $resources = id(new DrydockResourceQuery()) 19 + ->setViewer($viewer) 20 + ->withDatasourceQuery($raw_query) 21 + ->execute(); 22 + 23 + $handles = id(new PhabricatorHandleQuery()) 24 + ->setViewer($viewer) 25 + ->withPHIDs(mpull($resources, 'getPHID')) 26 + ->execute(); 27 + 28 + $results = array(); 29 + foreach ($handles as $handle) { 30 + $results[] = id(new PhabricatorTypeaheadResult()) 31 + ->setName($handle->getName()) 32 + ->setPHID($handle->getPHID()); 33 + } 34 + return $results; 35 + } 36 + }
+6 -1
src/applications/drydock/view/DrydockLogListView.php
··· 21 21 $resource_uri = '/drydock/resource/'.$log->getResourceID().'/'; 22 22 $lease_uri = '/drydock/lease/'.$log->getLeaseID().'/'; 23 23 24 + $resource_name = $log->getResourceID(); 25 + if ($log->getResourceID() !== null) { 26 + $resource_name = $log->getResource()->getName(); 27 + } 28 + 24 29 $rows[] = array( 25 30 phutil_tag( 26 31 'a', 27 32 array( 28 33 'href' => $resource_uri, 29 34 ), 30 - $log->getResourceID()), 35 + $resource_name), 31 36 phutil_tag( 32 37 'a', 33 38 array(