[Zodb-checkins] CVS: Zope3/src/zodb - serialize.py:1.7 interfaces.py:1.5 export.py:1.3 connection.py:1.4

Jeremy Hylton jeremy@zope.com
Tue, 28 Jan 2003 11:42:29 -0500


Update of /cvs-repository/Zope3/src/zodb
In directory cvs.zope.org:/tmp/cvs-serv21250

Modified Files:
	serialize.py interfaces.py export.py connection.py 
Log Message:
A bit of simple refactoring.

Move TmpStore definition below Connection definition in
connection.py.  The namegeddon merged two files in an unfortunate
order.

Rename Connection __getitem__() to get() and fixup all uses.

Define IAppConnection.


=== Zope3/src/zodb/serialize.py 1.6 => 1.7 ===
--- Zope3/src/zodb/serialize.py:1.6	Fri Jan 24 18:20:58 2003
+++ Zope3/src/zodb/serialize.py	Tue Jan 28 11:42:25 2003
@@ -251,7 +251,7 @@
         obj = self._cache.get(oid)
         if obj is not None:
             return obj
-        return self._conn[oid]
+        return self._conn.get(oid)
 
 class CopyReference:
     def __init__(self, ref):


=== Zope3/src/zodb/interfaces.py 1.4 => 1.5 ===
--- Zope3/src/zodb/interfaces.py:1.4	Fri Jan 24 18:20:58 2003
+++ Zope3/src/zodb/interfaces.py	Tue Jan 28 11:42:25 2003
@@ -231,13 +231,19 @@
     o A reference to an object in a different database connection.
     """
 
+class IAppConnection(Interface):
+    """Interface exported by database connection to applications."""
+
+    def root():
+        """Return the root of the database."""
+
 class IConnection(Interface):
     """Interface required of Connection by ZODB DB.
 
     The Connection also implements IPersistentDataManager.
     """
 
-    def reset(version):
+    def reset(version=""):
         """Reset connection to use specified version."""
 
     def getVersion():
@@ -249,10 +255,6 @@
         This marks the oid as invalid, but doesn't actually invalidate
         it.  The object data will be actually invalidated at certain
         transaction boundaries.
-
-        XXX The code suggests that invalidate() may sometimes be
-        called with None as the oid, which would mean the "entire
-        transaction" is invalidated.
         """
 
     def close():


=== Zope3/src/zodb/export.py 1.2 => 1.3 ===
--- Zope3/src/zodb/export.py:1.2	Wed Dec 25 09:12:16 2002
+++ Zope3/src/zodb/export.py	Tue Jan 28 11:42:25 2003
@@ -84,7 +84,7 @@
         t.savepoint()
         # Return the root imported object.
         if L:
-            return self[L[0]]
+            return self.get(L[0])
         else:
             return None
 


