index ecacacb8dfb3f6fed392c9990de41268a94c1cf9..1fc794888400e87c30a1df4ad50dd61ac872ef0e 100644 (file)
# FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-#
-# $Id: __init__.py,v 1.26 2004-02-11 23:55:08 richard Exp $
+#
+# $Id: __init__.py,v 1.40 2007-11-07 20:47:12 richard Exp $
'''Container for the hyperdb storage backend implementations.
-
-The __all__ variable is constructed containing only the backends which are
-available.
'''
__docformat__ = 'restructuredtext'
-__all__ = []
+import sys
-for backend in ['anydbm', ('mysql', 'MySQLdb'), 'bsddb', 'bsddb3', 'sqlite',
- 'metakit', ('postgresql', 'psycopg')]:
- if len(backend) == 2:
- backend, backend_module = backend
+# These names are used to suppress import errors.
+# If get_backend raises an ImportError with appropriate
+# module name, have_backend quietly returns False.
+# Otherwise the error is reraised.
+_modules = {
+ 'mysql': ('MySQLdb',),
+ 'postgresql': ('psycopg',),
+ 'tsearch2': ('psycopg',),
+ 'sqlite': ('pysqlite', 'pysqlite2', 'sqlite3', '_sqlite3', 'sqlite'),
+}
+
+def get_backend(name):
+ '''Get a specific backend by name.'''
+ vars = globals()
+ # if requested backend has been imported yet, return current instance
+ if name in vars:
+ return vars[name]
+ # import the backend module
+ module_name = 'back_%s' % name
+ try:
+ module = __import__(module_name, vars)
+ except:
+ # import failed, but in versions prior to 2.4, a (broken)
+ # module is left in sys.modules and package globals;
+ # subsequent imports would succeed and get the broken module.
+ # This no longer happens in Python 2.4 and later.
+ if sys.version_info < (2, 4):
+ del sys.modules['.'.join((__name__, module_name))]
+ del vars[module_name]
+ raise
else:
- backend_module = backend
+ vars[name] = module
+ return module
+
+def have_backend(name):
+ '''Is backend "name" available?'''
+ if name == 'tsearch2':
+ # currently not working
+ return 0
try:
- globals()[backend] = __import__('back_%s'%backend, globals())
- __all__.append(backend)
+ get_backend(name)
+ return 1
except ImportError, e:
- if not str(e).startswith('No module named %s'%backend_module):
- raise
+ for name in _modules.get(name, (name,)):
+ if str(e).startswith('No module named %s'%name):
+ return 0
+ raise
+ return 0
+
+def list_backends():
+ '''List all available backend names.
+
+ This function has side-effect of registering backward-compatible
+ globals for all available backends.
+
+ '''
+ l = []
+ for name in 'anydbm', 'mysql', 'sqlite', 'postgresql':
+ if have_backend(name):
+ l.append(name)
+ return l
-# vim: set filetype=python ts=4 sw=4 et si
+# vim: set filetype=python sts=4 sw=4 et si :