Skip to content
Prev Previous commit
Workaround sqlite query issues
Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliusknorr committed Apr 13, 2021
commit 990659b8f08a3fc0b9691ac4926a211ae11e0d24
72 changes: 40 additions & 32 deletions lib/Db/CardMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

namespace OCA\Deck\Db;

use DateTime;
use Exception;
use OCA\Deck\AppInfo\Application;
use OCA\Deck\Search\Query\SearchQuery;
Expand Down Expand Up @@ -54,7 +55,7 @@ public function __construct(
IUserManager $userManager,
IGroupManager $groupManager,
IManager $notificationManager,
$databaseType = 'sqlite',
$databaseType = 'sqlite3',
$database4ByteSupport = true
) {
parent::__construct($db, 'deck_cards', Card::class);
Expand Down Expand Up @@ -380,48 +381,48 @@ private function extendQueryByFilter(IQueryBuilder $qb, SearchQuery $query) {
}

foreach ($query->getDuedate() as $duedate) {
$dueDateColumn = $this->databaseType === 'sqlite3' ? $qb->createFunction('DATETIME(`c`.`duedate`)') : 'c.duedate';
$date = $duedate->getValue();
$supportedFilters = ['overdue', 'today', 'week', 'month', 'none'];
if (in_array($date, $supportedFilters, true)) {
$currentDate = new \DateTime();
$rangeDate = new \DateTime();
$currentDate = new DateTime();
$rangeDate = new DateTime();
if ($date === 'overdue') {
$qb->andWhere($qb->expr()->lt('c.duedate', $qb->createNamedParameter($currentDate, IQueryBuilder::PARAM_DATE)));
$qb->andWhere($qb->expr()->lt($dueDateColumn, $this->dateTimeParameter($qb, $currentDate)));
} elseif ($date === 'today') {
$rangeDate->add(new \DateInterval('P1D'));
$qb->andWhere($qb->expr()->gte('c.duedate', $qb->createNamedParameter($currentDate, IQueryBuilder::PARAM_DATE)));
$qb->andWhere($qb->expr()->lte('c.duedate', $qb->createNamedParameter($rangeDate, IQueryBuilder::PARAM_DATE)));
$rangeDate = $rangeDate->add(new \DateInterval('P1D'));
$qb->andWhere($qb->expr()->gte($dueDateColumn, $this->dateTimeParameter($qb, $currentDate)));
$qb->andWhere($qb->expr()->lte($dueDateColumn, $this->dateTimeParameter($qb, $rangeDate)));
} elseif ($date === 'week') {
$rangeDate->add(new \DateInterval('P7D'));
$qb->andWhere($qb->expr()->gte('c.duedate', $qb->createNamedParameter($currentDate, IQueryBuilder::PARAM_DATE)));
$qb->andWhere($qb->expr()->lte('c.duedate', $qb->createNamedParameter($rangeDate, IQueryBuilder::PARAM_DATE)));
$rangeDate = $rangeDate->add(new \DateInterval('P7D'));
$qb->andWhere($qb->expr()->gte($dueDateColumn, $this->dateTimeParameter($qb, $currentDate)));
$qb->andWhere($qb->expr()->lte($dueDateColumn, $this->dateTimeParameter($qb, $rangeDate)));
} elseif ($date === 'month') {
$rangeDate->add(new \DateInterval('P1M'));
$qb->andWhere($qb->expr()->gte('c.duedate', $qb->createNamedParameter($currentDate, IQueryBuilder::PARAM_DATE)));
$qb->andWhere($qb->expr()->lte('c.duedate', $qb->createNamedParameter($rangeDate, IQueryBuilder::PARAM_DATE)));
$rangeDate = $rangeDate->add(new \DateInterval('P1M'));
$qb->andWhere($qb->expr()->gte($dueDateColumn, $this->dateTimeParameter($qb, $currentDate)));
$qb->andWhere($qb->expr()->lte($dueDateColumn, $this->dateTimeParameter($qb, $rangeDate)));
} else {
$qb->andWhere($qb->expr()->isNull('c.duedate'));
}
}

try {
$date = new \DateTime($date);
if ($duedate->getComparator() === SearchQuery::COMPARATOR_LESS) {
$qb->andWhere($qb->expr()->lt('c.duedate', $qb->createNamedParameter($date, IQueryBuilder::PARAM_DATE)));
} elseif ($duedate->getComparator() === SearchQuery::COMPARATOR_LESS_EQUAL) {
// take the end of the day to include due dates at the same day (as datetime does't allow just setting the day)
$date->setTime(23, 59, 59);
$qb->andWhere($qb->expr()->lte('c.duedate', $qb->createNamedParameter($date, IQueryBuilder::PARAM_DATE)));
} elseif ($duedate->getComparator() === SearchQuery::COMPARATOR_MORE) {
// take the end of the day to exclude due dates at the same day (as datetime does't allow just setting the day)
$date->setTime(23, 59, 59);
$qb->andWhere($qb->expr()->gt('c.duedate', $qb->createNamedParameter($date, IQueryBuilder::PARAM_DATE)));
} elseif ($duedate->getComparator() === SearchQuery::COMPARATOR_MORE_EQUAL) {
$qb->andWhere($qb->expr()->gte('c.duedate', $qb->createNamedParameter($date, IQueryBuilder::PARAM_DATE)));
} else {
try {
$date = new DateTime($date);
if ($duedate->getComparator() === SearchQuery::COMPARATOR_LESS) {
$qb->andWhere($qb->expr()->lt($dueDateColumn, $this->dateTimeParameter($qb, $date)));
} elseif ($duedate->getComparator() === SearchQuery::COMPARATOR_LESS_EQUAL) {
// take the end of the day to include due dates at the same day (as datetime does't allow just setting the day)
$date->setTime(23, 59, 59);
$qb->andWhere($qb->expr()->lte($dueDateColumn, $this->dateTimeParameter($qb, $date)));
} elseif ($duedate->getComparator() === SearchQuery::COMPARATOR_MORE) {
// take the end of the day to exclude due dates at the same day (as datetime does't allow just setting the day)
$date->setTime(23, 59, 59);
$qb->andWhere($qb->expr()->gt($dueDateColumn, $this->dateTimeParameter($qb, $date)));
} elseif ($duedate->getComparator() === SearchQuery::COMPARATOR_MORE_EQUAL) {
$qb->andWhere($qb->expr()->gte($dueDateColumn, $this->dateTimeParameter($qb, $date)));
}
} catch (Exception $e) {
// Invalid date, ignoring
}
} catch (Exception $e) {
// Invalid date, ignoring
continue;
}
}

Expand Down Expand Up @@ -461,6 +462,13 @@ private function extendQueryByFilter(IQueryBuilder $qb, SearchQuery $query) {
}
}
}

