Differential D19789 Diff 47256 src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
| Show First 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | abstract class PhabricatorCursorPagedPolicyAwareQuery | ||||
| final protected function getPagingViewer() { | final protected function getPagingViewer() { | ||||
| if ($this->internalPaging) { | if ($this->internalPaging) { | ||||
| return PhabricatorUser::getOmnipotentUser(); | return PhabricatorUser::getOmnipotentUser(); | ||||
| } else { | } else { | ||||
| return $this->getViewer(); | return $this->getViewer(); | ||||
| } | } | ||||
| } | } | ||||
| final protected function buildLimitClause(AphrontDatabaseConnection $conn_r) { | final protected function buildLimitClause(AphrontDatabaseConnection $conn) { | ||||
| if ($this->shouldLimitResults()) { | if ($this->shouldLimitResults()) { | ||||
| $limit = $this->getRawResultLimit(); | $limit = $this->getRawResultLimit(); | ||||
| if ($limit) { | if ($limit) { | ||||
| return qsprintf($conn_r, 'LIMIT %d', $limit); | return qsprintf($conn, 'LIMIT %d', $limit); | ||||
| } | } | ||||
| } | } | ||||
| return ''; | return qsprintf($conn, ''); | ||||
| } | } | ||||
| protected function shouldLimitResults() { | protected function shouldLimitResults() { | ||||
| return true; | return true; | ||||
| } | } | ||||
| final protected function didLoadResults(array $results) { | final protected function didLoadResults(array $results) { | ||||
| if ($this->beforeID) { | if ($this->beforeID) { | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | /* -( Building Query Clauses )--------------------------------------------- */ | ||||
| } | } | ||||
| /** | /** | ||||
| * @task clauses | * @task clauses | ||||
| */ | */ | ||||
| protected function buildJoinClause(AphrontDatabaseConnection $conn) { | protected function buildJoinClause(AphrontDatabaseConnection $conn) { | ||||
| $joins = $this->buildJoinClauseParts($conn); | $joins = $this->buildJoinClauseParts($conn); | ||||
| return $this->formatJoinClause($joins); | return $this->formatJoinClause($conn, $joins); | ||||
| } | } | ||||
| /** | /** | ||||
| * @task clauses | * @task clauses | ||||
| */ | */ | ||||
| protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { | protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { | ||||
| $joins = array(); | $joins = array(); | ||||
| $joins[] = $this->buildEdgeLogicJoinClause($conn); | $joins[] = $this->buildEdgeLogicJoinClause($conn); | ||||
| $joins[] = $this->buildApplicationSearchJoinClause($conn); | $joins[] = $this->buildApplicationSearchJoinClause($conn); | ||||
| $joins[] = $this->buildNgramsJoinClause($conn); | $joins[] = $this->buildNgramsJoinClause($conn); | ||||
| $joins[] = $this->buildFerretJoinClause($conn); | $joins[] = $this->buildFerretJoinClause($conn); | ||||
| return $joins; | return $joins; | ||||
| } | } | ||||
| /** | /** | ||||
| * @task clauses | * @task clauses | ||||
| */ | */ | ||||
| protected function buildWhereClause(AphrontDatabaseConnection $conn) { | protected function buildWhereClause(AphrontDatabaseConnection $conn) { | ||||
| $where = $this->buildWhereClauseParts($conn); | $where = $this->buildWhereClauseParts($conn); | ||||
| return $this->formatWhereClause($where); | return $this->formatWhereClause($conn, $where); | ||||
| } | } | ||||
| /** | /** | ||||
| * @task clauses | * @task clauses | ||||
| */ | */ | ||||
| protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { | protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { | ||||
| $where = array(); | $where = array(); | ||||
| $where[] = $this->buildPagingClause($conn); | $where[] = $this->buildPagingClause($conn); | ||||
| $where[] = $this->buildEdgeLogicWhereClause($conn); | $where[] = $this->buildEdgeLogicWhereClause($conn); | ||||
| $where[] = $this->buildSpacesWhereClause($conn); | $where[] = $this->buildSpacesWhereClause($conn); | ||||
| $where[] = $this->buildNgramsWhereClause($conn); | $where[] = $this->buildNgramsWhereClause($conn); | ||||
| $where[] = $this->buildFerretWhereClause($conn); | $where[] = $this->buildFerretWhereClause($conn); | ||||
| $where[] = $this->buildApplicationSearchWhereClause($conn); | $where[] = $this->buildApplicationSearchWhereClause($conn); | ||||
| return $where; | return $where; | ||||
| } | } | ||||
| /** | /** | ||||
| * @task clauses | * @task clauses | ||||
| */ | */ | ||||
| protected function buildHavingClause(AphrontDatabaseConnection $conn) { | protected function buildHavingClause(AphrontDatabaseConnection $conn) { | ||||
| $having = $this->buildHavingClauseParts($conn); | $having = $this->buildHavingClauseParts($conn); | ||||
| return $this->formatHavingClause($having); | return $this->formatHavingClause($conn, $having); | ||||
| } | } | ||||
| /** | /** | ||||
| * @task clauses | * @task clauses | ||||
| */ | */ | ||||
| protected function buildHavingClauseParts(AphrontDatabaseConnection $conn) { | protected function buildHavingClauseParts(AphrontDatabaseConnection $conn) { | ||||
| $having = array(); | $having = array(); | ||||
| $having[] = $this->buildEdgeLogicHavingClause($conn); | $having[] = $this->buildEdgeLogicHavingClause($conn); | ||||
| return $having; | return $having; | ||||
| } | } | ||||
| /** | /** | ||||
| * @task clauses | * @task clauses | ||||
| */ | */ | ||||
| protected function buildGroupClause(AphrontDatabaseConnection $conn) { | protected function buildGroupClause(AphrontDatabaseConnection $conn) { | ||||
| if (!$this->shouldGroupQueryResultRows()) { | if (!$this->shouldGroupQueryResultRows()) { | ||||
| return ''; | return qsprintf($conn, ''); | ||||
| } | } | ||||
| return qsprintf( | return qsprintf( | ||||
| $conn, | $conn, | ||||
| 'GROUP BY %Q', | 'GROUP BY %Q', | ||||
| $this->getApplicationSearchObjectPHIDColumn()); | $this->getApplicationSearchObjectPHIDColumn($conn)); | ||||
| } | } | ||||
| /** | /** | ||||
| * @task clauses | * @task clauses | ||||
| */ | */ | ||||
| protected function shouldGroupQueryResultRows() { | protected function shouldGroupQueryResultRows() { | ||||
| if ($this->shouldGroupEdgeLogicResultRows()) { | if ($this->shouldGroupEdgeLogicResultRows()) { | ||||
| ▲ Show 20 Lines • Show All 740 Lines • ▼ Show 20 Lines | foreach ($parts as $key => $part) { | ||||
| if ($descending) { | if ($descending) { | ||||
| $sql[] = qsprintf($conn, '%Q DESC', $field); | $sql[] = qsprintf($conn, '%Q DESC', $field); | ||||
| } else { | } else { | ||||
| $sql[] = qsprintf($conn, '%Q ASC', $field); | $sql[] = qsprintf($conn, '%Q ASC', $field); | ||||
| } | } | ||||
| } | } | ||||
| return qsprintf($conn, 'ORDER BY %Q', implode(', ', $sql)); | return qsprintf($conn, 'ORDER BY %LQ', $sql); | ||||
| } | } | ||||
| /* -( Application Search )------------------------------------------------- */ | /* -( Application Search )------------------------------------------------- */ | ||||
| /** | /** | ||||
| * Constrain the query with an ApplicationSearch index, requiring field values | * Constrain the query with an ApplicationSearch index, requiring field values | ||||
| ▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | /* -( Application Search )------------------------------------------------- */ | ||||
| /** | /** | ||||
| * Get the name of the query's primary object PHID column, for constructing | * Get the name of the query's primary object PHID column, for constructing | ||||
| * JOIN clauses. Normally (and by default) this is just `"phid"`, but it may | * JOIN clauses. Normally (and by default) this is just `"phid"`, but it may | ||||
| * be something more exotic. | * be something more exotic. | ||||
| * | * | ||||
| * See @{method:getPrimaryTableAlias} if the column needs to be qualified with | * See @{method:getPrimaryTableAlias} if the column needs to be qualified with | ||||
| * a table alias. | * a table alias. | ||||
| * | * | ||||
| * @return string Column name. | * @param AphrontDatabaseConnection Connection executing queries. | ||||
| * @return PhutilQueryString Column name. | |||||
| * @task appsearch | * @task appsearch | ||||
| */ | */ | ||||
| protected function getApplicationSearchObjectPHIDColumn() { | protected function getApplicationSearchObjectPHIDColumn( | ||||
| AphrontDatabaseConnection $conn) { | |||||
| if ($this->getPrimaryTableAlias()) { | if ($this->getPrimaryTableAlias()) { | ||||
| $prefix = $this->getPrimaryTableAlias().'.'; | return qsprintf($conn, '%T.phid', $this->getPrimaryTableAlias()); | ||||
| } else { | } else { | ||||
| $prefix = ''; | return qsprintf($conn, 'phid'); | ||||
| } | } | ||||
| return $prefix.'phid'; | |||||
| } | } | ||||
| /** | /** | ||||
| * Determine if the JOINs built by ApplicationSearch might cause each primary | * Determine if the JOINs built by ApplicationSearch might cause each primary | ||||
| * object to return multiple result rows. Generally, this means the query | * object to return multiple result rows. Generally, this means the query | ||||
| * needs an extra GROUP BY clause. | * needs an extra GROUP BY clause. | ||||
| * | * | ||||
| Show All 37 Lines | /* -( Application Search )------------------------------------------------- */ | ||||
| /** | /** | ||||
| * Construct a GROUP BY clause appropriate for ApplicationSearch constraints. | * Construct a GROUP BY clause appropriate for ApplicationSearch constraints. | ||||
| * | * | ||||
| * @param AphrontDatabaseConnection Connection executing the query. | * @param AphrontDatabaseConnection Connection executing the query. | ||||
| * @return string Group clause. | * @return string Group clause. | ||||
| * @task appsearch | * @task appsearch | ||||
| */ | */ | ||||
| protected function buildApplicationSearchGroupClause( | protected function buildApplicationSearchGroupClause( | ||||
| AphrontDatabaseConnection $conn_r) { | AphrontDatabaseConnection $conn) { | ||||
| if ($this->getApplicationSearchMayJoinMultipleRows()) { | if ($this->getApplicationSearchMayJoinMultipleRows()) { | ||||
| return qsprintf( | return qsprintf( | ||||
| $conn_r, | $conn, | ||||
| 'GROUP BY %Q', | 'GROUP BY %Q', | ||||
| $this->getApplicationSearchObjectPHIDColumn()); | $this->getApplicationSearchObjectPHIDColumn()); | ||||
| } else { | } else { | ||||
| return ''; | return qsprintf($conn, ''); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Construct a JOIN clause appropriate for applying ApplicationSearch | * Construct a JOIN clause appropriate for applying ApplicationSearch | ||||
| * constraints. | * constraints. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | foreach ($this->applicationSearchConstraints as $key => $constraint) { | ||||
| $index, | $index, | ||||
| $constraint_clause); | $constraint_clause); | ||||
| break; | break; | ||||
| default: | default: | ||||
| throw new Exception(pht('Unknown constraint condition "%s"!', $cond)); | throw new Exception(pht('Unknown constraint condition "%s"!', $cond)); | ||||
| } | } | ||||
| } | } | ||||
| $phid_column = $this->getApplicationSearchObjectPHIDColumn(); | $phid_column = $this->getApplicationSearchObjectPHIDColumn($conn); | ||||
| $orderable = $this->getOrderableColumns(); | $orderable = $this->getOrderableColumns(); | ||||
| $vector = $this->getOrderVector(); | $vector = $this->getOrderVector(); | ||||
| foreach ($vector as $order) { | foreach ($vector as $order) { | ||||
| $spec = $orderable[$order->getOrderKey()]; | $spec = $orderable[$order->getOrderKey()]; | ||||
| if (empty($spec['customfield'])) { | if (empty($spec['customfield'])) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 946 Lines • ▼ Show 20 Lines | /* -( Edge Logic )--------------------------------------------------------- */ | ||||
| } | } | ||||
| /** | /** | ||||
| * @task edgelogic | * @task edgelogic | ||||
| */ | */ | ||||
| public function buildEdgeLogicJoinClause(AphrontDatabaseConnection $conn) { | public function buildEdgeLogicJoinClause(AphrontDatabaseConnection $conn) { | ||||
| $edge_table = PhabricatorEdgeConfig::TABLE_NAME_EDGE; | $edge_table = PhabricatorEdgeConfig::TABLE_NAME_EDGE; | ||||
| $phid_column = $this->getApplicationSearchObjectPHIDColumn(); | $phid_column = $this->getApplicationSearchObjectPHIDColumn($conn); | ||||
| $joins = array(); | $joins = array(); | ||||
| foreach ($this->edgeLogicConstraints as $type => $constraints) { | foreach ($this->edgeLogicConstraints as $type => $constraints) { | ||||
| $op_null = PhabricatorQueryConstraint::OPERATOR_NULL; | $op_null = PhabricatorQueryConstraint::OPERATOR_NULL; | ||||
| $has_null = isset($constraints[$op_null]); | $has_null = isset($constraints[$op_null]); | ||||
| // If we're going to process an only() operator, build a list of the | // If we're going to process an only() operator, build a list of the | ||||
| ▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | foreach ($this->edgeLogicConstraints as $type => $constraints) { | ||||
| $conn, | $conn, | ||||
| '%T.dst IS NULL', | '%T.dst IS NULL', | ||||
| $alias); | $alias); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if ($full && $null) { | if ($full && $null) { | ||||
| $full = $this->formatWhereSubclause($full); | $where[] = qsprintf($conn, '(%LA OR %LA)', $full, $null); | ||||
| $null = $this->formatWhereSubclause($null); | |||||
| $where[] = qsprintf($conn, '(%Q OR %Q)', $full, $null); | |||||
| } else if ($full) { | } else if ($full) { | ||||
| foreach ($full as $condition) { | foreach ($full as $condition) { | ||||
| $where[] = $condition; | $where[] = $condition; | ||||
| } | } | ||||
| } else if ($null) { | } else if ($null) { | ||||
| foreach ($null as $condition) { | foreach ($null as $condition) { | ||||
| $where[] = $condition; | $where[] = $condition; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 396 Lines • Show Last 20 Lines | |||||