diff --git a/lib/Database.php b/lib/Database.php index 3752403..ec37316 100644 --- a/lib/Database.php +++ b/lib/Database.php @@ -219,10 +219,11 @@ class Database { $values[] = $term; } } - $clause[] = "(".implode(" or ", $spec).")"; + $spec = sizeof($spec) > 1 ? "(".implode(" or ", $spec).")" : (string) array_pop($spec); + $clause[] = $spec; } $glue = $matchAny ? "or" : "and"; - $clause = $clause ? "(".implode(" $glue ", $clause).")" : ""; + $clause = sizeof($clause) > 1 ? "(".implode(" $glue ", $clause).")" : (string) array_pop($clause); return [$clause, $types, $values]; } diff --git a/tests/cases/Database/TestDatabase.php b/tests/cases/Database/TestDatabase.php index bd07e46..93f6f39 100644 --- a/tests/cases/Database/TestDatabase.php +++ b/tests/cases/Database/TestDatabase.php @@ -55,4 +55,25 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest { ["$params", $ints, $ints, "bool"], ]; } + + /** @dataProvider provideSearchClauses */ + public function testGenerateSearchClause(string $clause, array $values, array $inV, array $inC, bool $inAny) { + // this is not an exhaustive test; integration tests already cover the ins and outs of the functionality + $types = array_fill(0, sizeof($values), "str"); + $exp = [$clause, $types, $values]; + $this->assertSame($exp, self::$db->generateSearch($inV, $inC, $inAny)); + } + + public function provideSearchClauses() { + $terms = array_fill(0, Database::LIMIT_SET_SIZE + 1, "a"); + $clause = array_fill(0, Database::LIMIT_SET_SIZE + 1, "test like '%a%' escape '^'"); + $longString = str_repeat("0", Database::LIMIT_SET_STRING_LENGTH + 1); + return [ + ["test like ? escape '^'", ["%a%"], ["a"], ["test"], true], + ["(col1 like ? escape '^' or col2 like ? escape '^')", ["%a%", "%a%"], ["a"], ["col1", "col2"], true], + ["(".implode(" or ", $clause).")", [], $terms, ["test"], true], + ["(".implode(" and ", $clause).")", [], $terms, ["test"], false], + ["(".implode(" or ", $clause)." or test like ? escape '^')", ["%$longString%"], array_merge($terms, [$longString]), ["test"], true], + ]; + } }