Log message for revision 38625: Initial changes to support the use of multidatabases instead of Mount.py's homegrown mounting support.
Changed: U Zope/branches/zodb-blobs-branch/lib/python/DBTab/DBTab.py U Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/Mount.py U Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/MountedObject.py U Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/tests/testMountPoint.py U Zope/branches/zodb-blobs-branch/lib/python/Zope2/Startup/datatypes.py -=- Modified: Zope/branches/zodb-blobs-branch/lib/python/DBTab/DBTab.py =================================================================== --- Zope/branches/zodb-blobs-branch/lib/python/DBTab/DBTab.py 2005-09-25 17:02:02 UTC (rev 38624) +++ Zope/branches/zodb-blobs-branch/lib/python/DBTab/DBTab.py 2005-09-25 17:15:59 UTC (rev 38625) @@ -17,7 +17,6 @@ """ import sys -from thread import allocate_lock from ZODB.ActivityMonitor import ActivityMonitor import Globals @@ -31,11 +30,10 @@ def __init__(self, db_factories, mount_paths): self._started = 0 - self.opened = {} # { name -> Database instance } - self.lock = allocate_lock() self.db_factories = db_factories # { name -> DatabaseFactory } self.mount_paths = mount_paths # { virtual path -> name } + self.databases = {} def startup(self): """Opens the databases set to open_at_startup.""" @@ -76,45 +74,25 @@ def getDatabase(self, mount_path=None, name=None, is_root=0): """Returns an opened database. Requires either mount_path or name. """ - self.startup() + self.startup() # XXX get rid of this if name is None: - if mount_path is None: - raise ValueError('Either mount_path or name is required') - name = self.mount_paths.get(mount_path) - if name is None: - self._mountPathError(mount_path) - db = self.opened.get(name) + name = self.getName(mount_path) + db = self.databases.get(name, None) if db is None: - if not self.db_factories.has_key(name): - raise KeyError('%s is not a configured database' % repr(name)) - self.lock.acquire() - try: - # Check again, since the database may have been created - # by another thread before the lock was acquired. - db = self.opened.get(name) - if db is None: - db = self._createDatabase(name, is_root) - finally: - self.lock.release() + factory = self.getDatabaseFactory(name=name) + db = factory.open(name, self.databases) return db def getDatabaseFactory(self, mount_path=None, name=None): if name is None: - if mount_path is None: - raise ValueError('Either mount_path or name is required') - name = self.mount_paths.get(mount_path) - if name is None: - self._mountPathError(mount_path) + name = self.getName(mount_path) + if not self.db_factories.has_key(name): + raise KeyError('%s is not a configured database' % repr(name)) return self.db_factories[name] + def getName(self, mount_path): + name = self.mount_paths.get(mount_path) + if name is None: + self._mountPathError(mount_path) + return name - def _createDatabase(self, name, is_root): - factory = self.db_factories[name] - db = factory.open() - self.opened[name] = db - if not is_root: - Globals.opened.append(db) - # If it is the root database, Zope will add the database to - # Globals.opened. A database should not be listed twice. - return db - Modified: Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/Mount.py =================================================================== --- Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/Mount.py 2005-09-25 17:02:02 UTC (rev 38624) +++ Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/Mount.py 2005-09-25 17:15:59 UTC (rev 38625) @@ -69,17 +69,9 @@ def _getMountedConnection(self, anyjar): db_name = self._getDBName() - conn = anyjar._getMountedConnection(db_name) - if conn is None: - root_conn = anyjar._getRootConnection() - if db_name == self._getRootDBName(): - conn = root_conn - else: - conn = self._getDB().open(version=root_conn.getVersion()) - root_conn._addMountedConnection(db_name, conn) + conn = anyjar.get_connection(db_name) return conn - def _getOrOpenObject(self, parent): t = self._v_data if t is not None: @@ -143,95 +135,3 @@ traceback.print_tb(exc[2], 100, f) self._v_connect_error = (exc[0], exc[1], f.getvalue()) exc = None - - - -class ConnectionPatches: - # Changes to Connection.py that might fold into ZODB - - _root_connection = None - _mounted_connections = None - - def _getRootConnection(self): - root_conn = self._root_connection - if root_conn is None: - return self - else: - return root_conn - - def _getMountedConnection(self, name): - conns = self._getRootConnection()._mounted_connections - if conns is None: - return None - else: - return conns.get(name) - - def _addMountedConnection(self, name, conn): - if conn._root_connection is not None: - raise ValueError, 'Connection %s is already mounted' % repr(conn) - root_conn = self._getRootConnection() - conns = root_conn._mounted_connections - if conns is None: - conns = {} - root_conn._mounted_connections = conns - if conns.has_key(name): - raise KeyError, 'A connection named %s already exists' % repr(name) - conn._root_connection = root_conn - conns[name] = conn - - def _setDB(self, odb, *args, **kw): - self._real_setDB(odb, *args, **kw) - conns = self._mounted_connections - if conns: - for conn in conns.values(): - conn._setDB(conn._db, *args, **kw) - - def close(self): - if self._root_connection is not None: - raise RuntimeError("Should not close mounted connections directly") - conns = self._mounted_connections - if conns: - for conn in conns.values(): - # Notify the activity monitor - db = conn.db() - f = getattr(db, 'getActivityMonitor', None) - if f is not None: - am = f() - if am is not None: - am.closedConnection(conn) - conn.cacheGC() # This is a good time to do some GC - # XXX maybe we ought to call the close callbacks. - conn._storage = conn._normal_storage = None - conn._savepoint_storage = None - conn.new_oid = conn._opened = None - conn._debug_info = () - - # collector #1350: ensure that the connection is unregistered - # from the transaction manager (XXX API method?) - if conn._synch: - conn.transaction_manager.unregisterSynch(conn) - - # The mounted connection keeps a reference to - # its database, but nothing else. - # Note that mounted connections can not operate - # independently, so don't use _closeConnection() to - # return them to the pool. Only the root connection - # should be returned. - - # Close this connection only after the mounted connections - # have been closed. Otherwise, this connection gets returned - # to the pool too early and another thread might use this - # connection before the mounted connections have all been - # closed. - self._real_close() - -if 1: - # patch Connection.py. - from ZODB.Connection import Connection - Connection._real_setDB = Connection._setDB - Connection._real_close = Connection.close - - for k, v in ConnectionPatches.__dict__.items(): - if not k.startswith('__'): - setattr(Connection, k, v) - Modified: Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/MountedObject.py =================================================================== --- Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/MountedObject.py 2005-09-25 17:02:02 UTC (rev 38624) +++ Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/MountedObject.py 2005-09-25 17:15:59 UTC (rev 38625) @@ -107,7 +107,7 @@ obj = context.unrestrictedTraverse(id) # Commit a subtransaction to assign the new object to # the correct database. - transaction.commit(1) + transaction.savepoint() return obj @@ -133,6 +133,14 @@ id = path.split('/')[-1] MountPoint.__init__(self, id) + def _getMountedConnection(self, anyjar): + db_name = self._getDBName() + try: + conn = anyjar.get_connection(db_name) + except KeyError: + conn = self._getDB().open() + return conn + def mount_error_(self): return self._v_connect_error @@ -177,7 +185,7 @@ obj = Application() root[real_root] = obj # Get it into the database - transaction.commit(1) + transaction.savepoint() else: raise Modified: Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/tests/testMountPoint.py =================================================================== --- Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/tests/testMountPoint.py 2005-09-25 17:02:02 UTC (rev 38624) +++ Zope/branches/zodb-blobs-branch/lib/python/Products/ZODBMountPoint/tests/testMountPoint.py 2005-09-25 17:15:59 UTC (rev 38625) @@ -107,7 +107,7 @@ self.app._p_jar.close() del self.app del self.db - for db in self.conf.opened.values(): + for db in self.conf.databases.values(): db.close() del self.conf Modified: Zope/branches/zodb-blobs-branch/lib/python/Zope2/Startup/datatypes.py =================================================================== --- Zope/branches/zodb-blobs-branch/lib/python/Zope2/Startup/datatypes.py 2005-09-25 17:02:02 UTC (rev 38624) +++ Zope/branches/zodb-blobs-branch/lib/python/Zope2/Startup/datatypes.py 2005-09-25 17:15:59 UTC (rev 38625) @@ -149,18 +149,18 @@ mount_points[point] = name from DBTab.DBTab import DBTab section.dbtab = DBTab(mount_factories, mount_points) - + return section class ZopeDatabase(ZODBDatabase): """ A ZODB database datatype that can handle an extended set of attributes for use by DBTab """ - def createDB(self): - return ZODBDatabase.open(self) + def createDB(self, database_name, databases): + return ZODBDatabase.open(self, database_name, databases) - def open(self): - DB = self.createDB() + def open(self, database_name, databases): + DB = self.createDB(database_name, databases) if self.config.connection_class: # set the connection class DB.klass = self.config.connection_class _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins