summaryrefslogtreecommitdiff
path: root/portato
diff options
context:
space:
mode:
Diffstat (limited to 'portato')
-rw-r--r--portato/db/__init__.py95
-rw-r--r--portato/db/exceptions.py2
-rw-r--r--portato/gui/windows/preference.py8
3 files changed, 59 insertions, 46 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
diff --git a/portato/gui/windows/preference.py b/portato/gui/windows/preference.py
index 2b6974e..dd2a892 100644
--- a/portato/gui/windows/preference.py
+++ b/portato/gui/windows/preference.py
@@ -168,14 +168,12 @@ class PreferenceWindow (AbstractDialog):
self.databaseCombo = self.tree.get_widget("databaseCombo")
model = gtk.ListStore(str, str, str)
- ctr = 0
active = 0
- for k, name, desc in db.types:
- if k == dbtype:
+ for ctr, (key, t) in enumerate(db.types.iteritems()):
+ if key == dbtype:
active = ctr
- model.append([name, desc, k])
- ctr += 1
+ model.append([t.name, t.descr, key])
self.databaseCombo.set_model(model)
self.databaseCombo.set_active(active)