[Checkins] SVN: mongopersist/trunk/src/mongopersist/ merge branch find-spec-opt

Adam Groszer agroszer at gmail.com
Mon Mar 5 13:58:20 UTC 2012


Log message for revision 124512:
  merge branch find-spec-opt

Changed:
  U   mongopersist/trunk/src/mongopersist/datamanager.py
  U   mongopersist/trunk/src/mongopersist/interfaces.py
  U   mongopersist/trunk/src/mongopersist/mapping.py
  U   mongopersist/trunk/src/mongopersist/tests/test_datamanager.py
  U   mongopersist/trunk/src/mongopersist/zope/container.py

-=-
Modified: mongopersist/trunk/src/mongopersist/datamanager.py
===================================================================
--- mongopersist/trunk/src/mongopersist/datamanager.py	2012-03-05 13:40:49 UTC (rev 124511)
+++ mongopersist/trunk/src/mongopersist/datamanager.py	2012-03-05 13:58:19 UTC (rev 124512)
@@ -27,7 +27,15 @@
         None, obj,
         (new_doc.get('_py_serial', 0), serialize.u64(obj._p_serial)))
 
+def processSpec(collection, spec):
+    try:
+        adapter = interfaces.IMongoSpecProcessor(None)
+    except TypeError:
+        # by default nothing is registered, handle that case
+        return spec
 
+    return adapter.process(collection, spec)
+
 class Root(UserDict.DictMixin):
 
     database='mongopersist'
@@ -43,7 +51,8 @@
         self._collection_inst = db[self.collection]
 
     def __getitem__(self, key):
-        doc = self._collection_inst.find_one({'name': key})
+        doc = self._collection_inst.find_one(
+            processSpec(self._collection_inst, {'name': key}))
         if doc is None:
             raise KeyError(key)
         return self._jar.load(doc['ref'])
@@ -56,7 +65,8 @@
         self._collection_inst.insert(doc)
 
     def __delitem__(self, key):
-        doc = self._collection_inst.find_one({'name': key})
+        doc = self._collection_inst.find_one(
+            processSpec(self._collection_inst, {'name': key}))
         coll = self._jar._conn[doc['ref'].database][doc['ref'].collection]
         coll.remove(doc['ref'].id)
         self._collection_inst.remove({'name': key})

Modified: mongopersist/trunk/src/mongopersist/interfaces.py
===================================================================
--- mongopersist/trunk/src/mongopersist/interfaces.py	2012-03-05 13:40:49 UTC (rev 124511)
+++ mongopersist/trunk/src/mongopersist/interfaces.py	2012-03-05 13:58:19 UTC (rev 124512)
@@ -166,3 +166,10 @@
 
     def get():
         """Return a mongo data manager."""
+
+
+class IMongoSpecProcessor(zope.interface.Interface):
+    """An adapter to process find/update spec's"""
+
+    def process(collection, spec):
+        """return the processed spec here"""
\ No newline at end of file

Modified: mongopersist/trunk/src/mongopersist/mapping.py
===================================================================
--- mongopersist/trunk/src/mongopersist/mapping.py	2012-03-05 13:40:49 UTC (rev 124511)
+++ mongopersist/trunk/src/mongopersist/mapping.py	2012-03-05 13:58:19 UTC (rev 124512)
@@ -16,6 +16,7 @@
 import pymongo
 
 from mongopersist import interfaces
+from mongopersist.datamanager import processSpec
 
 class MongoCollectionMapping(UserDict.DictMixin, object):
     __mongo_database__ = None
@@ -35,7 +36,8 @@
     def __getitem__(self, key):
         filter = self.__mongo_filter__()
         filter[self.__mongo_mapping_key__] = key
-        doc = self.get_mongo_collection().find_one(filter)
+        coll = self.get_mongo_collection()
+        doc = coll.find_one(processSpec(coll, filter))
         if doc is None:
             raise KeyError(key)
         db_name = self.__mongo_database__ or self._m_jar.default_database
@@ -59,6 +61,7 @@
     def keys(self):
         filter = self.__mongo_filter__()
         filter[self.__mongo_mapping_key__] = {'$ne': None}
+        coll = self.get_mongo_collection()
         return [
             doc[self.__mongo_mapping_key__]
-            for doc in self.get_mongo_collection().find(filter)]
+            for doc in coll.find(processSpec(coll, filter))]

