Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion generator/config/expression/case.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ name: $case
link: 'https://www.mongodb.com/docs/manual/reference/operator/aggregation/switch/'
type:
- switchBranch
encode: flat_object
encode: object
wrapObject: false
description: |
Represents a single case in a $switch expression
arguments:
Expand Down
6 changes: 5 additions & 1 deletion generator/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,18 @@
"enum": [
"array",
"object",
"flat_object",
"single"
]
},
"description": {
"$comment": "The description of the argument from MongoDB's documentation.",
"type": "string"
},
"wrapObject": {
"$comment": "Wrap the properties in an object with the operator name",
"type": "boolean",
"default": true
},
"arguments": {
"$comment": "An optional list of arguments for the operator.",
"type": "array",
Expand Down
2 changes: 1 addition & 1 deletion generator/src/Definition/OperatorDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ public function __construct(
/** @var list<string> */
public array $type,
public string|null $description = null,
public bool $wrapObject = true,
array $arguments = [],
array $tests = [],
) {
$this->encode = match ($encode) {
'single' => Encode::Single,
'array' => Encode::Array,
'object' => Encode::Object,
'flat_object' => Encode::FlatObject,
default => throw new UnexpectedValueException(sprintf('Unexpected "encode" value for operator "%s". Got "%s"', $name, $encode)),
};

Expand Down
6 changes: 1 addition & 5 deletions generator/src/OperatorClassGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use function interface_exists;
use function rtrim;
use function sprintf;
use function var_export;

/**
* Generates a value object class for stages and operators.
Expand Down Expand Up @@ -62,6 +61,7 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition
$class->addComment('@internal');
$namespace->addUse(Encode::class);
$class->addConstant('ENCODE', new Literal('Encode::' . $operator->encode->name));
$class->addConstant('NAME', $operator->wrapObject ? $operator->name : null);

$encodeNames = [];
$constructor = $class->addMethod('__construct');
Expand Down Expand Up @@ -179,10 +179,6 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition
$class->addConstant('PROPERTIES', $encodeNames);
}

$class->addMethod('getOperator')
->setReturnType('string')
->setBody('return ' . var_export($operator->name, true) . ';');

return $namespace;
}

Expand Down
30 changes: 30 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@
<code><![CDATA[$val]]></code>
<code><![CDATA[$val]]></code>
</MixedAssignment>
<MixedInferredReturnType>
<code><![CDATA[stdClass]]></code>
</MixedInferredReturnType>
<MixedReturnStatement>
<code><![CDATA[$result]]></code>
</MixedReturnStatement>
<PossibleRawObjectIteration>
<code><![CDATA[$val]]></code>
</PossibleRawObjectIteration>
Expand Down Expand Up @@ -172,7 +178,26 @@
<code><![CDATA[stdClass]]></code>
</TooManyTemplateParams>
</file>
<file src="src/Builder/Type/CombinedFieldQuery.php">
<MixedArgument>
<code><![CDATA[$operator]]></code>
<code><![CDATA[$operator]]></code>
</MixedArgument>
<MixedArrayOffset>
<code><![CDATA[$seenOperators[$operator]]]></code>
</MixedArrayOffset>
<MixedAssignment>
<code><![CDATA[$operator]]></code>
</MixedAssignment>
</file>
<file src="src/Builder/Type/QueryObject.php">
<MixedArgument>
<code><![CDATA[$query::NAME]]></code>
</MixedArgument>
<MixedArrayOffset>
<code><![CDATA[$seenQueryOperators[$query::NAME]]]></code>
<code><![CDATA[$seenQueryOperators[$query::NAME]]]></code>
</MixedArrayOffset>
<MixedAssignment>
<code><![CDATA[$queries[$fieldPath]]]></code>
<code><![CDATA[$query]]></code>
Expand All @@ -183,6 +208,11 @@
is_array($queriesOrArrayOfQueries[0]) &&
count($queriesOrArrayOfQueries[0]) > 0]]></code>
</RedundantConditionGivenDocblockType>
<UndefinedConstant>
<code><![CDATA[$query::NAME]]></code>
<code><![CDATA[$query::NAME]]></code>
<code><![CDATA[$query::NAME]]></code>
</UndefinedConstant>
</file>
<file src="src/ChangeStream.php">
<DeprecatedConstant>
Expand Down
17 changes: 12 additions & 5 deletions src/Builder/Encoder/OperatorEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function encode(mixed $value): stdClass
return match ($value::ENCODE) {
Encode::Single => $this->encodeAsSingle($value),
Encode::Array => $this->encodeAsArray($value),
Encode::Object, Encode::FlatObject => $this->encodeAsObject($value),
Encode::Object => $this->encodeAsObject($value),
default => throw new LogicException(sprintf('Class "%s" does not have a valid ENCODE constant.', $value::class)),
};
}
Expand Down Expand Up @@ -89,9 +89,7 @@ private function encodeAsObject(OperatorInterface $value): stdClass
}
}

return $value::ENCODE === Encode::FlatObject
? $result
: $this->wrap($value, $result);
return $this->wrap($value, $result);
}

/**
Expand All @@ -108,10 +106,19 @@ private function encodeAsSingle(OperatorInterface $value): stdClass
throw new LogicException(sprintf('Class "%s" does not have a single property.', $value::class));
}

/**
* Wrap the result in an object if the operator has a name.
* The operator name is NULL, and the result is returned as is
* when wrapObject is false in the YAML configuration of the operator.
*/
private function wrap(OperatorInterface $value, mixed $result): stdClass
{
if ($value::NAME === null) {
return $result;
}

$object = new stdClass();
$object->{$value->getOperator()} = $result;
$object->{$value::NAME} = $result;

return $object;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Builder/Type/CombinedFieldQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,15 @@ static function (array $fieldQueries, QueryInterface|FieldQueryInterface|Type|st
);

// Validate FieldQuery types and non-duplicate operators
/** @var array<string, true> $seenOperators */
$seenOperators = [];
foreach ($this->fieldQueries as $fieldQuery) {
if ($fieldQuery instanceof stdClass) {
$fieldQuery = get_object_vars($fieldQuery);
}

if ($fieldQuery instanceof FieldQueryInterface && $fieldQuery instanceof OperatorInterface) {
$operator = $fieldQuery->getOperator();
$operator = $fieldQuery::NAME;
} elseif (is_array($fieldQuery)) {
if (count($fieldQuery) !== 1) {
throw new InvalidArgumentException(sprintf('Operator must contain exactly one key, %d given', count($fieldQuery)));
Expand Down
5 changes: 0 additions & 5 deletions src/Builder/Type/Encode.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ enum Encode
*/
case Object;

/**
* Same as Object, but only parameters are returned. The operator name will not be used.
*/
case FlatObject;

/**
* Get the single parameter value
*/
Expand Down
3 changes: 2 additions & 1 deletion src/Builder/Type/OperatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ interface OperatorInterface
/** @var array<string, string|null> */
public const PROPERTIES = [];

public function getOperator(): string;
/** @var string|null */
public const NAME = null;
}
6 changes: 3 additions & 3 deletions src/Builder/Type/QueryObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ private function __construct(array $queriesOrArrayOfQueries)
foreach ($queriesOrArrayOfQueries as $fieldPath => $query) {
if ($query instanceof QueryInterface) {
if ($query instanceof OperatorInterface) {
if (isset($seenQueryOperators[$query->getOperator()])) {
throw new InvalidArgumentException(sprintf('Query operator "%s" cannot be used multiple times in the same query.', $query->getOperator()));
if (isset($seenQueryOperators[$query::NAME])) {
throw new InvalidArgumentException(sprintf('Query operator "%s" cannot be used multiple times in the same query.', $query::NAME));
}

$seenQueryOperators[$query->getOperator()] = true;
$seenQueryOperators[$query::NAME] = true;
}

$queries[] = $query;
Expand Down