diff --git a/lib/Misc/QueryFilter.php b/lib/Misc/QueryFilter.php index f4a663d6..f099487d 100644 --- a/lib/Misc/QueryFilter.php +++ b/lib/Misc/QueryFilter.php @@ -13,8 +13,7 @@ class QueryFilter { protected $qWhereNot = []; // WHERE NOT clause components protected $tWhereNot = []; // WHERE NOT clause type bindings protected $vWhereNot = []; // WHERE NOT clause binding values - - public $filterRestrictive = true; + protected $filterRestrictive = true; // Whether to glue WHERE conditions with OR (false) or AND (true) public function setWhere(string $where, $types = null, $values = null): static { $this->qWhere[] = $where; @@ -34,13 +33,18 @@ class QueryFilter { return $this; } - public function setFilter(self $filter): static { + public function setWhereGroup(self $filter): static { $this->qWhere[] = "(".$filter->buildWhereBody().")"; $this->tWhere[] = $filter->getWhereTypes(); $this->vWhere[] = $filter->getWhereValues(); return $this; } + public function setWhereRestrictive(bool $restrictive): static { + $this->filterRestrictive = $restrictive; + return $this; + } + protected function getWhereTypes(): array { return ValueInfo::flatten([$this->tWhere, $this->tWhereNot]); } diff --git a/tests/cases/Misc/TestQuery.php b/tests/cases/Misc/TestQuery.php index f78ac2d2..e638d76a 100644 --- a/tests/cases/Misc/TestQuery.php +++ b/tests/cases/Misc/TestQuery.php @@ -7,6 +7,7 @@ declare(strict_types=1); namespace JKingWeb\Arsse\TestCase\Misc; use JKingWeb\Arsse\Misc\Query; +use JKingWeb\Arsse\Misc\QueryFilter; /** * @covers \JKingWeb\Arsse\Misc\Query @@ -91,4 +92,24 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest { $this->assertSame(["datetime", "str", "bool"], $q->getTypes()); $this->assertSame([1, 3, 2], $q->getValues()); } -} + + public function testNestedWhereConditions(): void { + $q = new Query("SELECT *, ? as const from table", "datetime", 1); + $f = new QueryFilter; + $f->setWhere("a = ?", "str", "ook")->setWhere("b = c")->setWhere("c = ?", "int", 42); + $this->assertSame("a = ? AND b = c AND c = ?", (string) $f); + $this->assertSame(["str", "int"], $f->getTypes()); + $this->assertSame(["ook", 42], $f->getValues()); + $q->setWhereGroup($f); + $f->setWhereRestrictive(false); + $this->assertSame("a = ? OR b = c OR c = ?", (string) $f); + $q->setWhereGroup($f); + $this->assertSame("SELECT *, ? as const from table WHERE (a = ? AND b = c AND c = ?) AND (a = ? OR b = c OR c = ?)", $q->getQuery()); + $this->assertSame(["datetime", "str", "int", "str", "int"], $q->getTypes()); + $this->assertSame([1, "ook", 42, "ook", 42], $q->getValues()); + $q->setWhereRestrictive(false); + $this->assertSame("SELECT *, ? as const from table WHERE (a = ? AND b = c AND c = ?) OR (a = ? OR b = c OR c = ?)", $q->getQuery()); + $this->assertSame(["datetime", "str", "int", "str", "int"], $q->getTypes()); + $this->assertSame([1, "ook", 42, "ook", 42], $q->getValues()); + } +} \ No newline at end of file