Skip to content

Commit ceac70d

Browse files
authored
PHPLIB-1273: Improve $switch syntax (#62)
* PHPLIB-1273: Improve $switch syntax * Restore previously deleted encoding type in schema * Introduce dedicated interface for branches in $switch * Remove optional parameter in encodeAsObject * Use case operator throughout tests
1 parent 040833d commit ceac70d

File tree

14 files changed

+128
-22
lines changed

14 files changed

+128
-22
lines changed

generator/config/expression/case.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# $schema: ../schema.json
2+
name: $case
3+
link: 'https://www.mongodb.com/docs/manual/reference/operator/aggregation/switch/'
4+
type:
5+
- switchBranch
6+
encode: flat_object
7+
description: |
8+
Represents a single case in a $switch expression
9+
arguments:
10+
-
11+
name: case
12+
type:
13+
- resolvesToBool
14+
description: |
15+
Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here.
16+
-
17+
name: then
18+
type:
19+
- expression
20+
description: |
21+
Can be any valid expression.

generator/config/expression/switch.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ arguments:
1010
-
1111
name: branches
1212
type:
13-
- array # of object{case:resolvesToBool, then:expression}
13+
- array # of CaseOperator
1414
description: |
1515
An array of control branch documents. Each branch is a document with the following fields:
1616
- case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here.

generator/config/expressions.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@
113113
'returnType' => Type\GeometryInterface::class,
114114
'acceptedTypes' => [Type\GeometryInterface::class, ...$bsonTypes['object']],
115115
],
116+
'switchBranch' => [
117+
'returnType' => Type\SwitchBranchInterface::class,
118+
'acceptedTypes' => [Type\SwitchBranchInterface::class, ...$bsonTypes['object']],
119+
],
116120

