[Checkins] SVN: relstorage/trunk/ Added the replica-conf option to the database adapters.
Shane Hathaway
shane at hathawaymix.org
Fri Oct 2 19:52:21 EDT 2009
Log message for revision 104759:
Added the replica-conf option to the database adapters.
Also rearranged docs, integrated docs about zodbconvert,
and added tests of the RelStorage ZConfig schema.
Changed:
U relstorage/trunk/CHANGES.txt
U relstorage/trunk/README.txt
U relstorage/trunk/relstorage/component.xml
U relstorage/trunk/relstorage/config.py
U relstorage/trunk/relstorage/tests/testmysql.py
U relstorage/trunk/relstorage/tests/testoracle.py
U relstorage/trunk/relstorage/tests/testpostgresql.py
-=-
Modified: relstorage/trunk/CHANGES.txt
===================================================================
--- relstorage/trunk/CHANGES.txt 2009-10-02 22:19:25 UTC (rev 104758)
+++ relstorage/trunk/CHANGES.txt 2009-10-02 23:52:21 UTC (rev 104759)
@@ -2,10 +2,14 @@
Unreleased
----------
-- Added the keep_history option to the database adapters. Set it
+- Added the keep-history option to the database adapters. Set it
to false to keep no history. (Packing is still required for
garbage collection and blob deletion.)
+- Added the replica-conf option to the database adapters. Set it
+ to a filename containing the location of database replicas. Changes
+ to the file take effect at transaction boundaries.
+
- Copied the ZConfig documentation of the storage options into README.
- Renamed relstorage.py to storage.py to overcome import issues.
Modified: relstorage/trunk/README.txt
===================================================================
--- relstorage/trunk/README.txt 2009-10-02 22:19:25 UTC (rev 104758)
+++ relstorage/trunk/README.txt 2009-10-02 23:52:21 UTC (rev 104759)
@@ -22,6 +22,8 @@
in-memory index of all objects, RelStorage starts quickly regardless of
database size.
* Supports undo, packing, and filesystem-based ZODB blobs.
+* Both history-preserving and history-free storage are available.
+* Capable of failover to replicated SQL databases.
* Free, open source (ZPL 2.1)
@@ -32,13 +34,10 @@
easy_install RelStorage
-If you are not using easy_install (part of the setuptools package), you can
-get the latest release at PyPI (http://pypi.python.org/pypi/RelStorage), then
-place the relstorage package in the lib/python directory of either the
-SOFTWARE_HOME or the INSTANCE_HOME. You can do this with the following
-command::
+To install RelStorage in Plone, see the instructions in the following
+article:
- python2.4 setup.py install --install-lib=${INSTANCE_HOME}/lib/python
+ http://shane.willowrise.com/archives/how-to-install-plone-with-relstorage-and-mysql/
RelStorage requires a version of ZODB that is aware of MVCC storages.
ZODB 3.9 supports RelStorage without any patches. ZODB 3.7 and 3.8 can
@@ -55,8 +54,9 @@
itself only with certain character set configurations. MySQLdb 1.2.2 fixes the
bug.
-Finally, modify etc/zope.conf of your Zope instance. Remove the main mount
-point and add one of the following blocks. For PostgreSQL::
+To integrate RelStorage in Zope 2, specify a RelStorage backend in
+``etc/zope.conf``. Remove the main mount point and add one of the
+following blocks. For PostgreSQL::
%import relstorage
<zodb_db main>
@@ -111,31 +111,95 @@
</relstorage>
</zodb_db>
+To use RelStorage with ``repoze.zodbconn``, a package that makes ZODB
+available to WSGI applications, create a configuration file with
+contents similar to the following::
-Migration
-=========
+ %import relstorage
+ <zodb main>
+ <relstorage>
+ <mysql>
+ db zodb
+ </mysql>
+ </relstorage>
+ cache-size 100000
+ </zodb>
-Migrating from FileStorage
---------------------------
+``repoze.zodbconn`` expects a ZODB URI. Use a URI of the form
+``zconfig://path/to/configuration#main``.
-You can convert a FileStorage instance to RelStorage and back using a utility
-called ZODBConvert. See http://wiki.zope.org/ZODB/ZODBConvert .
+Migrating Existing Data
+=======================
-Migrating from PGStorage
-------------------------
+The ``zodbconvert`` Utility
+---------------------------
-The following script migrates your database from PGStorage to RelStorage 1.0
-beta:
+RelStorage comes with a script named ``zodbconvert`` that converts
+databases to different formats. Use it to convert a FileStorage
+instance to RelStorage and back, or to convert between different kinds
+of RelStorage instances, or to convert other kinds of storages that
+support the storage iterator protocol.
- migrate.sql_
+When converting between two history-preserving databases (note that
+FileStorage uses a history-preserving format), ``zodbconvert`` utility
+preserves all objects and transactions, meaning you can still use the
+ZODB undo feature after the conversion, and you can convert back using
+the same process in reverse. When converting from a history-free
+database to either a history-free database or a history-preserving
+database, ``zodbconvert`` retains all data, but the converted
+transactions will not be undoable. When converting from a
+history-preserving storage to a history-free storage, ``zodbconvert``
+drops all historical information during the conversion.
- .. _migrate.sql: http://svn.zope.org/*checkout*/relstorage/trunk/notes/migrate.sql
+How to use ``zodbconvert``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
-After you do this, you still need to migrate from 1.0 beta to the latest
-release.
+Create a ZConfig style configuration file that specifies two storages,
+one named "source", the other "destination". The configuration file
+format is very much like zope.conf. Then run ``zodbconvert``, providing
+the name of the configuration file as a parameter.
+The utility does not modify the source storage. Before copying the
+data, the utility verifies the destination storage is completely empty.
+If the destination storage is not empty, the utility aborts without
+making any changes to the destination. (Adding transactions to an
+existing database is complex and out of scope for ``zodbconvert``.)
+Here is a sample ``zodbconvert`` configuration file::
+
+ <filestorage source>
+ path /zope/var/Data.fs
+ </filestorage>
+
+ <relstorage destination>
+ <mysql>
+ db zodb
+ </mysql>
+ </relstorage>
+
+This configuration file specifies that the utility should copy all of
+the transactions from Data.fs to a MySQL database called "zodb". If you
+want to reverse the conversion, exchange the names "source" and
+"destination". All storage types and storage parameters available in
+zope.conf are also available in this configuration file.
+
+Options for ``zodbconvert``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ ``--clear``
+ Clears all data from the destination storage before copying. Use
+ this only if you are certain the destination has no useful data.
+
+ ``--dry-run``
+ Opens both storages and analyzes what would be copied, but does not
+ actually copy.
+
+ ``--verbose``
+ List the transactions and objects as they are copied. This is very
+ verbose.
+
+
Migrating to a new version of RelStorage
----------------------------------------
@@ -170,118 +234,21 @@
.. _migrate-to-1.0.txt: http://svn.zope.org/*checkout*/relstorage/trunk/notes/migrate-to-1.0.txt
-Adapter Options
-===============
+RelStorage Options
+==================
-Common options
---------------
+Specify these options in zope.conf, as parameters for the
+``relstorage.storage.RelStorage`` constructor, or as attributes of a
+``relstorage.storage.Options`` instance. In the latter two cases, use
+underscores instead of dashes in the parameter names.
-All of the adapters support the following options.
-
-keep-history
-
- If this parameter is set to true (the default), the adapter
- will create and use a history-preserving database schema,
- similar to FileStorage. A history-preserving schema supports
- ZODB-level undo, but grows more quickly and requires extensive
- packing on a regular basis.
-
- If this parameter is set to false, the adapter will create and
- use a history-free database schema. Undo will not be supported,
- but the database will not grow as quickly. The database will
- still require regular garbage collection (which is accessible
- through the database pack mechanism.)
-
- This parameter must not change once the database schema has
- been installed. If you want to convert between a
- history-preserving and a history-free database, use the
- zodbconvert utility to copy to a new database.
-
-PostgreSQL adapter options
---------------------------
-
-In addition to the common options, the PostgreSQL adapter accepts:
-
-dsn
-
- Specifies the data source name for connecting to PostgreSQL.
- A PostgreSQL DSN is a list of parameters separated with
- whitespace. A typical DSN looks like::
-
- dbname='zodb' user='username' host='localhost' password='pass'
-
- If dsn is omitted, the adapter will connect to a local database with
- no password. Both the user and database name will match the
- name of the owner of the current process.
-
-MySQL options
--------------
-
-In addition to the common options, this adapter accepts most parameters
-supported by the MySQL-python library, including:
-
-host
- string, host to connect
-user
- string, user to connect as
-passwd
- string, password to use
-db
- string, database to use
-port
- integer, TCP/IP port to connect to
-unix_socket
- string, location of unix_socket (UNIX-ish only)
-conv
- mapping, maps MySQL FIELD_TYPE.* to Python functions which convert a
- string to the appropriate Python type
-connect_timeout
- number of seconds to wait before the connection attempt fails.
-compress
- if set, gzip compression is enabled
-named_pipe
- if set, connect to server via named pipe (Windows only)
-init_command
- command which is run once the connection is created
-read_default_file
- see the MySQL documentation for mysql_options()
-read_default_group
- see the MySQL documentation for mysql_options()
-client_flag
- client flags from MySQLdb.constants.CLIENT
-load_infile
- int, non-zero enables LOAD LOCAL INFILE, zero disables
-
-Oracle options
---------------
-
-In addition to the common options, the Oracle adapter accepts:
-
-user
- The Oracle account name
-password
- The Oracle account password
-dsn
- The Oracle data source name. The Oracle client library will
- normally expect to find the DSN in /etc/oratab.
-
-Optional Features
-=================
-
-Specify these options in zope.conf, as parameters for the RelStorage
-constructor, or as attributes of a relstorage.Options instance.
-In the latter two cases, use underscores instead of dashes in the
-parameter names.
-
-blob-dir
-
+``blob-dir``
If supplied, the storage will provide blob support and this
is the name of a directory to hold blob data. The directory will
be created if it doeesn't exist. If no value (or an empty value)
is provided, then no blob support will be provided.
-poll-interval
-
+``poll-interval``
Defer polling the database for the specified maximum time interval,
in seconds. Set to 0 (the default) to always poll. Fractional
seconds are allowed. Use this to lighten the database load on
@@ -303,8 +270,7 @@
affect database consistency, but does increase the probability
of conflict errors, leading to low performance.
-pack-gc
-
+``pack-gc``
If pack-gc is false, pack operations do not perform
garbage collection. Garbage collection is enabled by default.
@@ -317,24 +283,21 @@
Disabling garbage collection is also a hack that ensures
inter-database references never break.
-pack-dry-run
-
+``pack-dry-run``
If pack-dry-run is true, pack operations perform a full analysis
of what to pack, but no data is actually removed. After a dry run,
the pack_object, pack_state, and pack_state_tid tables are filled
with the list of object states and objects that would have been
removed.
-pack-batch-timeout
-
+``pack-batch-timeout``
Packing occurs in batches of transactions; this specifies the
timeout in seconds for each batch. Note that some database
configurations have unpredictable I/O performance
and might stall much longer than the timeout.
The default timeout is 5.0 seconds.
-pack-duty-cycle
-
+``pack-duty-cycle``
After each batch, the pack code pauses for a time to
allow concurrent transactions to commit. The pack-duty-cycle
specifies what fraction of time should be spent on packing.
@@ -347,15 +310,13 @@
The default is 0.5. Raise it to finish packing faster; lower it
to reduce the effect of packing on transaction commit performance.
-pack-max-delay
-
+``pack-max-delay``
This specifies a maximum delay between pack batches. Sometimes
the database takes an extra long time to finish a pack batch; at
those times it is useful to cap the delay imposed by the
pack-duty-cycle. The default is 20 seconds.
-cache-servers
-
+``cache-servers``
Specifies a list of memcache servers. Enabling memcache integration
is useful if the connection to the relational database has high
latency and the connection to memcache has significantly lower
@@ -367,13 +328,122 @@
"127.0.0.1:11211" is a common setting. The default is to disable
memcache integration.
-cache-module-name
-
+``cache-module-name``
Specifies which Python memcache module to use. The default is
"memcache", a pure Python module. There are several alternative
modules available through PyPI. This setting has no effect unless
cache-servers is set.
+Adapter Options
+===============
+
+Common Adapter Options
+----------------------
+
+All current RelStorage adapters support the following options.
+
+``keep-history``
+ If this parameter is set to true (the default), the adapter
+ will create and use a history-preserving database schema
+ like FileStorage. A history-preserving schema supports
+ ZODB-level undo, but also grows more quickly and requires extensive
+ packing on a regular basis.
+
+ If this parameter is set to false, the adapter will create and
+ use a history-free database schema. Undo will not be supported,
+ but the database will not grow as quickly. The database will
+ still require regular garbage collection (which is accessible
+ through the database pack mechanism.)
+
+ This parameter must not change once the database schema has
+ been installed, because the schemas for history-preserving and
+ history-free storage are different. If you want to convert
+ between a history-preserving and a history-free database, use
+ the ``zodbconvert`` utility to copy to a new database.
+
+``replica-conf``
+ If this parameter is provided, it specifies a text file that
+ contains a list of database replicas this adapter can choose
+ from. For MySQL and PostgreSQL, put in the replica file a list
+ of ``host:port`` or ``host`` values, one per line. For Oracle,
+ put in a list of DSN values. Blank lines and lines starting
+ with ``#`` are ignored.
+
+ The adapter prefers the first replica specified in the file. If
+ the first is not available, the adapter automatically tries the
+ rest of the replicas, in order. If the file changes, the
+ adapter will drop existing SQL database connections and make
+ new connections when ZODB starts a new transaction.
+
+
+PostgreSQL Adapter Options
+--------------------------
+
+In addition to the common options, the PostgreSQL adapter accepts:
+
+``dsn``
+ Specifies the data source name for connecting to PostgreSQL.
+ A PostgreSQL DSN is a list of parameters separated with
+ whitespace. A typical DSN looks like::
+
+ dbname='zodb' user='username' host='localhost' password='pass'
+
+ If dsn is omitted, the adapter will connect to a local database with
+ no password. Both the user and database name will match the
+ name of the owner of the current process.
+
+MySQL Adapter Options
+---------------------
+
+In addition to the common options, this adapter accepts most parameters
+supported by the MySQL-python library, including:
+
+``host``
+ string, host to connect
+``user``
+ string, user to connect as
+``passwd``
+ string, password to use
+``db``
+ string, database to use
+``port``
+ integer, TCP/IP port to connect to
+``unix_socket``
+ string, location of unix_socket (UNIX-ish only)
+``conv``
+ mapping, maps MySQL FIELD_TYPE.* to Python functions which convert a
+ string to the appropriate Python type
+``connect_timeout``
+ number of seconds to wait before the connection attempt fails.
+``compress``
+ if set, gzip compression is enabled
+``named_pipe``
+ if set, connect to server via named pipe (Windows only)
+``init_command``
+ command which is run once the connection is created
+``read_default_file``
+ see the MySQL documentation for mysql_options()
+``read_default_group``
+ see the MySQL documentation for mysql_options()
+``client_flag``
+ client flags from MySQLdb.constants.CLIENT
+``load_infile``
+ int, non-zero enables LOAD LOCAL INFILE, zero disables
+
+Oracle Adapter Options
+----------------------
+
+In addition to the common options, the Oracle adapter accepts:
+
+``user``
+ The Oracle account name
+``password``
+ The Oracle account password
+``dsn``
+ The Oracle data source name. The Oracle client library will
+ normally expect to find the DSN in /etc/oratab.
+
+
Development
===========
@@ -422,10 +492,14 @@
Q: Can RelStorage replace ZRS (Zope Replication Services)?
A: Yes, RelStorage inherits the asynchronous master/slave replication
- capability of MySQL and other databases. Currently looking for funding
- opportunities to support master/master replication.
+ capability of MySQL and other databases. The author is currently
+ looking for funding opportunities to support master/master replication.
+Q: How do I set up an environment to run the RelStorage tests?
+ A: See README.txt in the relstorage/tests directory.
+
+
Project URLs
============
Modified: relstorage/trunk/relstorage/component.xml
===================================================================
--- relstorage/trunk/relstorage/component.xml 2009-10-02 22:19:25 UTC (rev 104758)
+++ relstorage/trunk/relstorage/component.xml 2009-10-02 23:52:21 UTC (rev 104759)
@@ -135,8 +135,7 @@
</key>
</sectiontype>
- <sectiontype name="postgresql" implements="relstorage.adapter"
- datatype=".PostgreSQLAdapterFactory">
+ <sectiontype name="relstorage.adapter.common">
<key name="keep-history" datatype="boolean" default="true">
<description>
If this parameter is set to true (the default), the adapter
@@ -157,6 +156,26 @@
zodbconvert utility to copy to a new database.
</description>
</key>
+ <key name="replica-conf" datatype="string" required="no">
+ <description>
+ If this parameter is provided, it specifies a text file that
+ contains a list of database replicas this adapter can choose
+ from. For MySQL and PostgreSQL, put in the replica file a list
+ of ``host:port`` or ``host`` values, one per line. For Oracle,
+ put in a list of DSN values. Blank lines and lines starting
+ with ``#`` are ignored.
+
+ The adapter prefers the first replica specified in the file. If
+ the first is not available, the adapter automatically tries the
+ rest of the replicas, in order. If the file changes, the
+ adapter will drop existing SQL database connections and make
+ new connections when ZODB starts a new transaction.
+ </description>
+ </key>
+ </sectiontype>
+
+ <sectiontype name="postgresql" implements="relstorage.adapter"
+ datatype=".PostgreSQLAdapterFactory" extends="relstorage.adapter.common">
<key name="dsn" datatype="string" required="no" default="">
<description>
The PostgreSQL data source name. For example:
@@ -171,28 +190,7 @@
</sectiontype>
<sectiontype name="oracle" implements="relstorage.adapter"
- datatype=".OracleAdapterFactory">
- <key name="keep-history" datatype="boolean" default="true">
- <description>
- If this parameter is set to true (the default), the adapter
- will create and use a history-preserving database schema,
- similar to FileStorage. A history-preserving schema supports
- ZODB-level undo, but grows more quickly and requires extensive
- packing on a regular basis.
-
- If this parameter is set to false, the adapter will create and
- use a history-free database schema. Undo will not be supported,
- but the database will not grow as quickly. The database will
- still require regular garbage collection (which is accessible
- through the database pack mechanism.)
-
- This parameter must not change once the database schema has
- been installed. If you want to convert between a
- history-preserving and a history-free database, use the
- zodbconvert utility to copy to a new database.
- </description>
- </key>
-
+ datatype=".OracleAdapterFactory" extends="relstorage.adapter.common">
<key name="user" datatype="string" required="yes">
<description>
The Oracle account name
@@ -212,29 +210,7 @@
</sectiontype>
<sectiontype name="mysql" implements="relstorage.adapter"
- datatype=".MySQLAdapterFactory">
-
- <key name="keep-history" datatype="boolean" default="true">
- <description>
- If this parameter is set to true (the default), the adapter
- will create and use a history-preserving database schema,
- similar to FileStorage. A history-preserving schema supports
- ZODB-level undo, but grows more quickly and requires extensive
- packing on a regular basis.
-
- If this parameter is set to false, the adapter will create and
- use a history-free database schema. Undo will not be supported,
- but the database will not grow as quickly. The database will
- still require regular garbage collection (which is accessible
- through the database pack mechanism.)
-
- This parameter must not change once the database schema has
- been installed. If you want to convert between a
- history-preserving and a history-free database, use the
- zodbconvert utility to copy to a new database.
- </description>
- </key>
-
+ datatype=".MySQLAdapterFactory" extends="relstorage.adapter.common">
<key name="host" datatype="string" required="no">
<description>
host to connect
Modified: relstorage/trunk/relstorage/config.py
===================================================================
--- relstorage/trunk/relstorage/config.py 2009-10-02 22:19:25 UTC (rev 104758)
+++ relstorage/trunk/relstorage/config.py 2009-10-02 23:52:21 UTC (rev 104759)
@@ -38,6 +38,7 @@
return PostgreSQLAdapter(
dsn=self.config.dsn,
keep_history=self.config.keep_history,
+ replica_conf=self.config.replica_conf,
)
@@ -50,6 +51,7 @@
password=config.password,
dsn=config.dsn,
keep_history=config.keep_history,
+ replica_conf=config.replica_conf,
)
Modified: relstorage/trunk/relstorage/tests/testmysql.py
===================================================================
--- relstorage/trunk/relstorage/tests/testmysql.py 2009-10-02 22:19:25 UTC (rev 104758)
+++ relstorage/trunk/relstorage/tests/testmysql.py 2009-10-02 23:52:21 UTC (rev 104759)
@@ -37,7 +37,71 @@
passwd='relstoragetest',
)
-class HPMySQLTests(UseMySQLAdapter, HistoryPreservingRelStorageTests):
+
+class ZConfigTests:
+
+ def checkConfigureViaZConfig(self):
+ import tempfile
+ replica_conf = tempfile.NamedTemporaryFile()
+ try:
+ replica_conf.write("localhost")
+ replica_conf.flush()
+
+ if self.keep_history:
+ dbname = 'relstoragetest'
+ else:
+ dbname = 'relstoragetest_hf'
+ conf = """
+ %%import relstorage
+ <zodb main>
+ <relstorage>
+ <mysql>
+ db %s
+ user relstoragetest
+ passwd relstoragetest
+ keep-history %s
+ replica-conf %s
+ </mysql>
+ </relstorage>
+ </zodb>
+ """ % (
+ dbname,
+ self.keep_history and 'true' or 'false',
+ replica_conf.name,
+ )
+
+ schema_xml = """
+ <schema>
+ <import package="ZODB"/>
+ <section type="ZODB.database" name="main" attribute="database"/>
+ </schema>
+ """
+ import ZConfig
+ from StringIO import StringIO
+ schema = ZConfig.loadSchemaFile(StringIO(schema_xml))
+ config, handler = ZConfig.loadConfigFile(schema, StringIO(conf))
+
+ db = config.database.open()
+ try:
+ storage = db.storage
+ adapter = storage._adapter
+ from relstorage.adapters.mysql import MySQLAdapter
+ self.assert_(isinstance(adapter, MySQLAdapter))
+ self.assertEqual(adapter._params, {
+ 'passwd': 'relstoragetest',
+ 'db': dbname,
+ 'user': 'relstoragetest',
+ 'replica_conf': replica_conf.name,
+ })
+ self.assertEqual(adapter.keep_history, self.keep_history)
+ finally:
+ db.close()
+ finally:
+ replica_conf.close()
+
+
+class HPMySQLTests(UseMySQLAdapter, HistoryPreservingRelStorageTests,
+ ZConfigTests):
pass
class HPMySQLToFile(UseMySQLAdapter, HistoryPreservingToFileStorage):
@@ -46,7 +110,8 @@
class HPMySQLFromFile(UseMySQLAdapter, HistoryPreservingFromFileStorage):
pass
-class HFMySQLTests(UseMySQLAdapter, HistoryFreeRelStorageTests):
+class HFMySQLTests(UseMySQLAdapter, HistoryFreeRelStorageTests,
+ ZConfigTests):
pass
class HFMySQLToFile(UseMySQLAdapter, HistoryFreeToFileStorage):
Modified: relstorage/trunk/relstorage/tests/testoracle.py
===================================================================
--- relstorage/trunk/relstorage/tests/testoracle.py 2009-10-02 22:19:25 UTC (rev 104758)
+++ relstorage/trunk/relstorage/tests/testoracle.py 2009-10-02 23:52:21 UTC (rev 104759)
@@ -38,7 +38,72 @@
dsn=dsn,
)
-class HPOracleTests(UseOracleAdapter, HistoryPreservingRelStorageTests):
+
+class ZConfigTests:
+
+ def checkConfigureViaZConfig(self):
+ import tempfile
+ dsn = os.environ.get('ORACLE_TEST_DSN', 'XE')
+ replica_conf = tempfile.NamedTemporaryFile()
+ try:
+ replica_conf.write(dsn)
+ replica_conf.flush()
+
+ if self.keep_history:
+ dbname = 'relstoragetest'
+ else:
+ dbname = 'relstoragetest_hf'
+ conf = """
+ %%import relstorage
+ <zodb main>
+ <relstorage>
+ <oracle>
+ user %s
+ password relstoragetest
+ dsn %s
+ keep-history %s
+ replica-conf %s
+ </oracle>
+ </relstorage>
+ </zodb>
+ """ % (
+ dbname,
+ dsn,
+ self.keep_history and 'true' or 'false',
+ replica_conf.name,
+ )
+
+ schema_xml = """
+ <schema>
+ <import package="ZODB"/>
+ <section type="ZODB.database" name="main" attribute="database"/>
+ </schema>
+ """
+ import ZConfig
+ from StringIO import StringIO
+ schema = ZConfig.loadSchemaFile(StringIO(schema_xml))
+ config, handler = ZConfig.loadConfigFile(schema, StringIO(conf))
+
+ db = config.database.open()
+ try:
+ storage = db.storage
+ adapter = storage._adapter
+ from relstorage.adapters.oracle import OracleAdapter
+ self.assert_(isinstance(adapter, OracleAdapter))
+ self.assertEqual(adapter._user, dbname)
+ self.assertEqual(adapter._password, 'relstoragetest')
+ self.assertEqual(adapter._dsn, dsn)
+ self.assertEqual(adapter._twophase, False)
+ self.assertEqual(adapter.keep_history, self.keep_history)
+ self.assertEqual(adapter.replica_conf, replica_conf.name)
+ finally:
+ db.close()
+ finally:
+ replica_conf.close()
+
+
+class HPOracleTests(UseOracleAdapter, HistoryPreservingRelStorageTests,
+ ZConfigTests):
pass
class HPOracleToFile(UseOracleAdapter, HistoryPreservingToFileStorage):
@@ -47,7 +112,8 @@
class HPOracleFromFile(UseOracleAdapter, HistoryPreservingFromFileStorage):
pass
-class HFOracleTests(UseOracleAdapter, HistoryFreeRelStorageTests):
+class HFOracleTests(UseOracleAdapter, HistoryFreeRelStorageTests,
+ ZConfigTests):
pass
class HFOracleToFile(UseOracleAdapter, HistoryFreeToFileStorage):
Modified: relstorage/trunk/relstorage/tests/testpostgresql.py
===================================================================
--- relstorage/trunk/relstorage/tests/testpostgresql.py 2009-10-02 22:19:25 UTC (rev 104758)
+++ relstorage/trunk/relstorage/tests/testpostgresql.py 2009-10-02 23:52:21 UTC (rev 104759)
@@ -35,7 +35,68 @@
dsn='dbname=%s user=relstoragetest password=relstoragetest' % db
)
-class HPPostgreSQLTests(UsePostgreSQLAdapter, HistoryPreservingRelStorageTests):
+
+class ZConfigTests:
+
+ def checkConfigureViaZConfig(self):
+ import tempfile
+ replica_conf = tempfile.NamedTemporaryFile()
+ try:
+ replica_conf.write("localhost")
+ replica_conf.flush()
+
+ if self.keep_history:
+ dbname = 'relstoragetest'
+ else:
+ dbname = 'relstoragetest_hf'
+ dsn = (
+ "dbname='%s' user='relstoragetest' password='relstoragetest'"
+ % dbname)
+ conf = """
+ %%import relstorage
+ <zodb main>
+ <relstorage>
+ <postgresql>
+ dsn %s
+ keep-history %s
+ replica-conf %s
+ </postgresql>
+ </relstorage>
+ </zodb>
+ """ % (
+ dsn,
+ self.keep_history and 'true' or 'false',
+ replica_conf.name,
+ )
+
+ schema_xml = """
+ <schema>
+ <import package="ZODB"/>
+ <section type="ZODB.database" name="main" attribute="database"/>
+ </schema>
+ """
+ import ZConfig
+ from StringIO import StringIO
+ schema = ZConfig.loadSchemaFile(StringIO(schema_xml))
+ config, handler = ZConfig.loadConfigFile(schema, StringIO(conf))
+
+ db = config.database.open()
+ try:
+ storage = db.storage
+ adapter = storage._adapter
+ from relstorage.adapters.postgresql import PostgreSQLAdapter
+ self.assert_(isinstance(adapter, PostgreSQLAdapter))
+ self.assertEqual(adapter._dsn, dsn)
+ self.assertEqual(adapter.keep_history, self.keep_history)
+ self.assertEqual(adapter.replica_conf, replica_conf.name)
+ finally:
+ db.close()
+ finally:
+ replica_conf.close()
+
+
+class HPPostgreSQLTests(UsePostgreSQLAdapter, HistoryPreservingRelStorageTests,
+ ZConfigTests):
pass
class HPPostgreSQLToFile(UsePostgreSQLAdapter, HistoryPreservingToFileStorage):
@@ -45,7 +106,8 @@
HistoryPreservingFromFileStorage):
pass
-class HFPostgreSQLTests(UsePostgreSQLAdapter, HistoryFreeRelStorageTests):
+class HFPostgreSQLTests(UsePostgreSQLAdapter, HistoryFreeRelStorageTests,
+ ZConfigTests):
pass
class HFPostgreSQLToFile(UsePostgreSQLAdapter, HistoryFreeToFileStorage):
More information about the checkins
mailing list