private function dateTimeParameter(IQueryBuilder $qb, DateTime $dateTime) {
if ($this->databaseType === 'sqlite3') {
return $qb->createFunction('DATETIME("' . $dateTime->format('Y-m-d\TH:i:s') . '")');
}
return $qb->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATE);
}



Expand Down
6 changes: 4 additions & 2 deletions lib/Search/FilterStringParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ private function parseFilterToken(SearchQuery $query, string $token): bool {
}

protected function removeQuotes(string $token): string {
$token = ($token[0] === '"' && $token[mb_strlen($token) - 1] === '"') ? mb_substr($token, 1, -1): $token;
$token = ($token[0] === '\'' && $token[mb_strlen($token) - 1] === '\'') ? mb_substr($token, 1, -1): $token;
if (mb_strlen($token) > 1) {
$token = ($token[0] === '"' && $token[mb_strlen($token) - 1] === '"') ? mb_substr($token, 1, -1) : $token;
$token = ($token[0] === '\'' && $token[mb_strlen($token) - 1] === '\'') ? mb_substr($token, 1, -1) : $token;
}
return $token;
}
}
2 changes: 1 addition & 1 deletion lib/Search/Query/AQueryParameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class AQueryParameter {
protected $value;

public function getValue() {
if (is_string($this->value)) {
if (is_string($this->value) && mb_strlen($this->value) > 1) {
$param = ($this->value[0] === '"' && $this->value[mb_strlen($this->value) - 1] === '"') ? mb_substr($this->value, 1, -1): $this->value;
return $param;
}
Expand Down