[Zope-CVS] CVS: Products/AdaptableStorage/zodb - ASConnection.py:1.10 ASDB.py:1.3 ASStorage.py:1.7 public.py:1.3

Shane Hathaway shane@zope.com
Mon, 23 Dec 2002 23:29:35 -0500


Update of /cvs-repository/Products/AdaptableStorage/zodb
In directory cvs.zope.org:/tmp/cvs-serv30532/zodb

Modified Files:
	ASConnection.py ASDB.py ASStorage.py public.py 
Log Message:
Provided a way to configure ObjectMappers, with the intent of making
AdaptableStorage easier to explain.  Added IConfigurableObjectMapper
and converted all the mapper setup code to use it.  Included a
checkConfiguration() method which validates the entire object mapper
tree.  Then converted the DBTab-based configuration to use a mapper
factory, which can point to any mapper factory function installed
anywhere.  Tangents to this:

- Refactored Zope2FS and Zope2SQL to use the same code for setting up
mappers, leaving "holes" for the gateways.

- Added connect() and close() methods to ITPCConnection (which doesn't
technically exist yet since I need to choose a name for it. ;-) )

- Factored out common parts of the SQL gateways.

- Implemented the newKey() method of IKeyedObjectSystem, which will
help ZEO environments, in theory.



=== Products/AdaptableStorage/zodb/ASConnection.py 1.9 => 1.10 ===
--- Products/AdaptableStorage/zodb/ASConnection.py:1.9	Mon Dec 16 18:26:42 2002
+++ Products/AdaptableStorage/zodb/ASConnection.py	Mon Dec 23 23:29:34 2002
@@ -411,8 +411,10 @@
             return None
         return self._db._oid_encoder.decode(oid)
 
-##    def newKey(self):
-##        return self.new_oid()
+    def newKey(self):
+        oid = self.new_oid()
+        keychain = self._db._oid_encoder.decode(oid)
+        return keychain[-1]
 
 
     ### Volitalile object expiration ###


