diff --git a/generator/config/accumulator/bottom.yaml b/generator/config/accumulator/bottom.yaml index 4ebb897ea..1e363d193 100644 --- a/generator/config/accumulator/bottom.yaml +++ b/generator/config/accumulator/bottom.yaml @@ -12,7 +12,7 @@ arguments: - name: sortBy type: - - object # SortSpec + - sortBy description: | Specifies the order of results, with syntax similar to $sort. - diff --git a/generator/config/accumulator/bottomN.yaml b/generator/config/accumulator/bottomN.yaml index 30bca678c..355d8e09a 100644 --- a/generator/config/accumulator/bottomN.yaml +++ b/generator/config/accumulator/bottomN.yaml @@ -19,7 +19,7 @@ arguments: - name: sortBy type: - - object # SortSpec + - sortBy description: | Specifies the order of results, with syntax similar to $sort. - diff --git a/generator/config/accumulator/median.yaml b/generator/config/accumulator/median.yaml index 708ea3502..e743c6982 100644 --- a/generator/config/accumulator/median.yaml +++ b/generator/config/accumulator/median.yaml @@ -22,7 +22,7 @@ arguments: - name: method type: - - string # AccumulatorPercentile + - accumulatorPercentile description: | The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. tests: diff --git a/generator/config/accumulator/percentile.yaml b/generator/config/accumulator/percentile.yaml index b2a6147d4..b3c41b0e4 100644 --- a/generator/config/accumulator/percentile.yaml +++ b/generator/config/accumulator/percentile.yaml @@ -32,7 +32,7 @@ arguments: - name: method type: - - string # AccumulatorPercentile + - accumulatorPercentile description: | The method that mongod uses to calculate the percentile value. The method must be 'approximate'. tests: diff --git a/generator/config/accumulator/top.yaml b/generator/config/accumulator/top.yaml index 2f4deefa2..94923cccd 100644 --- a/generator/config/accumulator/top.yaml +++ b/generator/config/accumulator/top.yaml @@ -13,7 +13,7 @@ arguments: - name: sortBy type: - - object # SortSpec + - sortBy description: | Specifies the order of results, with syntax similar to $sort. - diff --git a/generator/config/accumulator/topN.yaml b/generator/config/accumulator/topN.yaml index c8073e09f..c5eff6056 100644 --- a/generator/config/accumulator/topN.yaml +++ b/generator/config/accumulator/topN.yaml @@ -19,7 +19,7 @@ arguments: - name: sortBy type: - - object # SortSpec + - sortBy description: | Specifies the order of results, with syntax similar to $sort. - diff --git a/generator/config/expression/median.yaml b/generator/config/expression/median.yaml index 2708f7f16..2aac26a1f 100644 --- a/generator/config/expression/median.yaml +++ b/generator/config/expression/median.yaml @@ -22,7 +22,7 @@ arguments: - name: method type: - - string # AccumulatorPercentile + - accumulatorPercentile description: | The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. tests: diff --git a/generator/config/expression/percentile.yaml b/generator/config/expression/percentile.yaml index 8c601cc83..b19fc1904 100644 --- a/generator/config/expression/percentile.yaml +++ b/generator/config/expression/percentile.yaml @@ -32,7 +32,7 @@ arguments: - name: method type: - - string # AccumulatorPercentile + - accumulatorPercentile description: | The method that mongod uses to calculate the percentile value. The method must be 'approximate'. tests: diff --git a/generator/config/expression/sortArray.yaml b/generator/config/expression/sortArray.yaml index 962ebf1ce..d558f2233 100644 --- a/generator/config/expression/sortArray.yaml +++ b/generator/config/expression/sortArray.yaml @@ -18,9 +18,9 @@ arguments: - name: sortBy type: - - object # SortSpec - int - sortSpec + - sortBy description: | The document specifies a sort ordering. tests: diff --git a/generator/config/expressions.php b/generator/config/expressions.php index a2c649e8e..f77b45e79 100644 --- a/generator/config/expressions.php +++ b/generator/config/expressions.php @@ -131,45 +131,36 @@ ], // @todo add enum values - 'Granularity' => [ + 'granularity' => [ 'acceptedTypes' => [...$bsonTypes['string']], ], - 'FullDocument' => [ + 'fullDocument' => [ 'acceptedTypes' => [...$bsonTypes['string']], ], - 'FullDocumentBeforeChange' => [ + 'fullDocumentBeforeChange' => [ 'acceptedTypes' => [...$bsonTypes['string']], ], - 'AccumulatorPercentile' => [ + 'accumulatorPercentile' => [ 'acceptedTypes' => [...$bsonTypes['string']], ], - 'WhenMatched' => [ + 'whenMatched' => [ 'acceptedTypes' => [...$bsonTypes['string']], ], - 'WhenNotMatched' => [ + 'whenNotMatched' => [ 'acceptedTypes' => [...$bsonTypes['string']], ], // @todo create specific model classes factories - 'OutCollection' => [ + 'outCollection' => [ 'acceptedTypes' => [...$bsonTypes['object']], ], - 'CollStats' => [ + 'range' => [ 'acceptedTypes' => [...$bsonTypes['object']], ], - 'Range' => [ + 'sortBy' => [ 'acceptedTypes' => [...$bsonTypes['object']], ], - 'FillOut' => [ - 'acceptedTypes' => [...$bsonTypes['object']], - ], - 'SortSpec' => [ - 'acceptedTypes' => [...$bsonTypes['object']], - ], - 'Window' => [ - 'acceptedTypes' => [...$bsonTypes['object']], - ], - 'GeoPoint' => [ + 'geoPoint' => [ 'acceptedTypes' => [...$bsonTypes['object']], ], diff --git a/generator/config/schema.json b/generator/config/schema.json index c92e6ddb7..63739ebcb 100644 --- a/generator/config/schema.json +++ b/generator/config/schema.json @@ -9,7 +9,7 @@ "name": { "$comment": "The name of the operator. Must start with a $", "type": "string", - "pattern": "^\\$[a-z0-9][a-zA-Z0-9]*$" + "pattern": "^\\$?[a-z][a-zA-Z0-9]*$" }, "link": { "$comment": "The link to the operator's documentation on MongoDB's website.", @@ -122,6 +122,16 @@ "timeUnit", "sortSpec", "any", + "granularity", + "fullDocument", + "fullDocumentBeforeChange", + "accumulatorPercentile", + "whenMatched", + "whenNotMatched", + "outCollection", + "range", + "sortBy", + "geoPoint", "resolvesToNumber", "numberFieldPath", "number", "resolvesToDouble", "doubleFieldPath", "double", "resolvesToString", "stringFieldPath", "string", diff --git a/generator/config/stage/bucketAuto.yaml b/generator/config/stage/bucketAuto.yaml index 48c102e11..73775fde8 100644 --- a/generator/config/stage/bucketAuto.yaml +++ b/generator/config/stage/bucketAuto.yaml @@ -30,7 +30,7 @@ arguments: - name: granularity type: - - object # Granularity + - granularity optional: true description: | A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. diff --git a/generator/config/stage/changeStream.yaml b/generator/config/stage/changeStream.yaml index 44fdb3c5c..be413ef5d 100644 --- a/generator/config/stage/changeStream.yaml +++ b/generator/config/stage/changeStream.yaml @@ -17,14 +17,14 @@ arguments: - name: fullDocument type: - - string # FullDocument + - fullDocument optional: true description: | Specifies whether change notifications include a copy of the full document when modified by update operations. - name: fullDocumentBeforeChange type: - - string # FullDocumentBeforeChange + - fullDocumentBeforeChange optional: true description: | Valid values are "off", "whenAvailable", or "required". If set to "off", the "fullDocumentBeforeChange" field of the output document is always omitted. If set to "whenAvailable", the "fullDocumentBeforeChange" field will be populated with the pre-image of the document modified by the current change event if such a pre-image is available, and will be omitted otherwise. If set to "required", then the "fullDocumentBeforeChange" field is always populated and an exception is thrown if the pre-image is not available. diff --git a/generator/config/stage/densify.yaml b/generator/config/stage/densify.yaml index a66cf18dd..46ccbd6dd 100644 --- a/generator/config/stage/densify.yaml +++ b/generator/config/stage/densify.yaml @@ -25,7 +25,7 @@ arguments: - name: range type: - - object # Range + - range description: | Specification for range based densification. tests: diff --git a/generator/config/stage/fill.yaml b/generator/config/stage/fill.yaml index d3a9ec390..2c98fac5c 100644 --- a/generator/config/stage/fill.yaml +++ b/generator/config/stage/fill.yaml @@ -29,7 +29,7 @@ arguments: - name: sortBy type: - - object # SortSpec + - sortBy optional: true description: | Specifies the field or fields to sort the documents within each partition. Uses the same syntax as the $sort stage. diff --git a/generator/config/stage/geoNear.yaml b/generator/config/stage/geoNear.yaml index c9968509d..4967a0823 100644 --- a/generator/config/stage/geoNear.yaml +++ b/generator/config/stage/geoNear.yaml @@ -11,6 +11,7 @@ arguments: name: distanceField type: - string + optional: true description: | The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. - @@ -53,7 +54,7 @@ arguments: - name: near type: - - object # GeoPoint + - geoPoint - resolvesToObject description: | The point for which to find the closest documents. diff --git a/generator/config/stage/merge.yaml b/generator/config/stage/merge.yaml index 2e24ec74e..766092d82 100644 --- a/generator/config/stage/merge.yaml +++ b/generator/config/stage/merge.yaml @@ -12,7 +12,7 @@ arguments: name: into type: - string - - object # OutCollection + - outCollection description: | The output collection. - @@ -33,7 +33,7 @@ arguments: - name: whenMatched type: - - string # WhenMatched + - whenMatched - pipeline optional: true description: | @@ -41,7 +41,7 @@ arguments: - name: whenNotMatched type: - - string # WhenNotMatched + - whenNotMatched optional: true description: | The behavior of $merge if a result document does not match an existing document in the out collection. diff --git a/generator/config/stage/out.yaml b/generator/config/stage/out.yaml index c4cc7948d..0c3597fdf 100644 --- a/generator/config/stage/out.yaml +++ b/generator/config/stage/out.yaml @@ -10,7 +10,7 @@ arguments: - name: coll type: - string - - object # OutCollection + - outCollection description: | Target database name to write documents from $out to. tests: diff --git a/generator/config/stage/setWindowFields.yaml b/generator/config/stage/setWindowFields.yaml index fba751d03..6f86472d7 100644 --- a/generator/config/stage/setWindowFields.yaml +++ b/generator/config/stage/setWindowFields.yaml @@ -11,7 +11,7 @@ arguments: - name: sortBy type: - - object # SortSpec + - sortBy description: | Specifies the field(s) to sort the documents by in the partition. Uses the same syntax as the $sort stage. Default is no sorting. - diff --git a/src/Builder/Stage/BucketAutoStage.php b/src/Builder/Stage/BucketAutoStage.php index 2de5b3c20..11c456e69 100644 --- a/src/Builder/Stage/BucketAutoStage.php +++ b/src/Builder/Stage/BucketAutoStage.php @@ -49,24 +49,24 @@ final class BucketAutoStage implements StageInterface, OperatorInterface public readonly Optional|Document|Serializable|stdClass|array $output; /** - * @var Optional|Document|Serializable|array|stdClass $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. + * @var Optional|string $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. * Available only if the all groupBy values are numeric and none of them are NaN. */ - public readonly Optional|Document|Serializable|stdClass|array $granularity; + public readonly Optional|string $granularity; /** * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $groupBy An expression to group documents by. To specify a field path, prefix the field name with a dollar sign $ and enclose it in quotes. * @param int $buckets A positive 32-bit integer that specifies the number of buckets into which input documents are grouped. * @param Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. * The default count field is not included in the output document when output is specified. Explicitly specify the count expression as part of the output document to include it. - * @param Optional|Document|Serializable|array|stdClass $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. + * @param Optional|string $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. * Available only if the all groupBy values are numeric and none of them are NaN. */ public function __construct( Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $groupBy, int $buckets, Optional|Document|Serializable|stdClass|array $output = Optional::Undefined, - Optional|Document|Serializable|stdClass|array $granularity = Optional::Undefined, + Optional|string $granularity = Optional::Undefined, ) { $this->groupBy = $groupBy; $this->buckets = $buckets; diff --git a/src/Builder/Stage/FactoryTrait.php b/src/Builder/Stage/FactoryTrait.php index 7ef8fb62b..7bbf3bc97 100644 --- a/src/Builder/Stage/FactoryTrait.php +++ b/src/Builder/Stage/FactoryTrait.php @@ -79,14 +79,14 @@ public static function bucket( * @param int $buckets A positive 32-bit integer that specifies the number of buckets into which input documents are grouped. * @param Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. * The default count field is not included in the output document when output is specified. Explicitly specify the count expression as part of the output document to include it. - * @param Optional|Document|Serializable|array|stdClass $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. + * @param Optional|string $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. * Available only if the all groupBy values are numeric and none of them are NaN. */ public static function bucketAuto( Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $groupBy, int $buckets, Optional|Document|Serializable|stdClass|array $output = Optional::Undefined, - Optional|Document|Serializable|stdClass|array $granularity = Optional::Undefined, + Optional|string $granularity = Optional::Undefined, ): BucketAutoStage { return new BucketAutoStage($groupBy, $buckets, $output, $granularity); } @@ -248,8 +248,8 @@ public static function fill( * Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/ - * @param string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Document|ResolvesToObject|Serializable|array|stdClass $near The point for which to find the closest documents. + * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. * @param Optional|string $key Specify the geospatial indexed field to use when calculating the distance. @@ -265,8 +265,8 @@ public static function fill( * Default: false. */ public static function geoNear( - string $distanceField, Document|Serializable|ResolvesToObject|stdClass|array $near, + Optional|string $distanceField = Optional::Undefined, Optional|Decimal128|Int64|float|int $distanceMultiplier = Optional::Undefined, Optional|string $includeLocs = Optional::Undefined, Optional|string $key = Optional::Undefined, @@ -275,7 +275,7 @@ public static function geoNear( Optional|QueryInterface|array $query = Optional::Undefined, Optional|bool $spherical = Optional::Undefined, ): GeoNearStage { - return new GeoNearStage($distanceField, $near, $distanceMultiplier, $includeLocs, $key, $maxDistance, $minDistance, $query, $spherical); + return new GeoNearStage($near, $distanceField, $distanceMultiplier, $includeLocs, $key, $maxDistance, $minDistance, $query, $spherical); } /** diff --git a/src/Builder/Stage/FluentFactoryTrait.php b/src/Builder/Stage/FluentFactoryTrait.php index 803ca9905..3cfd84cff 100644 --- a/src/Builder/Stage/FluentFactoryTrait.php +++ b/src/Builder/Stage/FluentFactoryTrait.php @@ -106,14 +106,14 @@ public function bucket( * @param int $buckets A positive 32-bit integer that specifies the number of buckets into which input documents are grouped. * @param Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. * The default count field is not included in the output document when output is specified. Explicitly specify the count expression as part of the output document to include it. - * @param Optional|Document|Serializable|array|stdClass $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. + * @param Optional|string $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. * Available only if the all groupBy values are numeric and none of them are NaN. */ public function bucketAuto( Type|ExpressionInterface|stdClass|array|string|int|float|bool|null $groupBy, int $buckets, Optional|Document|Serializable|stdClass|array $output = Optional::Undefined, - Optional|Document|Serializable|stdClass|array $granularity = Optional::Undefined, + Optional|string $granularity = Optional::Undefined, ): static { $this->pipeline[] = Stage::bucketAuto($groupBy, $buckets, $output, $granularity); @@ -295,8 +295,8 @@ public function fill( * Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/ - * @param string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Document|ResolvesToObject|Serializable|array|stdClass $near The point for which to find the closest documents. + * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. * @param Optional|string $key Specify the geospatial indexed field to use when calculating the distance. @@ -312,8 +312,8 @@ public function fill( * Default: false. */ public function geoNear( - string $distanceField, Document|Serializable|ResolvesToObject|stdClass|array $near, + Optional|string $distanceField = Optional::Undefined, Optional|Decimal128|Int64|int|float $distanceMultiplier = Optional::Undefined, Optional|string $includeLocs = Optional::Undefined, Optional|string $key = Optional::Undefined, @@ -322,7 +322,7 @@ public function geoNear( Optional|QueryInterface|array $query = Optional::Undefined, Optional|bool $spherical = Optional::Undefined, ): static { - $this->pipeline[] = Stage::geoNear($distanceField, $near, $distanceMultiplier, $includeLocs, $key, $maxDistance, $minDistance, $query, $spherical); + $this->pipeline[] = Stage::geoNear($near, $distanceField, $distanceMultiplier, $includeLocs, $key, $maxDistance, $minDistance, $query, $spherical); return $this; } diff --git a/src/Builder/Stage/GeoNearStage.php b/src/Builder/Stage/GeoNearStage.php index b2aa6588e..845fd2afa 100644 --- a/src/Builder/Stage/GeoNearStage.php +++ b/src/Builder/Stage/GeoNearStage.php @@ -35,8 +35,8 @@ final class GeoNearStage implements StageInterface, OperatorInterface public const NAME = '$geoNear'; public const PROPERTIES = [ - 'distanceField' => 'distanceField', 'near' => 'near', + 'distanceField' => 'distanceField', 'distanceMultiplier' => 'distanceMultiplier', 'includeLocs' => 'includeLocs', 'key' => 'key', @@ -46,12 +46,12 @@ final class GeoNearStage implements StageInterface, OperatorInterface 'spherical' => 'spherical', ]; - /** @var string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. */ - public readonly string $distanceField; - /** @var Document|ResolvesToObject|Serializable|array|stdClass $near The point for which to find the closest documents. */ public readonly Document|Serializable|ResolvesToObject|stdClass|array $near; + /** @var Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. */ + public readonly Optional|string $distanceField; + /** @var Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. */ public readonly Optional|Decimal128|Int64|float|int $distanceMultiplier; @@ -88,8 +88,8 @@ final class GeoNearStage implements StageInterface, OperatorInterface public readonly Optional|bool $spherical; /** - * @param string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Document|ResolvesToObject|Serializable|array|stdClass $near The point for which to find the closest documents. + * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. * @param Optional|string $key Specify the geospatial indexed field to use when calculating the distance. @@ -105,8 +105,8 @@ final class GeoNearStage implements StageInterface, OperatorInterface * Default: false. */ public function __construct( - string $distanceField, Document|Serializable|ResolvesToObject|stdClass|array $near, + Optional|string $distanceField = Optional::Undefined, Optional|Decimal128|Int64|float|int $distanceMultiplier = Optional::Undefined, Optional|string $includeLocs = Optional::Undefined, Optional|string $key = Optional::Undefined, @@ -115,8 +115,8 @@ public function __construct( Optional|QueryInterface|array $query = Optional::Undefined, Optional|bool $spherical = Optional::Undefined, ) { - $this->distanceField = $distanceField; $this->near = $near; + $this->distanceField = $distanceField; $this->distanceMultiplier = $distanceMultiplier; $this->includeLocs = $includeLocs; $this->key = $key; diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 2a9bc30b9..c92734a0c 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -35,6 +35,19 @@ public static function cannotCombineCodecAndTypeMap(): self return new self('Cannot provide both "codec" and "typeMap" options'); } + /** + * Thrown when an argument or option is expected to be a string or a document. + * + * @internal + * + * @param string $name Name of the argument or option + * @param mixed $value Actual value (used to derive the type) + */ + public static function expectedDocumentOrStringType(string $name, mixed $value): self + { + return new self(sprintf('Expected %s to have type "string" or "document" (array or object) but found "%s"', $name, get_debug_type($value))); + } + /** * Thrown when an argument or option is expected to be a document. * diff --git a/src/Operation/Aggregate.php b/src/Operation/Aggregate.php index 0588df188..b5da6470c 100644 --- a/src/Operation/Aggregate.php +++ b/src/Operation/Aggregate.php @@ -35,7 +35,6 @@ use function is_array; use function is_bool; use function is_integer; -use function is_object; use function is_string; use function MongoDB\is_document; use function MongoDB\is_last_pipeline_operator_write; @@ -146,8 +145,8 @@ public function __construct(private string $databaseName, private ?string $colle throw InvalidArgumentException::invalidType('"explain" option', $this->options['explain'], 'boolean'); } - if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_array($this->options['hint']) && ! is_object($this->options['hint'])) { - throw InvalidArgumentException::invalidType('"hint" option', $this->options['hint'], 'string or array or object'); + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); } if (isset($this->options['let']) && ! is_document($this->options['let'])) { diff --git a/src/Operation/Count.php b/src/Operation/Count.php index d79d49447..a6b03c57d 100644 --- a/src/Operation/Count.php +++ b/src/Operation/Count.php @@ -88,8 +88,8 @@ public function __construct(private string $databaseName, private string $collec throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); } - if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_array($this->options['hint']) && ! is_object($this->options['hint'])) { - throw InvalidArgumentException::invalidType('"hint" option', $this->options['hint'], 'string or array or object'); + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); } if (isset($this->options['limit']) && ! is_integer($this->options['limit'])) { diff --git a/src/Operation/Delete.php b/src/Operation/Delete.php index 7e264152f..84a803c79 100644 --- a/src/Operation/Delete.php +++ b/src/Operation/Delete.php @@ -26,8 +26,6 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnsupportedException; -use function is_array; -use function is_object; use function is_string; use function MongoDB\is_document; use function MongoDB\is_write_concern_acknowledged; @@ -96,8 +94,8 @@ public function __construct(private string $databaseName, private string $collec throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); } - if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_array($this->options['hint']) && ! is_object($this->options['hint'])) { - throw InvalidArgumentException::invalidType('"hint" option', $this->options['hint'], ['string', 'array', 'object']); + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); } if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { diff --git a/src/Operation/Distinct.php b/src/Operation/Distinct.php index 78dde7de5..c2aa3ef23 100644 --- a/src/Operation/Distinct.php +++ b/src/Operation/Distinct.php @@ -89,7 +89,7 @@ public function __construct(private string $databaseName, private string $collec } if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { - throw InvalidArgumentException::invalidType('"hint" option', $this->options['hint'], 'string or array or object'); + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); } if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { diff --git a/src/Operation/Find.php b/src/Operation/Find.php index 5817b5f1e..8d84c7bf0 100644 --- a/src/Operation/Find.php +++ b/src/Operation/Find.php @@ -33,7 +33,6 @@ use function is_array; use function is_bool; use function is_integer; -use function is_object; use function is_string; use function MongoDB\is_document; @@ -171,8 +170,8 @@ public function __construct(private string $databaseName, private string $collec } } - if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_array($this->options['hint']) && ! is_object($this->options['hint'])) { - throw InvalidArgumentException::invalidType('"hint" option', $this->options['hint'], 'string or array or object'); + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); } if (isset($this->options['limit']) && ! is_integer($this->options['limit'])) { diff --git a/src/Operation/FindAndModify.php b/src/Operation/FindAndModify.php index 27a888bc6..3d77dd643 100644 --- a/src/Operation/FindAndModify.php +++ b/src/Operation/FindAndModify.php @@ -151,8 +151,8 @@ public function __construct(private string $databaseName, private string $collec throw InvalidArgumentException::expectedDocumentType('"fields" option', $options['fields']); } - if (isset($options['hint']) && ! is_string($options['hint']) && ! is_array($options['hint']) && ! is_object($options['hint'])) { - throw InvalidArgumentException::invalidType('"hint" option', $options['hint'], ['string', 'array', 'object']); + if (isset($options['hint']) && ! is_string($options['hint']) && ! is_document($options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $options['hint']); } if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) { diff --git a/src/Operation/Update.php b/src/Operation/Update.php index 3e2da46af..9d1314e73 100644 --- a/src/Operation/Update.php +++ b/src/Operation/Update.php @@ -28,7 +28,6 @@ use function is_array; use function is_bool; -use function is_object; use function is_string; use function MongoDB\is_document; use function MongoDB\is_first_key_operator; @@ -122,8 +121,8 @@ public function __construct(private string $databaseName, private string $collec throw InvalidArgumentException::expectedDocumentType('"collation" option', $options['collation']); } - if (isset($options['hint']) && ! is_string($options['hint']) && ! is_array($options['hint']) && ! is_object($options['hint'])) { - throw InvalidArgumentException::invalidType('"hint" option', $options['hint'], ['string', 'array', 'object']); + if (isset($options['hint']) && ! is_string($options['hint']) && ! is_document($options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $options['hint']); } if (! is_bool($options['multi'])) { diff --git a/tests/TestCase.php b/tests/TestCase.php index c8c7db09d..2b6b86eb2 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -250,7 +250,7 @@ protected static function getInvalidDocumentCodecValues(): array */ protected static function getInvalidHintValues(): array { - return [123, 3.14, true]; + return [123, 3.14, true, PackedArray::fromPHP([])]; } /** diff --git a/tests/specifications b/tests/specifications index ce35696db..d9b434db8 160000 --- a/tests/specifications +++ b/tests/specifications @@ -1 +1 @@ -Subproject commit ce35696db1c8da0e15a067b8022c853f1d6d1292 +Subproject commit d9b434db87abec375df46864d4fedb2297bc80ec