[Zope3-checkins] CVS: Zope3/src/zodb/storage - mapping.py:1.3 interfaces.py:1.5 fsrecover.py:1.3 file.py:1.8 bdbminimal.py:1.11 bdbfull.py:1.12 base.py:1.13
Jeremy Hylton
jeremy@zope.com
Wed, 5 Feb 2003 18:29:06 -0500
Update of /cvs-repository/Zope3/src/zodb/storage
In directory cvs.zope.org:/tmp/cvs-serv16759/src/zodb/storage
Modified Files:
mapping.py interfaces.py fsrecover.py file.py bdbminimal.py
bdbfull.py base.py
Log Message:
Merge storage-interface-branch to trunk.
Rename methods that had underscores to use camel case.
new_oid => newObjectId
tpc_begin => tpcBegin
tpc_vote => tpcVote
tpc_finish => tpcFinish
tpc_abort => tpcAbort
transactionalUndo => undo
Remove some methods from storage interfaces.
Move storage-related exceptions to zodb.storage.interfaces.
Add __implements__ to storages and use for introspection in place of
supportsXXX().
=== Zope3/src/zodb/storage/mapping.py 1.2 => 1.3 ===
--- Zope3/src/zodb/storage/mapping.py:1.2 Wed Dec 25 09:12:19 2002
+++ Zope3/src/zodb/storage/mapping.py Wed Feb 5 18:28:32 2003
@@ -92,6 +92,7 @@
import zodb.db
from zodb import interfaces, utils
from zodb.storage import base
+from zodb.storage.interfaces import *
from zodb.serialize import findrefs
from zodb.timestamp import TimeStamp
from zodb.utils import z64
@@ -104,6 +105,8 @@
class MappingStorage(base.BaseStorage):
+ __implements__ = IStorage
+
def __init__(self, name='Mapping Storage'):
base.BaseStorage.__init__(self, name)
@@ -125,10 +128,10 @@
def store(self, oid, serial, data, version, transaction):
if transaction is not self._transaction:
- raise interfaces.StorageTransactionError(self, transaction)
+ raise StorageTransactionError(self, transaction)
if version:
- raise interfaces.Unsupported, "Versions aren't supported"
+ raise NotImplementedError
self._lock_acquire()
try:
=== Zope3/src/zodb/storage/interfaces.py 1.4 => 1.5 ===
--- Zope3/src/zodb/storage/interfaces.py:1.4 Tue Feb 4 11:40:57 2003
+++ Zope3/src/zodb/storage/interfaces.py Wed Feb 5 18:28:32 2003
@@ -17,6 +17,7 @@
"""
from zope.interface import Interface, Attribute
+from zodb.interfaces import POSError
__all__ = ["IStorage",
"IUndoStorage",
@@ -24,6 +25,14 @@
"IStorageIterator",
"ITransactionRecordIterator",
"IDataRecord",
+ # the rest are exceptions
+ "StorageError",
+ "StorageVersionError",
+ "StorageTransactionError",
+ "StorageSystemError",
+ "MountedStorageError",
+ "ReadOnlyError",
+ "TransactionTooLargeError",
]
class IStorage(Interface):
@@ -116,7 +125,7 @@
"""
pass
- def new_oid():
+ def newObjectId():
pass
def registerDB(db):
@@ -131,9 +140,6 @@
def copyTransactionsFrom(other, versbose=False):
pass
- def iterator(start=None, stop=None):
- pass
-
def lastTransaction():
pass
@@ -145,45 +151,27 @@
# two-phase commit
- def tpc_begin(txn):
- pass
-
- def tpc_vote(txn):
- pass
-
- def tpc_finish(txn):
- pass
-
- def tpc_abort(txn):
+ def tpcBegin(txn):
pass
- # storages that keep revisions
-
- def transactionalUndo(txnid, txn):
+ def tpcVote(txn):
pass
- def undoInfo(first=0, last=-20, specification=None):
+ def tpcFinish(txn):
pass
- # XXX Move undoLog -> _undoLog and remove from interface
- def undoLog(first, last, filter=None):
+ def tpcAbort(txn):
pass
def pack(t):
pass
- def getSerial(oid):
- pass
-
- def loadSerial(oid, serial):
- pass
-
class IUndoStorage(Interface):
def loadSerial(oid, serial):
pass
- def transactionalUndo(txnid, txn):
+ def undo(txnid, txn):
pass
def undoInfo(first=0, last=-20, specification=None):
@@ -192,6 +180,9 @@
def undoLog(first, last, filter=None):
"""deprecated, using undoInfo instead"""
+ def iterator(start=None, stop=None):
+ pass
+
class IVersionStorage(Interface):
# XXX should be renamed
def abortVersion(version):
@@ -250,3 +241,35 @@
wrote the data. The current transaction contains
a logical copy of that data.
""")
+
+class StorageError(POSError):
+ """Base class for storage based exceptions."""
+
+class StorageVersionError(StorageError):
+ """The storage version doesn't match the database version."""
+
+ def __init__(self, db_ver, storage_ver):
+ self.db_ver = db_ver
+ self.storage_ver = storage_ver
+
+ def __str__(self):
+ db = ".".join(self.db_ver)
+ storage = ".".join(self.storage_ver)
+ return ("Storage version %s passed to database version %s"
+ % (storage, db))
+
+class StorageTransactionError(StorageError):
+ """An operation was invoked for an invalid transaction or state."""
+
+class StorageSystemError(StorageError):
+ """Panic! Internal storage error!"""
+
+class MountedStorageError(StorageError):
+ """Unable to access mounted storage."""
+
+class ReadOnlyError(StorageError):
+ """Unable to modify objects in a read-only storage."""
+
+class TransactionTooLargeError(StorageTransactionError):
+ """The transaction exhausted some finite storage resource."""
+
=== Zope3/src/zodb/storage/fsrecover.py 1.2 => 1.3 ===
--- Zope3/src/zodb/storage/fsrecover.py:1.2 Wed Dec 25 09:12:19 2002
+++ Zope3/src/zodb/storage/fsrecover.py Wed Feb 5 18:28:32 2003
@@ -269,7 +269,7 @@
if verbose > 1: print
sys.stdout.flush()
- ofs.tpc_begin(transaction, tid, transaction.status)
+ ofs.tpcBegin(transaction, tid, transaction.status)
if verbose:
print 'begin', pos, _ts,
@@ -288,17 +288,17 @@
except:
if partial and nrec:
ofs._status='p'
- ofs.tpc_vote(transaction)
- ofs.tpc_finish(transaction)
+ ofs.tpcVote(transaction)
+ ofs.tpcFinish(transaction)
if verbose: print 'partial'
else:
- ofs.tpc_abort(transaction)
+ ofs.tpcAbort(transaction)
print "\n%s: %s\n" % sys.exc_info()[:2]
if not verbose: progress(prog1)
pos = scan(file, pos, file_size)
else:
- ofs.tpc_vote(transaction)
- ofs.tpc_finish(transaction)
+ ofs.tpcVote(transaction)
+ ofs.tpcFinish(transaction)
if verbose:
print 'finish'
sys.stdout.flush()
=== Zope3/src/zodb/storage/file.py 1.7 => 1.8 ===
--- Zope3/src/zodb/storage/file.py:1.7 Mon Feb 3 18:00:45 2003
+++ Zope3/src/zodb/storage/file.py Wed Feb 5 18:28:32 2003
@@ -127,6 +127,8 @@
$Id$
"""
+from __future__ import generators
+
import base64
from cPickle import Pickler, Unpickler, loads
import errno
@@ -144,7 +146,7 @@
fsync = None
import zodb.db
-from zodb.storage.base import BaseStorage, TransactionRecord, DataRecord
+from zodb.storage.base import BaseStorage
from zodb import conflict
from zodb import interfaces
from zodb.interfaces import UndoError, POSKeyError, MultipleUndoErrors
@@ -153,6 +155,8 @@
from zodb.lockfile import lock_file
from zodb.utils import p64, u64, cp, z64
from zodb.storage.fsindex import fsIndex
+from zodb.storage.interfaces import *
+from zodb.interfaces import ITransactionAttrs
t32 = 1L << 32
# the struct formats for the headers
@@ -175,7 +179,7 @@
logger.critical(message, *data)
raise CorruptedTransactionError(message % data)
-class FileStorageError(interfaces.StorageError):
+class FileStorageError(StorageError):
pass
class PackError(FileStorageError):
@@ -187,8 +191,7 @@
The format of the given file is not valid.
"""
-class CorruptedFileStorageError(FileStorageError,
- interfaces.StorageSystemError):
+class CorruptedFileStorageError(FileStorageError, StorageSystemError):
"""Corrupted file storage."""
class CorruptedTransactionError(CorruptedFileStorageError):
@@ -206,8 +209,7 @@
else:
return "Error reading unknown oid. Found %r" % self.buf
-class FileStorageQuotaError(FileStorageError,
- interfaces.StorageSystemError):
+class FileStorageQuotaError(FileStorageError, StorageSystemError):
"""File storage quota exceeded."""
def DB(file_name, create=0, read_only=0, stop=None, quota=None,
@@ -486,6 +488,8 @@
# default pack time is 0
_packt = z64
+ __implements__ = IStorage, IUndoStorage, IVersionStorage
+
def __init__(self, file_name, create=0, read_only=0, stop=None,
quota=None):
@@ -674,7 +678,7 @@
def commitVersion(self, src, dest, transaction, abort=None):
# We are going to commit by simply storing back pointers.
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
if not (src and isinstance(src, StringType)
and isinstance(dest, StringType)):
raise interfaces.VersionCommitError('Invalid source version')
@@ -688,7 +692,7 @@
"Internal error, can't abort to a version")
if transaction is not self._transaction:
- raise interfaces.StorageTransactionError(self, transaction)
+ raise StorageTransactionError(self, transaction)
self._lock_acquire()
try:
@@ -820,9 +824,9 @@
def store(self, oid, serial, data, version, transaction):
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
if transaction is not self._transaction:
- raise interfaces.StorageTransactionError(self, transaction)
+ raise StorageTransactionError(self, transaction)
self._lock_acquire()
try:
@@ -927,9 +931,9 @@
# should be considered just a hint, and is ignored if the transaction
# doesn't exist.
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
if transaction is not self._transaction:
- raise interfaces.StorageTransactionError(self, transaction)
+ raise StorageTransactionError(self, transaction)
self._lock_acquire()
try:
@@ -1009,12 +1013,6 @@
"at %d or %d", prev, bp)
return None
- def supportsUndo(self):
- return 1
-
- def supportsVersions(self):
- return 1
-
def _clear_temp(self):
self._tindex.clear()
self._tvindex.clear()
@@ -1036,7 +1034,7 @@
raise FileStorageError('too much extension data')
- def tpc_vote(self, transaction):
+ def tpcVote(self, transaction):
self._lock_acquire()
try:
if transaction is not self._transaction:
@@ -1104,9 +1102,6 @@
self._file.truncate(self._pos)
self._nextpos=0
- def supportsTransactionalUndo(self):
- return 1
-
def _undoDataInfo(self, oid, pos, tpos):
"""Return the serial, data pointer, data, and version for the oid
record at pos"""
@@ -1267,7 +1262,7 @@
finally:
self._lock_release()
- def transactionalUndo(self, transaction_id, transaction):
+ def undo(self, transaction_id, transaction):
"""Undo a transaction, given by transaction_id.
Do so by writing new data that reverses the action taken by
@@ -1280,9 +1275,9 @@
"""
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
if transaction is not self._transaction:
- raise interfaces.StorageTransactionError(self, transaction)
+ raise StorageTransactionError(self, transaction)
self._lock_acquire()
try:
@@ -1445,7 +1440,7 @@
"""
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
stop = timeStampFromTime(t).raw()
if stop == z64:
@@ -2180,33 +2175,18 @@
break
except:
error("couldn\'t write truncated data for %s", name)
- raise interfaces.StorageSystemError, (
- "Couldn't save truncated data")
+ raise StorageSystemError("Couldn't save truncated data")
seek(pos)
file.truncate()
-class Iterator:
- """A General simple iterator that uses the Python for-loop index protocol
- """
- __index=-1
- __current=None
-
- def __getitem__(self, i):
- __index=self.__index
- while i > __index:
- __index=__index+1
- self.__current=self.next(__index)
-
- self.__index=__index
- return self.__current
-
-
-class FileIterator(Iterator, FileStorageFormatter):
+class FileIterator(FileStorageFormatter):
"""Iterate over the transactions in a FileStorage file."""
_ltid = z64
_file = None
+ __implements__ = IStorageIterator
+
def __init__(self, file, start=None, stop=None):
if isinstance(file, StringType):
file = open(file, 'rb')
@@ -2253,16 +2233,16 @@
"(%s != %s)",
self._file.name, pos, u64(rtl), u64(stl))
- def next(self, index=0):
+ def __iter__(self):
if self._file is None:
# A closed iterator. XXX: Is IOError the best we can do? For
# now, mimic a read on a closed file.
- raise IOError, 'iterator is closed'
+ raise IOError("iterator is closed")
file=self._file
seek=file.seek
read=file.read
- pos=self._pos
-
+
+ pos = self._pos
while 1:
# Read the transaction record
seek(pos)
@@ -2312,7 +2292,7 @@
break
if self._stop is not None and tid > self._stop:
- raise IndexError, index
+ return
tpos=pos
tend=tpos+tl
@@ -2346,15 +2326,14 @@
warn("%s redundant transaction length check failed at %s",
self._file.name, pos)
break
- self._pos = pos + 8
-
- return result
-
- raise IndexError, index
+ pos += 8
+ yield result
-class RecordIterator(Iterator, FileStorageFormatter, TransactionRecord):
+class RecordIterator(FileStorageFormatter):
"""Iterate over the transactions in a FileStorage file."""
+ __implements__ = ITransactionRecordIterator, ITransactionAttrs
+
def __init__(self, tid, status, user, desc, ext, pos, tend, file, tpos):
self.tid = tid
self.status = status
@@ -2366,7 +2345,7 @@
self._file = file
self._tpos = tpos
- def next(self, index=0):
+ def __iter__(self):
pos = self._pos
while pos < self._tend:
# Read the data records for this transaction
@@ -2377,9 +2356,9 @@
if pos + dlen > self._tend or h.tloc != self._tpos:
warn("%s data record exceeds transaction record at %s",
file.name, pos)
- break
+ return
- self._pos = pos + dlen
+ pos += dlen
prev_txn = None
if h.plen:
data = self._file.read(h.plen)
@@ -2395,14 +2374,13 @@
data, _s, tid = self._loadBackTxn(h.oid, h.back)
prev_txn = self.getTxnFromData(h.oid, h.back)
- r = Record(h.oid, h.serial, h.version, data, prev_txn)
+ yield Record(h.oid, h.serial, h.version, data, prev_txn)
- return r
-
- raise IndexError, index
-
-class Record(DataRecord):
+class Record:
"""An abstract database record."""
+
+ __implements__ = IDataRecord
+
def __init__(self, *args):
self.oid, self.serial, self.version, self.data, self.data_txn = args
=== Zope3/src/zodb/storage/bdbminimal.py 1.10 => 1.11 ===
--- Zope3/src/zodb/storage/bdbminimal.py:1.10 Thu Jan 30 18:17:43 2003
+++ Zope3/src/zodb/storage/bdbminimal.py Wed Feb 5 18:28:32 2003
@@ -17,7 +17,7 @@
$Revision$
"""
-from zodb import interfaces
+from zodb.storage.interfaces import *
from zodb.utils import p64, u64
from zodb.serialize import findrefs
from zodb.conflict import ConflictResolvingStorage, ResolvedSerial
@@ -40,6 +40,9 @@
class BDBMinimalStorage(BerkeleyBase, ConflictResolvingStorage):
+
+ __implements__ = IStorage
+
def _init(self):
# Data Type Assumptions:
#
@@ -283,10 +286,10 @@
def store(self, oid, serial, data, version, transaction):
if transaction is not self._transaction:
- raise interfaces.StorageTransactionError(self, transaction)
+ raise StorageTransactionError(self, transaction)
# We don't support versions
if version <> '':
- raise interfaces.Unsupported, 'versions are not supported'
+ raise NotImplementedError
# All updates must be done with the application lock acquired
self._lock_acquire()
try:
@@ -343,7 +346,7 @@
def load(self, oid, version):
if version <> '':
- raise interfaces.Unsupported, 'versions are not supported'
+ raise NotImplementedError
self._lock_acquire()
try:
# Get the current serial number for this object
@@ -512,30 +515,7 @@
orec = self._oidqueue.consume(txn)
assert len(self._oidqueue) == 0
- #
- # Stuff we don't support
- #
-
- def supportsTransactionalUndo(self):
- return False
-
- def supportsUndo(self):
- return False
-
- def supportsVersions(self):
- return False
-
- # Don't implement these
- #
- # versionEmpty(self, version)
- # versions(self, max=None)
- # loadSerial(self, oid, serial)
# getSerial(self, oid)
- # transactionalUndo(self, tid, transaction)
- # undoLog(self, first=0, last=-20, filter=None)
- # history(self, oid, version=None, size=1, filter=None)
- # iterator(self, start=None, stop=None)
-
class _Autopack(_WorkThread):
=== Zope3/src/zodb/storage/bdbfull.py 1.11 => 1.12 ===
--- Zope3/src/zodb/storage/bdbfull.py:1.11 Tue Feb 4 11:44:44 2003
+++ Zope3/src/zodb/storage/bdbfull.py Wed Feb 5 18:28:32 2003
@@ -21,14 +21,14 @@
import cPickle as pickle
from struct import pack, unpack
-# I really don't want a 10 line import or __implements__ :/
from zodb.interfaces import *
+from zodb.storage.interfaces import *
from zodb.utils import p64, u64
from zodb.serialize import findrefs
from zodb.timestamp import TimeStamp
from zodb.conflict import ConflictResolvingStorage, ResolvedSerial
-# I really don't want a 10 line import or __implements__ :/
-from zodb.storage.interfaces import *
+from zodb.interfaces import ITransactionAttrs
+from zodb.storage.interfaces import StorageSystemError
from zodb.storage.base import db, ZERO, BerkeleyBase, PackStop, _WorkThread
from zodb.storage._helper import incr
@@ -54,8 +54,9 @@
class BDBFullStorage(BerkeleyBase, ConflictResolvingStorage):
+
__implements__ = IStorage, IUndoStorage, IVersionStorage
-
+
def _init(self):
# Data Type Assumptions:
#
@@ -1185,7 +1186,7 @@
self._objrevs.put(newserial+oid, prevrevid, txn=txn)
return rtnoids.keys()
- def transactionalUndo(self, tid, transaction):
+ def undo(self, tid, transaction):
if transaction is not self._transaction:
raise StorageTransactionError(self, transaction)
self._lock_acquire()
@@ -1678,17 +1679,6 @@
finally:
c.close()
self._lock_release()
-
- # Other interface assertions
- def supportsTransactionalUndo(self):
- return True
-
- def supportsUndo(self):
- return True
-
- def supportsVersions(self):
- return True
-
class _GetItemBase:
=== Zope3/src/zodb/storage/base.py 1.12 => 1.13 ===
--- Zope3/src/zodb/storage/base.py:1.12 Tue Feb 4 11:42:44 2003
+++ Zope3/src/zodb/storage/base.py Wed Feb 5 18:28:32 2003
@@ -40,9 +40,9 @@
db = None
berkeley_is_available = False
-from zodb import interfaces
from zodb.timestamp import newTimeStamp, TimeStamp
from zodb.interfaces import ITransactionAttrs
+from zodb.storage.interfaces import StorageTransactionError, ReadOnlyError
# BaseStorage provides primitives for lock acquisition and release, and a host
# of other methods, some of which are overridden here, some of which are not.
from zodb.lockfile import lock_file
@@ -84,12 +84,12 @@
def abortVersion(self, src, transaction):
if transaction is not self._transaction:
- raise interfaces.StorageTransactionError(self, transaction)
+ raise StorageTransactionError(self, transaction)
return []
def commitVersion(self, src, dest, transaction):
if transaction is not self._transaction:
- raise interfaces.StorageTransactionError(self, transaction)
+ raise StorageTransactionError(self, transaction)
return []
def close(self):
@@ -113,10 +113,10 @@
def modifiedInVersion(self, oid):
return ''
- def new_oid(self, last=None):
+ def newObjectId(self, last=None):
# 'last' is only for internal use, not part of the public API
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
if last is None:
self._lock_acquire()
try:
@@ -125,7 +125,7 @@
if d < 255:
last = last[:-1] + chr(d+1)
else:
- last = self.new_oid(last[:-1])
+ last = self.newObjectId(last[:-1])
self._oid = last
return last
finally:
@@ -135,7 +135,7 @@
if d < 255:
return last[:-1] + chr(d+1) + '\0'*(8-len(last))
else:
- return self.new_oid(last[:-1])
+ return self.newObjectId(last[:-1])
def registerDB(self, db):
pass # we don't care
@@ -143,15 +143,12 @@
def isReadOnly(self):
return self._is_read_only
- def supportsVersions(self):
- return False
-
def _clear_temp(self):
# Called by tpc_begin(), tpc_abort(), and tpc_finish(), this should be
# overridden in storages to clear out any temporary state.
pass
- def tpc_abort(self, transaction):
+ def tpcAbort(self, transaction):
self._lock_acquire()
try:
if transaction is not self._transaction:
@@ -167,10 +164,10 @@
# Subclasses should define this to supply abort actions.
pass
- def tpc_begin(self, transaction, tid=None, status=' '):
+ def tpcBegin(self, transaction, tid=None, status=' '):
assert ITransactionAttrs.isImplementedBy(transaction)
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
self._lock_acquire()
try:
if self._transaction is transaction:
@@ -202,7 +199,7 @@
# Subclasses should define this to supply transaction start actions.
pass
- def tpc_vote(self, transaction):
+ def tpcVote(self, transaction):
self._lock_acquire()
try:
if transaction is not self._transaction:
@@ -215,7 +212,7 @@
# Subclasses should define this to supply transaction vote actions.
pass
- def tpc_finish(self, transaction, f=None):
+ def tpcFinish(self, transaction, f=None):
self._lock_acquire()
try:
if transaction is not self._transaction:
@@ -282,7 +279,7 @@
def pack(self, t):
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
def getSerial(self, oid):
self._lock_acquire()
@@ -294,8 +291,7 @@
self._lock_release()
def loadSerial(self, oid, serial):
- raise interfaces.Unsupported, (
- "Retrieval of historical revisions is not supported")
+ raise NotImplementedError
def getExtensionMethods(self):
"""getExtensionMethods
@@ -338,23 +334,14 @@
if verbose:
print _ts
- self.tpc_begin(transaction, tid, transaction.status)
+ self.tpcBegin(transaction, tid, transaction.status)
for r in transaction:
if verbose:
print `r.oid`, r.version, len(r.data)
self.restore(r.oid, r.serial, r.data, r.version,
r.data_txn, transaction)
- self.tpc_vote(transaction)
- self.tpc_finish(transaction)
-
-class TransactionRecord:
- """Abstract base class for iterator protocol."""
-
- __implements__ = ITransactionAttrs
-
-class DataRecord:
- """Abstract base class for iterator protocol."""
-
+ self.tpcVote(transaction)
+ self.tpcFinish(transaction)
class BerkeleyConfig:
@@ -606,7 +593,7 @@
self._len = len(self._serials)
return self._len
- def new_oid(self, last=None):
+ def newObjectId(self, last=None):
"""Create a new object id.
If last is provided, the new oid will be one greater than that.
@@ -615,7 +602,7 @@
if self._len is not None:
# Increment the cached length
self._len += 1
- return BaseStorage.new_oid(self, last)
+ return BaseStorage.newObjectId(self, last)
def getSize(self):
"""Return the size of the database."""