Changeset View
Changeset View
Standalone View
Standalone View
src/applications/differential/query/DifferentialRevisionQuery.php
Show All 21 Lines | final class DifferentialRevisionQuery | ||||
private $repositoryPHIDs; | private $repositoryPHIDs; | ||||
private $updatedEpochMin; | private $updatedEpochMin; | ||||
private $updatedEpochMax; | private $updatedEpochMax; | ||||
private $statuses; | private $statuses; | ||||
private $isOpen; | private $isOpen; | ||||
private $createdEpochMin; | private $createdEpochMin; | ||||
private $createdEpochMax; | private $createdEpochMax; | ||||
private $noReviewers; | private $noReviewers; | ||||
private $paths; | |||||
const ORDER_MODIFIED = 'order-modified'; | const ORDER_MODIFIED = 'order-modified'; | ||||
const ORDER_CREATED = 'order-created'; | const ORDER_CREATED = 'order-created'; | ||||
private $needActiveDiffs = false; | private $needActiveDiffs = false; | ||||
private $needDiffIDs = false; | private $needDiffIDs = false; | ||||
private $needCommitPHIDs = false; | private $needCommitPHIDs = false; | ||||
private $needHashes = false; | private $needHashes = false; | ||||
Show All 20 Lines | public function withPath($repository_id, $path_id) { | ||||
$this->pathIDs[] = array( | $this->pathIDs[] = array( | ||||
'repositoryID' => $repository_id, | 'repositoryID' => $repository_id, | ||||
'pathID' => $path_id, | 'pathID' => $path_id, | ||||
); | ); | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Find revisions affecting one or more items in a list of paths. | |||||
* | |||||
* @param list<string> List of file paths. | |||||
* @return this | |||||
* @task config | |||||
*/ | |||||
public function withPaths(array $paths) { | |||||
$this->paths = $paths; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Filter results to revisions authored by one of the given PHIDs. Calling | * Filter results to revisions authored by one of the given PHIDs. Calling | ||||
* this function will clear anything set by previous calls to | * this function will clear anything set by previous calls to | ||||
* @{method:withAuthors}. | * @{method:withAuthors}. | ||||
* | * | ||||
* @param array List of PHIDs of authors | * @param array List of PHIDs of authors | ||||
* @return this | * @return this | ||||
* @task config | * @task config | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 497 Lines • ▼ Show 20 Lines | private function buildJoinsClause(AphrontDatabaseConnection $conn) { | ||||
if ($this->pathIDs) { | if ($this->pathIDs) { | ||||
$path_table = new DifferentialAffectedPath(); | $path_table = new DifferentialAffectedPath(); | ||||
$joins[] = qsprintf( | $joins[] = qsprintf( | ||||
$conn, | $conn, | ||||
'JOIN %T p ON p.revisionID = r.id', | 'JOIN %T p ON p.revisionID = r.id', | ||||
$path_table->getTableName()); | $path_table->getTableName()); | ||||
} | } | ||||
if ($this->paths) { | |||||
$path_table = new DifferentialAffectedPath(); | |||||
$joins[] = qsprintf( | |||||
$conn, | |||||
'JOIN %R paths ON paths.revisionID = r.id', | |||||
$path_table); | |||||
} | |||||
if ($this->commitHashes) { | if ($this->commitHashes) { | ||||
$joins[] = qsprintf( | $joins[] = qsprintf( | ||||
$conn, | $conn, | ||||
'JOIN %T hash_rel ON hash_rel.revisionID = r.id', | 'JOIN %T hash_rel ON hash_rel.revisionID = r.id', | ||||
ArcanistDifferentialRevisionHash::TABLE_NAME); | ArcanistDifferentialRevisionHash::TABLE_NAME); | ||||
} | } | ||||
if ($this->ccs) { | if ($this->ccs) { | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | private function buildJoinsClause(AphrontDatabaseConnection $conn) { | ||||
return $this->formatJoinClause($conn, $joins); | return $this->formatJoinClause($conn, $joins); | ||||
} | } | ||||
/** | /** | ||||
* @task internal | * @task internal | ||||
*/ | */ | ||||
protected function buildWhereClause(AphrontDatabaseConnection $conn) { | protected function buildWhereClause(AphrontDatabaseConnection $conn) { | ||||
$viewer = $this->getViewer(); | |||||
$where = array(); | $where = array(); | ||||
if ($this->pathIDs) { | if ($this->pathIDs) { | ||||
$path_clauses = array(); | $path_clauses = array(); | ||||
$repo_info = igroup($this->pathIDs, 'repositoryID'); | $repo_info = igroup($this->pathIDs, 'repositoryID'); | ||||
foreach ($repo_info as $repository_id => $paths) { | foreach ($repo_info as $repository_id => $paths) { | ||||
$path_clauses[] = qsprintf( | $path_clauses[] = qsprintf( | ||||
$conn, | $conn, | ||||
'(p.repositoryID = %d AND p.pathID IN (%Ld))', | '(p.repositoryID = %d AND p.pathID IN (%Ld))', | ||||
$repository_id, | $repository_id, | ||||
ipull($paths, 'pathID')); | ipull($paths, 'pathID')); | ||||
} | } | ||||
$path_clauses = qsprintf($conn, '%LO', $path_clauses); | $path_clauses = qsprintf($conn, '%LO', $path_clauses); | ||||
$where[] = $path_clauses; | $where[] = $path_clauses; | ||||
} | } | ||||
if ($this->paths !== null) { | |||||
$paths = $this->paths; | |||||
$path_map = id(new DiffusionPathIDQuery($paths)) | |||||
->loadPathIDs(); | |||||
if (!$path_map) { | |||||
// If none of the paths have entries in the PathID table, we can not | |||||
// possibly find any revisions affecting them. | |||||
throw new PhabricatorEmptyQueryException(); | |||||
} | |||||
$where[] = qsprintf( | |||||
$conn, | |||||
'paths.pathID IN (%Ld)', | |||||
array_fuse($path_map)); | |||||
// If we have repository PHIDs, additionally constrain this query to | |||||
// try to help MySQL execute it efficiently. | |||||
if ($this->repositoryPHIDs !== null) { | |||||
$repositories = id(new PhabricatorRepositoryQuery()) | |||||
->setViewer($viewer) | |||||
->setParentQuery($this) | |||||
->withPHIDs($this->repositoryPHIDs) | |||||
->execute(); | |||||
if (!$repositories) { | |||||
throw new PhabricatorEmptyQueryException(); | |||||
} | |||||
$repository_ids = mpull($repositories, 'getID'); | |||||
$where[] = qsprintf( | |||||
$conn, | |||||
'paths.repositoryID IN (%Ld)', | |||||
$repository_ids); | |||||
} | |||||
} | |||||
if ($this->authors) { | if ($this->authors) { | ||||
$where[] = qsprintf( | $where[] = qsprintf( | ||||
$conn, | $conn, | ||||
'r.authorPHID IN (%Ls)', | 'r.authorPHID IN (%Ls)', | ||||
$this->authors); | $this->authors); | ||||
} | } | ||||
if ($this->revIDs) { | if ($this->revIDs) { | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | /* -( Internals )---------------------------------------------------------- */ | ||||
* @task internal | * @task internal | ||||
*/ | */ | ||||
protected function shouldGroupQueryResultRows() { | protected function shouldGroupQueryResultRows() { | ||||
if (count($this->pathIDs) > 1) { | if (count($this->pathIDs) > 1) { | ||||
return true; | return true; | ||||
} | } | ||||
if ($this->paths) { | |||||
// (If we have exactly one repository and exactly one path, we don't | |||||
// technically need to group, but it's simpler to always group.) | |||||
return true; | |||||
} | |||||
if (count($this->ccs) > 1) { | if (count($this->ccs) > 1) { | ||||
return true; | return true; | ||||
} | } | ||||
if (count($this->reviewers) > 1) { | if (count($this->reviewers) > 1) { | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 278 Lines • Show Last 20 Lines |