diff --git a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php new file mode 100644 index 00000000..df6eecc8 --- /dev/null +++ b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php @@ -0,0 +1,36 @@ + + */ +class WebsearchToTsquery extends BaseVariadicFunction +{ + protected function getNodeMappingPattern(): array + { + return ['StringPrimary']; + } + + protected function getFunctionName(): string + { + return 'websearch_to_tsquery'; + } + + protected function getMinArgumentCount(): int + { + return 1; + } + + protected function getMaxArgumentCount(): int + { + return 2; + } +} diff --git a/tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php b/tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php new file mode 100644 index 00000000..44f4402c --- /dev/null +++ b/tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php @@ -0,0 +1,44 @@ + WebsearchToTsquery::class, + ]; + } + + #[Test] + public function websearch_to_tsquery_with_explicit_config(): void + { + $dql = "SELECT websearch_to_tsquery('english', '\"sad cat\" or \"fat rat\"') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsTexts t WHERE t.id = 1"; + $result = $this->executeDqlQuery($dql); + $this->assertSame("'sad' <-> 'cat' | 'fat' <-> 'rat'", $result[0]['result']); + } + + #[Test] + public function websearch_to_tsquery_with_default_config(): void + { + $dql = "SELECT websearch_to_tsquery('\"sad cat\" or \"fat rat\"') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsTexts t WHERE t.id = 1"; + $result = $this->executeDqlQuery($dql); + $this->assertSame("'sad' <-> 'cat' | 'fat' <-> 'rat'", $result[0]['result']); + } + + #[Test] + public function totsquery_throws_with_invalid_input(): void + { + $this->expectException(DriverException::class); + $this->expectExceptionMessageMatches('/text search configuration .*invalid_regconfig.* does not exist/i'); + $dql = "SELECT websearch_to_tsquery('invalid_regconfig', 'foo') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsTexts t WHERE t.id = 1"; + $this->executeDqlQuery($dql); + } +} diff --git a/tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php b/tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php new file mode 100644 index 00000000..9cebcea0 --- /dev/null +++ b/tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php @@ -0,0 +1,53 @@ + WebsearchToTsquery::class, + ]; + } + + protected function getExpectedSqlStatements(): array + { + return [ + 'converts text to tsquery with default config' => 'SELECT websearch_to_tsquery(c0_.text1) AS sclr_0 FROM ContainsTexts c0_', + 'converts function result to tsquery' => 'SELECT websearch_to_tsquery(UPPER(c0_.text1)) AS sclr_0 FROM ContainsTexts c0_', + 'converts text to tsquery with specified config' => "SELECT websearch_to_tsquery('english', c0_.text1) AS sclr_0 FROM ContainsTexts c0_", + ]; + } + + protected function getDqlStatements(): array + { + return [ + 'converts text to tsquery with default config' => \sprintf('SELECT WEBSEARCH_TO_TSQUERY(e.text1) FROM %s e', ContainsTexts::class), + 'converts function result to tsquery' => \sprintf('SELECT WEBSEARCH_TO_TSQUERY(UPPER(e.text1)) FROM %s e', ContainsTexts::class), + 'converts text to tsquery with specified config' => \sprintf("SELECT WEBSEARCH_TO_TSQUERY('english', e.text1) FROM %s e", ContainsTexts::class), + ]; + } + + #[Test] + public function throws_exception_for_too_many_arguments(): void + { + $this->expectException(InvalidArgumentForVariadicFunctionException::class); + + $dql = \sprintf("SELECT WEBSEARCH_TO_TSQUERY('english', e.text1, 'extra') FROM %s e", ContainsTexts::class); + $this->assertSqlFromDql('', $dql); + } +}