From f7748a95229f71b7f62a1e320243d5e55efc7bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Proch=C3=A1zka?= Date: Sun, 3 Mar 2024 13:15:09 +0100 Subject: [PATCH] Switch to using to_tsquery --- src/Functions/Query.php | 34 +-------------- src/Functions/Rank.php | 2 +- src/Functions/Search.php | 4 +- src/Utils/SearchQuery.php | 87 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 36 deletions(-) create mode 100644 src/Utils/SearchQuery.php diff --git a/src/Functions/Query.php b/src/Functions/Query.php index 7542394..2264f86 100644 --- a/src/Functions/Query.php +++ b/src/Functions/Query.php @@ -16,38 +16,6 @@ /** * "query" "(" Column, Query, Lang ")" */ -final class Query extends FunctionNode +final class Query extends Search { - public Node $column; - public Node $query; - public Node $lang; - - - public function parse(Parser $parser): void - { - $parser->match(Lexer::T_IDENTIFIER); // (2) - $parser->match(Lexer::T_OPEN_PARENTHESIS); // (3) - - $this->column = $parser->StringPrimary(); // (4) - - $parser->match(Lexer::T_COMMA); // (5) - - $this->query = $parser->InstanceOfParameter(); // (6) - - $parser->match(Lexer::T_COMMA); // (7) - - $this->lang = $parser->StringPrimary(); // (8) - - $parser->match(Lexer::T_CLOSE_PARENTHESIS); // (9) - } - - - public function getSql(SqlWalker $sqlWalker): string - { - $column = $sqlWalker->walkSimpleArithmeticExpression($this->column); - $query = $sqlWalker->walkSimpleArithmeticExpression($this->query); - $lang = $sqlWalker->walkSimpleArithmeticExpression($this->lang); - - return "{$column} @@ to_tsquery({$lang}, {$query})"; - } } diff --git a/src/Functions/Rank.php b/src/Functions/Rank.php index 213c717..bd814aa 100644 --- a/src/Functions/Rank.php +++ b/src/Functions/Rank.php @@ -48,6 +48,6 @@ public function getSql(SqlWalker $sqlWalker): string $query = $sqlWalker->walkSimpleArithmeticExpression($this->query); $lang = $sqlWalker->walkSimpleArithmeticExpression($this->lang); - return "ts_rank_cd({$column}, websearch_to_tsquery({$lang}, {$query}))"; + return "ts_rank_cd({$column}, to_tsquery({$lang}, {$query}))"; } } diff --git a/src/Functions/Search.php b/src/Functions/Search.php index cbe7690..3666920 100644 --- a/src/Functions/Search.php +++ b/src/Functions/Search.php @@ -16,7 +16,7 @@ /** * "search" "(" Column, Query, Lang ")" */ -final class Search extends FunctionNode +class Search extends FunctionNode { public Node $column; public Node $query; @@ -48,6 +48,6 @@ public function getSql(SqlWalker $sqlWalker): string $query = $sqlWalker->walkSimpleArithmeticExpression($this->query); $lang = $sqlWalker->walkSimpleArithmeticExpression($this->lang); - return "{$column} @@ websearch_to_tsquery({$lang}, {$query})"; + return "{$column} @@ to_tsquery({$lang}, {$query})"; } } diff --git a/src/Utils/SearchQuery.php b/src/Utils/SearchQuery.php new file mode 100644 index 0000000..65d3cea --- /dev/null +++ b/src/Utils/SearchQuery.php @@ -0,0 +1,87 @@ +'; + protected const MethodAnd = '&'; + protected const MethodOr = '|'; + + protected const TupleAnd = ['and', 'a', self::MethodAnd]; + protected const TupleOr = ['or', 'nebo', self::MethodOr]; + + public function __construct( + protected string $query, + protected string $methodDefault = self::MethodAnd, + ) { + } + + + public function __toString(): string + { + return $this->format(); + } + + + public function format(): string + { + $tokens = preg_split('/\s+/', $this->query); + $lastKey = array_key_last($tokens); + $method = $this->methodDefault; + $output = ''; + + foreach ($tokens as $key => $token) { + $token = strtolower($token); + + if (in_array($token, self::TupleAnd)) { + $output = substr($output, 0, -3).' '.self::MethodAnd.' '; + $method = $methodNext = $this->methodDefault; + continue; + } + + if (in_array($token, self::TupleOr)) { + $output = substr($output, 0, -3).' '.self::MethodOr.' '; + $method = $methodNext = $this->methodDefault; + continue; + } + + if (str_starts_with($token, self::CharFollow)) { + $token = substr($token, 1); + $methodNext = $method = self::MethodFollow; + } + + if (str_ends_with($token, self::CharFollow)) { + $token = substr($token, 0, -1); + $method = $this->methodDefault; + } + + if (str_ends_with($token, self::CharPartial)) { + $token = str_replace(self::CharPartial, self::ModifierPartial, $token); + } + + $output .= $token; + + if ($key <> $lastKey) { + $output .= ' '.$method.' '; + } + + $methodNext ??= $method; + $method = $methodNext; + } + + return $output; + } +}