Commit 3784c19e authored by Georges Dubus's avatar Georges Dubus

Removed support for postgres:// uri.

It is being moved to RelStorage.
parent c4d50f0b
......@@ -32,7 +32,7 @@ passing to the ``ZODB.DB.DB`` constructor. For example:
storage_factory, dbkw = resolve_uri(
'zeo://localhost:9001?connection_cache_size=20000')
# factory will be an instance of ClientStorageURIResolver
# factory will be an instance of ClientStorageURIResolver
# dbkw will be {'connection_cache_size':20000, 'pool_size':7,
# 'database_name':'unnamed'}
......@@ -45,8 +45,12 @@ URI Schemes
The URI schemes currently recognized in the ``zodbconn.uri`` setting
are ``file://``, ``zeo://``, ``zconfig://``, ``memory://``
``postgres://``. Documentation for these URI scheme syntaxes are
below.
. Documentation for these URI scheme syntaxes are below.
In addition to those schemes, the relstorage_ package adds support for
``postgres://``.
.. _relstorage : http://pypi.python.org/pypi/RelStorage
``file://`` URI scheme
~~~~~~~~~~~~~~~~~~~~~~
......@@ -107,7 +111,7 @@ blobstorage_layout
Misc
++++
demostorage
demostorage
boolean (if true, wrap FileStorage in a DemoStorage)
Example
......@@ -287,110 +291,6 @@ An example that combines a dbname with a query string::
memory://storagename?connection_cache_size=100&database_name=fleeb
``postgres://`` URI scheme
~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``postgres://`` URI scheme can be passed as ``zodbconn.uri`` to
create a RelStorage PostgresSQL database factory. The uri should
contain the user, the password, the host, the port and the db name
e.g.::
postgres://someuser:somepass@somehost:5432/somedb?connection_cache_size=20000
The URI scheme also accepts query string arguments. The query string
arguments honored by this scheme are as follows.
RelStorage-constructor related
++++++++++++++++++++++++++++++
These arguments generally inform the RelStorage constructor about
values of the same names.
poll_interval
int
cache_local_mb
int
commit_lock_timeout
int
commit_lock_id
int
read_only
boolean
shared_blob_dir
boolean
keep_history
boolean
pack_gc
boolean
pack_dry_run
boolean
strict_tpc
boolean
create
boolean
blob_cache_size
bytesize
blob_cache_size_check
bytesize
blob_cache_chunk_size
bytesize
replica_timeout
float
pack_batch_timeout
float
pack_duty_cycle
float
pack_max_delay
float
name
string
blob_dir
string
replica_conf
string
cache_module_name
string
cache_prefix
string
cache_delta_size_limit
string
cache_servers
string of the for "first,second,third"
Misc
++++
demostorage
boolean (if true, wrap RelStorage in a DemoStorage)
Connection-related
++++++++++++++++++
These arguments relate to connections created from the database.
connection_cache_size
integer (default 10000)
connection_pool_size
integer (default 7)
Database-related
++++++++++++++++
These arguments relate to the database (as opposed to storage)
settings.
database_name
string
Example
+++++++
An example that combines a path with a query string::
postgres://someuser:somepass@somehost:5432/somedb?connection_cache_size=20000
More Information
----------------
......
......@@ -44,9 +44,5 @@ setup(name='zodburi',
file = zodburi.resolvers:file_storage_resolver
zconfig = zodburi.resolvers:zconfig_resolver
memory = zodburi.resolvers:mapping_storage_resolver
postgres = zodburi.resolvers_relstorage:postgresql_resolver [postgres]
""",
extras_require={
'postgres': ['RelStorage', 'psycopg2'],
},
)
[tox]
envlist =
envlist =
py25,py26,py27,cover
[testenv]
commands =
commands =
python setup.py test -q
[testenv:py25]
deps =
zope.interface>=3.6.0,<4.0dev
transaction<1.2
commands =
commands =
python setup.py test -q
[testenv:cover]
basepython =
python2.6
commands =
commands =
python setup.py nosetests --with-xunit --with-xcoverage
deps =
nose
coverage==3.4
nosexcover
RelStorage
psycopg2
# we separate coverage into its own testenv because a) "last run wins" wrt
# cobertura jenkins reporting and b) pypy and jython can't handle any
......
import cgi
import urlparse
from ZODB.DemoStorage import DemoStorage
from .resolvers import Resolver
try:
from relstorage.adapters.postgresql import PostgreSQLAdapter
from relstorage.options import Options
from relstorage.storage import RelStorage
except ImportError: #pragma NO COVER
pass
else:
# Not a real resolver, but we use interpret_kwargs
class PostgreSQLAdapterHelper(Resolver):
_int_args = ('connect_timeout', )
_string_args = ('ssl_mode', )
def __call__(self, parsed_uri, kw):
dsn_args = [
('dbname', parsed_uri.path[1:]),
('user', parsed_uri.username),
('password', parsed_uri.password),
('host', parsed_uri.hostname),
('port', parsed_uri.port)
]
kw, unused = self.interpret_kwargs(kw)
dsn_args.extend(kw.items())
dsn = ' '.join("%s='%s'"%arg for arg in dsn_args)
def factory(options):
return PostgreSQLAdapter(dsn=dsn, options=options)
return factory, unused
# The relstorage support is inspired by django-zodb.
# Oracle and mysql should be easily implementable from here
class RelStorageURIResolver(Resolver):
_int_args = ('poll_interval', 'cache_local_mb', 'commit_lock_timeout',
'commit_lock_id', 'read_only', 'shared_blob_dir',
'keep_history', 'pack_gc', 'pack_dry_run', 'strict_tpc',
'create', 'demostorage',)
_string_args = ('name', 'blob_dir', 'replica_conf',
'cache_module_name', 'cache_prefix',
'cache_delta_size_limit')
_bytesize_args = ('blob_cache_size', 'blob_cache_size_check',
'blob_cache_chunk_size')
_float_args = ('replica_timeout', 'pack_batch_timeout',
'pack_duty_cycle', 'pack_max_delay')
_tuple_args = ('cache_servers',)
def __init__(self, adapter_helper):
self.adapter_helper = adapter_helper
def __call__(self, uri):
uri = uri.replace('postgres://', 'http://', 1)
parsed_uri = urlparse.urlsplit(uri)
kw = dict(cgi.parse_qsl(parsed_uri.query))
adapter_factory, kw = self.adapter_helper(parsed_uri, kw)
kw, unused = self.interpret_kwargs(kw)
demostorage = kw.pop('demostorage', False)
options = Options(**kw)
def factory():
adapter = adapter_factory(options)
storage = RelStorage(adapter=adapter, options=options)
if demostorage:
storage = DemoStorage(base=storage)
return storage
return factory, unused
postgresql_resolver = RelStorageURIResolver(PostgreSQLAdapterHelper())
......@@ -408,99 +408,6 @@ class TestMappingStorageURIResolver(Base, unittest.TestCase):
self.assertTrue(isinstance(storage, MappingStorage))
self.assertEqual(storage.__name__, 'storagename')
try:
from zodburi.resolvers_relstorage import RelStorageURIResolver
except ImportError: #pragma NO COVER
pass
else:
class TestPostgreSQLURIResolver(unittest.TestCase, Base):
def _getTargetClass(self):
from zodburi.resolvers_relstorage import RelStorageURIResolver
return RelStorageURIResolver
def _makeOne(self):
from zodburi.resolvers_relstorage import PostgreSQLAdapterHelper
klass = self._getTargetClass()
return klass(PostgreSQLAdapterHelper())
def setUp(self):
# relstorage.options.Options is little more than a dict.
# We make it comparable to simplify the tests.
from relstorage.options import Options
Options.__eq__ = lambda s, o: vars(s) == vars(o)
def test_bool_args(self):
resolver = self._makeOne()
f = resolver.interpret_kwargs
kwargs = f({'read_only':'1'})
self.assertEqual(kwargs[0], {'read_only':1})
kwargs = f({'read_only':'true'})
self.assertEqual(kwargs[0], {'read_only':1})
kwargs = f({'read_only':'on'})
self.assertEqual(kwargs[0], {'read_only':1})
kwargs = f({'read_only':'off'})
self.assertEqual(kwargs[0], {'read_only':0})
kwargs = f({'read_only':'no'})
self.assertEqual(kwargs[0], {'read_only':0})
kwargs = f({'read_only':'false'})
self.assertEqual(kwargs[0], {'read_only':0})
@mock.patch('zodburi.resolvers_relstorage.PostgreSQLAdapter')
@mock.patch('zodburi.resolvers_relstorage.RelStorage')
def test_call(self, RelStorage, PostgreSQLAdapter):
from relstorage.options import Options
resolver = self._makeOne()
factory, dbkw = resolver(
'postgres://someuser:somepass@somehost:5432/somedb'
'?read_only=1')
factory()
expected_options = Options(read_only=1)
PostgreSQLAdapter.assert_called_once_with(
dsn="dbname='somedb' user='someuser' password='somepass' "
"host='somehost' port='5432'", options=expected_options)
RelStorage.assert_called_once_with(
adapter=PostgreSQLAdapter(), options=expected_options)
@mock.patch('zodburi.resolvers_relstorage.PostgreSQLAdapter')
@mock.patch('zodburi.resolvers_relstorage.RelStorage')
def test_call_adapter_options(self, RelStorage, PostgreSQLAdapter):
from relstorage.options import Options
resolver = self._makeOne()
factory, dbkw = resolver(
'postgres://someuser:somepass@somehost:5432/somedb'
'?read_only=1&connect_timeout=10')
factory()
expected_options = Options(read_only=1)
PostgreSQLAdapter.assert_called_once_with(
dsn="dbname='somedb' user='someuser' password='somepass' "
"host='somehost' port='5432' connect_timeout='10'",
options=expected_options)
RelStorage.assert_called_once_with(
adapter=PostgreSQLAdapter(), options=expected_options)
@mock.patch('zodburi.resolvers_relstorage.PostgreSQLAdapter')
@mock.patch('zodburi.resolvers_relstorage.RelStorage')
def test_invoke_factory_demostorage(self, RelStorage, PostgreSQLAdapter):
from ZODB.DemoStorage import DemoStorage
resolver = self._makeOne()
factory, dbkw = resolver(
'postgres://someuser:somepass@somehost:5432/somedb'
'?read_only=1&demostorage=true')
self.assertTrue(isinstance(factory(), DemoStorage))
def test_dbargs(self):
resolver = self._makeOne()
factory, dbkw = resolver(
'postgres://someuser:somepass@somehost:5432/somedb'
'?read_only=1&connection_pool_size=1&connection_cache_size=1'
'&database_name=dbname')
self.assertEqual(dbkw, {'connection_pool_size': '1',
'connection_cache_size': '1',
'database_name': 'dbname'})
class TestEntryPoints(unittest.TestCase):
......@@ -513,13 +420,6 @@ class TestEntryPoints(unittest.TestCase):
('file', resolvers.FileStorageURIResolver),
('zconfig', resolvers.ZConfigURIResolver),
]
try:
from zodburi.resolvers_relstorage import RelStorageURIResolver
except ImportError: #pragma NO COVER
pass
else:
expected.append(
('postgres', RelStorageURIResolver))
for name, cls in expected:
target = load_entry_point('zodburi', 'zodburi.resolvers', name)
self.assertTrue(isinstance(target, cls))
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