Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport of join timestamps from options #3372

Merged
merged 6 commits into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions lib/Db/OptionMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,6 @@ public function findConfirmed(int $pollId): array {
return $this->findEntities($qb);
}

/**
* @return (int|null)[]
*/
public function findDateBoundaries(int $pollId): array {
$qb = $this->db->getQueryBuilder();

$qb->selectAlias($qb->func()->min('timestamp'), 'min')
->selectAlias($qb->func()->max('timestamp'), 'max')
->from($this->getTableName())
->where($qb->expr()->eq('poll_id', $qb->createNamedParameter($pollId, IQueryBuilder::PARAM_INT)));

return $qb->executeQuery()->fetchAll()[0];
}

/**
* @return (int|null)[]
*/
Expand Down
16 changes: 11 additions & 5 deletions lib/Db/Poll.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
* @method void setLastInteraction(int $value)
* @method string getMiscSettings()
* @method void setMiscSettings(string $value)
* @method int getMinDate()
* @method int getMaxDate()
*/

class Poll extends EntityWithUser implements JsonSerializable {
Expand All @@ -102,7 +104,6 @@ class Poll extends EntityWithUser implements JsonSerializable {
public const ONE_AND_HALF_DAY = 129600;

private IURLGenerator $urlGenerator;
private OptionMapper $optionMapper;
protected UserMapper $userMapper;
private VoteMapper $voteMapper;

Expand Down Expand Up @@ -132,6 +133,8 @@ class Poll extends EntityWithUser implements JsonSerializable {

// joined columns
protected bool $hasOrphanedVotes = false;
protected int $maxDate = 0;
protected int $minDate = 0;

public function __construct() {
$this->addType('created', 'int');
Expand All @@ -147,7 +150,8 @@ public function __construct() {
$this->addType('hideBookedUp', 'int');
$this->addType('useNo', 'int');
$this->addType('lastInteraction', 'int');
$this->optionMapper = Container::queryClass(OptionMapper::class);
$this->addType('maxDate', 'int');
$this->addType('minDate', 'int');
$this->urlGenerator = Container::queryClass(IURLGenerator::class);
$this->userMapper = Container::queryClass(UserMapper::class);
$this->voteMapper = Container::queryClass(VoteMapper::class);
Expand Down Expand Up @@ -321,7 +325,7 @@ public function getRelevantThresholdNet(): int {
$this->getCreated(),
$this->getLastInteraction(),
$this->getExpire(),
intval($this->optionMapper->findDateBoundaries($this->getId())['max']),
$this->getMaxDate(),
);
}

Expand All @@ -333,13 +337,15 @@ public function getOrphanedVotes(): int {
}

public function getDeadline(): int {
// if expiration is set return expiration date
if ($this->getExpire()) {
return $this->getExpire();
}

if ($this->getType() === Poll::TYPE_DATE) {
// use first date option as reminder deadline
return intval($this->optionMapper->findDateBoundaries($this->getId())['min']);
// use lowest date option as reminder deadline threshold
// if no options are set return is the current time
return $this->getMinDate();
}
throw new NoDeadLineException();
}
Expand Down
25 changes: 25 additions & 0 deletions lib/Db/PollMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,32 @@ protected function buildQuery(): IQueryBuilder {
// TODO: check if this is necessary, in case of empty table to avoid possibly nulled columns
// ->groupBy(self::TABLE . '.id')
->from($this->getTableName(), self::TABLE);
$this->joinOptionsForMaxDate($qb, self::TABLE);
$qb->groupBy(self::TABLE . '.id');
return $qb;
}

/**
* Joins options to evaluate min and max option date for date polls
* if text poll or no options are set,
* the min value is the current time,
* the max value is null
*/
protected function joinOptionsForMaxDate(IQueryBuilder &$qb, string $fromAlias): void {
$joinAlias = 'options';
$saveMin = (string) time();

// force value into a MIN function to avoid grouping errors
// $qb->selectAlias($qb->func()->max($joinAlias . '.timestamp'), 'max_date');
$qb->addSelect($qb->createFunction('coalesce(MAX(' . $joinAlias . '.timestamp), 0) AS max_date'))
->addSelect($qb->createFunction('coalesce(MIN(' . $joinAlias . '.timestamp), ' . $saveMin . ') AS min_date'));

$qb->leftJoin(
$fromAlias,
Option::TABLE,
$joinAlias,
$qb->expr()->eq($fromAlias . '.id', $joinAlias . '.poll_id'),
);
}

}
Loading
Loading