Give projects a proper on-demand datasource
Summary:
Fixes T5614. Ref T4420. Other than the "users" datasource and a couple of others, many datasources ignore what the user typed and just return all results, then rely on the client to filter them.
This works fine for rarely used ("legalpad documents") or always small ("task priorities", "applications") datasets, but is something we should graudally move away from as datasets get larger.
Add a token table to projects, populate it, and use it to drive the datasource query. Additionally, expose it on the applicationsearch UI.
Test Plan:
  - Ran migration.
  - Manually checked the table.
  - Searched for projects by name from ApplicationSearch.
  - Searched for projects by name from typeahead.
  - Manually checked the typeahead response.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T5614, T4420
Differential Revision: https://secure.phabricator.com/D9896
			
			
This commit is contained in:
		| @@ -9,6 +9,7 @@ final class PhabricatorProjectQuery | ||||
|   private $slugs; | ||||
|   private $phrictionSlugs; | ||||
|   private $names; | ||||
|   private $datasourceQuery; | ||||
|  | ||||
|   private $status       = 'status-any'; | ||||
|   const STATUS_ANY      = 'status-any'; | ||||
| @@ -57,6 +58,11 @@ final class PhabricatorProjectQuery | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function withDatasourceQuery($string) { | ||||
|     $this->datasourceQuery = $string; | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function needMembers($need_members) { | ||||
|     $this->needMembers = $need_members; | ||||
|     return $this; | ||||
| @@ -286,7 +292,7 @@ final class PhabricatorProjectQuery | ||||
|   } | ||||
|  | ||||
|   private function buildGroupClause($conn_r) { | ||||
|     if ($this->memberPHIDs) { | ||||
|     if ($this->memberPHIDs || $this->datasourceQuery) { | ||||
|       return 'GROUP BY p.id'; | ||||
|     } else { | ||||
|       return $this->buildApplicationSearchGroupClause($conn_r); | ||||
| @@ -296,7 +302,7 @@ final class PhabricatorProjectQuery | ||||
|   private function buildJoinClause($conn_r) { | ||||
|     $joins = array(); | ||||
|  | ||||
|     if (!$this->needMembers) { | ||||
|     if (!$this->needMembers !== null) { | ||||
|       $joins[] = qsprintf( | ||||
|         $conn_r, | ||||
|         'LEFT JOIN %T vm ON vm.src = p.phid AND vm.type = %d AND vm.dst = %s', | ||||
| @@ -305,7 +311,7 @@ final class PhabricatorProjectQuery | ||||
|         $this->getViewer()->getPHID()); | ||||
|     } | ||||
|  | ||||
|     if ($this->memberPHIDs) { | ||||
|     if ($this->memberPHIDs !== null) { | ||||
|       $joins[] = qsprintf( | ||||
|         $conn_r, | ||||
|         'JOIN %T e ON e.src = p.phid AND e.type = %d', | ||||
| @@ -313,13 +319,32 @@ final class PhabricatorProjectQuery | ||||
|         PhabricatorEdgeConfig::TYPE_PROJ_MEMBER); | ||||
|     } | ||||
|  | ||||
|     if ($this->slugs) { | ||||
|     if ($this->slugs !== null) { | ||||
|       $joins[] = qsprintf( | ||||
|         $conn_r, | ||||
|         'JOIN %T slug on slug.projectPHID = p.phid', | ||||
|         id(new PhabricatorProjectSlug())->getTableName()); | ||||
|     } | ||||
|  | ||||
|     if ($this->datasourceQuery !== null) { | ||||
|       $tokens = PhabricatorTypeaheadDatasource::tokenizeString( | ||||
|         $this->datasourceQuery); | ||||
|       if (!$tokens) { | ||||
|         throw new PhabricatorEmptyQueryException(); | ||||
|       } | ||||
|  | ||||
|       $likes = array(); | ||||
|       foreach ($tokens as $token) { | ||||
|         $likes[] = qsprintf($conn_r, 'token.token LIKE %>', $token); | ||||
|       } | ||||
|  | ||||
|       $joins[] = qsprintf( | ||||
|         $conn_r, | ||||
|         'JOIN %T token ON token.projectID = p.id AND (%Q)', | ||||
|         PhabricatorProject::TABLE_DATASOURCE_TOKEN, | ||||
|         '('.implode(') OR (', $likes).')'); | ||||
|     } | ||||
|  | ||||
|     $joins[] = $this->buildApplicationSearchJoinClause($conn_r); | ||||
|  | ||||
|     return implode(' ', $joins); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley