Skip to content

Commit 6a5ba9e

Browse files
refactor: allow node mapping in variadic functions to have different patterns, thus opening the path to a combination of node types (compared to the previous single type support) (#349)
1 parent 67265cc commit 6a5ba9e

21 files changed

+117
-13
lines changed

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Arr.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
*/
1818
class Arr extends BaseVariadicFunction
1919
{
20-
protected string $commonNodeMapping = 'StringPrimary';
20+
protected function getNodeMappingPattern(): array
21+
{
22+
return ['StringPrimary'];
23+
}
2124

2225
protected function customizeFunction(): void
2326
{

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayToJson.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class ArrayToJson extends BaseVariadicFunction
2626
{
2727
use BooleanValidationTrait;
2828

29+
protected function getNodeMappingPattern(): array
30+
{
31+
return ['StringPrimary'];
32+
}
33+
2934
protected function customizeFunction(): void
3035
{
3136
$this->setFunctionPrototype('array_to_json(%s)');

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseComparisonFunction.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@
1111
*/
1212
abstract class BaseComparisonFunction extends BaseVariadicFunction
1313
{
14-
protected string $commonNodeMapping = 'SimpleArithmeticExpression';
14+
protected function getNodeMappingPattern(): array
15+
{
16+
return ['SimpleArithmeticExpression'];
17+
}
1518
}

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,37 @@
1919
*/
2020
abstract class BaseVariadicFunction extends BaseFunction
2121
{
22-
protected string $commonNodeMapping = 'StringPrimary';
22+
/**
23+
* @return array<int|string, string>
24+
*/
25+
abstract protected function getNodeMappingPattern(): array;
2326

2427
/**
2528
* @throws ParserException
2629
*/
2730
protected function feedParserWithNodes(Parser $parser): void
2831
{
32+
foreach ($this->getNodeMappingPattern() as $nodeMappingPattern) {
33+
try {
34+
$this->feedParserWithNodesForNodeMappingPattern($parser, $nodeMappingPattern);
35+
36+
break;
37+
} catch (ParserException) {
38+
// swallow and continue with next pattern
39+
}
40+
}
41+
42+
$this->validateArguments(...$this->nodes); // @phpstan-ignore-line
43+
}
44+
45+
private function feedParserWithNodesForNodeMappingPattern(Parser $parser, string $nodeMappingPattern): void
46+
{
47+
$nodeMapping = \explode(',', $nodeMappingPattern);
2948
$lexer = $parser->getLexer();
3049

3150
try {
3251
// @phpstan-ignore-next-line
33-
$this->nodes[] = $parser->{$this->commonNodeMapping}();
52+
$this->nodes[] = $parser->{$nodeMapping[0]}();
3453
$lookaheadType = DoctrineLexer::getLookaheadType($lexer);
3554
if ($lookaheadType === null) {
3655
throw ParserException::missingLookaheadType();
@@ -40,18 +59,18 @@ protected function feedParserWithNodes(Parser $parser): void
4059
}
4160

4261
$shouldUseLexer = DoctrineOrm::isPre219();
43-
62+
$isNodeMappingASimplePattern = \count($nodeMapping) === 1;
63+
$nodeIndex = 1;
4464
while (($shouldUseLexer ? Lexer::T_CLOSE_PARENTHESIS : TokenType::T_CLOSE_PARENTHESIS) !== $lookaheadType) {
4565
if (($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA) === $lookaheadType) {
4666
$parser->match($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA);
4767
// @phpstan-ignore-next-line
48-
$this->nodes[] = $parser->{$this->commonNodeMapping}();
68+
$this->nodes[] = $parser->{$nodeMapping[$isNodeMappingASimplePattern ? 0 : $nodeIndex]}();
69+
$nodeIndex++;
4970
}
5071

5172
$lookaheadType = DoctrineLexer::getLookaheadType($lexer);
5273
}
53-
54-
$this->validateArguments(...$this->nodes); // @phpstan-ignore-line
5574
}
5675

5776
public function getSql(SqlWalker $sqlWalker): string

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAdd.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ class DateAdd extends BaseVariadicFunction
2525
{
2626
use TimezoneValidationTrait;
2727

28+
protected function getNodeMappingPattern(): array
29+
{
30+
return ['StringPrimary'];
31+
}
32+
2833
protected function customizeFunction(): void
2934
{
3035
$this->setFunctionPrototype('date_add(%s)');

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtract.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ class DateSubtract extends BaseVariadicFunction
2525
{
2626
use TimezoneValidationTrait;
2727

28+
protected function getNodeMappingPattern(): array
29+
{
30+
return ['StringPrimary'];
31+
}
32+
2833
protected function customizeFunction(): void
2934
{
3035
$this->setFunctionPrototype('date_subtract(%s)');

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObject.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
*/
1818
class JsonBuildObject extends BaseVariadicFunction
1919
{
20+
protected function getNodeMappingPattern(): array
21+
{
22+
return ['StringPrimary'];
23+
}
24+
2025
protected function customizeFunction(): void
2126
{
2227
$this->setFunctionPrototype('json_build_object(%s)');

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObject.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
*/
1818
class JsonbBuildObject extends BaseVariadicFunction
1919
{
20+
protected function getNodeMappingPattern(): array
21+
{
22+
return ['StringPrimary'];
23+
}
24+
2025
protected function customizeFunction(): void
2126
{
2227
$this->setFunctionPrototype('jsonb_build_object(%s)');

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbInsert.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class JsonbInsert extends BaseVariadicFunction
2626
{
2727
use BooleanValidationTrait;
2828

29+
protected function getNodeMappingPattern(): array
30+
{
31+
return ['StringPrimary'];
32+
}
33+
2934
protected function customizeFunction(): void
3035
{
3136
$this->setFunctionPrototype('jsonb_insert(%s)');

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExists.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class JsonbPathExists extends BaseVariadicFunction
2424
{
2525
use BooleanValidationTrait;
2626

27+
protected function getNodeMappingPattern(): array
28+
{
29+
return ['StringPrimary'];
30+
}
31+
2732
protected function customizeFunction(): void
2833
{
2934
$this->setFunctionPrototype('jsonb_path_exists(%s)');

0 commit comments

Comments
 (0)