=== Zope3/src/zodb/connection.py 1.3 => 1.4 ===
--- Zope3/src/zodb/connection.py:1.3	Tue Jan 21 13:18:44 2003
+++ Zope3/src/zodb/connection.py	Tue Jan 28 11:42:25 2003
@@ -11,139 +11,6 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-from zodb import interfaces
-from zodb.utils import p64, u64, Set, z64
-
-import tempfile
-
-class TmpStore:
-    """A storage to support savepoints."""
-
-    _bver = ''
-
-    def __init__(self, base_version):
-        self._transaction = None
-        if base_version:
-            self._bver = base_version
-        self._file = tempfile.TemporaryFile()
-        # _pos: current file position
-        # _tpos: file position at last commit point
-        self._pos = self._tpos = 0
-        # _index: map oid to pos of last committed version
-        self._index = {}
-        # _tindex: map oid to pos for new updates
-        self._tindex = {}
-        self._created = Set()
-        self._db = None
-
-    def close(self):
-        # XXX Is this necessary?
-        self._file.close()
-
-    def getName(self):
-        return self._db.getName()
-
-    def getSize(self):
-        return self._pos
-
-    def load(self, oid, version):
-        pos = self._index.get(oid, None)
-        if pos is None:
-            return self._storage.load(oid, self._bver)
-        self._file.seek(pos)
-        h = self._file.read(24)
-        if h[:8] != oid:
-            raise interfaces.StorageSystemError('Bad temporary storage')
-        size = u64(h[16:])
-        serial = h[8:16]
-        return self._file.read(size), serial
-
-    # XXX clarify difference between self._storage & self._db._storage
-
-    def modifiedInVersion(self, oid):
-        if self._index.has_key(oid):
-            return self._bver
-        return self._db._storage.modifiedInVersion(oid)
-
-    def new_oid(self):
-        return self._db._storage.new_oid()
-
-    def registerDB(self, db):
-        self._db = db
-        self._storage = db._storage
-
-    def store(self, oid, serial, data, version, transaction):
-        if transaction is not self._transaction:
-            raise interfaces.StorageTransactionError(self, transaction)
-        self._file.seek(self._pos)
-        l = len(data)
-        if serial is None:
-            serial = z64
-        self._file.write(oid + serial + p64(l))
-        self._file.write(data)
-        self._tindex[oid] = self._pos
-        self._pos += l + 24
-        return serial
-
-    def tpc_abort(self, transaction):
-        if transaction is not self._transaction:
-            return
-        self._tindex.clear()
-        self._transaction = None
-        self._pos = self._tpos
-
-    def tpc_begin(self, transaction):
-        if self._transaction is transaction:
-            return
-        self._transaction = transaction
-        self._tindex.clear() # Just to be sure!
-        self._pos = self._tpos
-
-    def tpc_vote(self, transaction):
-        pass
-
-    def tpc_finish(self, transaction, f=None):
-        if transaction is not self._transaction:
-            return
-        if f is not None:
-            f()
-        undo = UndoInfo(self, self._tpos, self._index.copy())
-        self._index.update(self._tindex)
-        self._tindex.clear()
-        self._tpos = self._pos
-        return undo
-
-    def undoLog(self, first, last, filter=None):
-        return ()
-
-    def versionEmpty(self, version):
-        # XXX what is this supposed to do?
-        if version == self._bver:
-            return len(self._index)
-
-    def rollback(self, pos, index):
-        if not (pos <= self._tpos <= self._pos):
-            msg = "transaction rolled back to early point"
-            raise interfaces.RollbackError(msg)
-        self._tpos = self._pos = pos
-        self._index = index
-        self._tindex.clear()
-
-class UndoInfo:
-
-    def __init__(self, store, pos, index):
-        self._store = store
-        self._pos = pos
-        self._index = index
-
-    def current(self, cur_store):
-        """Return true if the UndoInfo is for cur_store."""
-        return self._store is cur_store
-
-    def rollback(self):
-        self._store.rollback(self._pos, self._index)
-
-
 """Database connection support
 
 The Connection object serves as a data manager.  ZODB is organized so
@@ -176,28 +43,27 @@
 $Id$
 """
 
-from zodb import export
-
-from zodb.conflict import ResolvedSerial
-from zodb.interfaces import IConnection
-from zodb.interfaces import ConflictError, RollbackError
-from zodb.serialize import ConnectionObjectReader, \
-     getClassMetadata, ObjectWriter
-from zodb.utils import u64, Set, z64
-
-from transaction import get_transaction
-from persistence.cache import Cache
-from persistence.interfaces import IPersistentDataManager
-
 import cPickle
 from cStringIO import StringIO
+import logging
 import sys
+import tempfile
 import threading
 import time
 from types import StringType, ClassType, TupleType
-import logging
 
-class Connection(export.ExportImport):
+from zodb import interfaces
+from zodb.conflict import ResolvedSerial
+from zodb.export import ExportImport
+from zodb.interfaces import IConnection, ConflictError
+from zodb.serialize import ConnectionObjectReader, ObjectWriter
+from zodb.utils import p64, u64, Set, z64
+
+from transaction import get_transaction
+from persistence.cache import Cache
+from persistence.interfaces import IPersistentDataManager
+
+class Connection(ExportImport):
     """Object managers for individual object space.
 
     An object space is a version of collection of objects.  In a
@@ -208,25 +74,19 @@
     storage.
     """
 
