[Zope-Checkins] CVS: ZODB3/ZODB - StorageConfig.py:1.1 StorageTypes.py:1.1

Chris McDonough chrism@zope.com
23 Nov 2002 02:41:08 -0500


Cool!  It would also be nice to have a "createStorageFactory" method
which given a section object would return a callable which would create
a storage.  This would be useful for doing things (like setuid) before
actually creating a storage (like possibly writing a file) during the
larger scope of config file parsing.

On Sat, 2002-11-23 at 01:35, Guido van Rossum wrote:
> Update of /cvs-repository/ZODB3/ZODB
> In directory cvs.zope.org:/tmp/cvs-serv2742
> 
> Added Files:
> 	StorageConfig.py StorageTypes.py 
> Log Message:
> Move the storage configuration code here, where it belongs.
> 
> === Added File ZODB3/ZODB/StorageConfig.py ===
> ##############################################################################
> #
> # Copyright (c) 2002 Zope Corporation and Contributors.
> # All Rights Reserved.
> #
> # This software is subject to the provisions of the Zope Public License,
> # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
> # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
> # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
> # FOR A PARTICULAR PURPOSE.
> #
> ##############################################################################
> """Higher-level support for configuring storages.
> 
> Storages are configured a la DBTab.
> 
> A storage section has the form
> 
>   <Storage Name (dependent)>
>     # For example
>     type        FileStorage
>     file_name   var/Data.fs
>     read_only   1
>   </Storage>
> 
> where Name and (dependent) are optional.  Once you have retrieved the
> section object (probably with getSection("Storage", name), the
> function creatStorage() in this module will create the storage object
> for you.
> """
> 
> from StorageTypes import storage_types
> 
> def createStorage(section):
>     """Create a storage specified by a configuration section."""
>     klass, args = getStorageInfo(section)
>     return klass(**args)
> 
> def getStorageInfo(section):
>     """Extract a storage description from a configuration section.
> 
>     Return a tuple (klass, args) where klass is the storage class and
>     args is a dictionary of keyword arguments.  To create the storage,
>     call klass(**args).
> 
>     Adapted from DatabaseFactory.setStorageParams() in DBTab.py.
>     """
>     type = section.get("type")
>     if not type:
>         raise RuntimeError, "A storage type is required"
>     module = None
>     pos = type.rfind(".")
>     if pos >= 0:
>         # Specified the module
>         module, type = type[:pos], type[pos+1:]
>     converter = None
>     if not module:
>         # Use a default module and argument converter.
>         info = storage_types.get(type)
>         if not info:
>             raise RuntimeError, "Unknown storage type: %s" % type
>         module, converter = info
>     m = __import__(module, {}, {}, [type])
>     klass = getattr(m, type)
> 
>     args = {}
>     for key in section.keys():
>         if key.lower() != "type":
>             args[key] = section.get(key)
>     if converter is not None:
>         args = converter(**args)
>     return (klass, args)
> 
> 
> === Added File ZODB3/ZODB/StorageTypes.py ===
> ##############################################################################
> #
> # Copyright (c) 2002 Zope Corporation and Contributors.
> # All Rights Reserved.
> #
> # This software is subject to the provisions of the Zope Public License,
> # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
> # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
> # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
> # FOR A PARTICULAR PURPOSE
> #
> ##############################################################################
> """Default storage types.
> 
> Adapted from DBTab/StorageTypes.py.
> """
> 
> import re
> 
> from ZConfig.Common import asBoolean
> 
> 
> def convertFileStorageArgs(quota=None, stop=None, **kw):
>     if kw.has_key('name'):
>         # FileStorage doesn't accept a 'name' arg
>         del kw['name']
>     if quota is not None:
>         kw['quota'] = long(quota) or None
>     if stop is not None:
>         stop = long(stop)
>         if not stop:
>             stop = None
>         else:
>             from ZODB.utils import p64
>             stop = p64(stop)
>         kw['stop'] = stop
> 
>     # Boolean args
>     for name in (
>         'create', 'read_only'
>         ):
>         if kw.has_key(name):
>             kw[name] = asBoolean(kw[name])
> 
>     return kw
> 
> 
> # Match URLs of the form 'zeo://zope.example.com:1234'
> zeo_url_re = re.compile('zeo:/*(?P<host>[A-Za-z0-9\.-]+):(?P<port>[0-9]+)')
> 
> def convertAddresses(s):
>     # Allow multiple addresses using semicolons as a split character.
>     res = []
>     for a in s.split(';'):
>         a = a.strip()
>         if a:
>             mo = zeo_url_re.match(a)
>             if mo is not None:
>                 # ZEO URL
>                 host, port = mo.groups()
>                 res.append((host, int(port)))
>             else:
>                 # Socket file
>                 res.append(a)
>     return res
> 
> 
> def convertClientStorageArgs(addr=None, **kw):
>     if addr is None:
>         raise RuntimeError, 'An addr parameter is required for ClientStorage.'
>     kw['addr'] = convertAddresses(addr)
> 
>     # Integer args
>     for name in (
>         'cache_size', 'min_disconnect_poll', 'max_disconnect_poll',
>         ):
>         if kw.has_key(name):
>             kw[name] = int(kw[name])
> 
>     # Boolean args
>     for name in (
>         'wait', 'read_only', 'read_only_fallback',
>         ):
>         if kw.has_key(name):
>             kw[name] = asBoolean(kw[name])
> 
>     # The 'client' parameter must be None to be false.  Yuck.
>     if kw.has_key('client') and not kw['client']:
>         kw['client'] = None
> 
>     return kw
> 
> 
> def convertBDBStorageArgs(**kw):
>     from bsddb3Storage.BerkeleyBase import BerkeleyConfig
>     config = BerkeleyConfig()
>     for name in dir(BerkeleyConfig):
>         if name.startswith('_'):
>             continue
>         val = kw.get(name)
>         if val is not None:
>             if name != 'logdir':
>                 val = int(val)
>             setattr(config, name, val)
>             del kw[name]
>     # XXX: Nobody ever passes in env
>     assert not kw.has_key('env')
>     kw['config'] = config
>     return kw
> 
> 
> storage_types = {
>     'FileStorage': ('ZODB.FileStorage', convertFileStorageArgs),
>     'DemoStorage': ('ZODB.DemoStorage', None),
>     'MappingStorage': ('ZODB.MappingStorage', None),
>     'TemporaryStorage': ('Products.TemporaryFolder.TemporaryStorage', None),
>     'ClientStorage': ('ZEO.ClientStorage', convertClientStorageArgs),
>     'Full': ('bsddb3Storage.Full', convertBDBStorageArgs),
>     'Minimal': ('bsddb3Storage.Minimal', convertBDBStorageArgs),
>     }
> 
> 
> _______________________________________________
> Zope-Checkins maillist  -  Zope-Checkins@zope.org
> http://lists.zope.org/mailman/listinfo/zope-checkins