=== Products/AdaptableStorage/zodb/ASDB.py 1.2 => 1.3 ===
--- Products/AdaptableStorage/zodb/ASDB.py:1.2	Fri Dec  6 17:06:51 2002
+++ Products/AdaptableStorage/zodb/ASDB.py	Mon Dec 23 23:29:34 2002
@@ -16,11 +16,28 @@
 $Id$
 """
 
-
 from ZODB.DB import DB, Transaction, cPickle, cStringIO, allocate_lock
 
+from serial_public import IObjectMapper
+
 from ASConnection import ASConnection
+from ASStorage import ASStorage
 from OIDEncoder import OIDEncoder
+from StaticResource import StaticResource
+from interfaces.public import IResourceAccess, IOIDEncoder
+
+
+def callMapperFactory(factory, kw):
+    """Returns (mapper, tpc_conns) given the name of a factory and arguments.
+    """
+    pos = factory.rfind('.')
+    if pos < 0:
+        raise ValueError('factory must be a string containing <module>.<name>')
+    module = factory[:pos]
+    name = factory[pos + 1:]
+    m = __import__(module, {}, {}, (name,))
+    f = getattr(m, name)
+    return f(**kw)
 
 
 class ASDB (DB):
@@ -30,7 +47,10 @@
     klass = ASConnection
 
     # SDH: two extra args.
-    def __init__(self, storage, mapper_resource, oid_encoder=None,
+    def __init__(self, storage,
+                 mapper_resource=None,
+                 factory=None,
+                 oid_encoder=None,
                  pool_size=7,
                  cache_size=400,
                  cache_deactivate_after=60,
@@ -40,6 +60,23 @@
                  ):
         """Create an object database.
         """
+        if mapper_resource is None:
+            if factory is not None:
+                # Use a mapper factory
+                mapper, tpc_conns = callMapperFactory(factory)
+                assert IObjectMapper.isImplementedBy(mapper)
+                mapper_resource = StaticResource(mapper)
+            else:
+                if isinstance(storage, ASStorage):
+                    # Use the mapper from the storage
+                    mapper_resource = storage.getMapperResource()
+                else:
+                    raise RuntimeError('No mapper or factory specified')
+        else:
+            # mapper_resource was specified
+            assert IResourceAccess.isImplementedBy(mapper_resource)
+            assert factory is None
+        
         # Allocate locks:
         l=allocate_lock()
         self._a=l.acquire
@@ -64,6 +101,8 @@
 
         if oid_encoder is None:
             oid_encoder = OIDEncoder()
+        else:
+            assert IOIDEncoder.isImplementedBy(oid_encoder)
         self._oid_encoder = oid_encoder
         self._mapper_resource = mapper_resource
 


=== Products/AdaptableStorage/zodb/ASStorage.py 1.6 => 1.7 ===
--- Products/AdaptableStorage/zodb/ASStorage.py:1.6	Mon Dec  9 13:25:29 2002
+++ Products/AdaptableStorage/zodb/ASStorage.py	Mon Dec 23 23:29:34 2002
@@ -25,22 +25,32 @@
 
 from consts import SERIAL0, SERIAL1, DEBUG
 from OIDEncoder import OIDEncoder
+from interfaces.public import IResourceAccess, IOIDEncoder
 
 
 class ASStorage(BaseStorage.BaseStorage):
 
     def __init__(self, mapper_resource, tpc_conns=(),
                  oid_encoder=None, name=''):
+        assert IResourceAccess.isImplementedBy(mapper_resource)
         self._mapper_resource = mapper_resource
         if oid_encoder is None:
             oid_encoder = OIDEncoder()
+        else:
+            assert IOIDEncoder.isImplementedBy(oid_encoder)
         self._oid_encoder = oid_encoder
         self._tpc_conns = tpc_conns
         sort_keys = []
         names = []
-        for c in tpc_conns:
-            sort_keys.append(c.sortKey())
-            names.append(c.getName())
+        try:
+            for c in tpc_conns:
+                c.connect()
+                sort_keys.append(c.sortKey())
+                names.append(c.getName())
+        except:
+            for c in tpc_conns:
+                c.close()
+            raise
         self._sort_key = tuple(sort_keys)
         if not name:
             name = 'AdaptableStorage: ' + ', '.join(names)
@@ -56,6 +66,9 @@
     def sortKey(self):
         return self._sort_key
 
+    def getMapperResource(self):
+        return self._mapper_resource
+
     def hashSerial(self, serial):
         """Returns an 8-byte checksum.
         """
@@ -152,7 +165,12 @@
         return new_hash
 
     def new_oid(self):
-        raise POSException.StorageError("new_oid() is disabled.")
+        # Try to use the root keychain generator to make a keychain.
+        root_mapper = self._mapper_resource.access(self)
+        kgen = root_mapper.getKeychainGenerator()
+        event = MapperEvent(root_mapper, ())
+        keychain = kgen.makeKeychain(event, None, 1)
+        return self._oid_encoder.encode(keychain)
 
     def _clear_temp(self):
         pass
@@ -182,6 +200,8 @@
         return ''
 
     def close(self):
+        for c in self._tpc_conns:
+            c.close()
         self._mapper_resource.release(self)
 
 


=== Products/AdaptableStorage/zodb/public.py 1.2 => 1.3 ===
--- Products/AdaptableStorage/zodb/public.py:1.2	Fri Dec 13 15:42:03 2002
+++ Products/AdaptableStorage/zodb/public.py	Mon Dec 23 23:29:34 2002
@@ -18,7 +18,7 @@
 
 from interfaces.public import *
 from ASConnection import ASConnection
-from ASDB import ASDB
+from ASDB import ASDB, callMapperFactory
 from ASStorage import ASStorage
 from OIDEncoder import OIDEncoder
 from StaticResource import StaticResource