[Zope] Fixed - Re: Versions problem in 2.6.1
John Eikenberry
jae@kavi.com
Thu, 20 Feb 2003 15:38:21 -0800
--HlL+5n6rz5pIUxbD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
This is in relation to the thread referred to in the subject:
http://mail.zope.org/pipermail/zope/2003-February/131336.html
We recently came across this same problem, and after a bit of digging I've
got it fixed (for us at least).
What I did was comment out the break at around line 576 in
ZODB/FileStorage.py. This break was added between versions 2.6.0 and
2.6.1. For grepping purposes, here's a copy of the break and its preceeding
comment:
# Once we've found the data we are looking for,
# we can stop chasing backpointers.
break
Just comment out that break and all should be good to go.
I've attached a Hotfix style patch for the lazy. :)
--
John Eikenberry [jae@kavi.com]
______________________________________________________________
"A society that will trade a little liberty for a little order
will deserve neither and lose both."
--B. Franklin
--HlL+5n6rz5pIUxbD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="VersionCommit_HotFix.py"
# Fixes a bug introduced in zope-2.6.1 in ZODB/FileStorage.py
# Problem is that new files added in a version don't get committed when the
# version is saved/committed. The version is emptied but the locks are still
# around. Bad mojo.
#
# I'm going to submit a bug report on this to zope.org. I'll add the bug number
# once its in their system.
# Bug #817: http://collector.zope.org/Zope/817
from ZODB import FileStorage
import struct
from ZODB.utils import p64, U64
# constants copied from FileStorage
z64='\0'*8
# the struct formats for the headers
TRANS_HDR = ">8s8scHHH"
DATA_HDR = ">8s8s8s8sH8s"
# constants to support various header sizes
TRANS_HDR_LEN = 23
DATA_HDR_LEN = 42
DATA_VERSION_HDR_LEN = 58
if 1: # keep indent level consistent with original code
def _commitVersion(self, src, dest, transaction, abort=None):
# call after checking arguments and acquiring lock
srcpos = self._vindex_get(src, 0)
spos = p64(srcpos)
# middle holds bytes 16:34 of a data record:
# pos of transaction, len of version name, data length
# commit version never writes data, so data length is always 0
middle = struct.pack(">8sH8s", p64(self._pos), len(dest), z64)
if dest:
sd = p64(self._vindex_get(dest, 0))
heredelta = 66 + len(dest)
else:
sd = ''
heredelta = 50
here = self._pos + (self._tfile.tell() + self._thl)
oids = []
current_oids = {}
t = None
tstatus = ' '
if abort is None:
newserial = self._serial
while srcpos:
self._file.seek(srcpos)
h = self._file.read(DATA_VERSION_HDR_LEN)
# h -> oid, serial, prev(oid), tloc, vlen, plen, pnv, pv
oid = h[:8]
pnv = h[-16:-8]
if abort:
# If we are aborting, the serialno in the new data
# record should be the same as the serialno in the last
# non-version data record.
# XXX This might be the only time that the serialno
# of a data record does not match the transaction id.
self._file.seek(U64(pnv))
h_pnv = self._file.read(DATA_VERSION_HDR_LEN)
newserial = h_pnv[8:16]
if self._index.get(oid) == srcpos:
# This is a current record!
self._tindex[oid] = here
oids.append(oid)
self._tfile.write(oid + newserial + spos + middle)
if dest:
self._tvindex[dest] = here
self._tfile.write(pnv + sd + dest)
sd = p64(here)
self._tfile.write(abort and pnv or spos)
# data backpointer to src data
here += heredelta
current_oids[oid] = 1
# XXX jae - changed this
# # Once we've found the data we are looking for,
# # we can stop chasing backpointers.
# break
else:
# Hm. This is a non-current record. Is there a
# current record for this oid?
if not current_oids.has_key(oid):
# Nope. We're done *if* this transaction wasn't undone.
tloc = h[24:32]
if t != tloc:
# We haven't checked this transaction before,
# get it's status.
t = tloc
self._file.seek(U64(t) + 16)
tstatus = self._file.read(1)
if tstatus != 'u':
# Yee ha! We can quit
break
spos = h[-8:]
srcpos = U64(spos)
return oids
# apply hotfix
from zLOG import LOG, INFO
LOG('Hotfix', INFO, 'Applying %s.' % 'Version commit Fix (2.6.1)')
FileStorage.FileStorage._commitVersion = _commitVersion
--HlL+5n6rz5pIUxbD--