-    # instance variable that holds a TmpStore object used by sub-transactions
-    _tmp = None
-
-    # instance variable is None, or time.time() when opened
-    _opened = None
-
-    # Experimental. Other connections can register to be closed
-    # when we close by putting something here.
-
     __implements__ = IConnection, IPersistentDataManager
 
     def __init__(self, db, version='', cache_size=400):
         self._db = db
         self._storage = db._storage
-        self.new_oid = db._storage.new_oid
         self._version = version
         self._cache = cache = Cache(cache_size)
         self._reader = ConnectionObjectReader(self, self._cache)
         self._logger = logging.getLogger("zodb")
+        # a TmpStore object used by sub-transactions
+        self._tmp = None
+        # None, or time.time() when opened
+        self._opened = None
 
         # _invalidated queues invalidate messages delivered from the DB
         # _inv_lock prevents one thread from modifying the set while
@@ -241,8 +101,11 @@
         self._modified = Set()
         self._created = Set()
 
-    def getVersion(self):
-        return self._version
+        # new_oid is used by serialize
+        self.new_oid = self._storage.new_oid
+
+    def root(self):
+        return self.get(z64)
 
     def modifiedInVersion(self, oid):
         try:
@@ -250,10 +113,7 @@
         except KeyError:
             return self._version
 
-    def root(self):
-        return self.__getitem__(z64)
-
-    def __getitem__(self, oid):
+    def get(self, oid):
         # assume that a cache cannot store None as a valid object
         object = self._cache.get(oid)
         if object is not None:
@@ -276,8 +136,7 @@
         return object
 
     ######################################################################
-    # IPersistentDataManager
-    # requires the next three methods:
+    # IPersistentDataManager requires the next three methods:
     # setstate(), register(), mtime()
 
     def setstate(self, object):
@@ -344,6 +203,13 @@
         # required by the IPersistentDataManager interface, but unimplemented
         return None
 
+    ######################################################################
+    # IConnection requires the next three methods:
+    # getVersion(), reset(), cacheGC(), invalidate(), close()
+
+    def getVersion(self):
+        return self._version
+
     def reset(self, version=""):
         if version != self._version:
             # XXX I think it's necessary to clear the cache here, because
@@ -360,6 +226,20 @@
     def cacheGC(self):
         self._cache.incrgc()
 
+    def invalidate(self, oid):
+        """Invalidate a particular oid
+
+        This marks the oid as invalid, but doesn't actually invalidate
+        it.  The object data will be actually invalidated at certain
+        transaction boundaries.
+        """
+        assert oid is not None
+        self._inv_lock.acquire()
+        try:
+            self._invalidated.add(oid)
+        finally:
+            self._inv_lock.release()
+
     def close(self):
         self._cache.incrgc()
         self.applyCloseCallbacks()
@@ -396,20 +276,6 @@
     def cacheMinimize(self, dt=0):
         self._cache.minimize(dt)
 
-    def invalidate(self, oid):
-        """Invalidate a particular oid
-
-        This marks the oid as invalid, but doesn't actually invalidate
-        it.  The object data will be actually invalidated at certain
-        transaction boundaries.
-        """
-        assert oid is not None
-        self._inv_lock.acquire()
-        try:
-            self._invalidated.add(oid)
-        finally:
-            self._inv_lock.release()
-
     def _flush_invalidations(self):
         self._inv_lock.acquire()
         try:
@@ -425,7 +291,7 @@
         self._logger.debug("commit object %s", u64(oid))
 
         if oid is None or object._p_jar is not self:
-            oid = self.new_oid()
+            oid = self._storage.new_oid()
             object._p_jar = self
             object._p_oid = oid
             self._created.add(oid)
