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 ...@@ -31,7 +31,9 @@ import ZODB.MappingStorage
import ZODB.POSException import ZODB.POSException
import ZODB.utils import ZODB.utils
import zope.interface import zope.interface
from .ConflictResolution import ConflictResolvingStorage, ResolvedSerial from .ConflictResolution import ConflictResolvingStorage, ResolvedSerial
from .utils import load_current, maxtid
@zope.interface.implementer( @zope.interface.implementer(
ZODB.interfaces.IStorage, ZODB.interfaces.IStorage,
...@@ -167,11 +169,8 @@ class DemoStorage(ConflictResolvingStorage): ...@@ -167,11 +169,8 @@ class DemoStorage(ConflictResolvingStorage):
def __len__(self): def __len__(self):
return len(self.changes) return len(self.changes)
def load(self, oid, version=''): # still want load for old clients (e.g. zeo servers)
try: load = load_current
return self.changes.load(oid, version)
except ZODB.POSException.POSKeyError:
return self.base.load(oid, version)
def loadBefore(self, oid, tid): def loadBefore(self, oid, tid):
try: try:
...@@ -190,12 +189,27 @@ class DemoStorage(ConflictResolvingStorage): ...@@ -190,12 +189,27 @@ class DemoStorage(ConflictResolvingStorage):
pass pass
else: else:
if result and not result[-1]: if result and not result[-1]:
end_tid = None # The oid is current in the base. We need to find
t = self.changes.load(oid) # 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: while t:
end_tid = t[1] end_tid = t[1]
t = self.changes.loadBefore(oid, end_tid) 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 return result
def loadBlob(self, oid, serial): def loadBlob(self, oid, serial):
...@@ -240,10 +254,10 @@ class DemoStorage(ConflictResolvingStorage): ...@@ -240,10 +254,10 @@ class DemoStorage(ConflictResolvingStorage):
oid = ZODB.utils.p64(self._next_oid ) oid = ZODB.utils.p64(self._next_oid )
if oid not in self._issued_oids: if oid not in self._issued_oids:
try: try:
self.changes.load(oid, '') load_current(self.changes, oid)
except ZODB.POSException.POSKeyError: except ZODB.POSException.POSKeyError:
try: try:
self.base.load(oid, '') load_current(self.base, oid)
except ZODB.POSException.POSKeyError: except ZODB.POSException.POSKeyError:
self._next_oid += 1 self._next_oid += 1
self._issued_oids.add(oid) self._issued_oids.add(oid)
...@@ -288,12 +302,9 @@ class DemoStorage(ConflictResolvingStorage): ...@@ -288,12 +302,9 @@ class DemoStorage(ConflictResolvingStorage):
# See if we already have changes for this oid # See if we already have changes for this oid
try: try:
old = self.changes.load(oid, '')[1] old = load_current(self, oid)[1]
except ZODB.POSException.POSKeyError: except ZODB.POSException.POSKeyError:
try: old = serial
old = self.base.load(oid, '')[1]
except ZODB.POSException.POSKeyError:
old = serial
if old != serial: if old != serial:
rdata = self.tryToResolveConflict(oid, old, serial, data) rdata = self.tryToResolveConflict(oid, old, serial, data)
......
...@@ -70,6 +70,7 @@ from ZODB.fsIndex import fsIndex ...@@ -70,6 +70,7 @@ from ZODB.fsIndex import fsIndex
from ZODB.utils import as_bytes from ZODB.utils import as_bytes
from ZODB.utils import as_text from ZODB.utils import as_text
from ZODB.utils import cp from ZODB.utils import cp
from ZODB.utils import load_current
from ZODB.utils import mktemp from ZODB.utils import mktemp
from ZODB.utils import p64 from ZODB.utils import p64
from ZODB.utils import u64 from ZODB.utils import u64
...@@ -443,6 +444,8 @@ class FileStorage( ...@@ -443,6 +444,8 @@ class FileStorage(
except TypeError: except TypeError:
raise TypeError("invalid oid %r" % (oid,)) raise TypeError("invalid oid %r" % (oid,))
load = load_current # Keep load for now for old clients
def load(self, oid, version=''): def load(self, oid, version=''):
"""Return pickle data and serial number.""" """Return pickle data and serial number."""
assert not version assert not version
...@@ -1314,7 +1317,7 @@ class FileStorage( ...@@ -1314,7 +1317,7 @@ class FileStorage(
except ValueError: # "empty tree" error except ValueError: # "empty tree" error
next_oid = None next_oid = None
data, tid = self.load(oid, "") data, tid = load_current(self, oid)
return oid, tid, data, next_oid return oid, tid, data, next_oid
......
...@@ -134,15 +134,7 @@ class MappingStorage(object): ...@@ -134,15 +134,7 @@ class MappingStorage(object):
def __len__(self): def __len__(self):
return len(self._data) return len(self._data)
# ZODB.interfaces.IStorage load = ZODB.utils.load_current
@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)
# ZODB.interfaces.IStorage # ZODB.interfaces.IStorage
@ZODB.utils.locked(opened) @ZODB.utils.locked(opened)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
############################################################################## ##############################################################################
import ZODB.blob import ZODB.blob
import ZODB.interfaces import ZODB.interfaces
import ZODB.utils
import zope.interface import zope.interface
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
...@@ -45,9 +46,7 @@ class HexStorage(object): ...@@ -45,9 +46,7 @@ class HexStorage(object):
def __len__(self): def __len__(self):
return len(self.base) return len(self.base)
def load(self, oid, version=''): load = ZODB.utils.load_current
data, serial = self.base.load(oid, version)
return unhexlify(data[2:]), serial
def loadBefore(self, oid, tid): def loadBefore(self, oid, tid):
r = self.base.loadBefore(oid, tid) r = self.base.loadBefore(oid, tid)
......
...@@ -28,7 +28,6 @@ from ZODB._compat import Unpickler ...@@ -28,7 +28,6 @@ from ZODB._compat import Unpickler
from ZODB._compat import BytesIO from ZODB._compat import BytesIO
from ZODB._compat import ascii_bytes from ZODB._compat import ascii_bytes
__all__ = ['z64', __all__ = ['z64',
'p64', 'p64',
'u64', 'u64',
...@@ -375,3 +374,26 @@ if os.environ.get('DEBUG_LOCKING'): ...@@ -375,3 +374,26 @@ if os.environ.get('DEBUG_LOCKING'):
else: else:
from threading import Condition, Lock, RLock 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