diff options
author | René 'Necoro' Neumann <necoro@necoro.net> | 2010-05-20 13:01:27 +0200 |
---|---|---|
committer | René 'Necoro' Neumann <necoro@necoro.net> | 2010-05-20 13:01:27 +0200 |
commit | 261b162f4512609fb8fabd23f44e6ddc0536d43b (patch) | |
tree | 381c68b9879f981866c60104862ba0dc4df441f9 /portato/db | |
parent | 8c016e8ace989e3e1d0dadd7e54e61849341168f (diff) | |
download | portato-261b162f4512609fb8fabd23f44e6ddc0536d43b.tar.gz portato-261b162f4512609fb8fabd23f44e6ddc0536d43b.tar.bz2 portato-261b162f4512609fb8fabd23f44e6ddc0536d43b.zip |
More declarative handling of the database types
Diffstat (limited to '')
-rw-r--r-- | portato/db/__init__.py | 95 | ||||
-rw-r--r-- | portato/db/exceptions.py | 2 |
2 files changed, 56 insertions, 41 deletions
diff --git a/portato/db/__init__.py b/portato/db/__init__.py index 21d8f80..bb5c6fc 100644 --- a/portato/db/__init__.py +++ b/portato/db/__init__.py @@ -12,66 +12,79 @@ from __future__ import absolute_import +from collections import namedtuple + from . import database as db -from .exceptions import UnknownDatabaseTypeError, DatabaseInstantiationError +from .exceptions import UnknownDatabaseTypeError, DatabaseInstantiationError, DatabaseInitError from ..session import Session, SectionDict from ..helper import debug, warning, error, info +from ..odict import OrderedDict + +DBType = namedtuple("DBType", "name descr module cls alt") + +types = [ + ("eixsql", + DBType( + _("eix + SQLite"), + _("Similar to SQLite, but now uses the eix database to get the package information.\nThis should be much faster on startup, but requires that your eix database is always up-to-date.\nAdditionally, this is the only database allowing searching in descriptions."), + "eix_sql", "EixSQLDatabase", + "sql")), + ("sql", + DBType( + _("SQLite"), + _("Uses an SQLite-database to store package information.\nMay take longer to generate at the first time, but has advantages if portato is re-started with an unchanged portage tree. Additionally it allows to use fast SQL expressions for fetching the data."), + "sql", "SQLDatabase", + "dict")), + ("dict", + DBType( + _("Hashmap"), + _("Uses an in-memory hashmap to store package information.\nHas been used since at least version 0.3.3, but all information has to be regenerated on each startup."), + "hash", "HashDatabase", + None)) + ] -types = ( - ("eixsql", _("eix + SQLite"), _("Similar to SQLite, but now uses the eix database to get the package information.\nThis should be much faster on startup, but requires that your eix database is always up-to-date.\nAdditionally, this is the only database allowing searching in descriptions.")), - ("sql", _("SQLite"), _("Uses an SQLite-database to store package information.\nMay take longer to generate at the first time, but has advantages if portato is re-started with an unchanged portage tree. Additionally it allows to use fast SQL expressions for fetching the data.")), - ("dict", _("Hashmap"), _("Uses an in-memory hashmap to store package information.\nHas been used since at least version 0.3.3, but all information has to be regenerated on each startup.")) - ) +types = OrderedDict(types) class Database(db.Database): DEFAULT = "dict" def __new__ (cls, type = None): - if not '_the_instance' in cls.__dict__: - dbcls = cls._generate(type) - cls._the_instance = dbcls(cls._get_session()) - elif type is not None: - raise DatabaseInstantiationError("Database instantiation called with 'type' argument multiple times.") + try: + if not '_the_instance' in cls.__dict__: + dbcls = cls._generate(type) + cls._the_instance = dbcls(cls._get_session()) + elif type is not None: + raise DatabaseInstantiationError("Database instantiation called with 'type' argument multiple times.") + except (ImportError, DatabaseInitError) as e: + db = types[cls.DB_TYPE] + error(_("Cannot load %s."), db.cls) + error(_("Error: %s"), e) + + if db.alt is not None: + return cls.__new__(cls, db.alt) + else: + error(_("No alternative database given. Aborting.")) + raise DatabaseInstantiationError("Cannot load database.") + return cls._the_instance @classmethod def _generate(cls, type): - if type is None: warning("No database type specified! Falling back to default.") type = cls.DEFAULT - - cls.DB_TYPE = type - msg = _("Using database type '%s'") - if type == "sql": - info(msg, "SQLDatabase") - try: - from .sql import SQLDatabase - except ImportError: - warning(_("Cannot load %s."), "SQLDatabase") - return cls._generate("dict") - else: - return SQLDatabase - - elif type == "dict": - info(msg, "HashDatabase") - from .hash import HashDatabase - return HashDatabase - - elif type == "eixsql": - info(msg,"EixSQLDatabase") - try: - from .eix_sql import EixSQLDatabase - except ImportError: - warning(_("Cannot load %s."), "EixSQLDatabase.") - return cls._generate("sql") - else: - return EixSQLDatabase - - else: + try: + db = types[type] + except KeyError: error(_("Unknown database type: %s"), type) raise UnknownDatabaseTypeError, type + + cls.DB_TYPE = type + info(_("Using database type '%s'"), db.cls) + + mod = __import__(db.module, globals(), locals(), [db.cls]) + return getattr(mod, db.cls) @classmethod def _get_session(cls): diff --git a/portato/db/exceptions.py b/portato/db/exceptions.py index 8a6e424..82fa337 100644 --- a/portato/db/exceptions.py +++ b/portato/db/exceptions.py @@ -22,3 +22,5 @@ class DatabaseInstantiationError (DatabaseError): class UnsupportedSearchTypeError(DatabaseError): pass +class DatabaseInitError (DatabaseError): + pass |