diff --git a/resources/sql/autopatches/20160221.almanac.3.servicen.sql b/resources/sql/autopatches/20160221.almanac.3.servicen.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20160221.almanac.3.servicen.sql @@ -0,0 +1,7 @@ +CREATE TABLE {$NAMESPACE}_almanac.almanac_servicename_ngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT}, + KEY `key_object` (objectID), + KEY `key_ngram` (ngram, objectID) +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20160221.almanac.4.servicei.php b/resources/sql/autopatches/20160221.almanac.4.servicei.php new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20160221.almanac.4.servicei.php @@ -0,0 +1,11 @@ +getPHID(), + array( + 'force' => true, + )); +} diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -89,6 +89,7 @@ 'AlmanacServiceEditController' => 'applications/almanac/controller/AlmanacServiceEditController.php', 'AlmanacServiceEditor' => 'applications/almanac/editor/AlmanacServiceEditor.php', 'AlmanacServiceListController' => 'applications/almanac/controller/AlmanacServiceListController.php', + 'AlmanacServiceNameNgrams' => 'applications/almanac/storage/AlmanacServiceNameNgrams.php', 'AlmanacServicePHIDType' => 'applications/almanac/phid/AlmanacServicePHIDType.php', 'AlmanacServiceQuery' => 'applications/almanac/query/AlmanacServiceQuery.php', 'AlmanacServiceSearchEngine' => 'applications/almanac/query/AlmanacServiceSearchEngine.php', @@ -4082,12 +4083,14 @@ 'PhabricatorProjectInterface', 'AlmanacPropertyInterface', 'PhabricatorDestructibleInterface', + 'PhabricatorNgramsInterface', ), 'AlmanacServiceController' => 'AlmanacController', 'AlmanacServiceDatasource' => 'PhabricatorTypeaheadDatasource', 'AlmanacServiceEditController' => 'AlmanacServiceController', 'AlmanacServiceEditor' => 'PhabricatorApplicationTransactionEditor', 'AlmanacServiceListController' => 'AlmanacServiceController', + 'AlmanacServiceNameNgrams' => 'PhabricatorSearchNgrams', 'AlmanacServicePHIDType' => 'PhabricatorPHIDType', 'AlmanacServiceQuery' => 'AlmanacQuery', 'AlmanacServiceSearchEngine' => 'PhabricatorApplicationSearchEngine', diff --git a/src/applications/almanac/editor/AlmanacServiceEditor.php b/src/applications/almanac/editor/AlmanacServiceEditor.php --- a/src/applications/almanac/editor/AlmanacServiceEditor.php +++ b/src/applications/almanac/editor/AlmanacServiceEditor.php @@ -11,6 +11,10 @@ return pht('Almanac Service'); } + protected function supportsSearch() { + return true; + } + public function getTransactionTypes() { $types = parent::getTransactionTypes(); diff --git a/src/applications/almanac/query/AlmanacServiceQuery.php b/src/applications/almanac/query/AlmanacServiceQuery.php --- a/src/applications/almanac/query/AlmanacServiceQuery.php +++ b/src/applications/almanac/query/AlmanacServiceQuery.php @@ -54,6 +54,12 @@ return $this; } + public function withNameNgrams($ngrams) { + return $this->withNgramsConstraint( + new AlmanacServiceNameNgrams(), + $ngrams); + } + public function needBindings($need_bindings) { $this->needBindings = $need_bindings; return $this; @@ -66,7 +72,7 @@ protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { $joins = parent::buildJoinClauseParts($conn); - if ($this->devicePHIDs !== null) { + if ($this->shouldJoinBindingTable()) { $joins[] = qsprintf( $conn, 'JOIN %T binding ON service.phid = binding.servicePHID', @@ -178,6 +184,18 @@ return parent::didFilterPage($services); } + private function shouldJoinBindingTable() { + return ($this->devicePHIDs !== null); + } + + protected function shouldGroupQueryResultRows() { + if ($this->shouldJoinBindingTable()) { + return true; + } + + return parent::shouldGroupQueryResultRows(); + } + protected function getPrimaryTableAlias() { return 'service'; } diff --git a/src/applications/almanac/query/AlmanacServiceSearchEngine.php b/src/applications/almanac/query/AlmanacServiceSearchEngine.php --- a/src/applications/almanac/query/AlmanacServiceSearchEngine.php +++ b/src/applications/almanac/query/AlmanacServiceSearchEngine.php @@ -16,21 +16,27 @@ } public function newResultObject() { - // NOTE: We need to attach a service type in order to generate custom - // field definitions. - return AlmanacService::initializeNewService() - ->attachServiceType(new AlmanacCustomServiceType()); + return AlmanacService::initializeNewService(); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); + if ($map['match'] !== null) { + $query->withNameNgrams($map['match']); + } + return $query; } protected function buildCustomSearchFields() { - return array(); + return array( + id(new PhabricatorSearchTextField()) + ->setLabel(pht('Name Contains')) + ->setKey('match') + ->setDescription(pht('Search for services by name substring.')), + ); } protected function getURI($path) { diff --git a/src/applications/almanac/storage/AlmanacService.php b/src/applications/almanac/storage/AlmanacService.php --- a/src/applications/almanac/storage/AlmanacService.php +++ b/src/applications/almanac/storage/AlmanacService.php @@ -8,7 +8,8 @@ PhabricatorApplicationTransactionInterface, PhabricatorProjectInterface, AlmanacPropertyInterface, - PhabricatorDestructibleInterface { + PhabricatorDestructibleInterface, + PhabricatorNgramsInterface { protected $name; protected $nameIndex; @@ -231,4 +232,15 @@ $this->delete(); } + +/* -( PhabricatorNgramInterface )------------------------------------------ */ + + + public function newNgrams() { + return array( + id(new AlmanacServiceNameNgrams()) + ->setValue($this->getName()), + ); + } + } diff --git a/src/applications/almanac/storage/AlmanacServiceNameNgrams.php b/src/applications/almanac/storage/AlmanacServiceNameNgrams.php new file mode 100644 --- /dev/null +++ b/src/applications/almanac/storage/AlmanacServiceNameNgrams.php @@ -0,0 +1,18 @@ +