diff --git a/.github/workflows/sloth.yml b/.github/workflows/sloth.yml index 45800cc8..5099f0e4 100644 --- a/.github/workflows/sloth.yml +++ b/.github/workflows/sloth.yml @@ -36,6 +36,5 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} interval: 10 ignored: | - Auto Request Review CodeRabbit Scrutinizer diff --git a/docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md b/docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md index 02b37214..e7ba56e7 100644 --- a/docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md +++ b/docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md @@ -30,6 +30,7 @@ |---|---|---| | all | ALL_OF | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\All` | | any | ANY_OF | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Any` | +| any_value | ANY_VALUE | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\AnyValue` | | array_agg | ARRAY_AGG | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAgg` | | array_append | ARRAY_APPEND | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAppend` | | array_cat | ARRAY_CAT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayCat` | diff --git a/docs/INTEGRATING-WITH-DOCTRINE.md b/docs/INTEGRATING-WITH-DOCTRINE.md index 12121c1b..096e47bf 100644 --- a/docs/INTEGRATING-WITH-DOCTRINE.md +++ b/docs/INTEGRATING-WITH-DOCTRINE.md @@ -70,6 +70,10 @@ $configuration->addCustomStringFunction('INT8RANGE', MartinGeorgiev\Doctrine\ORM $configuration->addCustomStringFunction('NUMRANGE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Numrange::class); $configuration->addCustomStringFunction('TSRANGE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tsrange::class); $configuration->addCustomStringFunction('TSTZRANGE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tstzrange::class); +# Register array value extracting functions +$configuration->addCustomStringFunction('ALL_OF', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\All::class); +$configuration->addCustomStringFunction('ANY_OF', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Any::class); +$configuration->addCustomStringFunction('ANY_VALUE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\AnyValue::class); $em = EntityManager::create($dbParams, $configuration); ``` diff --git a/docs/INTEGRATING-WITH-LARAVEL.md b/docs/INTEGRATING-WITH-LARAVEL.md index c561de4b..3686662a 100644 --- a/docs/INTEGRATING-WITH-LARAVEL.md +++ b/docs/INTEGRATING-WITH-LARAVEL.md @@ -86,6 +86,7 @@ return [ # array and string specific functions 'IN_ARRAY' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\InArray::class, + 'ANY_VALUE' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\AnyValue::class, 'ARRAY' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Arr::class, 'ARRAY_APPEND' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAppend::class, 'ARRAY_CARDINALITY' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayCardinality::class, diff --git a/docs/INTEGRATING-WITH-SYMFONY.md b/docs/INTEGRATING-WITH-SYMFONY.md index fb514a23..dd46d361 100644 --- a/docs/INTEGRATING-WITH-SYMFONY.md +++ b/docs/INTEGRATING-WITH-SYMFONY.md @@ -64,7 +64,7 @@ doctrine: # alternative implementation of ALL() and ANY() where subquery is not required, useful for arrays ALL_OF: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\All ANY_OF: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Any - + # operators for working with array and json(b) data GREATEST: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Greatest LEAST: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Least @@ -79,6 +79,7 @@ doctrine: # array and string specific functions IN_ARRAY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\InArray + ANY_VALUE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\AnyValue ARRAY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Arr ARRAY_APPEND: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAppend ARRAY_CARDINALITY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayCardinality diff --git a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/AnyValue.php b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/AnyValue.php new file mode 100644 index 00000000..23db55a9 --- /dev/null +++ b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/AnyValue.php @@ -0,0 +1,22 @@ + + */ +class AnyValue extends BaseFunction +{ + protected function customizeFunction(): void + { + $this->setFunctionPrototype('any_value(%s)'); + $this->addNodeMapping('StringPrimary'); + } +} diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/AnyValueTest.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/AnyValueTest.php new file mode 100644 index 00000000..b0a1af07 --- /dev/null +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/AnyValueTest.php @@ -0,0 +1,39 @@ + AnyValue::class, + 'ARRAY' => Arr::class, + ]; + } + + protected function getExpectedSqlStatements(): array + { + return [ + 'from array field' => 'SELECT any_value(c0_.array1) AS sclr_0 FROM ContainsArrays c0_', + 'from text field' => 'SELECT any_value(c0_.text1) AS sclr_0 FROM ContainsTexts c0_', + 'from list of integers' => "SELECT any_value(ARRAY['red', 'green', 'blue']) AS sclr_0 FROM ContainsTexts c0_", + ]; + } + + protected function getDqlStatements(): array + { + return [ + 'from array field' => \sprintf('SELECT ANY_VALUE(e.array1) FROM %s e', ContainsArrays::class), + 'from text field' => \sprintf('SELECT ANY_VALUE(e.text1) FROM %s e', ContainsTexts::class), + 'from list of integers' => \sprintf("SELECT ANY_VALUE(ARRAY('red', 'green', 'blue')) FROM %s e", ContainsTexts::class), + ]; + } +}