Something went wrong. Try again.
@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
Something went wrong. Try again.
29 kB · 1002 lines
PHP
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003<?php
/** * @extends PhabricatorCursorPagedPolicyAwareQuery<PhabricatorRepositoryCommit> */final class DiffusionCommitQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids; private $phids; private $authorPHIDs; private $defaultRepository; private $identifiers; private $repositoryIDs; private $repositoryPHIDs; private $identifierMap; private $responsiblePHIDs; private $statuses; private $packagePHIDs; private $unreachable; private $permanent;
private $needAuditRequests; private $needAuditAuthority; private $auditIDs; private $auditorPHIDs; private $epochMin; private $epochMax; private $importing; private $ancestorsOf;
private $needCommitData; private $needDrafts; private $needIdentities;
private $mustFilterRefs = false; private $refRepository;
public function withIDs(array $ids) { $this->ids = $ids; return $this; }
public function withPHIDs(array $phids) { $this->phids = $phids; return $this; }
public function withAuthorPHIDs(array $phids) { $this->authorPHIDs = $phids; return $this; }
/** * Load commits by partial or full identifiers, e.g. "rXab82393", "rX1234", * or "a9caf12". When an identifier matches multiple commits, they will all * be returned; callers should be prepared to deal with more results than * they queried for. */ public function withIdentifiers(array $identifiers) { // Some workflows (like blame lookups) can pass in large numbers of // duplicate identifiers. We only care about unique identifiers, so // get rid of duplicates immediately. $identifiers = array_fuse($identifiers);
$this->identifiers = $identifiers; return $this; }
/** * Look up commits in a specific repository. This is a shorthand for calling * @{method:withDefaultRepository} and @{method:withRepositoryIDs}. */ public function withRepository(PhabricatorRepository $repository) { $this->withDefaultRepository($repository); $this->withRepositoryIDs(array($repository->getID())); return $this; }
/** * Look up commits in a specific repository. Prefer * @{method:withRepositoryIDs}; the underlying table is keyed by ID such * that this method requires a separate initial query to map PHID to ID. */ public function withRepositoryPHIDs(array $phids) { $this->repositoryPHIDs = $phids; return $this; }
/** * If a default repository is provided, ambiguous commit identifiers will * be assumed to belong to the default repository. * * For example, "r123" appearing in a commit message in repository X is * likely to be unambiguously "rX123". Normally the reference would be * considered ambiguous, but if you provide a default repository it will * be correctly resolved. */ public function withDefaultRepository(PhabricatorRepository $repository) { $this->defaultRepository = $repository; return $this; }
public function withRepositoryIDs(array $repository_ids) { $this->repositoryIDs = array_unique($repository_ids); return $this; }
public function needCommitData($need) { $this->needCommitData = $need; return $this; }
public function needDrafts($need) { $this->needDrafts = $need; return $this; }
public function needIdentities($need) { $this->needIdentities = $need; return $this; }
public function needAuditRequests($need) { $this->needAuditRequests = $need; return $this; }
/** * @param array<PhabricatorUser> $users */ public function needAuditAuthority(array $users) { assert_instances_of($users, PhabricatorUser::class); $this->needAuditAuthority = $users; return $this; }
public function withAuditIDs(array $ids) { $this->auditIDs = $ids; return $this; }
public function withAuditorPHIDs(array $auditor_phids) { $this->auditorPHIDs = $auditor_phids; return $this; }
public function withResponsiblePHIDs(array $responsible_phids) { $this->responsiblePHIDs = $responsible_phids; return $this; }
public function withPackagePHIDs(array $package_phids) { $this->packagePHIDs = $package_phids; return $this; }
public function withUnreachable($unreachable) { $this->unreachable = $unreachable; return $this; }
public function withPermanent($permanent) { $this->permanent = $permanent; return $this; }
public function withStatuses(array $statuses) { $this->statuses = $statuses; return $this; }
public function withEpochRange($min, $max) { $this->epochMin = $min; $this->epochMax = $max; return $this; }
public function withImporting($importing) { $this->importing = $importing; return $this; }
public function withAncestorsOf(array $refs) { $this->ancestorsOf = $refs; return $this; }
public function getIdentifierMap() { if ($this->identifierMap === null) { throw new Exception( pht( 'You must %s the query before accessing the identifier map.', 'execute()')); } return $this->identifierMap; }
protected function getPrimaryTableAlias() { return 'commit'; }
protected function willExecute() { if ($this->identifierMap === null) { $this->identifierMap = array(); } }
public function newResultObject() { return new PhabricatorRepositoryCommit(); }
protected function loadPage() { $table = $this->newResultObject(); $conn = $table->establishConnection('r');
$empty_exception = null; $subqueries = array(); if ($this->responsiblePHIDs) { $base_authors = $this->authorPHIDs; $base_auditors = $this->auditorPHIDs;
$responsible_phids = $this->responsiblePHIDs; if ($base_authors) { $all_authors = array_merge($base_authors, $responsible_phids); } else { $all_authors = $responsible_phids; }
if ($base_auditors) { $all_auditors = array_merge($base_auditors, $responsible_phids); } else { $all_auditors = $responsible_phids; }
$this->authorPHIDs = $all_authors; $this->auditorPHIDs = $base_auditors; try { $subqueries[] = $this->buildStandardPageQuery( $conn, $table->getTableName()); } catch (PhabricatorEmptyQueryException $ex) { $empty_exception = $ex; }
$this->authorPHIDs = $base_authors; $this->auditorPHIDs = $all_auditors; try { $subqueries[] = $this->buildStandardPageQuery( $conn, $table->getTableName()); } catch (PhabricatorEmptyQueryException $ex) { $empty_exception = $ex; } } else { $subqueries[] = $this->buildStandardPageQuery( $conn, $table->getTableName()); }
if (!$subqueries && $empty_exception) { throw $empty_exception; }
if (count($subqueries) > 1) { $unions = null; foreach ($subqueries as $subquery) { if (!$unions) { $unions = qsprintf( $conn, '(%Q)', $subquery); continue; }
$unions = qsprintf( $conn, '%Q UNION DISTINCT (%Q)', $unions, $subquery); }
$query = qsprintf( $conn, '%Q %Q %Q', $unions, $this->buildOrderClause($conn, true), $this->buildLimitClause($conn)); } else { $query = head($subqueries); }
$rows = queryfx_all($conn, '%Q', $query); $rows = $this->didLoadRawRows($rows);
return $table->loadAllFromArray($rows); }
protected function willFilterPage(array $commits) { $repository_ids = mpull($commits, 'getRepositoryID', 'getRepositoryID'); $repos = id(new PhabricatorRepositoryQuery()) ->setViewer($this->getViewer()) ->withIDs($repository_ids) ->execute();
$min_qualified = PhabricatorRepository::MINIMUM_QUALIFIED_HASH; $result = array();
foreach ($commits as $key => $commit) { $repo = idx($repos, $commit->getRepositoryID()); if ($repo) { $commit->attachRepository($repo); } else { $this->didRejectResult($commit); unset($commits[$key]); continue; }
// Build the identifierMap if ($this->identifiers !== null) { $ids = $this->identifiers; $prefixes = array( 'r'.$commit->getRepository()->getCallsign(), 'r'.$commit->getRepository()->getCallsign().':', 'R'.$commit->getRepository()->getID().':', '', // No prefix is valid too and will only match the commitIdentifier ); $suffix = $commit->getCommitIdentifier();
if ($commit->getRepository()->isSVN()) { foreach ($prefixes as $prefix) { if (isset($ids[$prefix.$suffix])) { $result[$prefix.$suffix][] = $commit; } } } else { // This awkward construction is so we can link the commits up in O(N) // time instead of O(N^2). for ($ii = $min_qualified; $ii <= strlen($suffix); $ii++) { $part = substr($suffix, 0, $ii); foreach ($prefixes as $prefix) { if (isset($ids[$prefix.$part])) { $result[$prefix.$part][] = $commit; } } } } } }
if ($result) { foreach ($result as $identifier => $matching_commits) { if (count($matching_commits) == 1) { $result[$identifier] = head($matching_commits); } else { // This reference is ambiguous (it matches more than one commit) so // don't link it. unset($result[$identifier]); } } $this->identifierMap += $result; }
return $commits; }
protected function didFilterPage(array $commits) { $viewer = $this->getViewer();
if ($this->mustFilterRefs) { // If this flag is set, the query has an "Ancestors Of" constraint and // at least one of the constraining refs had too many ancestors for us // to apply the constraint with a big "commitIdentifier IN (%Ls)" clause. // We're going to filter each page and hope we get a full result set // before the query overheats.
$ancestor_list = mpull($commits, 'getCommitIdentifier'); $ancestor_list = array_values($ancestor_list);
foreach ($this->ancestorsOf as $ref) { try { $ancestor_list = DiffusionQuery::callConduitWithDiffusionRequest( $viewer, DiffusionRequest::newFromDictionary( array( 'repository' => $this->refRepository, 'user' => $viewer, )), 'diffusion.internal.ancestors', array( 'ref' => $ref, 'commits' => $ancestor_list, )); } catch (ConduitClientException $ex) { throw new PhabricatorSearchConstraintException( $ex->getMessage()); }
if (!$ancestor_list) { break; } }
$ancestor_list = array_fuse($ancestor_list); foreach ($commits as $key => $commit) { $identifier = $commit->getCommitIdentifier(); if (!isset($ancestor_list[$identifier])) { $this->didRejectResult($commit); unset($commits[$key]); } }
if (!$commits) { return $commits; } }
if ($this->needCommitData) { $data = id(new PhabricatorRepositoryCommitData())->loadAllWhere( 'commitID in (%Ld)', mpull($commits, 'getID')); $data = mpull($data, null, 'getCommitID'); foreach ($commits as $commit) { $commit_data = idx($data, $commit->getID()); if (!$commit_data) { $commit_data = new PhabricatorRepositoryCommitData(); } $commit->attachCommitData($commit_data); } }
if ($this->needAuditRequests) { $requests = id(new PhabricatorRepositoryAuditRequest())->loadAllWhere( 'commitPHID IN (%Ls)', mpull($commits, 'getPHID'));
$requests = mgroup($requests, 'getCommitPHID'); foreach ($commits as $commit) { $audit_requests = idx($requests, $commit->getPHID(), array()); $commit->attachAudits($audit_requests); foreach ($audit_requests as $audit_request) { $audit_request->attachCommit($commit); } } }
if ($this->needIdentities) { $identity_phids = array_unique(array_merge( mpull($commits, 'getAuthorIdentityPHID'), mpull($commits, 'getCommitterIdentityPHID')));
$data = id(new PhabricatorRepositoryIdentityQuery()) ->withPHIDs($identity_phids) ->setViewer($this->getViewer()) ->execute(); $data = mpull($data, null, 'getPHID');
foreach ($commits as $commit) { $author_identity = idx($data, $commit->getAuthorIdentityPHID()); $committer_identity = idx($data, $commit->getCommitterIdentityPHID()); $commit->attachIdentities($author_identity, $committer_identity); } }
if ($this->needDrafts) { PhabricatorDraftEngine::attachDrafts( $viewer, $commits); }
if ($this->needAuditAuthority) { $authority_users = $this->needAuditAuthority;
// NOTE: This isn't very efficient since we're running two queries per // user, but there's currently no way to figure out authority for // multiple users in one query. Today, we only ever request authority for // a single user and single commit, so this has no practical impact.
// NOTE: We're querying with the viewership of query viewer, not the // actual users. If the viewer can't see a project or package, they // won't be able to see who has authority on it. This is safer than // showing them true authority, and should never matter today, but it // also doesn't seem like a significant disclosure and might be // reasonable to adjust later if it causes something weird or confusing // to happen.
$authority_map = array(); foreach ($authority_users as $authority_user) { $authority_phid = $authority_user->getPHID(); if (!$authority_phid) { continue; }
$result_phids = array();
// Users have authority over themselves. $result_phids[] = $authority_phid;
// Users have authority over packages they own. $owned_packages = id(new PhabricatorOwnersPackageQuery()) ->setViewer($viewer) ->withAuthorityPHIDs(array($authority_phid)) ->execute(); foreach ($owned_packages as $package) { $result_phids[] = $package->getPHID(); }
// Users have authority over projects they're members of. $projects = id(new PhabricatorProjectQuery()) ->setViewer($viewer) ->withMemberPHIDs(array($authority_phid)) ->execute(); foreach ($projects as $project) { $result_phids[] = $project->getPHID(); }
$result_phids = array_fuse($result_phids);
foreach ($commits as $commit) { $attach_phids = $result_phids;
// NOTE: When modifying your own commits, you act only on behalf of // yourself, not your packages or projects. The idea here is that you // can't accept your own commits. In the future, this might change or // depend on configuration. $author_phid = $commit->getAuthorPHID(); if ($author_phid == $authority_phid) { $attach_phids = array($author_phid); $attach_phids = array_fuse($attach_phids); }
$commit->attachAuditAuthority($authority_user, $attach_phids); } } }
return $commits; }
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn);
if ($this->repositoryPHIDs !== null) { $map_repositories = id(new PhabricatorRepositoryQuery()) ->setViewer($this->getViewer()) ->withPHIDs($this->repositoryPHIDs) ->execute();
if (!$map_repositories) { throw new PhabricatorEmptyQueryException(); } $repository_ids = mpull($map_repositories, 'getID'); if ($this->repositoryIDs !== null) { $repository_ids = array_merge($repository_ids, $this->repositoryIDs); } $this->withRepositoryIDs($repository_ids); }
if ($this->ancestorsOf !== null) { if ($this->repositoryIDs === null || count($this->repositoryIDs) !== 1) { throw new PhabricatorSearchConstraintException( pht( 'To search for commits which are ancestors of particular refs, '. 'you must constrain the search to exactly one repository.')); }
$repository_id = head($this->repositoryIDs); $history_limit = $this->getRawResultLimit() * 32; $viewer = $this->getViewer();
$repository = id(new PhabricatorRepositoryQuery()) ->setViewer($viewer) ->withIDs(array($repository_id)) ->executeOne();
if (!$repository) { throw new PhabricatorEmptyQueryException(); }
if ($repository->isSVN()) { throw new PhabricatorSearchConstraintException( pht( 'Subversion does not support searching for ancestors of '. 'a particular ref. This operation is not meaningful in '. 'Subversion.')); }
if ($repository->isHg()) { throw new PhabricatorSearchConstraintException( pht( 'Mercurial does not currently support searching for ancestors of '. 'a particular ref.')); }
$can_constrain = true; $history_identifiers = array(); foreach ($this->ancestorsOf as $key => $ref) { try { $raw_history = DiffusionQuery::callConduitWithDiffusionRequest( $viewer, DiffusionRequest::newFromDictionary( array( 'repository' => $repository, 'user' => $viewer, )), 'diffusion.historyquery', array( 'commit' => $ref, 'limit' => $history_limit, )); } catch (ConduitClientException $ex) { throw new PhabricatorSearchConstraintException( $ex->getMessage()); }
$ref_identifiers = array(); foreach ($raw_history['pathChanges'] as $change) { $ref_identifiers[] = $change['commitIdentifier']; }
// If this ref had fewer total commits than the limit, we're safe to // apply the constraint as a large `IN (...)` query for a list of // commit identifiers. This is efficient. if ($history_limit) { if (count($ref_identifiers) >= $history_limit) { $can_constrain = false; break; } }
$history_identifiers += array_fuse($ref_identifiers); }
// If all refs had a small number of ancestors, we can just put the // constraint into the query here and we're done. Otherwise, we need // to filter each page after it comes out of the MySQL layer. if ($can_constrain) { $where[] = qsprintf( $conn, 'commit.commitIdentifier IN (%Ls)', $history_identifiers); } else { $this->mustFilterRefs = true; $this->refRepository = $repository; } }
if ($this->ids !== null) { $where[] = qsprintf( $conn, 'commit.id IN (%Ld)', $this->ids); }
if ($this->phids !== null) { $where[] = qsprintf( $conn, 'commit.phid IN (%Ls)', $this->phids); }
if ($this->repositoryIDs !== null) { $where[] = qsprintf( $conn, 'commit.repositoryID IN (%Ld)', $this->repositoryIDs); }
if ($this->authorPHIDs !== null) { $author_phids = $this->authorPHIDs; if ($author_phids) { $author_phids = $this->selectPossibleAuthors($author_phids); if (!$author_phids) { throw new PhabricatorEmptyQueryException( pht('Author PHIDs contain no possible authors.')); } }
$where[] = qsprintf( $conn, 'commit.authorPHID IN (%Ls)', $author_phids); }
if ($this->epochMin !== null) { $where[] = qsprintf( $conn, 'commit.epoch >= %d', $this->epochMin); }
if ($this->epochMax !== null) { $where[] = qsprintf( $conn, 'commit.epoch <= %d', $this->epochMax); }
if ($this->importing !== null) { if ($this->importing) { $where[] = qsprintf( $conn, '(commit.importStatus & %d) != %d', PhabricatorRepositoryCommit::IMPORTED_ALL, PhabricatorRepositoryCommit::IMPORTED_ALL); } else { $where[] = qsprintf( $conn, '(commit.importStatus & %d) = %d', PhabricatorRepositoryCommit::IMPORTED_ALL, PhabricatorRepositoryCommit::IMPORTED_ALL); } }
if ($this->identifiers !== null) { $min_unqualified = PhabricatorRepository::MINIMUM_UNQUALIFIED_HASH; $min_qualified = PhabricatorRepository::MINIMUM_QUALIFIED_HASH;
$refs = array(); $bare = array(); foreach ($this->identifiers as $identifier) { $matches = null; preg_match('/^(?:[rR]([A-Z]+:?|[0-9]+:))?(.*)$/', $identifier, $matches); $repo = nonempty(rtrim($matches[1], ':'), null); $commit_identifier = nonempty($matches[2], null);
if ($repo === null) { if ($this->defaultRepository) { $repo = $this->defaultRepository->getPHID(); } }
if ($repo === null) { if (strlen($commit_identifier) < $min_unqualified) { continue; } $bare[] = $commit_identifier; } else { $refs[] = array( 'repository' => $repo, 'identifier' => $commit_identifier, ); } }
$sql = array();
foreach ($bare as $identifier) { $sql[] = qsprintf( $conn, '(commit.commitIdentifier LIKE %> AND '. 'LENGTH(commit.commitIdentifier) = 40)', $identifier); }
if ($refs) { $repositories = ipull($refs, 'repository');
$repos = id(new PhabricatorRepositoryQuery()) ->setViewer($this->getViewer()) ->withIdentifiers($repositories); $repos->execute();
$repos = $repos->getIdentifierMap(); foreach ($refs as $key => $ref) { $repo = idx($repos, $ref['repository']); if (!$repo) { continue; }
if ($repo->isSVN()) { if (!ctype_digit((string)$ref['identifier'])) { continue; } $sql[] = qsprintf( $conn, '(commit.repositoryID = %d AND commit.commitIdentifier = %s)', $repo->getID(), // NOTE: Because the 'commitIdentifier' column is a string, MySQL // ignores the index if we hand it an integer. Hand it a string. // See T3377. (int)$ref['identifier']); } else { if (!phutil_nonempty_string($ref['identifier']) || strlen($ref['identifier']) < $min_qualified) { continue; }
$identifier = $ref['identifier']; if (strlen($identifier) == 40) { // MySQL seems to do slightly better with this version if the // clause, so issue it if we have a full commit hash. $sql[] = qsprintf( $conn, '(commit.repositoryID = %d AND commit.commitIdentifier = %s)', $repo->getID(), $identifier); } else { $sql[] = qsprintf( $conn, '(commit.repositoryID = %d AND commit.commitIdentifier LIKE %>)', $repo->getID(), $identifier); } } } }
if (!$sql) { // If we discarded all possible identifiers (e.g., they all referenced // bogus repositories or were all too short), make sure the query finds // nothing. throw new PhabricatorEmptyQueryException( pht('No commit identifiers.')); }
$where[] = qsprintf($conn, '%LO', $sql); }
if ($this->auditIDs !== null) { $where[] = qsprintf( $conn, 'auditor.id IN (%Ld)', $this->auditIDs); }
if ($this->auditorPHIDs !== null) { $where[] = qsprintf( $conn, 'auditor.auditorPHID IN (%Ls)', $this->auditorPHIDs); }
if ($this->statuses !== null) { $statuses = DiffusionCommitAuditStatus::newModernKeys( $this->statuses);
$where[] = qsprintf( $conn, 'commit.auditStatus IN (%Ls)', $statuses); }
if ($this->packagePHIDs !== null) { $where[] = qsprintf( $conn, 'package.dst IN (%Ls)', $this->packagePHIDs); }
if ($this->unreachable !== null) { if ($this->unreachable) { $where[] = qsprintf( $conn, '(commit.importStatus & %d) = %d', PhabricatorRepositoryCommit::IMPORTED_UNREACHABLE, PhabricatorRepositoryCommit::IMPORTED_UNREACHABLE); } else { $where[] = qsprintf( $conn, '(commit.importStatus & %d) = 0', PhabricatorRepositoryCommit::IMPORTED_UNREACHABLE); } }
if ($this->permanent !== null) { if ($this->permanent) { $where[] = qsprintf( $conn, '(commit.importStatus & %d) = %d', PhabricatorRepositoryCommit::IMPORTED_PERMANENT, PhabricatorRepositoryCommit::IMPORTED_PERMANENT); } else { $where[] = qsprintf( $conn, '(commit.importStatus & %d) = 0', PhabricatorRepositoryCommit::IMPORTED_PERMANENT); } }
return $where; }
protected function didFilterResults(array $filtered) { if ($this->identifierMap) { foreach ($this->identifierMap as $name => $commit) { if (isset($filtered[$commit->getPHID()])) { unset($this->identifierMap[$name]); } } } }
private function shouldJoinAuditor() { return ($this->auditIDs || $this->auditorPHIDs); }
private function shouldJoinOwners() { return (bool)$this->packagePHIDs; }
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { $join = parent::buildJoinClauseParts($conn); $audit_request = new PhabricatorRepositoryAuditRequest();
if ($this->shouldJoinAuditor()) { $join[] = qsprintf( $conn, 'JOIN %T auditor ON commit.phid = auditor.commitPHID', $audit_request->getTableName()); }
if ($this->shouldJoinOwners()) { $join[] = qsprintf( $conn, 'JOIN %T package ON commit.phid = package.src AND package.type = %s', PhabricatorEdgeConfig::TABLE_NAME_EDGE, DiffusionCommitHasPackageEdgeType::EDGECONST); }
return $join; }
protected function shouldGroupQueryResultRows() { if ($this->shouldJoinAuditor()) { return true; }
if ($this->shouldJoinOwners()) { return true; }
return parent::shouldGroupQueryResultRows(); }
public function getQueryApplicationClass() { return PhabricatorDiffusionApplication::class; }
public function getOrderableColumns() { return parent::getOrderableColumns() + array( 'epoch' => array( 'table' => $this->getPrimaryTableAlias(), 'column' => 'epoch', 'type' => 'int', 'reverse' => false, ), ); }
protected function newPagingMapFromPartialObject($object) { return array( 'id' => (int)$object->getID(), 'epoch' => (int)$object->getEpoch(), ); }
public function getBuiltinOrders() { $parent = parent::getBuiltinOrders();
// Rename the default ID-based orders. $parent['importnew'] = array( 'name' => pht('Import Date (Newest First)'), ) + $parent['newest'];
$parent['importold'] = array( 'name' => pht('Import Date (Oldest First)'), ) + $parent['oldest'];
return array( 'newest' => array( 'vector' => array('epoch', 'id'), 'name' => pht('Commit Date (Newest First)'), ), 'oldest' => array( 'vector' => array('-epoch', '-id'), 'name' => pht('Commit Date (Oldest First)'), ), ) + $parent; }
private function selectPossibleAuthors(array $phids) { // See PHI1057. Select PHIDs which might possibly be commit authors from // a larger list of PHIDs. This primarily filters out packages and projects // from "Responsible Users: ..." queries. Our goal in performing this // filtering is to improve the performance of the final query.
foreach ($phids as $key => $phid) { if (phid_get_type($phid) !== PhabricatorPeopleUserPHIDType::TYPECONST) { unset($phids[$key]); } }
return $phids; }
}