[Zodb-checkins]
SVN: ZODB/branches/blob-merge-branch/src/ZODB/Blobs/
Still-broken undo code that doesn't pdb.set_trace ; -)
Chris McDonough
chrism at plope.com
Tue Feb 28 14:47:15 EST 2006
Log message for revision 65605:
Still-broken undo code that doesn't pdb.set_trace ;-)
It was impossible to commit a transaction that involved a blob that hadn't
had its 'open' method called, because the blob filename is computed during open.
Changed:
U ZODB/branches/blob-merge-branch/src/ZODB/Blobs/BlobStorage.py
U ZODB/branches/blob-merge-branch/src/ZODB/Blobs/tests/connection.txt
-=-
Modified: ZODB/branches/blob-merge-branch/src/ZODB/Blobs/BlobStorage.py
===================================================================
--- ZODB/branches/blob-merge-branch/src/ZODB/Blobs/BlobStorage.py 2006-02-28 19:47:13 UTC (rev 65604)
+++ ZODB/branches/blob-merge-branch/src/ZODB/Blobs/BlobStorage.py 2006-02-28 19:47:14 UTC (rev 65605)
@@ -61,21 +61,24 @@
# something else
self._lock_acquire()
- try:
- targetpath = self.fshelper.getPathForOID(oid)
- if not os.path.exists(targetpath):
- os.makedirs(targetpath, 0700)
-
- targetname = self.fshelper.getBlobFilename(oid, serial)
- os.rename(blobfilename, targetname)
+ # the user may not have called "open" on the blob object,
+ # in which case, the blob will not have a filename.
+ if blobfilename is not None:
+ try:
+ targetpath = self.fshelper.getPathForOID(oid)
+ if not os.path.exists(targetpath):
+ os.makedirs(targetpath, 0700)
- # XXX if oid already in there, something is really hosed.
- # The underlying storage should have complained anyway
- self.dirty_oids.append((oid, serial))
- finally:
- self._lock_release()
- return self._tid
+ targetname = self.fshelper.getBlobFilename(oid, serial)
+ os.rename(blobfilename, targetname)
+ # XXX if oid already in there, something is really hosed.
+ # The underlying storage should have complained anyway
+ self.dirty_oids.append((oid, serial))
+ finally:
+ self._lock_release()
+ return self._tid
+
def tpc_finish(self, *arg, **kw):
""" We need to override the base storage's tpc_finish instead of
providing a _finish method because methods found on the proxied object
@@ -193,29 +196,52 @@
return orig_size + blob_size
def undo(self, serial_id, transaction):
- import pdb; pdb.set_trace()
- serial, keys = getProxiedObject(self).undo(serial_id, transaction)
+ undo_serial, keys = getProxiedObject(self).undo(serial_id, transaction)
+ # serial_id is the transaction id of the txn that we wish to undo.
+ # "undo_serial" is the transaction id of txn in which the undo is
+ # performed. "keys" is the list of oids that are involved in the
+ # undo transaction.
+
+ # The serial_id is assumed to be given to us base-64 encoded
+ # (belying the web UI legacy of the ZODB code :-()
+ serial_id = base64.decodestring(serial_id+'\n')
+
self._lock_acquire()
+
try:
- # The old serial_id is given in base64 encoding ...
- serial_id = base64.decodestring(serial_id+ '\n')
+ # we get all the blob oids on the filesystem related to the
+ # transaction we want to undo.
for oid in self.fshelper.getOIDsForSerial(serial_id):
- load_result = self.loadBefore(oid, serial_id)
+ # we want to find the serial id of the previous revision
+ # of this blob object.
+ load_result = self.loadBefore(oid, serial_id)
+
if load_result is None:
- continue
-
- data, serial_before, serial_after = load_result
-
- orig_fn = self.fshelper.getBlobFilename(oid, serial_before)
+ # There was no previous revision of this blob
+ # object. The blob was created in the transaction
+ # represented by serial_id. We copy the blob data
+ # to a new file that references the undo
+ # transaction in case a user wishes to undo this
+ # undo.
+ orig_fn = self.fshelper.getBlobFilename(oid, serial_id)
+ new_fn = self.fshelper.getBlobFilename(oid, undo_serial)
+ else:
+ # A previous revision of this blob existed before the
+ # transaction implied by "serial_id". We copy the blob
+ # data to a new file that references the undo transaction
+ # in case a user wishes to undo this undo.
+ data, serial_before, serial_after = load_result
+ orig_fn = self.fshelper.getBlobFilename(oid, serial_before)
+ new_fn = self.fshelper.getBlobFilename(oid, undo_serial)
orig = open(orig_fn, "r")
- new_fn = self.fshelper.getBlobFilename(oid, serial)
new = open(new_fn, "wb")
utils.cp(orig, new)
orig.close()
new.close()
- self.dirty_oids.append((oid, serial))
+ self.dirty_oids.append((oid, undo_serial))
+
finally:
self._lock_release()
- return serial, keys
+ return undo_serial, keys
Modified: ZODB/branches/blob-merge-branch/src/ZODB/Blobs/tests/connection.txt
===================================================================
--- ZODB/branches/blob-merge-branch/src/ZODB/Blobs/tests/connection.txt 2006-02-28 19:47:13 UTC (rev 65604)
+++ ZODB/branches/blob-merge-branch/src/ZODB/Blobs/tests/connection.txt 2006-02-28 19:47:14 UTC (rev 65605)
@@ -19,6 +19,7 @@
>>> from ZODB.Blobs.interfaces import IBlob
>>> from ZODB.Blobs.Blob import Blob
+ >>> import transaction
>>> blob = Blob()
>>> data = blob.open("w")
>>> data.write("I'm a happy Blob.")
@@ -40,9 +41,16 @@
>>> connection = database.open()
>>> root = connection.root()
>>> root['myblob'] = blob
- >>> import transaction
>>> transaction.commit()
+We can also commit a transaction that seats a blob into place without
+calling the blob's open method (this currently fails):
+
+ >>> nothing = transaction.begin()
+ >>> anotherblob = Blob()
+ >>> root['anotherblob'] = anotherblob
+ >>> nothing = transaction.commit()
+
Getting stuff out of there works similar:
>>> connection2 = database.open()
@@ -65,7 +73,8 @@
...
Unsupported: Storing Blobs in <ZODB.MappingStorage.MappingStorage instance at ...> is not supported.
-While we are testing this, we don't need the storage directory and databases anymore:
+While we are testing this, we don't need the storage directory and
+databases anymore:
>>> import shutil
>>> shutil.rmtree(blob_dir)
More information about the Zodb-checkins
mailing list