[Zope-Checkins] SVN: Zope/branches/zodb-blobs-branch/lib/python/
Initial changes to support the use of multidatabases instead
of Mount.py's homegrown mounting support.
Chris McDonough
chrism at plope.com
Sun Sep 25 13:16:00 EDT 2005
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
More information about the Zope-Checkins
mailing list