[Zodb-checkins] SVN: ZODB/trunk/src/Z Now require Blob files to be stored even for unopened blobs.

Jim Fulton jim at zope.com
Sun Jun 10 11:36:54 EDT 2007


Log message for revision 76582:
  Now require Blob files to be stored even for unopened blobs.
  

Changed:
  U   ZODB/trunk/src/ZEO/ClientStorage.py
  U   ZODB/trunk/src/ZEO/ServerStub.py
  U   ZODB/trunk/src/ZEO/StorageServer.py
  U   ZODB/trunk/src/ZEO/zrpc/connection.py
  U   ZODB/trunk/src/ZODB/Connection.py
  U   ZODB/trunk/src/ZODB/ExportImport.py
  U   ZODB/trunk/src/ZODB/blob.py
  U   ZODB/trunk/src/ZODB/interfaces.py
  U   ZODB/trunk/src/ZODB/tests/blob_connection.txt

-=-
Modified: ZODB/trunk/src/ZEO/ClientStorage.py
===================================================================
--- ZODB/trunk/src/ZEO/ClientStorage.py	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZEO/ClientStorage.py	2007-06-10 15:36:53 UTC (rev 76582)
@@ -899,8 +899,7 @@
         else:
             self._server.storeBlob(
                 oid, serial, data, blobfilename, version, txn)
-            if blobfilename is not None:
-                self._tbuf.storeBlob(oid, blobfilename)
+            self._tbuf.storeBlob(oid, blobfilename)
         return serials
 
     def _storeBlob_shared(self, oid, serial, data, filename, version, txn):
@@ -965,6 +964,7 @@
         # Load a blob.  If it isn't present and we have a shared blob
         # directory, then assume that it doesn't exist on the server
         # and return None.
+
         if self.fshelper is None:
             raise POSException.Unsupported("No blob cache directory is "
                                            "configured.")
@@ -976,8 +976,8 @@
 
         if self.blob_cache_writable:
             # We're using a server shared cache.  If the file isn't
-            # here, it's not anywahere.
-            return None
+            # here, it's not anywhere.
+            raise POSKeyError("No blob file", oid, serial)
 
         # First, we'll create the directory for this oid, if it doesn't exist. 
         targetpath = self.fshelper.getPathForOID(oid)
@@ -1040,7 +1040,7 @@
             if self._have_blob(blob_filename, oid, serial):
                 return blob_filename
 
-            return None
+            raise POSKeyError("No blob file", oid, serial)
 
         finally:
             lock.close()

Modified: ZODB/trunk/src/ZEO/ServerStub.py
===================================================================
--- ZODB/trunk/src/ZEO/ServerStub.py	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZEO/ServerStub.py	2007-06-10 15:36:53 UTC (rev 76582)
@@ -226,11 +226,6 @@
         # the data into memory, so we use a message iterator.  This
         # allows us to read the blob data as needed.
 
-        if blobfilename is None:
-            self.rpc.callAsync('storeEmptyBlob',
-                               oid, serial, data, version, id(txn))
-            return
-
         def store():
             yield ('storeBlobStart', ())
             f = open(blobfilename, 'rb')

Modified: ZODB/trunk/src/ZEO/StorageServer.py
===================================================================
--- ZODB/trunk/src/ZEO/StorageServer.py	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZEO/StorageServer.py	2007-06-10 15:36:53 UTC (rev 76582)
@@ -539,9 +539,6 @@
         os.close(fd)
         self.blob_log.append((oid, serial, data, tempname, version))
 
-    def storeEmptyBlob(self, oid, serial, data, version, id):
-        self.blob_log.append((oid, serial, data, None, version))
-
     def storeBlobShared(self, oid, serial, data, filename, version, id):
         # Reconstruct the full path from the filename in the OID directory
         filename = os.path.join(self.storage.fshelper.getPathForOID(oid),

Modified: ZODB/trunk/src/ZEO/zrpc/connection.py
===================================================================
--- ZODB/trunk/src/ZEO/zrpc/connection.py	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZEO/zrpc/connection.py	2007-06-10 15:36:53 UTC (rev 76582)
@@ -305,7 +305,6 @@
     # Z308 -- named after the ZODB release 3.8
     #         Added blob-support server methods:
     #             sendBlob
-    #             storeEmptyBlob
     #             storeBlobStart
     #             storeBlobChunk
     #             storeBlobEnd

Modified: ZODB/trunk/src/ZODB/Connection.py
===================================================================
--- ZODB/trunk/src/ZODB/Connection.py	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZODB/Connection.py	2007-06-10 15:36:53 UTC (rev 76582)
@@ -1072,7 +1072,6 @@
 
     def savepoint(self):
         if self._savepoint_storage is None:
-            # XXX what to do about IBlobStorages?
             tmpstore = TmpStore(self._version, self._normal_storage)
             self._savepoint_storage = tmpstore
             self._storage = self._savepoint_storage
@@ -1115,12 +1114,8 @@
 
         for oid in oids:
             data, serial = src.load(oid, src)
-            try:
+            if isinstance(self._reader.getGhost(data), Blob):
                 blobfilename = src.loadBlob(oid, serial)
-            except (POSKeyError, Unsupported):
-                s = self._storage.store(oid, serial, data,
-                                        self._version, transaction)
-            else:
                 s = self._storage.storeBlob(oid, serial, data, blobfilename,
                                             self._version, transaction)
                 # we invalidate the object here in order to ensure
@@ -1128,6 +1123,10 @@
                 # unghostify it, which will cause its blob data
                 # to be reattached "cleanly"
                 self.invalidate(s, {oid:True})
+            else:
+                s = self._storage.store(oid, serial, data,
+                                        self._version, transaction)
+
             self._handle_serial(s, oid, change=False)
         src.close()
 
@@ -1240,8 +1239,6 @@
     def storeBlob(self, oid, serial, data, blobfilename, version,
                   transaction):
         serial = self.store(oid, serial, data, version, transaction)
-        assert isinstance(serial, str) # XXX in theory serials could be
-                                       # something else
 
         targetpath = self._getBlobPath(oid)
         if not os.path.exists(targetpath):
@@ -1259,7 +1256,7 @@
                 self._storage)
         filename = self._getCleanFilename(oid, serial)
         if not os.path.exists(filename):
