Commit 3833be7e authored by Chris Rossi's avatar Chris Rossi

Convert db resolvers to storage resolvers.

parent 085b1577
......@@ -13,6 +13,7 @@ except:
CHANGES = ''
requires = ['ZODB3']
tests_require = requires + ['mock']
setup(name='zodburi',
version='0.1a1',
......@@ -31,7 +32,7 @@ setup(name='zodburi',
include_package_data=True,
zip_safe=False,
tests_require = requires,
install_requires = requires,
install_requires = tests_require,
test_suite="zodburi",
)
......@@ -23,6 +23,16 @@ class SuffixMultiplier:
return int(v[:-self._keysz]) * m
return int(v) * self._default
byte_size = SuffixMultiplier({'kb': 1024,
convert_bytesize = SuffixMultiplier({'kb': 1024,
'mb': 1024*1024,
'gb': 1024*1024*1024L,})
def convert_int(value):
# boolean values are also treated as integers
value = value.lower()
if value in FALSETYPES:
return 0
if value in TRUETYPES:
return 1
return int(value)
......@@ -3,10 +3,7 @@ import cgi
from cStringIO import StringIO
import urlparse
from zodburi.datatypes import byte_size
from zodburi.datatypes import FALSETYPES
from zodburi.datatypes import TRUETYPES
from ZEO.ClientStorage import ClientStorage
from ZODB.FileStorage.FileStorage import FileStorage
from ZODB.DemoStorage import DemoStorage
from ZODB.MappingStorage import MappingStorage
......@@ -14,58 +11,39 @@ from ZODB.blob import BlobStorage
from ZODB.DB import DB
import ZConfig
def interpret_int_args(argnames, kw):
newkw = {}
# boolean values are also treated as integers
for name in argnames:
value = kw.get(name)
if value is not None:
value = value.lower()
if value in FALSETYPES:
value = 0
if value in TRUETYPES:
value = 1
value = int(value)
newkw[name] = value
return newkw
def interpret_string_args(argnames, kw):
newkw = {}
# strings
for name in argnames:
value = kw.get(name)
if value is not None:
newkw[name] = value
return newkw
def interpret_bytesize_args(argnames, kw):
newkw = {}
# suffix multiplied
for name in argnames:
value = kw.get(name)
if value is not None:
newkw[name] = byte_size(value)
return newkw
from zodburi.datatypes import convert_bytesize
from zodburi.datatypes import convert_int
class Resolver(object):
_int_args = ()
_string_args = ()
_bytesize_args = ()
def interpret_kwargs(self, kw):
unused = kw.copy()
new = {}
newkw = interpret_int_args(self._int_args, kw)
new.update(newkw)
newkw = interpret_string_args(self._string_args, kw)
new.update(newkw)
newkw = interpret_bytesize_args(self._bytesize_args, kw)
new.update(newkw)
return new
convert_string = lambda s: s
converters = (
convert_int,
convert_string,
convert_bytesize)
args = (
self._int_args,
self._string_args,
self._bytesize_args)
for convert, arg_names in zip(converters, args):
for arg_name in arg_names:
value = unused.pop(arg_name, None)
if value is not None:
value = convert(value)
new[arg_name] = value
return new, unused
class MappingStorageURIResolver(Resolver):
_int_args = ('connection_cache_size', 'connection_pool_size')
_string_args = ('database_name',)
_bytesize_args = ()
def __call__(self, uri):
prefix, rest = uri.split('memory://', 1)
result = rest.split('?', 1)
......@@ -75,23 +53,19 @@ class MappingStorageURIResolver(Resolver):
else:
name, query = result
kw = dict(cgi.parse_qsl(query))
kw = self.interpret_kwargs(kw)
dbkw = get_dbkw(kw)
kw, unused = self.interpret_kwargs(kw)
args = (name,)
dbitems = dbkw.items()
dbitems.sort()
key = (args, tuple(dbitems))
def factory():
storage = MappingStorage(*args)
return DB(storage, **dbkw)
return key, args, kw, factory
return MappingStorage(*args)
return factory, unused
class FileStorageURIResolver(Resolver):
# XXX missing: blob_dir, packer, pack_keep_old, pack_gc, stop
_int_args = ('create', 'read_only', 'demostorage', 'connection_cache_size',
'connection_pool_size')
_string_args = ('blobstorage_dir', 'blobstorage_layout', 'database_name')
_int_args = ('create', 'read_only', 'demostorage')
_string_args = ('blobstorage_dir', 'blobstorage_layout')
_bytesize_args = ('quota',)
def __call__(self, uri):
# we can't use urlparse.urlsplit here due to Windows filenames
prefix, rest = uri.split('file://', 1)
......@@ -102,15 +76,9 @@ class FileStorageURIResolver(Resolver):
else:
path, query = result
path = os.path.normpath(path)
kw = dict(cgi.parse_qsl(query))
kw = self.interpret_kwargs(kw)
dbkw = get_dbkw(kw)
items = kw.items()
items.sort()
args = (path,)
dbitems = dbkw.items()
dbitems.sort()
key = (args, tuple(items), tuple(dbitems))
kw = dict(cgi.parse_qsl(query))
kw, unused = self.interpret_kwargs(kw)
demostorage = False
if 'demostorage'in kw:
......@@ -129,34 +97,30 @@ class FileStorageURIResolver(Resolver):
filestorage = FileStorage(*args, **kw)
blobstorage = BlobStorage(blobstorage_dir, filestorage,
layout=blobstorage_layout)
demostorage = DemoStorage(base=blobstorage)
return DB(demostorage, **dbkw)
return DemoStorage(base=blobstorage)
elif blobstorage_dir:
def factory():
filestorage = FileStorage(*args, **kw)
blobstorage = BlobStorage(blobstorage_dir, filestorage,
return BlobStorage(blobstorage_dir, filestorage,
layout=blobstorage_layout)
return DB(blobstorage, **dbkw)
elif demostorage:
def factory():
filestorage = FileStorage(*args, **kw)
demostorage = DemoStorage(base=filestorage)
return DB(demostorage, **dbkw)
return DemoStorage(base=filestorage)
else:
def factory():
filestorage = FileStorage(*args, **kw)
return DB(filestorage, **dbkw)
return FileStorage(*args, **kw)
return factory, unused
return key, args, kw, factory
class ClientStorageURIResolver(Resolver):
_int_args = ('debug', 'min_disconnect_poll', 'max_disconnect_poll',
'wait_for_server_on_startup', 'wait', 'wait_timeout',
'read_only', 'read_only_fallback', 'shared_blob_dir',
'demostorage', 'connection_cache_size',
'connection_pool_size')
'demostorage')
_string_args = ('storage', 'name', 'client', 'var', 'username',
'password', 'realm', 'blob_dir', 'database_name')
'password', 'realm', 'blob_dir')
_bytesize_args = ('cache_size', )
def __call__(self, uri):
......@@ -177,28 +141,15 @@ class ClientStorageURIResolver(Resolver):
path = os.path.normpath(path)
args = (path,)
kw = dict(cgi.parse_qsl(query))
kw = self.interpret_kwargs(kw)
dbkw = get_dbkw(kw)
items = kw.items()
items.sort()
dbitems = dbkw.items()
dbitems.sort()
key = (args, tuple(items), tuple(dbitems))
kw, unused = self.interpret_kwargs(kw)
if 'demostorage' in kw:
kw.pop('demostorage')
def factory():
from ZEO.ClientStorage import ClientStorage
from ZODB.DB import DB
from ZODB.DemoStorage import DemoStorage
demostorage = DemoStorage(base=ClientStorage(*args, **kw))
return DB(demostorage, **dbkw) #pragma NO COVERAGE
return DemoStorage(base=ClientStorage(*args, **kw))
else:
def factory():
from ZEO.ClientStorage import ClientStorage
from ZODB.DB import DB
clientstorage = ClientStorage(*args, **kw)
return DB(clientstorage, **dbkw) #pragma NO COVERAGE
return key, args, kw, factory
return ClientStorage(*args, **kw)
return factory, unused
def get_dbkw(kw):
dbkw = {}
......@@ -220,7 +171,7 @@ class ZConfigURIResolver(object):
schema_xml_template = """
<schema>
<import package="ZODB"/>
<multisection type="ZODB.database" attribute="databases" />
<multisection type="ZODB.storage" attribute="storages" />
</schema>
"""
......@@ -232,16 +183,16 @@ class ZConfigURIResolver(object):
schema_xml = self.schema_xml_template
schema = ZConfig.loadSchemaFile(StringIO(schema_xml))
config, handler = ZConfig.loadConfig(schema, path)
for database in config.databases:
for factory in config.storages:
if not frag:
# use the first defined in the file
break
elif frag == database.name:
elif frag == factory.name:
# match found
break
else:
raise KeyError("No database named %s found" % frag)
return (path, frag), (), {}, database.open
raise KeyError("No storage named %s found" % frag)
return factory.open, {}
RESOLVERS = {
......
This diff is collapsed.
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