Added support for manipulate param in find_and_modify for consistency with find method

This commit is contained in:
Sergey Azovskov 2014-06-05 18:42:27 +06:00 committed by Bernie Hackett
parent c7bbafe373
commit 5ccd02653a
2 changed files with 46 additions and 2 deletions

View File

@ -1622,7 +1622,8 @@ class Collection(common.BaseObject):
return res.get("results")
def find_and_modify(self, query={}, update=None,
upsert=False, sort=None, full_response=False, **kwargs):
upsert=False, sort=None, full_response=False,
manipulate=True, **kwargs):
"""Update and return an object.
This is a thin wrapper around the findAndModify_ command. The
@ -1654,6 +1655,9 @@ class Collection(common.BaseObject):
- `new`: return updated rather than original object
(default ``False``)
- `fields`: see second argument to :meth:`find` (default all)
- `manipulate`: (optional): If True (the default), apply any
outgoing SON manipulators before returning. Do not works when
`full_response` is set to True.
- `**kwargs`: any other options the findAndModify_ command
supports can be passed here.
@ -1720,7 +1724,10 @@ class Collection(common.BaseObject):
if full_response:
return out
else:
return out.get('value')
document = out.get('value')
if manipulate:
document = self.__database._fix_outgoing(document, self)
return document
def __iter__(self):
return self

View File

@ -2350,6 +2350,43 @@ class TestCollection(unittest.TestCase):
for doc in c.find(compile_re=False):
self.assertTrue(isinstance(doc['r'], Regex))
def test_find_and_modify_with_manipulator(self):
class AddCollectionNameManipulator(SONManipulator):
def will_copy(self):
return True
def transform_incoming(self, son, collection):
copy = SON(son)
if 'collection' in copy:
del copy['collection']
return copy
def transform_outgoing(self, son, collection):
copy = SON(son)
copy['collection'] = collection.name
return copy
self.db.add_son_manipulator(AddCollectionNameManipulator())
c = self.db.test
c.drop()
c.insert({'_id': 1, 'i': 1})
# Test correct findAndModify
# With manipulators
self.assertEqual({'_id': 1, 'i': 1, 'collection': 'test'},
c.find_and_modify({'_id': 1}, {'$inc': {'i': 1}}))
self.assertEqual({'_id': 1, 'i': 3, 'collection': 'test'},
c.find_and_modify({'_id': 1}, {'$inc': {'i': 1}},
new=True))
# With out manipulators
self.assertEqual({'_id': 1, 'i': 3},
c.find_and_modify({'_id': 1}, {'$inc': {'i': 1}},
manipulate=False))
self.assertEqual({'_id': 1, 'i': 5},
c.find_and_modify({'_id': 1}, {'$inc': {'i': 1}},
new=True, manipulate=False))
if __name__ == "__main__":
unittest.main()