Modified: mongopersist/trunk/src/mongopersist/tests/test_datamanager.py
===================================================================
--- mongopersist/trunk/src/mongopersist/tests/test_datamanager.py	2012-03-05 13:40:49 UTC (rev 124511)
+++ mongopersist/trunk/src/mongopersist/tests/test_datamanager.py	2012-03-05 13:58:19 UTC (rev 124512)
@@ -18,7 +18,7 @@
 import transaction
 from pymongo import dbref, objectid
 
-from mongopersist import testing, datamanager
+from mongopersist import interfaces, testing, datamanager
 
 class Foo(persistent.Persistent):
     def __init__(self, name=None):
@@ -346,6 +346,45 @@
       ('MongoDataManager', 0)
     """
 
+def doctest_processSpec():
+    r"""processSpec(): General test
+
+    A simple helper function that returns the spec itself if no
+    IMongoSpecProcessor adapter is registered.
+
+      >>> from zope.testing.cleanup import CleanUp as PlacelessSetup
+      >>> PlacelessSetup().setUp()
+
+
+      >>> datamanager.processSpec('a_collection', {'life': 42})
+      {'life': 42}
+
+    Now let's register an adapter
+
+      >>> class Processor(object):
+      ...     def __init__(self, context):
+      ...         pass
+      ...     def process(self, collection, spec):
+      ...         print 'passed in:', collection, spec
+      ...         return {'life': 24}
+
+      >>> import zope.interface
+      >>> from zope.component import provideAdapter
+      >>> provideAdapter(Processor, (zope.interface.Interface,), interfaces.IMongoSpecProcessor)
+
+    And see what happens on processSpec:
+
+      >>> datamanager.processSpec('a_collection', {'life': 42})
+      passed in: a_collection {'life': 42}
+      {'life': 24}
+
+    We get the processed spec in return.
+
+
+      >>> PlacelessSetup().tearDown()
+
+    """
+
 def test_suite():
     return doctest.DocTestSuite(
         setUp=testing.setUp, tearDown=testing.tearDown,

Modified: mongopersist/trunk/src/mongopersist/zope/container.py
===================================================================
--- mongopersist/trunk/src/mongopersist/zope/container.py	2012-03-05 13:40:49 UTC (rev 124511)
+++ mongopersist/trunk/src/mongopersist/zope/container.py	2012-03-05 13:58:19 UTC (rev 124512)
@@ -22,6 +22,7 @@
 
 from mongopersist import interfaces, serialize
 from mongopersist.zope import interfaces as zinterfaces
+from mongopersist.datamanager import processSpec
 
 class MongoContained(contained.Contained):
 
@@ -156,7 +157,8 @@
             raise KeyError(key)
         filter = self._m_get_items_filter()
         filter[self._m_mapping_key] = key
-        doc = self.get_collection().find_one(filter, fields=())
+        coll = self.get_collection()
+        doc = coll.find_one(processSpec(coll, filter), fields=())
         if doc is None:
             raise KeyError(key)
         dbref = pymongo.dbref.DBRef(
@@ -197,9 +199,10 @@
     def keys(self):
         filter = self._m_get_items_filter()
         filter[self._m_mapping_key] = {'$ne': None}
+        coll = self.get_collection()
         keys = [
             doc[self._m_mapping_key]
-            for doc in self.get_collection().find(filter)
+            for doc in coll.find(processSpec(coll, filter))
             if not doc[self._m_mapping_key] in self._deleted]
         keys += self._added.keys()
         return keys
@@ -208,7 +211,8 @@
         if spec is None:
             spec  = {}
         spec.update(self._m_get_items_filter())
-        return self.get_collection().find(spec, *args, **kwargs)
+        coll = self.get_collection()
+        return coll.find(processSpec(coll, spec), *args, **kwargs)
 
     def find(self, spec=None, fields=None, *args, **kwargs):
         # If fields were not specified, we only request the oid and the key.
@@ -230,7 +234,8 @@
         if not isinstance(spec_or_id, dict):
             spec_or_id = {'_id': spec_or_id}
         spec_or_id.update(self._m_get_items_filter())
-        return self.get_collection().find_one(spec_or_id, *args, **kwargs)
+        coll = self.get_collection()
+        return coll.find_one(processSpec(coll, spec_or_id), *args, **kwargs)
 
     def find_one(self, spec_or_id=None, fields=None, *args, **kwargs):
         # If fields were not specified, we only request the oid and the key.



More information about the checkins mailing list