Commit 1e783423 authored by Jim Fulton's avatar Jim Fulton Committed by GitHub

Merge pull request #68 from zopefoundation/load-calls-loadBefore

Load calls load before
parents 7d81f21a addec006
......@@ -31,7 +31,9 @@ import ZODB.MappingStorage
import ZODB.POSException
import ZODB.utils
import zope.interface
from .ConflictResolution import ConflictResolvingStorage, ResolvedSerial
from .utils import load_current, maxtid
@zope.interface.implementer(
ZODB.interfaces.IStorage,
......@@ -167,11 +169,8 @@ class DemoStorage(ConflictResolvingStorage):
def __len__(self):
return len(self.changes)
def load(self, oid, version=''):
try:
return self.changes.load(oid, version)
except ZODB.POSException.POSKeyError:
return self.base.load(oid, version)
# still want load for old clients (e.g. zeo servers)
load = load_current
def loadBefore(self, oid, tid):
try:
......@@ -190,12 +189,27 @@ class DemoStorage(ConflictResolvingStorage):
pass
else:
if result and not result[-1]:
end_tid = None
t = self.changes.load(oid)
# The oid is current in the base. We need to find
# the end tid in the base by fining the first tid
# in the changes. Unfortunately, there isn't an
# api for this, so we have to walk back using
# loadBefore.
if tid == maxtid:
# Special case: we were looking for the
# current value. We won't find anything in
# changes, so we're done.
return result
end_tid = maxtid
t = self.changes.loadBefore(oid, end_tid)
while t:
end_tid = t[1]
t = self.changes.loadBefore(oid, end_tid)
result = result[:2] + (end_tid,)
result = result[:2] + (
end_tid if end_tid != maxtid else None,
)
return result
def loadBlob(self, oid, serial):
......@@ -240,10 +254,10 @@ class DemoStorage(ConflictResolvingStorage):
oid = ZODB.utils.p64(self._next_oid )
if oid not in self._issued_oids:
try:
self.changes.load(oid, '')
load_current(self.changes, oid)
except ZODB.POSException.POSKeyError:
try:
self.base.load(oid, '')
load_current(self.base, oid)
except ZODB.POSException.POSKeyError:
self._next_oid += 1
self._issued_oids.add(oid)
......@@ -288,12 +302,9 @@ class DemoStorage(ConflictResolvingStorage):
# See if we already have changes for this oid
try:
old = self.changes.load(oid, '')[1]
old = load_current(self, oid)[1]
except ZODB.POSException.POSKeyError:
try:
old = self.base.load(oid, '')[1]
except ZODB.POSException.POSKeyError:
old = serial
old = serial
if old != serial:
rdata = self.tryToResolveConflict(oid, old, serial, data)
......
......@@ -70,6 +70,7 @@ from ZODB.fsIndex import fsIndex
from ZODB.utils import as_bytes
from ZODB.utils import as_text
from ZODB.utils import cp
from ZODB.utils import load_current
from ZODB.utils import mktemp
from ZODB.utils import p64
from ZODB.utils import u64
......@@ -443,6 +444,8 @@ class FileStorage(
except TypeError:
raise TypeError("invalid oid %r" % (oid,))
load = load_current # Keep load for now for old clients
def load(self, oid, version=''):
"""Return pickle data and serial number."""
assert not version
......@@ -1314,7 +1317,7 @@ class FileStorage(
except ValueError: # "empty tree" error
next_oid = None
data, tid = self.load(oid, "")
data, tid = load_current(self, oid)
return oid, tid, data, next_oid
......
......@@ -134,15 +134,7 @@ class MappingStorage(object):
def __len__(self):
return len(self._data)
# ZODB.interfaces.IStorage
@ZODB.utils.locked(opened)
def load(self, oid, version=''):
assert not version, "Versions are not supported"
tid_data = self._data.get(oid)
if tid_data:
tid = tid_data.maxKey()
return tid_data[tid], tid
raise ZODB.POSException.POSKeyError(oid)
load = ZODB.utils.load_current
# ZODB.interfaces.IStorage
@ZODB.utils.locked(opened)
......
......@@ -13,6 +13,7 @@
##############################################################################
import ZODB.blob
import ZODB.interfaces
import ZODB.utils
import zope.interface
from binascii import hexlify, unhexlify
......@@ -45,9 +46,7 @@ class HexStorage(object):
def __len__(self):
return len(self.base)
def load(self, oid, version=''):
data, serial = self.base.load(oid, version)
return unhexlify(data[2:]), serial
load = ZODB.utils.load_current
def loadBefore(self, oid, tid):
r = self.base.loadBefore(oid, tid)
......
......@@ -28,7 +28,6 @@ from ZODB._compat import Unpickler
from ZODB._compat import BytesIO
from ZODB._compat import ascii_bytes
__all__ = ['z64',
'p64',
'u64',
......@@ -375,3 +374,26 @@ if os.environ.get('DEBUG_LOCKING'):
else:
from threading import Condition, Lock, RLock
import ZODB.POSException
def load_current(storage, oid, version=''):
"""Load the most recent revision of an object by calling loadBefore
Starting in ZODB 5, it's no longer necessary for storages to
provide a load method.
This function is mainly intended to facilitate transitioning from
load to loadBefore. It's mainly useful for tests that are meant
to test storages, but do so by calling load on the storages.
This function will likely become unnecessary and be deprecated
some time in the future.
"""
assert not version
r = storage.loadBefore(oid, maxtid)
if r is None:
raise ZODB.POSException.POSKeyError(oid)
assert r[2] is None
return r[:2]
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