mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-30 10:42:41 +01:00
Modernize DifferentialRevisionSearchEngine
Summary: Ref T10939. Ref T4144. This moves the revision SearchEngine to modern code so I can add some kind of bucketing layer on top of it. This seems to have worked pretty cleanly. One thing is that I removed the ability to search for "pending drafts": - This was added in D1927 from a bootcamp task, was an indirect solution to a questionable problem, and almost certainly would not meet the bar today. - Later, in D3324, we added the icons to the list. I think this is a better solution in general. In particular, it specifically addressed the query being kind of junky. - At the time, Differential had a prebuilt "Drafts" filter. This was removed in D6347 with the move to ApplicationSearch, which simplified the large number of prebuilt filters. Although we got a lot of feedback about that, none requested that the drafts filter be restored. Test Plan: Searched for responsible users, subscribers, orders, projects, repositories. Reviewers: chad Reviewed By: chad Maniphest Tasks: T4144, T10939 Differential Revision: https://secure.phabricator.com/D15921
This commit is contained in:
parent
03a1deba23
commit
3a727c31e2
3 changed files with 81 additions and 215 deletions
|
@ -91,18 +91,6 @@ final class DifferentialRevisionQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter results to revisions with comments authored by the given PHIDs.
|
||||
*
|
||||
* @param array List of PHIDs of authors
|
||||
* @return this
|
||||
* @task config
|
||||
*/
|
||||
public function withDraftRepliesByAuthors(array $author_phids) {
|
||||
$this->draftAuthors = $author_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter results to revisions which CC one of the listed people. Calling this
|
||||
* function will clear anything set by previous calls to @{method:withCCs}.
|
||||
|
@ -239,27 +227,6 @@ final class DifferentialRevisionQuery
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set result ordering. Provide a class constant, such as
|
||||
* `DifferentialRevisionQuery::ORDER_CREATED`.
|
||||
*
|
||||
* @task config
|
||||
*/
|
||||
public function setOrder($order_constant) {
|
||||
switch ($order_constant) {
|
||||
case self::ORDER_CREATED:
|
||||
$this->setOrderVector(array('id'));
|
||||
break;
|
||||
case self::ORDER_MODIFIED:
|
||||
$this->setOrderVector(array('updated', 'id'));
|
||||
break;
|
||||
default:
|
||||
throw new Exception(pht('Unknown order "%s".', $order_constant));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether or not the query will load and attach relationships.
|
||||
|
@ -371,6 +338,11 @@ final class DifferentialRevisionQuery
|
|||
/* -( Query Execution )---------------------------------------------------- */
|
||||
|
||||
|
||||
public function newResultObject() {
|
||||
return new DifferentialRevision();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the query as configured, returning matching
|
||||
* @{class:DifferentialRevision} objects.
|
||||
|
@ -379,11 +351,9 @@ final class DifferentialRevisionQuery
|
|||
* @task exec
|
||||
*/
|
||||
protected function loadPage() {
|
||||
$table = new DifferentialRevision();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
||||
$data = $this->loadData();
|
||||
|
||||
$table = $this->newResultObject();
|
||||
return $table->loadAllFromArray($data);
|
||||
}
|
||||
|
||||
|
@ -519,7 +489,7 @@ final class DifferentialRevisionQuery
|
|||
}
|
||||
|
||||
private function loadData() {
|
||||
$table = new DifferentialRevision();
|
||||
$table = $this->newResultObject();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
||||
$selects = array();
|
||||
|
@ -605,7 +575,7 @@ final class DifferentialRevisionQuery
|
|||
|
||||
$joins = $this->buildJoinsClause($conn_r);
|
||||
$where = $this->buildWhereClause($conn_r);
|
||||
$group_by = $this->buildGroupByClause($conn_r);
|
||||
$group_by = $this->buildGroupClause($conn_r);
|
||||
$having = $this->buildHavingClause($conn_r);
|
||||
|
||||
$this->buildingGlobalOrder = false;
|
||||
|
@ -849,19 +819,37 @@ final class DifferentialRevisionQuery
|
|||
/**
|
||||
* @task internal
|
||||
*/
|
||||
private function buildGroupByClause($conn_r) {
|
||||
protected function shouldGroupQueryResultRows() {
|
||||
|
||||
$join_triggers = array_merge(
|
||||
$this->pathIDs,
|
||||
$this->ccs,
|
||||
$this->reviewers);
|
||||
|
||||
$needs_distinct = (count($join_triggers) > 1);
|
||||
|
||||
if ($needs_distinct) {
|
||||
return 'GROUP BY r.id';
|
||||
} else {
|
||||
return '';
|
||||
if (count($join_triggers) > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::shouldGroupQueryResultRows();
|
||||
}
|
||||
|
||||
public function getBuiltinOrders() {
|
||||
$orders = parent::getBuiltinOrders() + array(
|
||||
'updated' => array(
|
||||
'vector' => array('updated', 'id'),
|
||||
'name' => pht('Date Updated (Latest First)'),
|
||||
'aliases' => array(self::ORDER_MODIFIED),
|
||||
),
|
||||
'outdated' => array(
|
||||
'vector' => array('-updated', '-id'),
|
||||
'name' => pht('Date Updated (Oldest First)'),
|
||||
),
|
||||
);
|
||||
|
||||
// Alias the "newest" builtin to the historical key for it.
|
||||
$orders['newest']['aliases'][] = self::ORDER_CREATED;
|
||||
|
||||
return $orders;
|
||||
}
|
||||
|
||||
protected function getDefaultOrderVector() {
|
||||
|
|
|
@ -25,189 +25,68 @@ final class DifferentialRevisionSearchEngine
|
|||
return parent::getPageSize($saved);
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||
$saved = new PhabricatorSavedQuery();
|
||||
|
||||
$saved->setParameter(
|
||||
'responsiblePHIDs',
|
||||
$this->readUsersFromRequest($request, 'responsibles'));
|
||||
protected function buildQueryFromParameters(array $map) {
|
||||
$query = $this->newQuery();
|
||||
|
||||
$saved->setParameter(
|
||||
'authorPHIDs',
|
||||
$this->readUsersFromRequest($request, 'authors'));
|
||||
|
||||
$saved->setParameter(
|
||||
'reviewerPHIDs',
|
||||
$this->readUsersFromRequest(
|
||||
$request,
|
||||
'reviewers',
|
||||
array(
|
||||
PhabricatorProjectProjectPHIDType::TYPECONST,
|
||||
)));
|
||||
|
||||
$saved->setParameter(
|
||||
'subscriberPHIDs',
|
||||
$this->readSubscribersFromRequest($request, 'subscribers'));
|
||||
|
||||
$saved->setParameter(
|
||||
'repositoryPHIDs',
|
||||
$request->getArr('repositories'));
|
||||
|
||||
$saved->setParameter(
|
||||
'projects',
|
||||
$this->readProjectsFromRequest($request, 'projects'));
|
||||
|
||||
$saved->setParameter(
|
||||
'draft',
|
||||
$request->getBool('draft'));
|
||||
|
||||
$saved->setParameter(
|
||||
'order',
|
||||
$request->getStr('order'));
|
||||
|
||||
$saved->setParameter(
|
||||
'status',
|
||||
$request->getStr('status'));
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||
$query = id(new DifferentialRevisionQuery())
|
||||
->needFlags(true)
|
||||
->needDrafts(true)
|
||||
->needRelationships(true);
|
||||
|
||||
$user_datasource = id(new PhabricatorPeopleUserFunctionDatasource())
|
||||
->setViewer($this->requireViewer());
|
||||
|
||||
$responsible_phids = $saved->getParameter('responsiblePHIDs', array());
|
||||
$responsible_phids = $user_datasource->evaluateTokens($responsible_phids);
|
||||
if ($responsible_phids) {
|
||||
$query->withResponsibleUsers($responsible_phids);
|
||||
if ($map['responsiblePHIDs']) {
|
||||
$query->withResponsibleUsers($map['responsiblePHIDs']);
|
||||
}
|
||||
|
||||
$this->setQueryProjects($query, $saved);
|
||||
|
||||
$author_phids = $saved->getParameter('authorPHIDs', array());
|
||||
$author_phids = $user_datasource->evaluateTokens($author_phids);
|
||||
if ($author_phids) {
|
||||
$query->withAuthors($author_phids);
|
||||
if ($map['authorPHIDs']) {
|
||||
$query->withAuthors($map['authorPHIDs']);
|
||||
}
|
||||
|
||||
$reviewer_phids = $saved->getParameter('reviewerPHIDs', array());
|
||||
if ($reviewer_phids) {
|
||||
$query->withReviewers($reviewer_phids);
|
||||
if ($map['reviewerPHIDs']) {
|
||||
$query->withReviewers($map['reviewerPHIDs']);
|
||||
}
|
||||
|
||||
$sub_datasource = id(new PhabricatorMetaMTAMailableFunctionDatasource())
|
||||
->setViewer($this->requireViewer());
|
||||
$subscriber_phids = $saved->getParameter('subscriberPHIDs', array());
|
||||
$subscriber_phids = $sub_datasource->evaluateTokens($subscriber_phids);
|
||||
if ($subscriber_phids) {
|
||||
$query->withCCs($subscriber_phids);
|
||||
if ($map['repositoryPHIDs']) {
|
||||
$query->withRepositoryPHIDs($map['repositoryPHIDs']);
|
||||
}
|
||||
|
||||
$repository_phids = $saved->getParameter('repositoryPHIDs', array());
|
||||
if ($repository_phids) {
|
||||
$query->withRepositoryPHIDs($repository_phids);
|
||||
}
|
||||
|
||||
$draft = $saved->getParameter('draft', false);
|
||||
if ($draft && $this->requireViewer()->isLoggedIn()) {
|
||||
$query->withDraftRepliesByAuthors(
|
||||
array($this->requireViewer()->getPHID()));
|
||||
}
|
||||
|
||||
$status = $saved->getParameter('status');
|
||||
if (idx($this->getStatusOptions(), $status)) {
|
||||
$query->withStatus($status);
|
||||
}
|
||||
|
||||
$order = $saved->getParameter('order');
|
||||
if (idx($this->getOrderOptions(), $order)) {
|
||||
$query->setOrder($order);
|
||||
} else {
|
||||
$query->setOrder(DifferentialRevisionQuery::ORDER_CREATED);
|
||||
if ($map['status']) {
|
||||
$query->withStatus($map['status']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function buildSearchForm(
|
||||
AphrontFormView $form,
|
||||
PhabricatorSavedQuery $saved) {
|
||||
|
||||
$responsible_phids = $saved->getParameter('responsiblePHIDs', array());
|
||||
$author_phids = $saved->getParameter('authorPHIDs', array());
|
||||
$reviewer_phids = $saved->getParameter('reviewerPHIDs', array());
|
||||
$subscriber_phids = $saved->getParameter('subscriberPHIDs', array());
|
||||
$repository_phids = $saved->getParameter('repositoryPHIDs', array());
|
||||
$only_draft = $saved->getParameter('draft', false);
|
||||
$projects = $saved->getParameter('projects', array());
|
||||
|
||||
$form
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Responsible Users'))
|
||||
->setName('responsibles')
|
||||
->setDatasource(new PhabricatorPeopleUserFunctionDatasource())
|
||||
->setValue($responsible_phids))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Authors'))
|
||||
->setName('authors')
|
||||
->setDatasource(new PhabricatorPeopleUserFunctionDatasource())
|
||||
->setValue($author_phids))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Reviewers'))
|
||||
->setName('reviewers')
|
||||
->setDatasource(new PhabricatorProjectOrUserDatasource())
|
||||
->setValue($reviewer_phids))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Subscribers'))
|
||||
->setName('subscribers')
|
||||
->setDatasource(new PhabricatorMetaMTAMailableFunctionDatasource())
|
||||
->setValue($subscriber_phids))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Repositories'))
|
||||
->setName('repositories')
|
||||
->setDatasource(new DiffusionRepositoryDatasource())
|
||||
->setValue($repository_phids))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Tags'))
|
||||
->setName('projects')
|
||||
->setDatasource(new PhabricatorProjectLogicalDatasource())
|
||||
->setValue($projects))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Status'))
|
||||
->setName('status')
|
||||
->setOptions($this->getStatusOptions())
|
||||
->setValue($saved->getParameter('status')));
|
||||
|
||||
if ($this->requireViewer()->isLoggedIn()) {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormCheckboxControl())
|
||||
->addCheckbox(
|
||||
'draft',
|
||||
1,
|
||||
pht('Show only revisions with a draft comment.'),
|
||||
$only_draft));
|
||||
}
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Order'))
|
||||
->setName('order')
|
||||
->setOptions($this->getOrderOptions())
|
||||
->setValue($saved->getParameter('order')));
|
||||
protected function buildCustomSearchFields() {
|
||||
return array(
|
||||
id(new PhabricatorUsersSearchField())
|
||||
->setLabel(pht('Responsible Users'))
|
||||
->setKey('responsiblePHIDs')
|
||||
->setAliases(array('responsiblePHID', 'responsibles', 'responsible'))
|
||||
->setDescription(
|
||||
pht('Find revisions that a given user is responsible for.')),
|
||||
id(new PhabricatorUsersSearchField())
|
||||
->setLabel(pht('Authors'))
|
||||
->setKey('authorPHIDs')
|
||||
->setAliases(array('author', 'authors', 'authorPHID'))
|
||||
->setDescription(
|
||||
pht('Find revisions with specific authors.')),
|
||||
id(new PhabricatorSearchDatasourceField())
|
||||
->setLabel(pht('Reviewers'))
|
||||
->setKey('reviewerPHIDs')
|
||||
->setAliases(array('reviewer', 'reviewers', 'reviewerPHID'))
|
||||
->setDatasource(new DiffusionAuditorDatasource())
|
||||
->setDescription(
|
||||
pht('Find revisions with specific reviewers.')),
|
||||
id(new PhabricatorSearchDatasourceField())
|
||||
->setLabel(pht('Repositories'))
|
||||
->setKey('repositoryPHIDs')
|
||||
->setAliases(array('repository', 'repositories', 'repositoryPHID'))
|
||||
->setDatasource(new DiffusionRepositoryDatasource())
|
||||
->setDescription(
|
||||
pht('Find revisions from specific repositories.')),
|
||||
id(new PhabricatorSearchSelectField())
|
||||
->setLabel(pht('Status'))
|
||||
->setKey('status')
|
||||
->setOptions($this->getStatusOptions())
|
||||
->setDescription(
|
||||
pht('Find revisions with particular statuses.')),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
|
|
|
@ -148,8 +148,7 @@ final class ManiphestTaskSearchEngine
|
|||
}
|
||||
|
||||
protected function buildQueryFromParameters(array $map) {
|
||||
$query = id(new ManiphestTaskQuery())
|
||||
->needProjectPHIDs(true);
|
||||
$query = $this->newQuery();
|
||||
|
||||
if ($map['assignedPHIDs']) {
|
||||
$query->withOwners($map['assignedPHIDs']);
|
||||
|
|
Loading…
Reference in a new issue