PYTHON-2957 Support 'let' option for multiple CRUD commands (#804)
This commit is contained in:
parent
e3d1d6f5b4
commit
046d789d9f
@ -1,6 +1,22 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Changes in Version 4.1
|
||||
----------------------
|
||||
|
||||
- :meth:`pymongo.collection.Collection.update_one`,
|
||||
:meth:`pymongo.collection.Collection.update_many`,
|
||||
:meth:`pymongo.collection.Collection.delete_one`,
|
||||
:meth:`pymongo.collection.Collection.delete_many`,
|
||||
:meth:`pymongo.collection.Collection.aggregate`,
|
||||
:meth:`pymongo.collection.Collection.find_one_and_delete`,
|
||||
:meth:`pymongo.collection.Collection.find_one_and_replace`,
|
||||
:meth:`pymongo.collection.Collection.find_one_and_update`,
|
||||
and :meth:`pymongo.collection.Collection.find` all support a new keyword
|
||||
argument ``let`` which is a map of parameter names and values. Parameters
|
||||
can then be accessed as variables in an aggregate expression context.
|
||||
|
||||
|
||||
Changes in Version 4.0
|
||||
----------------------
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ class _AggregationCommand(object):
|
||||
:meth:`pymongo.database.Database.aggregate` instead.
|
||||
"""
|
||||
def __init__(self, target, cursor_class, pipeline, options,
|
||||
explicit_session, user_fields=None, result_processor=None):
|
||||
explicit_session, let=None, user_fields=None, result_processor=None):
|
||||
if "explain" in options:
|
||||
raise ConfigurationError("The explain option is not supported. "
|
||||
"Use Database.command instead.")
|
||||
@ -44,6 +44,9 @@ class _AggregationCommand(object):
|
||||
self._performs_write = True
|
||||
|
||||
common.validate_is_mapping('options', options)
|
||||
if let:
|
||||
common.validate_is_mapping("let", let)
|
||||
options["let"] = let
|
||||
self._options = options
|
||||
|
||||
# This is the batchSize that will be used for setting the initial
|
||||
|
||||
@ -593,7 +593,7 @@ class Collection(common.BaseObject):
|
||||
check_keys=False, multi=False,
|
||||
write_concern=None, op_id=None, ordered=True,
|
||||
bypass_doc_val=False, collation=None, array_filters=None,
|
||||
hint=None, session=None, retryable_write=False):
|
||||
hint=None, session=None, retryable_write=False, let=None):
|
||||
"""Internal update / replace helper."""
|
||||
common.validate_boolean("upsert", upsert)
|
||||
collation = validate_collation_or_none(collation)
|
||||
@ -626,6 +626,9 @@ class Collection(common.BaseObject):
|
||||
command = SON([('update', self.name),
|
||||
('ordered', ordered),
|
||||
('updates', [update_doc])])
|
||||
if let:
|
||||
common.validate_is_mapping("let", let)
|
||||
command["let"] = let
|
||||
if not write_concern.is_server_default:
|
||||
command['writeConcern'] = write_concern.document
|
||||
|
||||
@ -663,7 +666,7 @@ class Collection(common.BaseObject):
|
||||
check_keys=False, multi=False,
|
||||
write_concern=None, op_id=None, ordered=True,
|
||||
bypass_doc_val=False, collation=None, array_filters=None,
|
||||
hint=None, session=None):
|
||||
hint=None, session=None, let=None):
|
||||
"""Internal update / replace helper."""
|
||||
def _update(session, sock_info, retryable_write):
|
||||
return self._update(
|
||||
@ -672,7 +675,7 @@ class Collection(common.BaseObject):
|
||||
write_concern=write_concern, op_id=op_id, ordered=ordered,
|
||||
bypass_doc_val=bypass_doc_val, collation=collation,
|
||||
array_filters=array_filters, hint=hint, session=session,
|
||||
retryable_write=retryable_write)
|
||||
retryable_write=retryable_write, let=let)
|
||||
|
||||
return self.__database.client._retryable_write(
|
||||
(write_concern or self.write_concern).acknowledged and not multi,
|
||||
@ -759,7 +762,7 @@ class Collection(common.BaseObject):
|
||||
def update_one(self, filter, update, upsert=False,
|
||||
bypass_document_validation=False,
|
||||
collation=None, array_filters=None, hint=None,
|
||||
session=None):
|
||||
session=None, let=None):
|
||||
"""Update a single document matching the filter.
|
||||
|
||||
>>> for doc in db.test.find():
|
||||
@ -802,10 +805,16 @@ class Collection(common.BaseObject):
|
||||
MongoDB 4.2 and above.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
- `let` (optional): Map of parameter names and values. Values must be
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
|
||||
:Returns:
|
||||
- An instance of :class:`~pymongo.results.UpdateResult`.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hint`` parameter.
|
||||
.. versionchanged:: 3.9
|
||||
@ -830,12 +839,12 @@ class Collection(common.BaseObject):
|
||||
write_concern=write_concern,
|
||||
bypass_doc_val=bypass_document_validation,
|
||||
collation=collation, array_filters=array_filters,
|
||||
hint=hint, session=session),
|
||||
hint=hint, session=session, let=let),
|
||||
write_concern.acknowledged)
|
||||
|
||||
def update_many(self, filter, update, upsert=False, array_filters=None,
|
||||
bypass_document_validation=False, collation=None,
|
||||
hint=None, session=None):
|
||||
hint=None, session=None, let=None):
|
||||
"""Update one or more documents that match the filter.
|
||||
|
||||
>>> for doc in db.test.find():
|
||||
@ -878,10 +887,16 @@ class Collection(common.BaseObject):
|
||||
MongoDB 4.2 and above.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
- `let` (optional): Map of parameter names and values. Values must be
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
|
||||
:Returns:
|
||||
- An instance of :class:`~pymongo.results.UpdateResult`.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hint`` parameter.
|
||||
.. versionchanged:: 3.9
|
||||
@ -906,7 +921,7 @@ class Collection(common.BaseObject):
|
||||
write_concern=write_concern,
|
||||
bypass_doc_val=bypass_document_validation,
|
||||
collation=collation, array_filters=array_filters,
|
||||
hint=hint, session=session),
|
||||
hint=hint, session=session, let=let),
|
||||
write_concern.acknowledged)
|
||||
|
||||
def drop(self, session=None):
|
||||
@ -938,7 +953,8 @@ class Collection(common.BaseObject):
|
||||
def _delete(
|
||||
self, sock_info, criteria, multi,
|
||||
write_concern=None, op_id=None, ordered=True,
|
||||
collation=None, hint=None, session=None, retryable_write=False):
|
||||
collation=None, hint=None, session=None, retryable_write=False,
|
||||
let=None):
|
||||
"""Internal delete helper."""
|
||||
common.validate_is_mapping("filter", criteria)
|
||||
write_concern = write_concern or self.write_concern
|
||||
@ -965,6 +981,10 @@ class Collection(common.BaseObject):
|
||||
if not write_concern.is_server_default:
|
||||
command['writeConcern'] = write_concern.document
|
||||
|
||||
if let:
|
||||
common.validate_is_document_type("let", let)
|
||||
command["let"] = let
|
||||
|
||||
# Delete command.
|
||||
result = sock_info.command(
|
||||
self.__database.name,
|
||||
@ -980,20 +1000,21 @@ class Collection(common.BaseObject):
|
||||
def _delete_retryable(
|
||||
self, criteria, multi,
|
||||
write_concern=None, op_id=None, ordered=True,
|
||||
collation=None, hint=None, session=None):
|
||||
collation=None, hint=None, session=None, let=None):
|
||||
"""Internal delete helper."""
|
||||
def _delete(session, sock_info, retryable_write):
|
||||
return self._delete(
|
||||
sock_info, criteria, multi,
|
||||
write_concern=write_concern, op_id=op_id, ordered=ordered,
|
||||
collation=collation, hint=hint, session=session,
|
||||
retryable_write=retryable_write)
|
||||
retryable_write=retryable_write, let=let)
|
||||
|
||||
return self.__database.client._retryable_write(
|
||||
(write_concern or self.write_concern).acknowledged and not multi,
|
||||
_delete, session)
|
||||
|
||||
def delete_one(self, filter, collation=None, hint=None, session=None):
|
||||
def delete_one(self, filter, collation=None, hint=None, session=None,
|
||||
let=None):
|
||||
"""Delete a single document matching the filter.
|
||||
|
||||
>>> db.test.count_documents({'x': 1})
|
||||
@ -1017,10 +1038,16 @@ class Collection(common.BaseObject):
|
||||
MongoDB 4.4 and above.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
- `let` (optional): Map of parameter names and values. Values must be
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
|
||||
:Returns:
|
||||
- An instance of :class:`~pymongo.results.DeleteResult`.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hint`` parameter.
|
||||
.. versionchanged:: 3.6
|
||||
@ -1034,10 +1061,11 @@ class Collection(common.BaseObject):
|
||||
self._delete_retryable(
|
||||
filter, False,
|
||||
write_concern=write_concern,
|
||||
collation=collation, hint=hint, session=session),
|
||||
collation=collation, hint=hint, session=session, let=let),
|
||||
write_concern.acknowledged)
|
||||
|
||||
def delete_many(self, filter, collation=None, hint=None, session=None):
|
||||
def delete_many(self, filter, collation=None, hint=None, session=None,
|
||||
let=None):
|
||||
"""Delete one or more documents matching the filter.
|
||||
|
||||
>>> db.test.count_documents({'x': 1})
|
||||
@ -1061,10 +1089,16 @@ class Collection(common.BaseObject):
|
||||
MongoDB 4.4 and above.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
- `let` (optional): Map of parameter names and values. Values must be
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
|
||||
:Returns:
|
||||
- An instance of :class:`~pymongo.results.DeleteResult`.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hint`` parameter.
|
||||
.. versionchanged:: 3.6
|
||||
@ -1078,7 +1112,7 @@ class Collection(common.BaseObject):
|
||||
self._delete_retryable(
|
||||
filter, True,
|
||||
write_concern=write_concern,
|
||||
collation=collation, hint=hint, session=session),
|
||||
collation=collation, hint=hint, session=session, let=let),
|
||||
write_concern.acknowledged)
|
||||
|
||||
def find_one(self, filter=None, *args, **kwargs):
|
||||
@ -1889,15 +1923,16 @@ class Collection(common.BaseObject):
|
||||
return options
|
||||
|
||||
def _aggregate(self, aggregation_command, pipeline, cursor_class, session,
|
||||
explicit_session, **kwargs):
|
||||
explicit_session, let=None, **kwargs):
|
||||
cmd = aggregation_command(
|
||||
self, cursor_class, pipeline, kwargs, explicit_session,
|
||||
self, cursor_class, pipeline, kwargs, explicit_session, let,
|
||||
user_fields={'cursor': {'firstBatch': 1}})
|
||||
|
||||
return self.__database.client._retryable_read(
|
||||
cmd.get_cursor, cmd.get_read_preference(session), session,
|
||||
retryable=not cmd._performs_write)
|
||||
|
||||
def aggregate(self, pipeline, session=None, **kwargs):
|
||||
def aggregate(self, pipeline, session=None, let=None, **kwargs):
|
||||
"""Perform an aggregation using the aggregation framework on this
|
||||
collection.
|
||||
|
||||
@ -1944,6 +1979,8 @@ class Collection(common.BaseObject):
|
||||
A :class:`~pymongo.command_cursor.CommandCursor` over the result
|
||||
set.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
.. versionchanged:: 4.0
|
||||
Removed the ``useCursor`` option.
|
||||
.. versionchanged:: 3.9
|
||||
@ -1973,6 +2010,7 @@ class Collection(common.BaseObject):
|
||||
CommandCursor,
|
||||
session=s,
|
||||
explicit_session=session is not None,
|
||||
let=let,
|
||||
**kwargs)
|
||||
|
||||
def aggregate_raw_batches(self, pipeline, session=None, **kwargs):
|
||||
@ -2232,7 +2270,7 @@ class Collection(common.BaseObject):
|
||||
def __find_and_modify(self, filter, projection, sort, upsert=None,
|
||||
return_document=ReturnDocument.BEFORE,
|
||||
array_filters=None, hint=None, session=None,
|
||||
**kwargs):
|
||||
let=None, **kwargs):
|
||||
"""Internal findAndModify helper."""
|
||||
|
||||
common.validate_is_mapping("filter", filter)
|
||||
@ -2243,6 +2281,9 @@ class Collection(common.BaseObject):
|
||||
cmd = SON([("findAndModify", self.__name),
|
||||
("query", filter),
|
||||
("new", return_document)])
|
||||
if let:
|
||||
common.validate_is_mapping("let", let)
|
||||
cmd["let"] = let
|
||||
cmd.update(kwargs)
|
||||
if projection is not None:
|
||||
cmd["fields"] = helpers._fields_list_to_dict(projection,
|
||||
@ -2290,7 +2331,7 @@ class Collection(common.BaseObject):
|
||||
|
||||
def find_one_and_delete(self, filter,
|
||||
projection=None, sort=None, hint=None,
|
||||
session=None, **kwargs):
|
||||
session=None, let=None, **kwargs):
|
||||
"""Finds a single document and deletes it, returning the document.
|
||||
|
||||
>>> db.test.count_documents({'x': 1})
|
||||
@ -2337,7 +2378,13 @@ class Collection(common.BaseObject):
|
||||
- `**kwargs` (optional): additional command arguments can be passed
|
||||
as keyword arguments (for example maxTimeMS can be used with
|
||||
recent server versions).
|
||||
- `let` (optional): Map of parameter names and values. Values must be
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hint`` parameter.
|
||||
.. versionchanged:: 3.6
|
||||
@ -2356,13 +2403,13 @@ class Collection(common.BaseObject):
|
||||
.. versionadded:: 3.0
|
||||
"""
|
||||
kwargs['remove'] = True
|
||||
return self.__find_and_modify(filter, projection, sort,
|
||||
return self.__find_and_modify(filter, projection, sort, let=let,
|
||||
hint=hint, session=session, **kwargs)
|
||||
|
||||
def find_one_and_replace(self, filter, replacement,
|
||||
projection=None, sort=None, upsert=False,
|
||||
return_document=ReturnDocument.BEFORE,
|
||||
hint=None, session=None, **kwargs):
|
||||
hint=None, session=None, let=None, **kwargs):
|
||||
"""Finds a single document and replaces it, returning either the
|
||||
original or the replaced document.
|
||||
|
||||
@ -2412,10 +2459,16 @@ class Collection(common.BaseObject):
|
||||
MongoDB 4.4 and above.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
- `let` (optional): Map of parameter names and values. Values must be
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
- `**kwargs` (optional): additional command arguments can be passed
|
||||
as keyword arguments (for example maxTimeMS can be used with
|
||||
recent server versions).
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
.. versionchanged:: 3.11
|
||||
Added the ``hint`` option.
|
||||
.. versionchanged:: 3.6
|
||||
@ -2436,14 +2489,14 @@ class Collection(common.BaseObject):
|
||||
common.validate_ok_for_replace(replacement)
|
||||
kwargs['update'] = replacement
|
||||
return self.__find_and_modify(filter, projection,
|
||||
sort, upsert, return_document,
|
||||
sort, upsert, return_document, let=let,
|
||||
hint=hint, session=session, **kwargs)
|
||||
|
||||
def find_one_and_update(self, filter, update,
|
||||
projection=None, sort=None, upsert=False,
|
||||
return_document=ReturnDocument.BEFORE,
|
||||
array_filters=None, hint=None, session=None,
|
||||
**kwargs):
|
||||
let=None, **kwargs):
|
||||
"""Finds a single document and updates it, returning either the
|
||||
original or the updated document.
|
||||
|
||||
@ -2533,10 +2586,16 @@ class Collection(common.BaseObject):
|
||||
MongoDB 4.4 and above.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
- `let` (optional): Map of parameter names and values. Values must be
|
||||
constant or closed expressions that do not reference document
|
||||
fields. Parameters can then be accessed as variables in an
|
||||
aggregate expression context (e.g. "$$var").
|
||||
- `**kwargs` (optional): additional command arguments can be passed
|
||||
as keyword arguments (for example maxTimeMS can be used with
|
||||
recent server versions).
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
Added ``let`` parameter.
|
||||
.. versionchanged:: 3.11
|
||||
Added the ``hint`` option.
|
||||
.. versionchanged:: 3.9
|
||||
@ -2561,7 +2620,7 @@ class Collection(common.BaseObject):
|
||||
kwargs['update'] = update
|
||||
return self.__find_and_modify(filter, projection,
|
||||
sort, upsert, return_document,
|
||||
array_filters, hint=hint,
|
||||
array_filters, hint=hint, let=let,
|
||||
session=session, **kwargs)
|
||||
|
||||
def __iter__(self):
|
||||
|
||||
@ -24,7 +24,8 @@ from bson import RE_TYPE, _convert_raw_document_lists_to_streams
|
||||
from bson.code import Code
|
||||
from bson.son import SON
|
||||
from pymongo import helpers
|
||||
from pymongo.common import validate_boolean, validate_is_mapping
|
||||
from pymongo.common import (validate_boolean, validate_is_mapping,
|
||||
validate_is_document_type)
|
||||
from pymongo.collation import validate_collation_or_none
|
||||
from pymongo.errors import (ConnectionFailure,
|
||||
InvalidOperation,
|
||||
@ -140,7 +141,7 @@ class Cursor(object):
|
||||
collation=None, hint=None, max_scan=None, max_time_ms=None,
|
||||
max=None, min=None, return_key=None, show_record_id=None,
|
||||
snapshot=None, comment=None, session=None,
|
||||
allow_disk_use=None):
|
||||
allow_disk_use=None, let=None):
|
||||
"""Create a new cursor.
|
||||
|
||||
Should not be called directly by application developers - see
|
||||
@ -197,6 +198,10 @@ class Cursor(object):
|
||||
if projection is not None:
|
||||
projection = helpers._fields_list_to_dict(projection, "projection")
|
||||
|
||||
if let:
|
||||
validate_is_document_type("let", let)
|
||||
|
||||
self.__let = let
|
||||
self.__spec = spec
|
||||
self.__projection = projection
|
||||
self.__skip = skip
|
||||
@ -370,6 +375,8 @@ class Cursor(object):
|
||||
operators["$explain"] = True
|
||||
if self.__hint:
|
||||
operators["$hint"] = self.__hint
|
||||
if self.__let:
|
||||
operators["let"] = self.__let
|
||||
if self.__comment:
|
||||
operators["$comment"] = self.__comment
|
||||
if self.__max_scan:
|
||||
|
||||
@ -56,109 +56,6 @@
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "aggregate",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"pipeline": [
|
||||
{
|
||||
"$match": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$project": {
|
||||
"_id": 0,
|
||||
"x": "$$x",
|
||||
"y": "$$y",
|
||||
"rand": "$$rand"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1,
|
||||
"x": "foo",
|
||||
"y": {
|
||||
"$literal": "bar"
|
||||
},
|
||||
"rand": {
|
||||
"$rand": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"expectResult": [
|
||||
{
|
||||
"x": "foo",
|
||||
"y": "bar",
|
||||
"rand": {
|
||||
"$$type": "double"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"aggregate": "coll0",
|
||||
"pipeline": [
|
||||
{
|
||||
"$match": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$project": {
|
||||
"_id": 0,
|
||||
"x": "$$x",
|
||||
"y": "$$y",
|
||||
"rand": "$$rand"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1,
|
||||
"x": "foo",
|
||||
"y": {
|
||||
"$literal": "bar"
|
||||
},
|
||||
"rand": {
|
||||
"$rand": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Aggregate with let option and dollar-prefixed $literal value",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0",
|
||||
"topologies": [
|
||||
"single",
|
||||
"replicaset"
|
||||
]
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "aggregate",
|
||||
|
||||
201
test/crud/unified/deleteMany-let.json
Normal file
201
test/crud/unified/deleteMany-let.json
Normal file
@ -0,0 +1,201 @@
|
||||
{
|
||||
"description": "deleteMany-let",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"name": "name"
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"name": "name"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "deleteMany with let option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "deleteMany",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$name",
|
||||
"$$name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"let": {
|
||||
"name": "name"
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"deletedCount": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"delete": "coll0",
|
||||
"deletes": [
|
||||
{
|
||||
"q": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$name",
|
||||
"$$name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"limit": 0
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"name": "name"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deleteMany with let option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "3.6.0",
|
||||
"maxServerVersion": "4.4.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "deleteMany",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$name",
|
||||
"$$name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"let": {
|
||||
"name": "name"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorContains": "'delete.let' is an unknown field",
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"delete": "coll0",
|
||||
"deletes": [
|
||||
{
|
||||
"q": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$name",
|
||||
"$$name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"limit": 0
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"name": "name"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"name": "name"
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"name": "name"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
191
test/crud/unified/deleteOne-let.json
Normal file
191
test/crud/unified/deleteOne-let.json
Normal file
@ -0,0 +1,191 @@
|
||||
{
|
||||
"description": "deleteOne-let",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "deleteOne with let option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "deleteOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"deletedCount": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"delete": "coll0",
|
||||
"deletes": [
|
||||
{
|
||||
"q": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"limit": 1
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "deleteOne with let option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "3.6.0",
|
||||
"maxServerVersion": "4.4.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "deleteOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorContains": "'delete.let' is an unknown field",
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"delete": "coll0",
|
||||
"deletes": [
|
||||
{
|
||||
"q": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"limit": 1
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
148
test/crud/unified/find-let.json
Normal file
148
test/crud/unified/find-let.json
Normal file
@ -0,0 +1,148 @@
|
||||
{
|
||||
"description": "find-let",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "Find with let option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "find",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
"expectResult": [
|
||||
{
|
||||
"_id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"find": "coll0",
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Find with let option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "3.6.0",
|
||||
"maxServerVersion": "4.4.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "find",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"let": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorContains": "Unrecognized field 'let'",
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"find": "coll0",
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"let": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
180
test/crud/unified/findOneAndDelete-let.json
Normal file
180
test/crud/unified/findOneAndDelete-let.json
Normal file
@ -0,0 +1,180 @@
|
||||
{
|
||||
"description": "findOneAndDelete-let",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "findOneAndDelete with let option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "findOneAndDelete",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"findAndModify": "coll0",
|
||||
"query": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remove": true,
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "findOneAndDelete with let option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "4.2.0",
|
||||
"maxServerVersion": "4.4.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "findOneAndDelete",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorContains": "field 'let' is an unknown field",
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"findAndModify": "coll0",
|
||||
"query": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remove": true,
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
197
test/crud/unified/findOneAndReplace-let.json
Normal file
197
test/crud/unified/findOneAndReplace-let.json
Normal file
@ -0,0 +1,197 @@
|
||||
{
|
||||
"description": "findOneAndReplace-let",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "findOneAndReplace with let option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "findOneAndReplace",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"replacement": {
|
||||
"x": "x"
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"findAndModify": "coll0",
|
||||
"query": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"update": {
|
||||
"x": "x"
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": "x"
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "findOneAndReplace with let option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "4.2.0",
|
||||
"maxServerVersion": "4.4.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "findOneAndReplace",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"replacement": {
|
||||
"x": "x"
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorContains": "field 'let' is an unknown field",
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"findAndModify": "coll0",
|
||||
"query": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"update": {
|
||||
"x": "x"
|
||||
},
|
||||
"let": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
217
test/crud/unified/findOneAndUpdate-let.json
Normal file
217
test/crud/unified/findOneAndUpdate-let.json
Normal file
@ -0,0 +1,217 @@
|
||||
{
|
||||
"description": "findOneAndUpdate-let",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "findOneAndUpdate with let option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "findOneAndUpdate",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1,
|
||||
"x": "foo"
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"_id": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"findAndModify": "coll0",
|
||||
"query": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1,
|
||||
"x": "foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": "foo"
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "findOneAndUpdate with let option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "4.2.0",
|
||||
"maxServerVersion": "4.4.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "findOneAndUpdate",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1,
|
||||
"x": "foo"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorContains": "field 'let' is an unknown field",
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"findAndModify": "coll0",
|
||||
"query": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1,
|
||||
"x": "foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
243
test/crud/unified/updateMany-let.json
Normal file
243
test/crud/unified/updateMany-let.json
Normal file
@ -0,0 +1,243 @@
|
||||
{
|
||||
"description": "updateMany-let",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"name": "name"
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"name": "name"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "updateMany with let option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "updateMany",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$name",
|
||||
"$$name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x",
|
||||
"y": "$$y"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"name": "name",
|
||||
"x": "foo",
|
||||
"y": {
|
||||
"$literal": "bar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"matchedCount": 2,
|
||||
"modifiedCount": 2,
|
||||
"upsertedCount": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$name",
|
||||
"$$name"
|
||||
]
|
||||
}
|
||||
},
|
||||
"u": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x",
|
||||
"y": "$$y"
|
||||
}
|
||||
}
|
||||
],
|
||||
"multi": true
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"name": "name",
|
||||
"x": "foo",
|
||||
"y": {
|
||||
"$literal": "bar"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"name": "name",
|
||||
"x": "foo",
|
||||
"y": "bar"
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"name": "name",
|
||||
"x": "foo",
|
||||
"y": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "updateMany with let option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "3.6.0",
|
||||
"maxServerVersion": "4.4.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "updateMany",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"x": "foo"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorContains": "'update.let' is an unknown field",
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": 1
|
||||
},
|
||||
"u": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
],
|
||||
"multi": true
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"x": "foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"name": "name"
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"name": "name"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
215
test/crud/unified/updateOne-let.json
Normal file
215
test/crud/unified/updateOne-let.json
Normal file
@ -0,0 +1,215 @@
|
||||
{
|
||||
"description": "updateOne-let",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "crud-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "UpdateOne with let option",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.0"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "updateOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1,
|
||||
"x": "foo"
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"matchedCount": 1,
|
||||
"modifiedCount": 1,
|
||||
"upsertedCount": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"$expr": {
|
||||
"$eq": [
|
||||
"$_id",
|
||||
"$$id"
|
||||
]
|
||||
}
|
||||
},
|
||||
"u": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"id": 1,
|
||||
"x": "foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": "foo"
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "UpdateOne with let option unsupported (server-side error)",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "3.6.0",
|
||||
"maxServerVersion": "4.4.99"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"name": "updateOne",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"update": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"x": "foo"
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorContains": "'update.let' is an unknown field",
|
||||
"isClientError": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"update": "coll0",
|
||||
"updates": [
|
||||
{
|
||||
"q": {
|
||||
"_id": 1
|
||||
},
|
||||
"u": [
|
||||
{
|
||||
"$set": {
|
||||
"x": "$$x"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"let": {
|
||||
"x": "foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outcome": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "crud-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1
|
||||
},
|
||||
{
|
||||
"_id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -2178,6 +2178,23 @@ class TestCollection(IntegrationTest):
|
||||
with self.assertRaises(NotImplementedError):
|
||||
bool(Collection(self.db, 'test'))
|
||||
|
||||
@client_context.require_version_min(5, 0, 0)
|
||||
def test_helpers_with_let(self):
|
||||
c = self.db.test
|
||||
helpers = [(c.delete_many, ({}, {})), (c.delete_one, ({}, {})),
|
||||
(c.find, ({})), (c.update_many, ({}, {'$inc': {'x': 3}})),
|
||||
(c.update_one, ({}, {'$inc': {'x': 3}})),
|
||||
(c.find_one_and_delete, ({}, {})),
|
||||
(c.find_one_and_replace, ({}, {})),
|
||||
(c.aggregate, ([], {}))]
|
||||
for let in [10, "str"]:
|
||||
for helper, args in helpers:
|
||||
with self.assertRaisesRegex(TypeError,
|
||||
"let must be an instance of dict"):
|
||||
helper(*args, let=let)
|
||||
for helper, args in helpers:
|
||||
helper(*args, let={})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user