Allow users to query feed by a date range
Summary: Ref T12762.
Test Plan:
- Ran queries with start date, end date, both, neither.
- Used EXPLAIN to try to make sure doing the bitshift isn't going to be a performance issue.
{F4978842}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12762
Differential Revision: https://secure.phabricator.com/D18029
This commit is contained in:
@@ -5,6 +5,8 @@ final class PhabricatorFeedQuery
|
||||
|
||||
private $filterPHIDs;
|
||||
private $chronologicalKeys;
|
||||
private $rangeMin;
|
||||
private $rangeMax;
|
||||
|
||||
public function withFilterPHIDs(array $phids) {
|
||||
$this->filterPHIDs = $phids;
|
||||
@@ -16,6 +18,12 @@ final class PhabricatorFeedQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withEpochInRange($range_min, $range_max) {
|
||||
$this->rangeMin = $range_min;
|
||||
$this->rangeMax = $range_max;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new PhabricatorFeedStoryData();
|
||||
}
|
||||
@@ -74,6 +82,24 @@ final class PhabricatorFeedQuery
|
||||
implode(', ', $keys));
|
||||
}
|
||||
|
||||
// NOTE: We may not have 64-bit PHP, so do the shifts in MySQL instead.
|
||||
// From EXPLAIN, it appears like MySQL is smart enough to compute the
|
||||
// result and make use of keys to execute the query.
|
||||
|
||||
if ($this->rangeMin !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'ref.chronologicalKey >= (%d << 32)',
|
||||
$this->rangeMin);
|
||||
}
|
||||
|
||||
if ($this->rangeMax !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'ref.chronologicalKey < (%d << 32)',
|
||||
$this->rangeMax);
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,12 @@ final class PhabricatorFeedSearchEngine
|
||||
->setDatasource(new PhabricatorProjectDatasource())
|
||||
->setLabel(pht('Include Projects'))
|
||||
->setKey('projectPHIDs'),
|
||||
id(new PhabricatorSearchDateControlField())
|
||||
->setLabel(pht('Occurs After'))
|
||||
->setKey('rangeStart'),
|
||||
id(new PhabricatorSearchDateControlField())
|
||||
->setLabel(pht('Occurs Before'))
|
||||
->setKey('rangeEnd'),
|
||||
|
||||
// NOTE: This is a legacy field retained only for backward
|
||||
// compatibility. If the projects field used EdgeLogic, we could use
|
||||
@@ -71,6 +77,30 @@ final class PhabricatorFeedSearchEngine
|
||||
$query->withFilterPHIDs($phids);
|
||||
}
|
||||
|
||||
$range_min = $map['rangeStart'];
|
||||
if ($range_min) {
|
||||
$range_min = $range_min->getEpoch();
|
||||
}
|
||||
|
||||
$range_max = $map['rangeEnd'];
|
||||
if ($range_max) {
|
||||
$range_max = $range_max->getEpoch();
|
||||
}
|
||||
|
||||
if ($range_min && $range_max) {
|
||||
if ($range_min > $range_max) {
|
||||
throw new PhabricatorSearchConstraintException(
|
||||
pht(
|
||||
'The specified "Occurs Before" date is earlier in time than the '.
|
||||
'specified "Occurs After" date, so this query can never match '.
|
||||
'any results.'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($range_min || $range_max) {
|
||||
$query->withEpochInRange($range_min, $range_max);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user