Commit 01d8d833 authored by Jim Fulton's avatar Jim Fulton

As a convenience, the connection root method for returning teh root

object can now *also* be used as an object with attributes mapped to
the root-object keys.
parent ace0e8a9
...@@ -14,6 +14,10 @@ New Features ...@@ -14,6 +14,10 @@ New Features
New Features New Features
------------ ------------
- As a convenience, the connection root method for returning teh root
object can now *also* be used as an object with attributes mapped to
the root-object keys.
- Databases have a new method, transaction, that can be used with the - Databases have a new method, transaction, that can be used with the
Python (2.5 and later) with statement:: Python (2.5 and later) with statement::
......
...@@ -356,9 +356,10 @@ class Connection(ExportImport, object): ...@@ -356,9 +356,10 @@ class Connection(ExportImport, object):
finally: finally:
self._inv_lock.release() self._inv_lock.release()
@property
def root(self): def root(self):
"""Return the database root object.""" """Return the database root object."""
return self.get(z64) return RootConvenience(self.get(z64))
def get_connection(self, database_name): def get_connection(self, database_name):
"""Return a Connection for the named database.""" """Return a Connection for the named database."""
...@@ -1333,3 +1334,32 @@ class TmpStore: ...@@ -1333,3 +1334,32 @@ class TmpStore:
# a copy of the index here. An alternative would be to ensure that # a copy of the index here. An alternative would be to ensure that
# all callers pass copies. As is, our callers do not make copies. # all callers pass copies. As is, our callers do not make copies.
self.index = index.copy() self.index = index.copy()
class RootConvenience(object):
def __init__(self, root):
self.__dict__['_root'] = root
def __getattr__(self, name):
try:
return self._root[name]
except KeyError:
raise AttributeError(name)
def __setattr__(self, name, v):
self._root[name] = v
def __delattr__(self, name):
try:
del self._root[name]
except KeyError:
raise AttributeError(name)
def __call__(self):
return self._root
def __repr__(self):
names = " ".join(sorted(self._root))
if len(names) > 60:
names = names[:57].rsplit(' ', 1)[0] + ' ...'
return "<root: %s>" % names
...@@ -519,6 +519,43 @@ def test_invalidateCache(): ...@@ -519,6 +519,43 @@ def test_invalidateCache():
>>> db.close() >>> db.close()
""" """
def connection_root_convenience():
"""Connection root attributes can now be used as objects with attributes
>>> db = ZODB.tests.util.DB()
>>> conn = db.open()
>>> conn.root.x
Traceback (most recent call last):
...
AttributeError: x
>>> del conn.root.x
Traceback (most recent call last):
...
AttributeError: x
>>> conn.root()['x'] = 1
>>> conn.root.x
1
>>> conn.root.y = 2
>>> sorted(conn.root().items())
[('x', 1), ('y', 2)]
>>> conn.root
<root: x y>
>>> del conn.root.x
>>> sorted(conn.root().items())
[('y', 2)]
>>> conn.root.rather_long_name = 1
>>> conn.root.rather_long_name2 = 1
>>> conn.root.rather_long_name4 = 1
>>> conn.root.rather_long_name5 = 1
>>> conn.root
<root: rather_long_name rather_long_name2 rather_long_name4 ...>
"""
class _PlayPersistent(Persistent): class _PlayPersistent(Persistent):
def setValueWithSize(self, size=0): self.value = size*' ' def setValueWithSize(self, size=0): self.value = size*' '
__init__ = setValueWithSize __init__ = setValueWithSize
......
...@@ -192,7 +192,7 @@ if sys.version_info >= (2, 6): ...@@ -192,7 +192,7 @@ if sys.version_info >= (2, 6):
and see that it isn't automatically committed or aborted as we use and see that it isn't automatically committed or aborted as we use
the transaction context manager. the transaction context manager.
>>> db = ZODB.DB('data.fs') >>> db = ZODB.tests.util.DB()
>>> conn = db.open() >>> conn = db.open()
>>> conn.root()['x'] = conn.root().__class__() >>> conn.root()['x'] = conn.root().__class__()
>>> transaction.commit() >>> transaction.commit()
...@@ -236,6 +236,8 @@ if sys.version_info >= (2, 6): ...@@ -236,6 +236,8 @@ if sys.version_info >= (2, 6):
>>> conn3.root()['x'] >>> conn3.root()['x']
{'x': 1} {'x': 1}
>>> db.close()
""" """
def test_suite(): def test_suite():
......
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