@@ -658,6 +524,133 @@
     def rollback(self):
         if not self._tmp_undo.current(self._conn._storage):
             msg = "savepoint has already been committed"
-            raise RollbackError(msg)
+            raise interfaces.RollbackError(msg)
         self._tmp_undo.rollback()
         self._conn._cache.invalidateMany(self._conn._modified)
+
+class TmpStore:
+    """A storage to support savepoints."""
+
+    _bver = ''
+
+    def __init__(self, base_version):
+        self._transaction = None
+        if base_version:
+            self._bver = base_version
+        self._file = tempfile.TemporaryFile()
+        # _pos: current file position
+        # _tpos: file position at last commit point
+        self._pos = self._tpos = 0
+        # _index: map oid to pos of last committed version
+        self._index = {}
+        # _tindex: map oid to pos for new updates
+        self._tindex = {}
+        self._created = Set()
+        self._db = None
+
+    def close(self):
+        # XXX Is this necessary?
+        self._file.close()
+
+    def getName(self):
+        return self._db.getName()
+
+    def getSize(self):
+        return self._pos
+
+    def load(self, oid, version):
+        pos = self._index.get(oid, None)
+        if pos is None:
+            return self._storage.load(oid, self._bver)
+        self._file.seek(pos)
+        h = self._file.read(24)
+        if h[:8] != oid:
+            raise interfaces.StorageSystemError('Bad temporary storage')
+        size = u64(h[16:])
+        serial = h[8:16]
+        return self._file.read(size), serial
+
+    # XXX clarify difference between self._storage & self._db._storage
+
+    def modifiedInVersion(self, oid):
+        if self._index.has_key(oid):
+            return self._bver
+        return self._db._storage.modifiedInVersion(oid)
+
+    def new_oid(self):
+        return self._db._storage.new_oid()
+
+    def registerDB(self, db):
+        self._db = db
+        self._storage = db._storage
+
+    def store(self, oid, serial, data, version, transaction):
+        if transaction is not self._transaction:
+            raise interfaces.StorageTransactionError(self, transaction)
+        self._file.seek(self._pos)
+        l = len(data)
+        if serial is None:
+            serial = z64
+        self._file.write(oid + serial + p64(l))
+        self._file.write(data)
+        self._tindex[oid] = self._pos
+        self._pos += l + 24
+        return serial
+
+    def tpc_abort(self, transaction):
+        if transaction is not self._transaction:
+            return
+        self._tindex.clear()
+        self._transaction = None
+        self._pos = self._tpos
+
+    def tpc_begin(self, transaction):
+        if self._transaction is transaction:
+            return
+        self._transaction = transaction
+        self._tindex.clear() # Just to be sure!
+        self._pos = self._tpos
+
+    def tpc_vote(self, transaction):
+        pass
+
+    def tpc_finish(self, transaction, f=None):
+        if transaction is not self._transaction:
+            return
+        if f is not None:
+            f()
+        undo = UndoInfo(self, self._tpos, self._index.copy())
+        self._index.update(self._tindex)
+        self._tindex.clear()
+        self._tpos = self._pos
+        return undo
+
+    def undoLog(self, first, last, filter=None):
+        return ()
+
+    def versionEmpty(self, version):
+        # XXX what is this supposed to do?
+        if version == self._bver:
+            return len(self._index)
+
+    def rollback(self, pos, index):
+        if not (pos <= self._tpos <= self._pos):
+            msg = "transaction rolled back to early point"
+            raise interfaces.RollbackError(msg)
+        self._tpos = self._pos = pos
+        self._index = index
+        self._tindex.clear()
+
+class UndoInfo:
+
+    def __init__(self, store, pos, index):
+        self._store = store
+        self._pos = pos
+        self._index = index
+
+    def current(self, cur_store):
+        """Return true if the UndoInfo is for cur_store."""
+        return self._store is cur_store
+
+    def rollback(self):
+        self._store.rollback(self._pos, self._index)