diff --git a/docs/INTEGRATING-WITH-DOCTRINE.md b/docs/INTEGRATING-WITH-DOCTRINE.md index 3edbb93e..6a61e120 100644 --- a/docs/INTEGRATING-WITH-DOCTRINE.md +++ b/docs/INTEGRATING-WITH-DOCTRINE.md @@ -163,6 +163,7 @@ $configuration->addCustomStringFunction('REGEXP_MATCH', MartinGeorgiev\Doctrine\ $configuration->addCustomStringFunction('STRCONCAT', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrConcat::class); $configuration->addCustomStringFunction('REGEXP_REPLACE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpReplace::class); $configuration->addCustomStringFunction('ROW', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Row::class); +$configuration->addCustomStringFunction('DISTANCE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance::class); # aggregation functions $configuration->addCustomStringFunction('ARRAY_AGG', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAgg::class); diff --git a/docs/INTEGRATING-WITH-LARAVEL.md b/docs/INTEGRATING-WITH-LARAVEL.md index ba511120..e9b3a796 100644 --- a/docs/INTEGRATING-WITH-LARAVEL.md +++ b/docs/INTEGRATING-WITH-LARAVEL.md @@ -218,6 +218,7 @@ return [ 'REGEXP_SUBSTR' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpSubstr::class, 'STRCONCAT' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrConcat::class, // the `||` operator 'ROW' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Row::class, + 'DISTANCE' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance::class, # aggregation functions 'ARRAY_AGG' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAgg::class, diff --git a/docs/INTEGRATING-WITH-SYMFONY.md b/docs/INTEGRATING-WITH-SYMFONY.md index 32083e96..479cde4f 100644 --- a/docs/INTEGRATING-WITH-SYMFONY.md +++ b/docs/INTEGRATING-WITH-SYMFONY.md @@ -212,6 +212,7 @@ doctrine: REGEXP_SUBSTR: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpSubstr ROW: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Row STRCONCAT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrConcat + DISTANCE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance # aggregation functions ARRAY_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAgg diff --git a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php new file mode 100644 index 00000000..e59447b1 --- /dev/null +++ b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php @@ -0,0 +1,18 @@ +`). + * + * @see https://www.postgresql.org/docs/17/earthdistance.html#EARTHDISTANCE-POINT-BASED + * @since 3.1 + * + * @author Sébastien Jean + */ +class Distance extends BaseFunction +{ + protected function customizeFunction(): void + { + $this->setFunctionPrototype('(%s <@> %s)'); + $this->addNodeMapping('StringPrimary'); + $this->addNodeMapping('StringPrimary'); + } +} diff --git a/tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php b/tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php new file mode 100644 index 00000000..1d56d2d6 --- /dev/null +++ b/tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php @@ -0,0 +1,36 @@ + Distance::class, + ]; + } + + protected function getExpectedSqlStatements(): array + { + return [ + "SELECT (c0_.point1 <@> '(2.320041, 48.858889)') AS sclr_0 FROM ContainsPoints c0_", + 'SELECT (c0_.point1 <@> c0_.point2) AS sclr_0 FROM ContainsPoints c0_', + "SELECT ('(1.0, 1.0)' <@> '(2.0, 2.0)') AS sclr_0 FROM ContainsPoints c0_", + ]; + } + + protected function getDqlStatements(): array + { + return [ + \sprintf("SELECT DISTANCE(e.point1, '(2.320041, 48.858889)') FROM %s e", ContainsPoints::class), + \sprintf('SELECT DISTANCE(e.point1, e.point2) FROM %s e', ContainsPoints::class), + \sprintf("SELECT DISTANCE('(1.0, 1.0)', '(2.0, 2.0)') FROM %s e", ContainsPoints::class), + ]; + } +}