fixes #119: correctly filter query results

This commit is contained in:
Davide Alberani 2016-05-11 21:09:57 +02:00
parent 0c664a955d
commit 410ea028f3
2 changed files with 61 additions and 56 deletions

View file

@ -22,6 +22,58 @@ from bson.objectid import ObjectId
re_objectid = re.compile(r'[0-9a-f]{24}') re_objectid = re.compile(r'[0-9a-f]{24}')
_force_conversion = {
'seq_hex': str,
'persons.seq_hex': str
}
def convert_obj(obj):
"""Convert an object in a format suitable to be stored in MongoDB.
:param obj: object to convert
:return: object that can be stored in MongoDB.
"""
if obj is None:
return None
if isinstance(obj, bool):
return obj
try:
return ObjectId(obj)
except:
pass
try:
i_obj = int(obj)
if i_obj > 2**64 - 1:
return obj
return i_obj
except:
pass
return obj
def convert(seq):
"""Convert an object to a format suitable to be stored in MongoDB,
descending lists, tuples and dictionaries (a copy is returned).
:param seq: sequence or object to convert
:return: object that can be stored in MongoDB.
"""
if isinstance(seq, dict):
d = {}
for key, item in seq.iteritems():
if key in _force_conversion:
d[key] = _force_conversion[key](item)
else:
d[key] = convert(item)
return d
if isinstance(seq, (list, tuple)):
return [convert(x) for x in seq]
return convert_obj(seq)
class EventManDB(object): class EventManDB(object):
"""MongoDB connector.""" """MongoDB connector."""
db = None db = None
@ -36,11 +88,6 @@ class EventManDB(object):
'increment': '$inc' 'increment': '$inc'
} }
_force_conversion = {
'seq_hex': str,
'persons.seq_hex': str
}
def __init__(self, url=None, dbName='eventman'): def __init__(self, url=None, dbName='eventman'):
"""Initialize the instance, connecting to the database. """Initialize the instance, connecting to the database.
@ -70,50 +117,6 @@ class EventManDB(object):
self.db = self.connection[self._dbName] self.db = self.connection[self._dbName]
return self.db return self.db
def convert_obj(self, obj):
"""Convert an object in a format suitable to be stored in MongoDB.
:param obj: object to convert
:return: object that can be stored in MongoDB.
"""
if obj is None:
return None
if isinstance(obj, bool):
return obj
try:
return ObjectId(obj)
except:
pass
try:
i_obj = int(obj)
if i_obj > 2**64 - 1:
return obj
return i_obj
except:
pass
return obj
def convert(self, seq):
"""Convert an object in a format suitable to be stored in MongoDB,
descending lists, tuples and dictionaries (a copy is returned).
:param seq: sequence or object to convert
:return: object that can be stored in MongoDB.
"""
if isinstance(seq, dict):
d = {}
for key, item in seq.iteritems():
if key in self._force_conversion:
d[key] = self._force_conversion[key](item)
else:
d[key] = self.convert(item)
return d
if isinstance(seq, (list, tuple)):
return [self.convert(x) for x in seq]
return self.convert_obj(seq)
def get(self, collection, _id): def get(self, collection, _id):
"""Get a single document with the specified `_id`. """Get a single document with the specified `_id`.
@ -125,7 +128,7 @@ class EventManDB(object):
:return: the document with the given `_id` :return: the document with the given `_id`
:rtype: dict :rtype: dict
""" """
results = self.query(collection, self.convert({'_id': _id})) results = self.query(collection, convert({'_id': _id}))
return results and results[0] or {} return results and results[0] or {}
def query(self, collection, query=None): def query(self, collection, query=None):
@ -140,7 +143,7 @@ class EventManDB(object):
:rtype: list :rtype: list
""" """
db = self.connect() db = self.connect()
query = self.convert(query or {}) query = convert(query or {})
return list(db[collection].find(query)) return list(db[collection].find(query))
def add(self, collection, data): def add(self, collection, data):
@ -155,7 +158,7 @@ class EventManDB(object):
:rtype: dict :rtype: dict
""" """
db = self.connect() db = self.connect()
data = self.convert(data) data = convert(data)
_id = db[collection].insert(data) _id = db[collection].insert(data)
return self.get(collection, _id) return self.get(collection, _id)
@ -171,7 +174,7 @@ class EventManDB(object):
:rtype: bool :rtype: bool
""" """
db = self.connect() db = self.connect()
data = self.convert(data) data = convert(data)
ret = db[collection].update(data, {'$set': data}, upsert=True) ret = db[collection].update(data, {'$set': data}, upsert=True)
return ret['updatedExisting'] return ret['updatedExisting']
@ -209,8 +212,8 @@ class EventManDB(object):
:rtype: tuple of (bool, dict) :rtype: tuple of (bool, dict)
""" """
db = self.connect() db = self.connect()
data = self.convert(data or {}) data = convert(data or {})
_id_or_query = self.convert(_id_or_query) _id_or_query = convert(_id_or_query)
if isinstance(_id_or_query, (list, tuple)): if isinstance(_id_or_query, (list, tuple)):
_id_or_query = {'$or': self._buildSearchPattern(data, _id_or_query)} _id_or_query = {'$or': self._buildSearchPattern(data, _id_or_query)}
elif not isinstance(_id_or_query, dict): elif not isinstance(_id_or_query, dict):
@ -243,6 +246,6 @@ class EventManDB(object):
db = self.connect() db = self.connect()
if not isinstance(_id_or_query, dict): if not isinstance(_id_or_query, dict):
_id_or_query = {'_id': _id_or_query} _id_or_query = {'_id': _id_or_query}
_id_or_query = self.convert(_id_or_query) _id_or_query = convert(_id_or_query)
db[collection].remove(_id_or_query) db[collection].remove(_id_or_query)

View file

@ -169,11 +169,13 @@ class CollectionHandler(BaseHandler):
:param results: the list to be filtered :param results: the list to be filtered
:type results: list :type results: list
:param params: a dictionary of items that must all be present in an original list item to be included in the return :param params: a dictionary of items that must all be present in an original list item to be included in the return
:type params: dict
:return: list of items that have all the keys with the same values as params :return: list of items that have all the keys with the same values as params
:rtype: list""" :rtype: list"""
if not params: if not params:
return results return results
params = backend.convert(params)
filtered = [] filtered = []
for result in results: for result in results:
add = True add = True