117121
// @todo add enum values
118122
'Granularity' => [

generator/config/schema.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"filter",
3030
"window",
3131
"geometry",
32+
"switchBranch",
3233
"resolvesToAny",
3334
"resolvesToNumber",
3435
"resolvesToDouble",
@@ -59,6 +60,7 @@
5960
"enum": [
6061
"array",
6162
"object",
63+
"flat_object",
6264
"dollar_object",
6365
"single",
6466
"group"

generator/src/Definition/OperatorDefinition.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public function __construct(
3939
'single' => Encode::Single,
4040
'array' => Encode::Array,
4141
'object' => Encode::Object,
42+
'flat_object' => Encode::FlatObject,
4243
'dollar_object' => Encode::DollarObject,
4344
'group' => Encode::Group,
4445
default => throw new UnexpectedValueException(sprintf('Unexpected "encode" value for operator "%s". Got "%s"', $name, $encode)),

src/Builder/Encoder/OperatorEncoder.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function encode(mixed $value): stdClass
4646
return $this->encodeAsArray($value);
4747

4848
case Encode::Object:
49+
case Encode::FlatObject:
4950
return $this->encodeAsObject($value);
5051

5152
case Encode::DollarObject:
@@ -107,7 +108,9 @@ private function encodeAsObject(OperatorInterface $value): stdClass
107108
$result->{$key} = $this->recursiveEncode($val);
108109
}
109110

110-
return $this->wrap($value, $result);
111+
return $value::ENCODE === Encode::FlatObject
112+
? $result
113+
: $this->wrap($value, $result);
111114
}
112115

113116
private function encodeAsDollarObject(OperatorInterface $value): stdClass

src/Builder/Expression/CaseOperator.php

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Builder/Expression/FactoryTrait.php

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Builder/Type/Encode.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ enum Encode
2323
*/
2424
case Object;
2525

26+
/**
27+
* Same as Object, but only parameters are returned. The operator name will not be used.
28+
*/
29+
case FlatObject;
30+
2631
/**
2732
* Parameters are encoded as an object with keys matching the parameter names prefixed with a dollar sign ($)
2833
*/
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MongoDB\Builder\Type;
6+
7+
/**
8+
* Interface for branches in $switch operators
9+
*
10+
* @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/switch/
11+
*/
12+
interface SwitchBranchInterface
13+
{
14+
}

tests/Builder/Expression/ConvertOperatorTest.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
use MongoDB\Builder\Stage;
1111
use MongoDB\Tests\Builder\PipelineTestCase;
1212

13-
use function MongoDB\object;
14-
1513
/**
1614
* Test $convert expression
1715
*/
@@ -43,7 +41,7 @@ public function testExample(): void
4341
Stage::project(
4442
totalPrice: Expression::switch(
4543
branches: [
46-
object(
44+
Expression::case(
4745
case: Expression::eq(
4846
Expression::type(
4947
Expression::fieldPath('convertedPrice'),
@@ -52,7 +50,7 @@ public function testExample(): void
5250
),
5351
then: 'NaN',
5452
),
55-
object(
53+
Expression::case(
5654
case: Expression::eq(
5755
Expression::type(
5856
Expression::fieldPath('convertedQty'),

tests/Builder/Expression/IsNumberOperatorTest.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
use MongoDB\Builder\Stage;
1111
use MongoDB\Tests\Builder\PipelineTestCase;
1212

13-
use function MongoDB\object;
14-
1513
/**
1614
* Test $isNumber expression
1715
*/
@@ -28,35 +26,35 @@ public function testConditionallyModifyFieldsUsingIsNumber(): void
2826
then: Expression::fieldPath('grade'),
2927
else: Expression::switch(
3028
branches: [
31-
object(
29+
Expression::case(
3230
case: Expression::eq(
3331
Expression::fieldPath('grade'),
3432
'A',
3533
),
3634
then: 4,
3735
),
38-
object(
36+
Expression::case(
3937
case: Expression::eq(
4038
Expression::fieldPath('grade'),
4139
'B',
4240
),
4341
then: 3,
4442
),
45-
object(
43+
Expression::case(
4644
case: Expression::eq(
4745
Expression::fieldPath('grade'),
4846
'C',
4947
),
5048
then: 2,
5149
),
52-
object(
50+
Expression::case(
5351
case: Expression::eq(
5452
Expression::fieldPath('grade'),
5553
'D',
5654
),
5755
then: 1,
5856
),
59-
object(
57+
Expression::case(
6058
case: Expression::eq(
6159
Expression::fieldPath('grade'),
6260
'F',

tests/Builder/Expression/SwitchOperatorTest.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
use MongoDB\Builder\Stage;
1010
use MongoDB\Tests\Builder\PipelineTestCase;
1111

12-
use function MongoDB\object;
13-
1412
/**
1513
* Test $switch expression
1614
*/
@@ -23,7 +21,7 @@ public function testExample(): void
2321
name: 1,
2422
summary: Expression::switch(
2523
branches: [
26-
object(
24+
Expression::case(
2725
case: Expression::gte(
2826
Expression::avg(
2927
Expression::intFieldPath('scores'),
@@ -32,7 +30,7 @@ public function testExample(): void
3230
),
3331
then: 'Doing great!',
3432
),
35-
object(
33+
Expression::case(
3634
case:Expression::and(
3735
Expression::gte(
3836
Expression::avg(
@@ -49,7 +47,7 @@ public function testExample(): void
4947
),
5048
then: 'Doing pretty well.',
5149
),
52-
object(
50+
Expression::case(
5351
case: Expression::lt(
5452
Expression::avg(
5553
Expression::intFieldPath('scores'),

tests/Builder/Expression/ToBoolOperatorTest.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
use MongoDB\Builder\Stage;
1010
use MongoDB\Tests\Builder\PipelineTestCase;
1111

12-
use function MongoDB\object;
13-
1412
/**
1513
* Test $toBool expression
1614
*/
@@ -22,14 +20,14 @@ public function testExample(): void
2220
Stage::addFields(
2321
convertedShippedFlag: Expression::switch(
2422
branches: [
25-
object(
23+
Expression::case(
2624
case: Expression::eq(
2725
Expression::fieldPath('shipped'),
2826
'false',
2927
),
3028
then: false,
3129
),
32-
object(
30+
Expression::case(
3331
case: Expression::eq(
3432
Expression::fieldPath('shipped'),
3533
'',

0 commit comments

Comments
 (0)