[Zodb-checkins] CVS: StandaloneZODB/ZODB - FileStorage.py:1.77.4.1
Barry Warsaw
barry@wooz.org
Wed, 23 Jan 2002 16:42:04 -0500
Update of /cvs-repository/StandaloneZODB/ZODB
In directory cvs.zope.org:/tmp/cvs-serv12297
Modified Files:
Tag: Recovery
FileStorage.py
Log Message:
We're defining a new API method called recover() that looks a lot like
store() but which has some important differences:
- The `serial' argument to recover() names the serial number of the
/current/ object revision, not the previous one.
- recover() skips various consistency checks that store() performs,
including the checks for ConflictError and VersionLockError. Thus
it believes the data its given, which /must/ be known to be accurate
(or you could end up corrupting your storage). Also, it ought to be
a bit faster since it does less work than store().
- recover() doesn't return anything.
Note that recover() must still be called within a two-phase commit.
=== StandaloneZODB/ZODB/FileStorage.py 1.77 => 1.77.4.1 ===
self._lock_release()
+ def recover(self, oid, serial, data, version, transaction):
+ # A lot like store() but without all the consistency checks. This
+ # should only be used when we /know/ the data is good, hence the
+ # method name. While the signature looks like store() there are some
+ # differences:
+ #
+ # - serial is the serial number of /this/ revision, not of the
+ # previous revision. It is used instead of self._serial, which is
+ # ignored.
+ #
+ # - Nothing is returned
+ if self._is_read_only:
+ raise POSException.ReadOnlyError()
+ if transaction is not self._transaction:
+ raise POSException.StorageTransactionError(self, transaction)
+
+ self._lock_acquire()
+ try:
+ # Position of the non-version data
+ pnv = None
+ # We need to get some information about previous revisions of the
+ # object. Specifically, we need the position of the non-version
+ # data if this update is in a version. We also need the position
+ # of the previous record in this version.
+ old = self._index_get(oid, 0)
+ if old:
+ self._file.seek(old)
+ # Read the previous revision record
+ h = self._file.read(42)
+ doid,oserial,sprev,stloc,vlen,splen = unpack(">8s8s8s8sH8s", h)
+ if doid != oid:
+ raise CorruptedDataError, h
+ # Calculate the file position in the temporary file
+ here = self._pos + self._tfile.tell() + self._thl
+ # And update the temp file index
+ self._tindex[oid] = here
+ # Write the recovery data record
+ self._tfile.write(pack('>8s8s8s8sH8s',
+ oid, serial, p64(old), p64(self._pos),
+ len(version), p64(len(data))))
+ # We need to write some version information if this revision is
+ # happening in a version.
+ if version:
+ # If there's a previous revision in this version, write the
+ # position, otherwise write the position of the previous
+ # non-version revision.
+ if pnv:
+ self._tfile.write(pnv)
+ else:
+ self._tfile.write(p64(old))
+ # Link to the last record for this version
+ pv = self._tvindex.get(version, 0)
+ if not pv:
+ self._vindex_get(version, 0)
+ self._tfile.write(p64(pv))
+ self._tvindex[version] = here
+ self._tfile.write(version)
+ # And finally, write the data
+ self._tfile.write(data)
+ finally:
+ self._lock_release()
+
def supportsUndo(self):
return 1