diff --git a/src/applications/repository/query/PhabricatorRepositoryQuery.php b/src/applications/repository/query/PhabricatorRepositoryQuery.php --- a/src/applications/repository/query/PhabricatorRepositoryQuery.php +++ b/src/applications/repository/query/PhabricatorRepositoryQuery.php @@ -10,7 +10,6 @@ private $uuids; private $nameContains; private $remoteURIs; - private $anyProjectPHIDs; private $datasourceQuery; private $numericIdentifiers; @@ -99,11 +98,6 @@ return $this; } - public function withAnyProjects(array $projects) { - $this->anyProjectPHIDs = $projects; - return $this; - } - public function withDatasourceQuery($query) { $this->datasourceQuery = $query; return $this; @@ -163,10 +157,13 @@ $data = queryfx_all( $conn_r, - 'SELECT * FROM %T r %Q %Q %Q %Q', + '%Q FROM %T r %Q %Q %Q %Q %Q %Q', + $this->buildSelectClause($conn_r), $table->getTableName(), - $this->buildJoinsClause($conn_r), + $this->buildJoinClause($conn_r), $this->buildWhereClause($conn_r), + $this->buildGroupClause($conn_r), + $this->buildHavingClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r)); @@ -390,32 +387,46 @@ return $map; } - private function buildJoinsClause(AphrontDatabaseConnection $conn_r) { - $joins = array(); - - $join_summary_table = $this->needCommitCounts || - $this->needMostRecentCommits; - - $vector = $this->getOrderVector(); - if ($vector->containsKey('committed') || - $vector->containsKey('size')) { - $join_summary_table = true; + protected function buildSelectClause(AphrontDatabaseConnection $conn) { + $parts = $this->buildSelectClauseParts($conn); + if ($this->shouldJoinSummaryTable()) { + $parts[] = 's.*'; } + return $this->formatSelectClause($parts); + } - if ($join_summary_table) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { + $joins = $this->buildJoinClauseParts($conn_r); + + if ($this->shouldJoinSummaryTable()) { $joins[] = qsprintf( $conn_r, 'LEFT JOIN %T s ON r.id = s.repositoryID', PhabricatorRepository::TABLE_SUMMARY); } - if ($this->anyProjectPHIDs) { - $joins[] = qsprintf( - $conn_r, - 'JOIN edge e ON e.src = r.phid'); + return $this->formatJoinClause($joins); + } + + private function shouldJoinSummaryTable() { + if ($this->needCommitCounts) { + return true; } - return implode(' ', $joins); + if ($this->needMostRecentCommits) { + return true; + } + + $vector = $this->getOrderVector(); + if ($vector->containsKey('committed')) { + return true; + } + + if ($vector->containsKey('size')) { + return true; + } + + return false; } protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { @@ -492,13 +503,6 @@ $this->nameContains); } - if ($this->anyProjectPHIDs) { - $where[] = qsprintf( - $conn_r, - 'e.dst IN (%Ls)', - $this->anyProjectPHIDs); - } - if (strlen($this->datasourceQuery)) { // This handles having "rP" match callsigns starting with "P...". $query = trim($this->datasourceQuery); diff --git a/src/applications/repository/query/PhabricatorRepositorySearchEngine.php b/src/applications/repository/query/PhabricatorRepositorySearchEngine.php --- a/src/applications/repository/query/PhabricatorRepositorySearchEngine.php +++ b/src/applications/repository/query/PhabricatorRepositorySearchEngine.php @@ -20,7 +20,10 @@ $saved->setParameter('hosted', $request->getStr('hosted')); $saved->setParameter('types', $request->getArr('types')); $saved->setParameter('name', $request->getStr('name')); - $saved->setParameter('anyProjectPHIDs', $request->getArr('anyProjects')); + + $saved->setParameter( + 'projects', + $this->readProjectsFromRequest($request, 'projects')); return $saved; } @@ -60,10 +63,9 @@ $query->withNameContains($name); } - $any_project_phids = $saved->getParameter('anyProjectPHIDs'); - if ($any_project_phids) { - $query->withAnyProjects($any_project_phids); - } + $adjusted = clone $saved; + $adjusted->setParameter('projects', $this->readProjectTokens($saved)); + $this->setQueryProjects($query, $adjusted); return $query; } @@ -76,7 +78,7 @@ $types = $saved_query->getParameter('types', array()); $types = array_fuse($types); $name = $saved_query->getParameter('name'); - $any_project_phids = $saved_query->getParameter('anyProjectPHIDs', array()); + $projects = $this->readProjectTokens($saved_query); $form ->appendChild( @@ -91,10 +93,10 @@ ->setValue($name)) ->appendControl( id(new AphrontFormTokenizerControl()) - ->setDatasource(new PhabricatorProjectDatasource()) - ->setName('anyProjects') - ->setLabel(pht('In Any Project')) - ->setValue($any_project_phids)) + ->setDatasource(new PhabricatorProjectLogicalDatasource()) + ->setName('projects') + ->setLabel(pht('Projects')) + ->setValue($projects)) ->appendChild( id(new AphrontFormSelectControl()) ->setName('status') @@ -266,4 +268,15 @@ return $list; } + private function readProjectTokens(PhabricatorSavedQuery $saved) { + $projects = $saved->getParameter('projects', array()); + + $any = $saved->getParameter('anyProjectPHIDs', array()); + foreach ($any as $project) { + $projects[] = 'any('.$project.')'; + } + + return $projects; + } + }