[Zodb-checkins] SVN: ZODB/trunk/src/ZODB/ The databasesFrom... methods now support multiple databases.
Jim Fulton
jim at zope.com
Thu Apr 30 07:43:49 EDT 2009
Log message for revision 99604:
The databasesFrom... methods now support multiple databases.
Added an option to disallow cross-database references.
Changed:
U ZODB/trunk/src/ZODB/config.py
U ZODB/trunk/src/ZODB/config.xml
U ZODB/trunk/src/ZODB/tests/testConfig.py
-=-
Modified: ZODB/trunk/src/ZODB/config.py
===================================================================
--- ZODB/trunk/src/ZODB/config.py 2009-04-30 11:43:47 UTC (rev 99603)
+++ ZODB/trunk/src/ZODB/config.py 2009-04-30 11:43:49 UTC (rev 99604)
@@ -49,9 +49,16 @@
config, handler = ZConfig.loadConfig(getDbSchema(), url)
return databaseFromConfig(config.database)
-def databaseFromConfig(section):
- return section.open()
+def databaseFromConfig(database_factories):
+ databases = {}
+ first = None
+ for factory in database_factories:
+ db = factory.open(databases)
+ if first is None:
+ first = db
+ return first
+
def storageFromString(s):
return storageFromFile(StringIO(s))
@@ -93,9 +100,17 @@
section = self.config
storage = section.storage.open()
options = {}
- if section.pool_timeout is not None:
- options['pool_timeout'] = section.pool_timeout
+ def _option(name, oname=None):
+ v = getattr(section, name)
+ if v is not None:
+ if oname is None:
+ oname = name
+ options[oname] = v
+
+ _option('pool_timeout')
+ _option('allow_implicit_cross_references', 'xrefs')
+
try:
return ZODB.DB(
storage,
@@ -106,7 +121,7 @@
historical_cache_size=section.historical_cache_size,
historical_cache_size_bytes=section.historical_cache_size_bytes,
historical_timeout=section.historical_timeout,
- database_name=section.database_name,
+ database_name=section.database_name or self.name or '',
databases=databases,
**options)
except:
Modified: ZODB/trunk/src/ZODB/config.xml
===================================================================
--- ZODB/trunk/src/ZODB/config.xml 2009-04-30 11:43:47 UTC (rev 99603)
+++ ZODB/trunk/src/ZODB/config.xml 2009-04-30 11:43:49 UTC (rev 99604)
@@ -2,6 +2,7 @@
<import package="ZODB"/>
- <section type="ZODB.database" name="*" attribute="database"/>
+ <multisection type="ZODB.database" name="*" attribute="database"
+ required="yes" />
</schema>
Modified: ZODB/trunk/src/ZODB/tests/testConfig.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testConfig.py 2009-04-30 11:43:47 UTC (rev 99603)
+++ ZODB/trunk/src/ZODB/tests/testConfig.py 2009-04-30 11:43:49 UTC (rev 99604)
@@ -12,23 +12,26 @@
#
##############################################################################
-import os
+import doctest
+import tempfile
+import unittest
+
import transaction
-import unittest
-import ZEO.ClientStorage
import ZODB.config
-import ZODB.POSException
-import ZODB.tests.util
-from zope.testing import doctest
+from ZODB.POSException import ReadOnlyError
-class ConfigTestBase(ZODB.tests.util.TestCase):
+class ConfigTestBase(unittest.TestCase):
def _opendb(self, s):
return ZODB.config.databaseFromString(s)
+ def tearDown(self):
+ if getattr(self, "storage", None) is not None:
+ self.storage.cleanup()
+
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()
@@ -56,26 +59,28 @@
""")
def test_file_config1(self):
+ path = tempfile.mktemp()
self._test(
"""
<zodb>
<filestorage>
- path Data.fs
+ path %s
</filestorage>
</zodb>
- """)
+ """ % path)
def test_file_config2(self):
+ path = tempfile.mktemp()
cfg = """
<zodb>
<filestorage>
- path Data.fs
+ path %s
create false
read-only true
</filestorage>
</zodb>
- """
- self.assertRaises(ZODB.POSException.ReadOnlyError, self._test, cfg)
+ """ % path
+ self.assertRaises(ReadOnlyError, self._test, cfg)
def test_demo_config(self):
cfg = """
@@ -110,54 +115,116 @@
</zodb>
"""
config, handle = ZConfig.loadConfigFile(getDbSchema(), StringIO(cfg))
- self.assertEqual(config.database.config.storage.config.blob_dir,
+ self.assertEqual(config.database[0].config.storage.config.blob_dir,
None)
self.assertRaises(ClientDisconnected, self._test, cfg)
cfg = """
<zodb>
<zeoclient>
- blob-dir blobs
+ blob-dir /tmp
server localhost:56897
wait false
</zeoclient>
</zodb>
"""
config, handle = ZConfig.loadConfigFile(getDbSchema(), StringIO(cfg))
- self.assertEqual(
- os.path.abspath(config.database.config.storage.config.blob_dir),
- os.path.abspath('blobs'))
+ self.assertEqual(config.database[0].config.storage.config.blob_dir,
+ '/tmp')
self.assertRaises(ClientDisconnected, self._test, cfg)
-def db_connection_pool_timeout():
+def database_xrefs_config():
+ r"""
+ >>> db = ZODB.config.databaseFromString(
+ ... "<zodb>\n<mappingstorage>\n</mappingstorage>\n</zodb>\n")
+ >>> db.xrefs
+ True
+ >>> db = ZODB.config.databaseFromString(
+ ... "<zodb>\nallow-implicit-cross-references true\n"
+ ... "<mappingstorage>\n</mappingstorage>\n</zodb>\n")
+ >>> db.xrefs
+ True
+ >>> db = ZODB.config.databaseFromString(
+ ... "<zodb>\nallow-implicit-cross-references false\n"
+ ... "<mappingstorage>\n</mappingstorage>\n</zodb>\n")
+ >>> db.xrefs
+ False
"""
-Test that the database pool timeout option works:
+def multi_atabases():
+ r"""If there are multiple codb sections -> multidatabase
+
>>> db = ZODB.config.databaseFromString('''
- ... <zodb>
- ... <mappingstorage/>
- ... </zodb>
+ ... <zodb>
+ ... <mappingstorage>
+ ... </mappingstorage>
+ ... </zodb>
+ ... <zodb Foo>
+ ... <mappingstorage>
+ ... </mappingstorage>
+ ... </zodb>
+ ... <zodb>
+ ... database-name Bar
+ ... <mappingstorage>
+ ... </mappingstorage>
+ ... </zodb>
... ''')
- >>> db.pool._timeout == 1<<31
- True
+ >>> sorted(db.databases)
+ ['', 'Bar', 'foo']
- >>> db = ZODB.config.databaseFromString('''
- ... <zodb>
- ... pool-timeout 600
- ... <mappingstorage/>
- ... </zodb>
- ... ''')
- >>> db.pool._timeout == 600
+ >>> db.database_name
+ ''
+ >>> db.databases[db.database_name] is db
True
+ >>> db.databases['foo'] is not db
+ True
+ >>> db.databases['Bar'] is not db
+ True
+ >>> db.databases['Bar'] is not db.databases['foo']
+ True
+ Can't have repeats:
+
+ >>> ZODB.config.databaseFromString('''
+ ... <zodb 1>
+ ... <mappingstorage>
+ ... </mappingstorage>
+ ... </zodb>
+ ... <zodb 1>
+ ... <mappingstorage>
+ ... </mappingstorage>
+ ... </zodb>
+ ... <zodb 1>
+ ... <mappingstorage>
+ ... </mappingstorage>
+ ... </zodb>
+ ... ''') # doctest: +NORMALIZE_WHITESPACE
+ Traceback (most recent call last):
+ ...
+ ConfigurationSyntaxError:
+ section names must not be re-used within the same container:'1' (line 9)
+
+ >>> ZODB.config.databaseFromString('''
+ ... <zodb>
+ ... <mappingstorage>
+ ... </mappingstorage>
+ ... </zodb>
+ ... <zodb>
+ ... <mappingstorage>
+ ... </mappingstorage>
+ ... </zodb>
+ ... ''') # doctest: +NORMALIZE_WHITESPACE
+ Traceback (most recent call last):
+ ...
+ ValueError: database_name '' already in databases
+
"""
-
def test_suite():
suite = unittest.TestSuite()
+ suite.addTest(doctest.DocTestSuite())
suite.addTest(unittest.makeSuite(ZODBConfigTest))
suite.addTest(unittest.makeSuite(ZEOConfigTest))
- suite.addTest(doctest.DocTestSuite())
return suite
More information about the Zodb-checkins
mailing list