Commit 3b8bedca authored by Jim Fulton's avatar Jim Fulton

Added support for copying to blob cache when renaming fails to the

savepoint storage.

Also added a test for the normal blob case.
parent 12b21617
...@@ -30,7 +30,7 @@ from persistent import PickleCache ...@@ -30,7 +30,7 @@ from persistent import PickleCache
from persistent.interfaces import IPersistentDataManager from persistent.interfaces import IPersistentDataManager
from ZODB.interfaces import IConnection from ZODB.interfaces import IConnection
from ZODB.interfaces import IBlobStorage from ZODB.interfaces import IBlobStorage
from ZODB.blob import Blob from ZODB.blob import Blob, rename_or_copy_blob
from transaction.interfaces import ISavepointDataManager from transaction.interfaces import ISavepointDataManager
from transaction.interfaces import IDataManagerSavepoint from transaction.interfaces import IDataManagerSavepoint
from transaction.interfaces import ISynchronizer from transaction.interfaces import ISynchronizer
...@@ -1245,7 +1245,7 @@ class TmpStore: ...@@ -1245,7 +1245,7 @@ class TmpStore:
os.makedirs(targetpath, 0700) os.makedirs(targetpath, 0700)
targetname = self._getCleanFilename(oid, serial) targetname = self._getCleanFilename(oid, serial)
utils.rename_or_copy(blobfilename, targetname) rename_or_copy_blob(blobfilename, targetname)
def loadBlob(self, oid, serial): def loadBlob(self, oid, serial):
"""Return the filename where the blob file can be found. """Return the filename where the blob file can be found.
......
...@@ -278,6 +278,66 @@ def gc_blob_removes_uncommitted_data(): ...@@ -278,6 +278,66 @@ def gc_blob_removes_uncommitted_data():
False False
""" """
def commit_from_wrong_partition():
"""
It should be possible to commit changes even when a blob is on a
different partition.
We can simulare this by temporarily breaking os.rename. :)
>>> def fail(*args):
... raise OSError
>>> os_rename = os.rename
>>> os.rename = fail
>>> import logging, sys
>>> logger = logging.getLogger('ZODB.blob.copied')
>>> handler = logging.StreamHandler(sys.stdout)
>>> logger.propagate = False
>>> logger.setLevel(logging.DEBUG)
>>> logger.addHandler(handler)
>>> import transaction
>>> from ZODB.MappingStorage import MappingStorage
>>> from ZODB.blob import BlobStorage
>>> from ZODB.DB import DB
>>> from tempfile import mkdtemp
>>> base_storage = MappingStorage("test")
>>> blob_dir = mkdtemp()
>>> blob_storage = BlobStorage(blob_dir, base_storage)
>>> database = DB(blob_storage)
>>> connection = database.open()
>>> root = connection.root()
>>> from ZODB.blob import Blob
>>> root['blob'] = Blob()
>>> root['blob'].open('w').write('test')
>>> transaction.commit() # doctest: +ELLIPSIS
Copied blob file ...
>>> root['blob'].open().read()
'test'
Works with savepoints too:
>>> root['blob2'] = Blob()
>>> root['blob2'].open('w').write('test2')
>>> _ = transaction.savepoint() # doctest: +ELLIPSIS
Copied blob file ...
>>> transaction.commit() # doctest: +ELLIPSIS
Copied blob file ...
>>> root['blob2'].open().read()
'test2'
>>> os.rename = os_rename
>>> logger.propagate = True
>>> logger.setLevel(0)
>>> logger.removeHandler(handler)
"""
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(ZODBBlobConfigTest)) suite.addTest(unittest.makeSuite(ZODBBlobConfigTest))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment