Changeset View
Changeset View
Standalone View
Standalone View
src/applications/feed/query/PhabricatorFeedQuery.php
| <?php | <?php | ||||
| final class PhabricatorFeedQuery | final class PhabricatorFeedQuery | ||||
| extends PhabricatorCursorPagedPolicyAwareQuery { | extends PhabricatorCursorPagedPolicyAwareQuery { | ||||
| private $filterPHIDs; | private $filterPHIDs; | ||||
| private $chronologicalKeys; | private $chronologicalKeys; | ||||
| public function setFilterPHIDs(array $phids) { | public function withFilterPHIDs(array $phids) { | ||||
| $this->filterPHIDs = $phids; | $this->filterPHIDs = $phids; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function withChronologicalKeys(array $keys) { | public function withChronologicalKeys(array $keys) { | ||||
| $this->chronologicalKeys = $keys; | $this->chronologicalKeys = $keys; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| protected function loadPage() { | public function newResultObject() { | ||||
| $story_table = new PhabricatorFeedStoryData(); | return new PhabricatorFeedStoryData(); | ||||
| $conn = $story_table->establishConnection('r'); | } | ||||
| $data = queryfx_all( | |||||
| $conn, | |||||
| 'SELECT story.* FROM %T story %Q %Q %Q %Q %Q', | |||||
| $story_table->getTableName(), | |||||
| $this->buildJoinClause($conn), | |||||
| $this->buildWhereClause($conn), | |||||
| $this->buildGroupClause($conn), | |||||
| $this->buildOrderClause($conn), | |||||
| $this->buildLimitClause($conn)); | |||||
| return $data; | protected function loadPage() { | ||||
| // NOTE: We return raw rows from this method, which is a little unusual. | |||||
| return $this->loadStandardPageRows($this->newResultObject()); | |||||
| } | } | ||||
| protected function willFilterPage(array $data) { | protected function willFilterPage(array $data) { | ||||
| return PhabricatorFeedStory::loadAllFromRows($data, $this->getViewer()); | return PhabricatorFeedStory::loadAllFromRows($data, $this->getViewer()); | ||||
| } | } | ||||
| protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { | protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { | ||||
| $joins = parent::buildJoinClauseParts($conn); | |||||
| // NOTE: We perform this join unconditionally (even if we have no filter | // NOTE: We perform this join unconditionally (even if we have no filter | ||||
| // PHIDs) to omit rows which have no story references. These story data | // PHIDs) to omit rows which have no story references. These story data | ||||
| // rows are notifications or realtime alerts. | // rows are notifications or realtime alerts. | ||||
| $ref_table = new PhabricatorFeedStoryReference(); | $ref_table = new PhabricatorFeedStoryReference(); | ||||
| return qsprintf( | $joins[] = qsprintf( | ||||
| $conn_r, | $conn, | ||||
| 'JOIN %T ref ON ref.chronologicalKey = story.chronologicalKey', | 'JOIN %T ref ON ref.chronologicalKey = story.chronologicalKey', | ||||
| $ref_table->getTableName()); | $ref_table->getTableName()); | ||||
| return $joins; | |||||
| } | } | ||||
| protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { | protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { | ||||
| $where = array(); | $where = parent::buildWhereClauseParts($conn); | ||||
| if ($this->filterPHIDs) { | if ($this->filterPHIDs !== null) { | ||||
| $where[] = qsprintf( | $where[] = qsprintf( | ||||
| $conn_r, | $conn, | ||||
| 'ref.objectPHID IN (%Ls)', | 'ref.objectPHID IN (%Ls)', | ||||
| $this->filterPHIDs); | $this->filterPHIDs); | ||||
| } | } | ||||
| if ($this->chronologicalKeys) { | if ($this->chronologicalKeys !== null) { | ||||
| // NOTE: We want to use integers in the query so we can take advantage | // NOTE: We want to use integers in the query so we can take advantage | ||||
| // of keys, but can't use %d on 32-bit systems. Make sure all the keys | // of keys, but can't use %d on 32-bit systems. Make sure all the keys | ||||
| // are integers and then format them raw. | // are integers and then format them raw. | ||||
| $keys = $this->chronologicalKeys; | $keys = $this->chronologicalKeys; | ||||
| foreach ($keys as $key) { | foreach ($keys as $key) { | ||||
| if (!ctype_digit($key)) { | if (!ctype_digit($key)) { | ||||
| throw new Exception( | throw new Exception( | ||||
| pht("Key '%s' is not a valid chronological key!", $key)); | pht("Key '%s' is not a valid chronological key!", $key)); | ||||
| } | } | ||||
| } | } | ||||
| $where[] = qsprintf( | $where[] = qsprintf( | ||||
| $conn_r, | $conn, | ||||
| 'ref.chronologicalKey IN (%Q)', | 'ref.chronologicalKey IN (%Q)', | ||||
| implode(', ', $keys)); | implode(', ', $keys)); | ||||
| } | } | ||||
| $where[] = $this->buildPagingClause($conn_r); | return $where; | ||||
| return $this->formatWhereClause($where); | |||||
| } | } | ||||
| protected function buildGroupClause(AphrontDatabaseConnection $conn_r) { | protected function buildGroupClause(AphrontDatabaseConnection $conn) { | ||||
| if ($this->filterPHIDs) { | if ($this->filterPHIDs !== null) { | ||||
| return qsprintf($conn_r, 'GROUP BY ref.chronologicalKey'); | return qsprintf($conn, 'GROUP BY ref.chronologicalKey'); | ||||
| } else { | } else { | ||||
| return qsprintf($conn_r, 'GROUP BY story.chronologicalKey'); | return qsprintf($conn, 'GROUP BY story.chronologicalKey'); | ||||
| } | } | ||||
| } | } | ||||
| protected function getDefaultOrderVector() { | protected function getDefaultOrderVector() { | ||||
| return array('key'); | return array('key'); | ||||
| } | } | ||||
| public function getOrderableColumns() { | public function getOrderableColumns() { | ||||
| Show All 16 Lines | final class PhabricatorFeedQuery | ||||
| protected function getResultCursor($item) { | protected function getResultCursor($item) { | ||||
| if ($item instanceof PhabricatorFeedStory) { | if ($item instanceof PhabricatorFeedStory) { | ||||
| return $item->getChronologicalKey(); | return $item->getChronologicalKey(); | ||||
| } | } | ||||
| return $item['chronologicalKey']; | return $item['chronologicalKey']; | ||||
| } | } | ||||
| protected function getPrimaryTableAlias() { | |||||
| return 'story'; | |||||
| } | |||||
| public function getQueryApplicationClass() { | public function getQueryApplicationClass() { | ||||
| return 'PhabricatorFeedApplication'; | return 'PhabricatorFeedApplication'; | ||||
| } | } | ||||
| } | } | ||||