-            raise POSKeyError, "Not an existing blob."
+            raise POSKeyError("No blob file", oid, serial)
         return filename
 
     def _getBlobPath(self, oid):

Modified: ZODB/trunk/src/ZODB/ExportImport.py
===================================================================
--- ZODB/trunk/src/ZODB/ExportImport.py	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZODB/ExportImport.py	2007-06-10 15:36:53 UTC (rev 76582)
@@ -20,10 +20,11 @@
 from tempfile import TemporaryFile
 import logging
 
-from ZODB.POSException import ExportError, POSKeyError
-from ZODB.utils import p64, u64, cp, mktemp
+from ZODB.blob import Blob
 from ZODB.interfaces import IBlobStorage
+from ZODB.POSException import ExportError, POSKeyError
 from ZODB.serialize import referencesf
+from ZODB.utils import p64, u64, cp, mktemp
 
 logger = logging.getLogger('ZODB.ExportImport')
 
@@ -55,14 +56,10 @@
                 f.writelines([oid, p64(len(p)), p])
 
             if supports_blobs:
-                if 'Blob' not in p:
-                    continue # filter out most non-blobs
+                if not isinstance(self._reader.getGhost(p), Blob):
+                    continue # not a blob
                 
                 blobfilename = self._storage.loadBlob(oid, serial)
-                if blobfilename is None:
-                    # This could be a non-blob or a blob with unsaved data.
-                    continue
-
                 f.write(blob_begin_marker)
                 f.write(p64(os.stat(blobfilename).st_size))
                 blobdata = open(blobfilename, "rb")

Modified: ZODB/trunk/src/ZODB/blob.py
===================================================================
--- ZODB/trunk/src/ZODB/blob.py	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZODB/blob.py	2007-06-10 15:36:53 UTC (rev 76582)
@@ -245,6 +245,8 @@
         # hand uncommitted data to connection, relinquishing responsibility
         # for it.
         filename = self._p_blob_uncommitted
+        if filename is None and self._p_blob_committed is None:
+            filename = self._create_uncommitted_file()
         self._p_blob_uncommitted = self._p_blob_ref = None
         return filename
 
@@ -413,22 +415,21 @@
 
         # 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:
-            self._lock_acquire()
-            try:
-                targetpath = self.fshelper.getPathForOID(oid)
-                if not os.path.exists(targetpath):
-                    os.makedirs(targetpath, 0700)
+        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)
-                utils.rename_or_copy(blobfilename, targetname)
+            targetname = self.fshelper.getBlobFilename(oid, serial)
+            utils.rename_or_copy(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
+            # 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
 
     @non_overridable
     def tpc_finish(self, *arg, **kw):
@@ -456,7 +457,7 @@
         """
         filename = self.fshelper.getBlobFilename(oid, serial)
         if not os.path.exists(filename):
-            return None
+            raise POSKeyError("No blob file", oid, serial)
         return filename
 
     @non_overridable

Modified: ZODB/trunk/src/ZODB/interfaces.py
===================================================================
--- ZODB/trunk/src/ZODB/interfaces.py	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZODB/interfaces.py	2007-06-10 15:36:53 UTC (rev 76582)
@@ -946,7 +946,7 @@
     def loadBlob(oid, serial):
         """Return the filename of the Blob data for this OID and serial.
 
-        Returns a filename or None if no Blob data is connected with this OID. 
+        Returns a filename. 
 
         Raises POSKeyError if the blobfile cannot be found.
         """

Modified: ZODB/trunk/src/ZODB/tests/blob_connection.txt
===================================================================
--- ZODB/trunk/src/ZODB/tests/blob_connection.txt	2007-06-10 15:23:00 UTC (rev 76581)
+++ ZODB/trunk/src/ZODB/tests/blob_connection.txt	2007-06-10 15:36:53 UTC (rev 76582)
@@ -44,7 +44,7 @@
     >>> transaction.commit()
 
 We can also commit a transaction that seats a blob into place without
-calling the blob's open method (this currently fails):
+calling the blob's open method:
 
     >>> nothing = transaction.begin()
     >>> anotherblob = Blob()



More information about the Zodb-checkins mailing list