[Zope3-checkins] CVS: Zope3/src/zodb/storage - bdbfull.py:1.22
Barry Warsaw
barry@wooz.org
Wed, 9 Apr 2003 13:57:59 -0400
Update of /cvs-repository/Zope3/src/zodb/storage
In directory cvs.zope.org:/tmp/cvs-serv13369
Modified Files:
bdbfull.py
Log Message:
_begin(), _dobegin(), _finish(): Fix signatures since user,
description, ext is never passed here. Get the information from
self._ude where needed.
_unpack_txnmeta(): Refactor the decoding of the transaction metadata
string, including utf-8 decoding the stored user and description 8-bit
strings back to Unicode. Also factors out the unpickling of the
extension object.
_doundolog(), _nexttxn(): Use _unpack_txnmeta()
_RecordIterator.__init__(): The ext object passed in here is already
unpickled.
=== Zope3/src/zodb/storage/bdbfull.py 1.21 => 1.22 ===
--- Zope3/src/zodb/storage/bdbfull.py:1.21 Thu Apr 3 17:16:48 2003
+++ Zope3/src/zodb/storage/bdbfull.py Wed Apr 9 13:57:58 2003
@@ -164,10 +164,14 @@
# 8-byte unsigned long integer
# desclen is the length in characters of the `desc' field as an
# 8-byte unsigned long integer
- # user is the user information passed to tpc_finish()
- # desc is the description info passed to tpc_finish()
- # ext is the extra info passed to tpc_finish(). It is a
- # dictionary that we get already pickled by BaseStorage.
+ # user is the user information passed in the transaction object
+ # desc is the description info passed in the transaction object
+ # ext is the extra info passed in the transaction object. It is a
+ # mapping that we get already pickled by BaseStorage.
+ #
+ # Note: txnBegin() can get user and desc as Unicode strings, so
+ # they are stored in this table as utf-8 encoded byte strings, and
+ # decoded back to Unicode when requested.
#
# txnoids -- {tid -> [oid]}
# Maps transaction ids to the oids of the objects modified by the
@@ -451,25 +455,27 @@
self._packmark.put(oid, PRESENT, txn=txn)
self._oids.truncate(txn)
- def _dobegin(self, txn, tid, u, d, e):
- # When a transaction begins, we set the pending flag to ABORT,
- # meaning, if we crash between now and the time we vote, all changes
- # will be aborted.
- #
+ def _dobegin(self, txn, tid):
# It's more convenient to store the transaction metadata now, rather
# than in the _finish() call. Doesn't matter because if the ZODB
- # transaction were to abort, we'd clean this up anyway.
- userlen = len(u)
- desclen = len(d)
+ # transaction were to abort, we'd clean this up anyway. Watch out for
+ # Unicode user or description data. XXX Assume the extended data is
+ # /not/ Unicode -- it's usually a pickle.
+ user, desc, ext = self._ude
+ userlen = len(user)
+ desclen = len(desc)
lengths = pack('>2I', userlen, desclen)
- data = lengths + u + d + e
+ data = lengths + user + desc + ext
+ # When a transaction begins, we set the pending flag to ABORT,
+ # meaning, if we crash between now and the time we vote, all changes
+ # will be aborted.
self._pending.put(tid, ABORT, txn=txn)
self._txnMetadata.put(tid, data, txn=txn)
- def _begin(self, tid, u, d, e):
- self._withtxn(self._dobegin, self._serial, u, d, e)
+ def _begin(self, tid):
+ self._withtxn(self._dobegin, self._serial)
- def _finish(self, tid, u, d, e):
+ def _finish(self, tid):
self._withtxn(self._docommit, self._serial)
self._ltid = tid
@@ -1231,6 +1237,24 @@
finally:
self._lock_release()
+ def _unpack_txnmeta(self, txnmeta):
+ userlen, desclen = unpack('>2I', txnmeta[:8])
+ usafe = txnmeta[8:8+userlen]
+ dsafe = txnmeta[8+userlen:8+userlen+desclen]
+ # user and desc are utf-8 encoded
+ user = usafe.decode('utf-8')
+ desc = dsafe.decode('utf-8')
+ extdata = txnmeta[8+userlen+desclen:]
+ # ext is a pickled mapping. Any exceptions are ignored, but XXX can
+ # we (and FileStorage :) do better?
+ ext = {}
+ if extdata:
+ try:
+ ext = pickle.loads(extdata)
+ except Exception, e:
+ self.log('Error unpickling extension data: %s', e)
+ return user, desc, ext
+
def _doundolog(self, first, last, filter):
# Get the last packtime
packtime = self._last_packtime()
@@ -1248,26 +1272,16 @@
rec = c.prev()
if tid <= packtime:
break
- userlen, desclen = unpack('>2I', txnmeta[:8])
- user = txnmeta[8:8+userlen]
- desc = txnmeta[8+userlen:8+userlen+desclen]
- ext = txnmeta[8+userlen+desclen:]
+ user, desc, ext = self._unpack_txnmeta(txnmeta)
# Create a dictionary for the TransactionDescription
txndesc = {'id' : tid,
'time' : TimeStamp(tid).timeTime(),
'user_name' : user,
'description': desc,
}
- # The extension stuff is a picklable mapping, so if we can
- # unpickle it, we update the TransactionDescription dictionary
- # with that data. BAW: The bare except is disgusting, but I'm
- # too lazy to figure out what exceptions could actually be
- # raised here...
- if ext:
- try:
- txndesc.update(pickle.loads(ext))
- except:
- pass
+ # Update the transaction description dictionary with the
+ # extension mapping.
+ txndesc.update(ext)
# Now call the filter to see if this transaction should be
# added to the return list...
if filter is None or filter(txndesc):
@@ -1652,7 +1666,7 @@
rec = c.next()
if rec is None:
raise IndexError
- tid, data = rec
+ tid, txnmeta = rec
# Now unpack the necessary information. Don't impedence match the
# status flag (that's done by the caller).
packtime = self._last_packtime()
@@ -1660,10 +1674,7 @@
packedp = True
else:
packedp = False
- userlen, desclen = unpack('>2I', data[:8])
- user = data[8:8+userlen]
- desc = data[8+userlen:8+userlen+desclen]
- ext = data[8+userlen+desclen:]
+ user, desc, ext = self._unpack_txnmeta(txnmeta)
return tid, packedp, user, desc, ext
finally:
if c:
@@ -1759,10 +1770,7 @@
self.status = ' '
self.user = user
self.description = desc
- try:
- self._extension = pickle.loads(ext)
- except EOFError:
- self._extension = {}
+ self._extension = ext
# BAW: touching the storage's private parts!
self._table = self._storage._txnoids
self._cursor = None