Commit c03a7433 authored by Jim Fulton's avatar Jim Fulton

Add support for additional database configuration parameters:

pool_timeout, cache_size_bytes, historical_pool_size,
historical_cache_size, historical_cache_size_bytes,
historical_timeout, and large_record_size
parent 059e53f0
......@@ -4,6 +4,11 @@
2.1 (unreleased)
----------------
- Add support for additional database configuration parameters:
pool_timeout, cache_size_bytes, historical_pool_size,
historical_cache_size, historical_cache_size_bytes,
historical_timeout, and large_record_size
- Add support for Python 3.5.
- Drop support for Python 2.6 and 3.2.
......
import re
from pkg_resources import iter_entry_points
......@@ -16,6 +17,25 @@ def resolve_uri(uri):
else:
raise KeyError('No resolver found for uri: %s' % uri)
connection_parameters = '''
pool_size pool_timeout cache_size cache_size_bytes
historical_pool_size historical_cache_size historical_cache_size_bytes
historical_timeout large_record_size
'''.strip().split()
parameters = dict(database_name = 'database_name')
for parameter in connection_parameters:
parameters['connection_' + parameter] = parameter
has_units = re.compile('\s*(\d+)\s*([kmg])b\s*$').match
units = dict(k=1<<10, m=1<<20, g=1<<30)
def _parse_bytes(s):
m = has_units(s.lower())
if m:
v, uname = m.group(1, 2)
return int(v) * units[uname]
else:
return int(s)
def _get_dbkw(kw):
dbkw = {
......@@ -23,12 +43,15 @@ def _get_dbkw(kw):
'pool_size': 7,
'database_name': 'unnamed',
}
if 'connection_cache_size' in kw:
dbkw['cache_size'] = int(kw.pop('connection_cache_size'))
if 'connection_pool_size' in kw:
dbkw['pool_size'] = int(kw.pop('connection_pool_size'))
if 'database_name' in kw:
dbkw['database_name'] = kw.pop('database_name')
for parameter in parameters:
if parameter in kw:
v = kw.pop(parameter)
if parameter.startswith('connection_'):
if parameter.endswith('_bytes'):
v = _parse_bytes(v)
else:
v = int(v)
dbkw[parameters[parameter]] = v
if kw:
raise KeyError('Unrecognized database keyword(s): %s' % ', '.join(kw))
......
......@@ -194,10 +194,10 @@ class ZConfigURIResolver(object):
if isinstance(config_item, ZODBDatabase):
config = config_item.config
factory = config.storage
dbkw = {
'connection_cache_size': config.cache_size,
'connection_pool_size': config.pool_size,
}
from zodburi import connection_parameters
dbkw = {'connection_' + name: getattr(config, name)
for name in connection_parameters
if getattr(config, name) is not None}
if config.database_name:
dbkw['database_name'] = config.database_name
else:
......
......@@ -17,16 +17,22 @@ class TestResolveURI(unittest.TestCase):
@mock.patch('zodburi.resolvers.MappingStorage')
def test_it_with_dbkw(self, MappingStorage):
from zodburi import resolve_uri
factory, dbkw = resolve_uri(
'memory://test?connection_cache_size=1&connection_pool_size=2&'
'database_name=dbname')
from zodburi import resolve_uri, connection_parameters, parameters
uri = 'memory://test?database_name=dbname'
for i, parameter in enumerate(connection_parameters):
uri += '&connection_%s=%d' % (parameter, i)
if parameter == 'cache_size_bytes':
uri += 'MB'
factory, dbkw = resolve_uri(uri)
factory()
MappingStorage.assert_called_once_with('test')
self.assertEqual(dbkw, {
'cache_size': 1,
'pool_size': 2,
'database_name': 'dbname'})
expect = dict(database_name='dbname')
for i, parameter in enumerate(connection_parameters):
parameter = 'connection_' + parameter
expect[parameters[parameter]] = i
if parameter == 'connection_cache_size_bytes':
expect[parameters[parameter]] *= 1<<20
self.assertEqual(dbkw, expect)
def test_it_cant_resolve(self):
from zodburi import resolve_uri
......
......@@ -423,9 +423,15 @@ class TestZConfigURIResolver(unittest.TestCase):
storage = factory()
from ZODB.MappingStorage import MappingStorage
self.assertTrue(isinstance(storage, MappingStorage))
self.assertEqual(dbkw, {
'connection_cache_size': 5000,
'connection_pool_size': 7})
self.assertEqual(dbkw,
{'connection_cache_size': 5000,
'connection_cache_size_bytes': 0,
'connection_historical_cache_size': 1000,
'connection_historical_cache_size_bytes': 0,
'connection_historical_pool_size': 3,
'connection_historical_timeout': 300,
'connection_large_record_size': 16777216,
'connection_pool_size': 7})
def test_named_database(self):
self.tmp.write(b"""
......@@ -443,10 +449,46 @@ class TestZConfigURIResolver(unittest.TestCase):
storage = factory()
from ZODB.MappingStorage import MappingStorage
self.assertTrue(isinstance(storage, MappingStorage))
self.assertEqual(dbkw, {
'connection_cache_size': 20000,
'connection_pool_size': 5,
'database_name': 'foo'})
self.assertEqual(dbkw,
{'connection_cache_size': 20000,
'connection_cache_size_bytes': 0,
'connection_historical_cache_size': 1000,
'connection_historical_cache_size_bytes': 0,
'connection_historical_pool_size': 3,
'connection_historical_timeout': 300,
'connection_large_record_size': 16777216,
'connection_pool_size': 5,
'database_name': 'foo'})
def test_database_all_options(self):
from zodburi import connection_parameters
self.tmp.write(("""
<zodb x>
<mappingstorage>
</mappingstorage>
database-name foo
%s
</zodb>
""" % '\n'.join("%s %s" % (
name.replace('_', '-'),
'%sMB' % i if name.endswith('_bytes') else i,
)
for (i, name)
in enumerate(connection_parameters)
)).encode())
self.tmp.flush()
resolver = self._makeOne()
factory, dbkw = resolver('zconfig://%s#x' % self.tmp.name)
storage = factory()
from ZODB.MappingStorage import MappingStorage
self.assertTrue(isinstance(storage, MappingStorage))
expect = dict(database_name='foo')
for i, parameter in enumerate(connection_parameters):
parameter = 'connection_' + parameter
expect[parameter] = i
if parameter.endswith('_bytes'):
expect[parameter] *= 1<<20
self.assertEqual(dbkw, expect)
class TestMappingStorageURIResolver(Base, unittest.TestCase):
......
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