diff --git a/src/applications/almanac/query/AlmanacServiceQuery.php b/src/applications/almanac/query/AlmanacServiceQuery.php index d961b2e4ab..85217d1247 100644 --- a/src/applications/almanac/query/AlmanacServiceQuery.php +++ b/src/applications/almanac/query/AlmanacServiceQuery.php @@ -75,7 +75,7 @@ final class AlmanacServiceQuery return $table->loadAllFromArray($data); } - protected function buildJoinClause($conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { $joins = array(); if ($this->devicePHIDs !== null) { diff --git a/src/applications/conpherence/query/ConpherenceThreadQuery.php b/src/applications/conpherence/query/ConpherenceThreadQuery.php index c191a763b4..b7be434fa3 100644 --- a/src/applications/conpherence/query/ConpherenceThreadQuery.php +++ b/src/applications/conpherence/query/ConpherenceThreadQuery.php @@ -129,7 +129,7 @@ final class ConpherenceThreadQuery } } - private function buildJoinClause($conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { $joins = array(); if ($this->participantPHIDs !== null) { diff --git a/src/applications/diffusion/query/DiffusionCommitQuery.php b/src/applications/diffusion/query/DiffusionCommitQuery.php index 8fd9d0c73e..e6f67e44c8 100644 --- a/src/applications/diffusion/query/DiffusionCommitQuery.php +++ b/src/applications/diffusion/query/DiffusionCommitQuery.php @@ -511,7 +511,7 @@ final class DiffusionCommitQuery } } - private function buildJoinClause($conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { $joins = array(); $audit_request = new PhabricatorRepositoryAuditRequest(); diff --git a/src/applications/feed/query/PhabricatorFeedQuery.php b/src/applications/feed/query/PhabricatorFeedQuery.php index 424658b342..29be87c428 100644 --- a/src/applications/feed/query/PhabricatorFeedQuery.php +++ b/src/applications/feed/query/PhabricatorFeedQuery.php @@ -37,7 +37,7 @@ final class PhabricatorFeedQuery return PhabricatorFeedStory::loadAllFromRows($data, $this->getViewer()); } - private function buildJoinClause(AphrontDatabaseConnection $conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { // NOTE: We perform this join unconditionally (even if we have no filter // PHIDs) to omit rows which have no story references. These story data // rows are notifications or realtime alerts. diff --git a/src/applications/files/query/PhabricatorFileQuery.php b/src/applications/files/query/PhabricatorFileQuery.php index a15be0c0bb..aa4e0be16c 100644 --- a/src/applications/files/query/PhabricatorFileQuery.php +++ b/src/applications/files/query/PhabricatorFileQuery.php @@ -215,7 +215,7 @@ final class PhabricatorFileQuery return $files; } - private function buildJoinClause(AphrontDatabaseConnection $conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { $joins = array(); if ($this->transforms) { diff --git a/src/applications/legalpad/query/LegalpadDocumentQuery.php b/src/applications/legalpad/query/LegalpadDocumentQuery.php index e2e43e0e28..4a5f2c8663 100644 --- a/src/applications/legalpad/query/LegalpadDocumentQuery.php +++ b/src/applications/legalpad/query/LegalpadDocumentQuery.php @@ -134,7 +134,7 @@ final class LegalpadDocumentQuery return $documents; } - private function buildJoinClause($conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { $joins = array(); if ($this->contributorPHIDs !== null) { diff --git a/src/applications/owners/query/PhabricatorOwnersPackageQuery.php b/src/applications/owners/query/PhabricatorOwnersPackageQuery.php index 64640c3ab8..3bbb3b8fe2 100644 --- a/src/applications/owners/query/PhabricatorOwnersPackageQuery.php +++ b/src/applications/owners/query/PhabricatorOwnersPackageQuery.php @@ -35,7 +35,7 @@ final class PhabricatorOwnersPackageQuery return $table->loadAllFromArray($data); } - private function buildJoinClause(AphrontDatabaseConnection $conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { $joins = array(); if ($this->ownerPHIDs) { diff --git a/src/applications/phortune/query/PhortuneAccountQuery.php b/src/applications/phortune/query/PhortuneAccountQuery.php index a567aa2d38..c91e5f0111 100644 --- a/src/applications/phortune/query/PhortuneAccountQuery.php +++ b/src/applications/phortune/query/PhortuneAccountQuery.php @@ -102,7 +102,7 @@ final class PhortuneAccountQuery return $this->formatWhereClause($where); } - private function buildJoinClause(AphrontDatabaseConnection $conn) { + protected function buildJoinClause(AphrontDatabaseConnection $conn) { $joins = array(); if ($this->memberPHIDs) { diff --git a/src/applications/phortune/query/PhortuneMerchantQuery.php b/src/applications/phortune/query/PhortuneMerchantQuery.php index 41a6f1004d..aa730393ff 100644 --- a/src/applications/phortune/query/PhortuneMerchantQuery.php +++ b/src/applications/phortune/query/PhortuneMerchantQuery.php @@ -82,7 +82,7 @@ final class PhortuneMerchantQuery return $this->formatWhereClause($where); } - private function buildJoinClause(AphrontDatabaseConnection $conn) { + protected function buildJoinClause(AphrontDatabaseConnection $conn) { $joins = array(); if ($this->memberPHIDs !== null) { diff --git a/src/applications/phriction/query/PhrictionDocumentQuery.php b/src/applications/phriction/query/PhrictionDocumentQuery.php index 83684cfb3c..b4e80af936 100644 --- a/src/applications/phriction/query/PhrictionDocumentQuery.php +++ b/src/applications/phriction/query/PhrictionDocumentQuery.php @@ -190,7 +190,7 @@ final class PhrictionDocumentQuery return $documents; } - private function buildJoinClause(AphrontDatabaseConnection $conn) { + protected function buildJoinClause(AphrontDatabaseConnection $conn) { $join = ''; if ($this->getOrderVector()->containsKey('updated')) { diff --git a/src/applications/project/query/PhabricatorProjectQuery.php b/src/applications/project/query/PhabricatorProjectQuery.php index f743be7295..655d1f0850 100644 --- a/src/applications/project/query/PhabricatorProjectQuery.php +++ b/src/applications/project/query/PhabricatorProjectQuery.php @@ -336,7 +336,7 @@ final class PhabricatorProjectQuery } } - private function buildJoinClause($conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { $joins = array(); if (!$this->needMembers !== null) { diff --git a/src/infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php b/src/infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php index eb9441aa8f..34cab99afa 100644 --- a/src/infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php +++ b/src/infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php @@ -145,7 +145,7 @@ final class PhabricatorWorkerTriggerQuery return $triggers; } - private function buildJoinClause(AphrontDatabaseConnection $conn_r) { + protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { $joins = array(); if (($this->nextEpochMin !== null) || diff --git a/src/infrastructure/query/PhabricatorQuery.php b/src/infrastructure/query/PhabricatorQuery.php index 1662e16ac5..f57c43c0ee 100644 --- a/src/infrastructure/query/PhabricatorQuery.php +++ b/src/infrastructure/query/PhabricatorQuery.php @@ -1,17 +1,122 @@ flattenSubclause($parts); if (!$parts) { return ''; } - return 'WHERE ('.implode(') AND (', $parts).')'; + return 'WHERE '.$this->formatWhereSubclause($parts); + } + + + /** + * @task format + */ + protected function formatWhereSubclause(array $parts) { + $parts = $this->flattenSubclause($parts); + if (!$parts) { + return null; + } + + return '('.implode(') AND (', $parts).')'; + } + + + /** + * @task format + */ + protected function formatSelectClause(array $parts) { + $parts = $this->flattenSubclause($parts); + if (!$parts) { + throw new Exception(pht('Can not build empty select clause!')); + } + + return 'SELECT '.$this->formatSelectSubclause($parts); + } + + + /** + * @task format + */ + protected function formatSelectSubclause(array $parts) { + $parts = $this->flattenSubclause($parts); + if (!$parts) { + return null; + } + return implode(', ', $parts); + } + + + /** + * @task format + */ + protected function formatJoinClause(array $parts) { + $parts = $this->flattenSubclause($parts); + if (!$parts) { + return ''; + } + + return implode(' ', $parts); + } + + + /** + * @task format + */ + protected function formatHavingClause(array $parts) { + $parts = $this->flattenSubclause($parts); + if (!$parts) { + return ''; + } + + return 'HAVING '.$this->formatHavingSubclause($parts); + } + + + /** + * @task format + */ + protected function formatHavingSubclause(array $parts) { + $parts = $this->flattenSubclause($parts); + if (!$parts) { + return null; + } + + return '('.implode(') AND (', $parts).')'; + } + + + /** + * @task format + */ + private function flattenSubclause(array $parts) { + $result = array(); + foreach ($parts as $part) { + if (is_array($part)) { + foreach ($this->flattenSubclause($part) as $subpart) { + $result[] = $subpart; + } + } else if (strlen($part)) { + $result[] = $part; + } + } + return $result; } } diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php index d532d1cf0f..347fb89315 100644 --- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php +++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php @@ -180,11 +180,84 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery /* -( Building Query Clauses )--------------------------------------------- */ + /** + * @task clauses + */ + protected function buildSelectClause(AphrontDatabaseConnection $conn) { + $parts = $this->buildSelectClauseParts($conn); + return $this->formatSelectClause($parts); + } + + + /** + * @task clauses + */ + protected function buildSelectClauseParts(AphrontDatabaseConnection $conn) { + $select = array(); + + $alias = $this->getPrimaryTableAlias(); + if ($alias) { + $select[] = qsprintf($conn, '%T.*', $alias); + } else { + $select[] = '*'; + } + + return $select; + } + + + /** + * @task clauses + */ + protected function buildJoinClause(AphrontDatabaseConnection $conn) { + $joins = $this->buildJoinClauseParts($conn); + return $this->formatJoinClause($joins); + } + + + /** + * @task clauses + */ + protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { + $joins = array(); + return $joins; + } + + /** * @task clauses */ protected function buildWhereClause(AphrontDatabaseConnection $conn) { - throw new PhutilMethodNotImplementedException(); + $where = $this->buildWhereClauseParts($conn); + return $this->formatWhereClause($where); + } + + + /** + * @task clauses + */ + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = array(); + $where[] = $this->buildPagingClause($conn); + return $where; + } + + + /** + * @task clauses + */ + protected function buildHavingClause(AphrontDatabaseConnection $conn) { + $having = $this->buildHavingClauseParts($conn); + return $this->formatHavingClause($having); + } + + + /** + * @task clauses + */ + protected function buildHavingClauseParts(AphrontDatabaseConnection $conn) { + $having = array(); + return $having; }