Commit 0e8b79d1 authored by Jim Fulton's avatar Jim Fulton

Exposed database storages using the public "storage" attribute.

(The storage is also available as "_storage" for backward
compatibility, mainly for test code.)
parent 0d27b65c
......@@ -73,10 +73,10 @@ This tests tries to provoke this bug by:
... _ = lock.acquire()
... try:
... time.sleep(.1)
... assert (db._storage.lastTransaction()
... == db._storage._server.lastTransaction()), (
... db._storage.lastTransaction(),
... db._storage._server.lastTransactiion())
... assert (db.storage.lastTransaction()
... == db.storage._server.lastTransaction()), (
... db.storage.lastTransaction(),
... db.storage._server.lastTransactiion())
... conn = db.open()
... for i in range(1000):
... if conn.root()[i].value != conn2.root()[i].value:
......
......@@ -93,8 +93,8 @@ class Connection(ExportImport, object):
# Multi-database support
self.connections = {self._db.database_name: self}
self._normal_storage = self._storage = db._storage
self.new_oid = db._storage.new_oid
self._normal_storage = self._storage = db.storage
self.new_oid = db.storage.new_oid
self._savepoint_storage = None
# Do we need to join a txn manager?
......
......@@ -407,7 +407,7 @@ class DB(object):
self._historical_cache_size_bytes = historical_cache_size_bytes
# Setup storage
self._storage = storage
self.storage = storage
self.references = ZODB.serialize.referencesf
try:
storage.registerDB(self)
......@@ -455,7 +455,7 @@ class DB(object):
self.history = storage.history
def _setupUndoMethods(self):
storage = self._storage
storage = self.storage
try:
self.supportsUndo = storage.supportsUndo
except AttributeError:
......@@ -471,6 +471,10 @@ class DB(object):
raise NotImplementedError
self.undo = undo
@property
def _storage(self): # Backward compatibility
return self.storage
# This is called by Connection.close().
def _returnToPool(self, connection):
"""Return a connection to the pool.
......@@ -614,7 +618,7 @@ class DB(object):
is closed, so they stop behaving usefully. Perhaps close()
should also close all the Connections.
"""
self._storage.close()
self.storage.close()
def getCacheSize(self):
return self._cache_size
......@@ -623,16 +627,16 @@ class DB(object):
return self._cache_size_bytes
def lastTransaction(self):
return self._storage.lastTransaction()
return self.storage.lastTransaction()
def getName(self):
return self._storage.getName()
return self.storage.getName()
def getPoolSize(self):
return self.pool.size
def getSize(self):
return self._storage.getSize()
return self.storage.getSize()
def getHistoricalCacheSize(self):
return self._historical_cache_size
......@@ -668,7 +672,7 @@ class DB(object):
self._connectionMap(lambda c: c.invalidateCache())
def objectCount(self):
return len(self._storage)
return len(self.storage)
def open(self, transaction_manager=None, at=None, before=None):
"""Return a database Connection for use by application code.
......@@ -782,7 +786,7 @@ class DB(object):
t = time()
t -= days * 86400
try:
self._storage.pack(t, self.references)
self.storage.pack(t, self.references)
except:
logger.error("packing", exc_info=True)
raise
......@@ -891,9 +895,9 @@ class ResourceManager(object):
def __init__(self, db):
self._db = db
# Delegate the actual 2PC methods to the storage
self.tpc_vote = self._db._storage.tpc_vote
self.tpc_finish = self._db._storage.tpc_finish
self.tpc_abort = self._db._storage.tpc_abort
self.tpc_vote = self._db.storage.tpc_vote
self.tpc_finish = self._db.storage.tpc_finish
self.tpc_abort = self._db.storage.tpc_abort
# Get a number from a simple thread-safe counter, then
# increment it, for the purpose of sorting ResourceManagers by
......@@ -908,12 +912,12 @@ class ResourceManager(object):
resource_counter_lock.release()
def sortKey(self):
return "%s:%016x" % (self._db._storage.sortKey(), self._count)
return "%s:%016x" % (self._db.storage.sortKey(), self._count)
def tpc_begin(self, txn, sub=False):
if sub:
raise ValueError("doesn't support sub-transactions")
self._db._storage.tpc_begin(txn)
self._db.storage.tpc_begin(txn)
# The object registers itself with the txn manager, so the ob
# argument to the methods below is self.
......@@ -932,5 +936,5 @@ class TransactionalUndo(ResourceManager):
def commit(self, ob, t):
# XXX see XXX in ResourceManager
tid, oids = self._db._storage.undo(self._tid, t)
tid, oids = self._db.storage.undo(self._tid, t)
self._db.invalidate(tid, dict.fromkeys(oids, 1))
......@@ -355,6 +355,15 @@ class IDatabase(IStorageDB):
entry.
""")
storage = Attribute(
"""The object that provides storage for the database
This attribute is useful primarily for tests. Normal
application code should rarely, if ever, have a need to use
this attribute.
""")
def open(transaction_manager=None, serial=''):
"""Return an IConnection object for use by application code.
......
......@@ -26,7 +26,7 @@ class ConfigTestBase(ZODB.tests.util.TestCase):
def _test(self, s):
db = self._opendb(s)
self.storage = db._storage
self.storage = db.storage
# Do something with the database to make sure it works
cn = db.open()
rt = cn.root()
......
......@@ -96,7 +96,7 @@ class ConnectionDotAdd(ZODB.tests.util.TestCase):
self.assert_(obj._p_oid is None)
self.assert_(obj._p_jar is None)
self.assertRaises(KeyError, self.datamgr.get, oid)
self.assertEquals(self.db._storage._stored, [oid])
self.assertEquals(self.db.storage._stored, [oid])
def checkCommit(self):
obj = StubObject()
......@@ -111,8 +111,8 @@ class ConnectionDotAdd(ZODB.tests.util.TestCase):
# This next assert_ is covered by an assert in tpc_finish.
##self.assert_(not self.datamgr._added)
self.assertEquals(self.db._storage._stored, [oid])
self.assertEquals(self.db._storage._finished, [oid])
self.assertEquals(self.db.storage._stored, [oid])
self.assertEquals(self.db.storage._finished, [oid])
def checkModifyOnGetstate(self):
member = StubObject()
......@@ -123,7 +123,7 @@ class ConnectionDotAdd(ZODB.tests.util.TestCase):
self.datamgr.tpc_begin(self.transaction)
self.datamgr.commit(self.transaction)
self.datamgr.tpc_finish(self.transaction)
storage = self.db._storage
storage = self.db.storage
self.assert_(obj._p_oid in storage._stored, "object was not stored")
self.assert_(subobj._p_oid in storage._stored,
"subobject was not stored")
......@@ -352,7 +352,7 @@ class UserMethodTests(unittest.TestCase):
An expedient way to create a read-only storage:
>>> db._storage.isReadOnly = lambda: True
>>> db.storage.isReadOnly = lambda: True
>>> cn = db.open()
>>> cn.isReadOnly()
True
......@@ -753,7 +753,7 @@ class TestConnectionInterface(unittest.TestCase):
class StubDatabase:
def __init__(self):
self._storage = StubStorage()
self.storage = StubStorage()
classFactory = None
database_name = 'stubdatabase'
......
......@@ -135,7 +135,7 @@ True
We can confirm that we have a non-current revision by asking the
storage.
>>> db._storage.isCurrent(r2["a"]._p_oid, r2["a"]._p_serial)
>>> db.storage.isCurrent(r2["a"]._p_oid, r2["a"]._p_serial)
False
It's possible to modify "a", but we get a conflict error when we
......
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