@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.

Allow Almanac services to be searched by substring

Summary: Ref T10246. Build an ngram index for Almanac services, and use it to support improved search.

Test Plan: {F1121725}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10246

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

+86 -7
+7
resources/sql/autopatches/20160221.almanac.3.servicen.sql
··· 1 + CREATE TABLE {$NAMESPACE}_almanac.almanac_servicename_ngrams ( 2 + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 + objectID INT UNSIGNED NOT NULL, 4 + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT}, 5 + KEY `key_object` (objectID), 6 + KEY `key_ngram` (ngram, objectID) 7 + ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+11
resources/sql/autopatches/20160221.almanac.4.servicei.php
··· 1 + <?php 2 + 3 + $table = new AlmanacService(); 4 + 5 + foreach (new LiskMigrationIterator($table) as $service) { 6 + PhabricatorSearchWorker::queueDocumentForIndexing( 7 + $service->getPHID(), 8 + array( 9 + 'force' => true, 10 + )); 11 + }
+3
src/__phutil_library_map__.php
··· 89 89 'AlmanacServiceEditController' => 'applications/almanac/controller/AlmanacServiceEditController.php', 90 90 'AlmanacServiceEditor' => 'applications/almanac/editor/AlmanacServiceEditor.php', 91 91 'AlmanacServiceListController' => 'applications/almanac/controller/AlmanacServiceListController.php', 92 + 'AlmanacServiceNameNgrams' => 'applications/almanac/storage/AlmanacServiceNameNgrams.php', 92 93 'AlmanacServicePHIDType' => 'applications/almanac/phid/AlmanacServicePHIDType.php', 93 94 'AlmanacServiceQuery' => 'applications/almanac/query/AlmanacServiceQuery.php', 94 95 'AlmanacServiceSearchEngine' => 'applications/almanac/query/AlmanacServiceSearchEngine.php', ··· 4082 4083 'PhabricatorProjectInterface', 4083 4084 'AlmanacPropertyInterface', 4084 4085 'PhabricatorDestructibleInterface', 4086 + 'PhabricatorNgramsInterface', 4085 4087 ), 4086 4088 'AlmanacServiceController' => 'AlmanacController', 4087 4089 'AlmanacServiceDatasource' => 'PhabricatorTypeaheadDatasource', 4088 4090 'AlmanacServiceEditController' => 'AlmanacServiceController', 4089 4091 'AlmanacServiceEditor' => 'PhabricatorApplicationTransactionEditor', 4090 4092 'AlmanacServiceListController' => 'AlmanacServiceController', 4093 + 'AlmanacServiceNameNgrams' => 'PhabricatorSearchNgrams', 4091 4094 'AlmanacServicePHIDType' => 'PhabricatorPHIDType', 4092 4095 'AlmanacServiceQuery' => 'AlmanacQuery', 4093 4096 'AlmanacServiceSearchEngine' => 'PhabricatorApplicationSearchEngine',
+4
src/applications/almanac/editor/AlmanacServiceEditor.php
··· 11 11 return pht('Almanac Service'); 12 12 } 13 13 14 + protected function supportsSearch() { 15 + return true; 16 + } 17 + 14 18 public function getTransactionTypes() { 15 19 $types = parent::getTransactionTypes(); 16 20
+19 -1
src/applications/almanac/query/AlmanacServiceQuery.php
··· 54 54 return $this; 55 55 } 56 56 57 + public function withNameNgrams($ngrams) { 58 + return $this->withNgramsConstraint( 59 + new AlmanacServiceNameNgrams(), 60 + $ngrams); 61 + } 62 + 57 63 public function needBindings($need_bindings) { 58 64 $this->needBindings = $need_bindings; 59 65 return $this; ··· 66 72 protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { 67 73 $joins = parent::buildJoinClauseParts($conn); 68 74 69 - if ($this->devicePHIDs !== null) { 75 + if ($this->shouldJoinBindingTable()) { 70 76 $joins[] = qsprintf( 71 77 $conn, 72 78 'JOIN %T binding ON service.phid = binding.servicePHID', ··· 176 182 } 177 183 178 184 return parent::didFilterPage($services); 185 + } 186 + 187 + private function shouldJoinBindingTable() { 188 + return ($this->devicePHIDs !== null); 189 + } 190 + 191 + protected function shouldGroupQueryResultRows() { 192 + if ($this->shouldJoinBindingTable()) { 193 + return true; 194 + } 195 + 196 + return parent::shouldGroupQueryResultRows(); 179 197 } 180 198 181 199 protected function getPrimaryTableAlias() {
+11 -5
src/applications/almanac/query/AlmanacServiceSearchEngine.php
··· 16 16 } 17 17 18 18 public function newResultObject() { 19 - // NOTE: We need to attach a service type in order to generate custom 20 - // field definitions. 21 - return AlmanacService::initializeNewService() 22 - ->attachServiceType(new AlmanacCustomServiceType()); 19 + return AlmanacService::initializeNewService(); 23 20 } 24 21 25 22 protected function buildQueryFromParameters(array $map) { 26 23 $query = $this->newQuery(); 27 24 25 + if ($map['match'] !== null) { 26 + $query->withNameNgrams($map['match']); 27 + } 28 + 28 29 return $query; 29 30 } 30 31 31 32 32 33 protected function buildCustomSearchFields() { 33 - return array(); 34 + return array( 35 + id(new PhabricatorSearchTextField()) 36 + ->setLabel(pht('Name Contains')) 37 + ->setKey('match') 38 + ->setDescription(pht('Search for services by name substring.')), 39 + ); 34 40 } 35 41 36 42 protected function getURI($path) {
+13 -1
src/applications/almanac/storage/AlmanacService.php
··· 8 8 PhabricatorApplicationTransactionInterface, 9 9 PhabricatorProjectInterface, 10 10 AlmanacPropertyInterface, 11 - PhabricatorDestructibleInterface { 11 + PhabricatorDestructibleInterface, 12 + PhabricatorNgramsInterface { 12 13 13 14 protected $name; 14 15 protected $nameIndex; ··· 229 230 } 230 231 231 232 $this->delete(); 233 + } 234 + 235 + 236 + /* -( PhabricatorNgramInterface )------------------------------------------ */ 237 + 238 + 239 + public function newNgrams() { 240 + return array( 241 + id(new AlmanacServiceNameNgrams()) 242 + ->setValue($this->getName()), 243 + ); 232 244 } 233 245 234 246 }
+18
src/applications/almanac/storage/AlmanacServiceNameNgrams.php
··· 1 + <?php 2 + 3 + final class AlmanacServiceNameNgrams 4 + extends PhabricatorSearchNgrams { 5 + 6 + public function getNgramKey() { 7 + return 'servicename'; 8 + } 9 + 10 + public function getColumnName() { 11 + return 'name'; 12 + } 13 + 14 + public function getApplicationName() { 15 + return 'almanac'; 16 + } 17 + 18 + }