Skip to content

Commit be90545

Browse files
authored
feat: add support for websearch_to_tsquery (#437)
1 parent 9724452 commit be90545

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
/**
8+
* Implementation of PostgreSQL WEBSEARCH_TO_TSQUERY().
9+
*
10+
* @see https://www.postgresql.org/docs/current/textsearch-controls.html
11+
* @since 3.5
12+
*
13+
* @author Jan Klan <jan@klan.com.au>
14+
*/
15+
class WebsearchToTsquery extends BaseVariadicFunction
16+
{
17+
protected function getNodeMappingPattern(): array
18+
{
19+
return ['StringPrimary'];
20+
}
21+
22+
protected function getFunctionName(): string
23+
{
24+
return 'websearch_to_tsquery';
25+
}
26+
27+
protected function getMinArgumentCount(): int
28+
{
29+
return 1;
30+
}
31+
32+
protected function getMaxArgumentCount(): int
33+
{
34+
return 2;
35+
}
36+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use Doctrine\DBAL\Exception\DriverException;
8+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\WebsearchToTsquery;
9+
use PHPUnit\Framework\Attributes\Test;
10+
11+
class WebsearchToTsqueryTest extends TextTestCase
12+
{
13+
protected function getStringFunctions(): array
14+
{
15+
return [
16+
'websearch_to_tsquery' => WebsearchToTsquery::class,
17+
];
18+
}
19+
20+
#[Test]
21+
public function websearch_to_tsquery_with_explicit_config(): void
22+
{
23+
$dql = "SELECT websearch_to_tsquery('english', '\"sad cat\" or \"fat rat\"') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsTexts t WHERE t.id = 1";
24+
$result = $this->executeDqlQuery($dql);
25+
$this->assertSame("'sad' <-> 'cat' | 'fat' <-> 'rat'", $result[0]['result']);
26+
}
27+
28+
#[Test]
29+
public function websearch_to_tsquery_with_default_config(): void
30+
{
31+
$dql = "SELECT websearch_to_tsquery('\"sad cat\" or \"fat rat\"') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsTexts t WHERE t.id = 1";
32+
$result = $this->executeDqlQuery($dql);
33+
$this->assertSame("'sad' <-> 'cat' | 'fat' <-> 'rat'", $result[0]['result']);
34+
}
35+
36+
#[Test]
37+
public function totsquery_throws_with_invalid_input(): void
38+
{
39+
$this->expectException(DriverException::class);
40+
$this->expectExceptionMessageMatches('/text search configuration .*invalid_regconfig.* does not exist/i');
41+
$dql = "SELECT websearch_to_tsquery('invalid_regconfig', 'foo') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsTexts t WHERE t.id = 1";
42+
$this->executeDqlQuery($dql);
43+
}
44+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Unit\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsTexts;
8+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseVariadicFunction;
9+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Exception\InvalidArgumentForVariadicFunctionException;
10+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\WebsearchToTsquery;
11+
use PHPUnit\Framework\Attributes\Test;
12+
13+
class WebsearchToTsqueryTest extends BaseVariadicFunctionTestCase
14+
{
15+
protected function createFixture(): BaseVariadicFunction
16+
{
17+
return new WebsearchToTsquery('WEBSEARCH_TO_TSQUERY');
18+
}
19+
20+
protected function getStringFunctions(): array
21+
{
22+
return [
23+
'WEBSEARCH_TO_TSQUERY' => WebsearchToTsquery::class,
24+
];
25+
}
26+
27+
protected function getExpectedSqlStatements(): array
28+
{
29+
return [
30+
'converts text to tsquery with default config' => 'SELECT websearch_to_tsquery(c0_.text1) AS sclr_0 FROM ContainsTexts c0_',
31+
'converts function result to tsquery' => 'SELECT websearch_to_tsquery(UPPER(c0_.text1)) AS sclr_0 FROM ContainsTexts c0_',
32+
'converts text to tsquery with specified config' => "SELECT websearch_to_tsquery('english', c0_.text1) AS sclr_0 FROM ContainsTexts c0_",
33+
];
34+
}
35+
36+
protected function getDqlStatements(): array
37+
{
38+
return [
39+
'converts text to tsquery with default config' => \sprintf('SELECT WEBSEARCH_TO_TSQUERY(e.text1) FROM %s e', ContainsTexts::class),
40+
'converts function result to tsquery' => \sprintf('SELECT WEBSEARCH_TO_TSQUERY(UPPER(e.text1)) FROM %s e', ContainsTexts::class),
41+
'converts text to tsquery with specified config' => \sprintf("SELECT WEBSEARCH_TO_TSQUERY('english', e.text1) FROM %s e", ContainsTexts::class),
42+
];
43+
}
44+
45+
#[Test]
46+
public function throws_exception_for_too_many_arguments(): void
47+
{
48+
$this->expectException(InvalidArgumentForVariadicFunctionException::class);
49+
50+
$dql = \sprintf("SELECT WEBSEARCH_TO_TSQUERY('english', e.text1, 'extra') FROM %s e", ContainsTexts::class);
51+
$this->assertSqlFromDql('', $dql);
52+
}
53+
}

0 commit comments

Comments
 (0)