summaryrefslogtreecommitdiff
path: root/portato/db
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.net>2010-09-06 17:47:26 +0200
committerRené 'Necoro' Neumann <necoro@necoro.net>2010-09-06 17:47:26 +0200
commit4ac3a9d99ffe2a7763f2f109903866ed56f52842 (patch)
tree74680ea1bec1792c53813c98601dd674fa09faee /portato/db
parentefccd35b43ab610e762d353bc917d3afb17c9a61 (diff)
parentb8078063684b5683126cf9bd5b09808666b91af8 (diff)
downloadportato-4ac3a9d99ffe2a7763f2f109903866ed56f52842.tar.gz
portato-4ac3a9d99ffe2a7763f2f109903866ed56f52842.tar.bz2
portato-4ac3a9d99ffe2a7763f2f109903866ed56f52842.zip
Merged 0.14.1
Diffstat (limited to 'portato/db')
-rw-r--r--portato/db/__init__.py95
-rw-r--r--portato/db/eix_sql.py7
-rw-r--r--portato/db/exceptions.py2
-rw-r--r--portato/db/sql.py2
4 files changed, 64 insertions, 42 deletions
diff --git a/portato/db/__init__.py b/portato/db/__init__.py
index 74479e6..6672284 100644
--- a/portato/db/__init__.py
+++ b/portato/db/__init__.py
@@ -10,66 +10,79 @@
#
# Written by René 'Necoro' Neumann <necoro@necoro.net>
+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/eix_sql.py b/portato/db/eix_sql.py
index 2a693e9..e93a613 100644
--- a/portato/db/eix_sql.py
+++ b/portato/db/eix_sql.py
@@ -20,10 +20,14 @@ except ImportError:
import os
from .sql import SQLDatabase
+from .exceptions import DatabaseInitError
from ..eix import EixReader
from ..helper import debug, warning
from ..backend import system
+class EixInitError (DatabaseInitError):
+ pass
+
class EixSQLDatabase (SQLDatabase):
CACHE_FILE = "/var/cache/eix"
@@ -35,6 +39,9 @@ class EixSQLDatabase (SQLDatabase):
warning(_("Cache file '%s' does not exist. Using default instead."), self.cache)
self.cache = self.CACHE_FILE
+ if not os.path.exists(self.cache):
+ raise EixInitError(_("Cache file '%s' does not exist.") % self.cache)
+
debug("Using '%s' as eix cache file.", self.cache)
session["cache"] = self.cache
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/db/sql.py b/portato/db/sql.py
index a891e1a..7eb1a3b 100644
--- a/portato/db/sql.py
+++ b/portato/db/sql.py
@@ -261,7 +261,7 @@ class SQLDatabase (Database):
if self._type & self.SEARCH_NAME:
if "/" in restrict:
- rest = "(name LIKE '%s%%' AND cat LIKE '%s')" % restrict.split("/",1)
+ rest = "(name LIKE '%s%%' AND cat LIKE '%s')" % tuple(restrict.split("/",1))
else:
rest = "(name LIKE '%%%(restrict)s%%' OR cat LIKE '%(restrict)s%%')" % {"restrict":restrict}