summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.net>2009-01-28 12:58:53 +0100
committerRené 'Necoro' Neumann <necoro@necoro.net>2009-01-28 12:58:53 +0100
commit320f6f6270853b0209611ac6ec642994a90220b5 (patch)
tree70e4d3d151fa00ab906ac175ad3c063e0f639d5c
parentabbc143c81d9c5b808d5c8ee14acc33835871fd5 (diff)
downloadportato-320f6f6270853b0209611ac6ec642994a90220b5.tar.gz
portato-320f6f6270853b0209611ac6ec642994a90220b5.tar.bz2
portato-320f6f6270853b0209611ac6ec642994a90220b5.zip
Moved SQLDatabase
Diffstat (limited to '')
-rw-r--r--portato/db/database.py2
-rw-r--r--portato/db/sql.py227
-rw-r--r--portato/gui/utils.py252
3 files changed, 233 insertions, 248 deletions
diff --git a/portato/db/database.py b/portato/db/database.py
index 0ff71a7..7d8e378 100644
--- a/portato/db/database.py
+++ b/portato/db/database.py
@@ -10,6 +10,8 @@
#
# Written by René 'Necoro' Neumann <necoro@necoro.net>
+from __future__ import absolute_import, with_statement
+
class PkgData (object):
__slots__ = ("cat", "pkg", "inst")
diff --git a/portato/db/sql.py b/portato/db/sql.py
new file mode 100644
index 0000000..c80fd91
--- /dev/null
+++ b/portato/db/sql.py
@@ -0,0 +1,227 @@
+# -*- coding: utf-8 -*-
+#
+# File: portato/db/sql.py
+# This file is part of the Portato-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2009 René 'Necoro' Neumann
+# This is free software. You may redistribute copies of it under the terms of
+# the GNU General Public License version 2.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# Written by René 'Necoro' Neumann <necoro@necoro.net>
+
+from __future__ import absolute_import, with_statement
+
+try:
+ import sqlite3 as sql
+except ImportError:
+ from pysqlite2 import dbapi2 as sql
+
+import anydbm
+import hashlib
+import os
+
+from functools import wraps
+from threading import RLock
+
+from ..helper import info, error, debug
+from ..backend import system
+from .database import Database, PkgData
+
+class SQLDatabase (Database):
+
+ FORBIDDEN = (".bzr", ".svn", ".git", "CVS", ".hg", "_darcs")
+
+ def __init__ (self):
+ """Constructor."""
+ self._restrict = ""
+ self._lock = RLock()
+
+ pkgdb = os.path.join(SESSION_DIR, "package.db")
+ pkgdb_existed = os.path.exists(pkgdb)
+
+ if pkgdb_existed:
+ debug("package.db already existant")
+ else:
+ debug("package.db not existant")
+
+ pkg_conn = sql.connect(os.path.join(SESSION_DIR, "package.db"))
+ pkg_conn.row_factory = sql.Row
+ pkg_conn.execute("""
+ CREATE TABLE IF NOT EXISTS packages
+ (
+ name TEXT,
+ cat TEXT,
+ inst INTEGER
+ )""")
+
+ pkg_conn.commit()
+
+ self.was_updated = self.updated()
+ if self.was_updated or not pkgdb_existed:
+ info(_("Cleaning database..."))
+ pkg_conn.execute("DELETE FROM packages") # empty db at beginning
+ info(_("Populating database..."))
+ self.populate(connection = pkg_conn)
+
+ pkg_conn.close()
+
+ descr_conn = sql.connect(os.path.join(SESSION_DIR, "descr.db"))
+ descr_conn.execute("""
+ CREATE TABLE IF NOT EXISTS descriptions
+ (
+ cp TEXT,
+ descr TEXT
+ )""")
+ descr_conn.close()
+
+ def updated (self):
+ changed = False
+
+ def walk (path):
+ debug("Walking %s", path)
+
+ for root, dirs, files in os.walk(path):
+ for f in files:
+ path = os.path.join(root, f)
+ yield "%s %s" % (f, os.stat(path).st_mtime)
+
+ for forbidden in self.FORBIDDEN:
+ if forbidden in dirs:
+ dirs.remove(forbidden)
+
+ overlays = system.get_global_settings("PORTDIR_OVERLAY").split()
+ hashes = {}
+ for overlay in overlays:
+ hashes[overlay] = hashlib.md5("".join(walk(overlay))).hexdigest()
+
+ timestamp = os.path.join(system.get_global_settings("PORTDIR"), "metadata/timestamp")
+ hashes["ROOT"] = hashlib.md5("%s %s" % (timestamp, os.stat(timestamp).st_mtime)).hexdigest()
+
+ dbpath = os.path.join(SESSION_DIR, "portdirs.db")
+ db_existed = os.path.exists(dbpath)
+ db = anydbm.open(dbpath, "c")
+ try:
+ if db_existed:
+ debug("portdirs.db already existant")
+ for key in set(db.keys())- set(hashes.keys()):
+ debug("Overlay '%s' has been removed", key)
+ del db[key]
+ changed = True
+
+ for key in hashes.iterkeys():
+
+ if key not in db.keys():
+ debug("Overlay '%s' has been added.", key)
+ changed = True
+
+ elif db[key] != hashes[key]:
+ debug("Overlay '%s' has been changed.", key)
+ changed = True
+
+ db[key] = hashes[key]
+ else:
+ debug("portdirs.db not existant")
+ for key in hashes.iterkeys():
+ db[key] = hashes[key]
+
+ finally:
+ db.close()
+
+ return changed
+
+ def lock (f):
+ @wraps(f)
+ def wrapper (self, *args, **kwargs):
+ with self._lock:
+ r = f(self, *args, **kwargs)
+
+ return r
+
+ return wrapper
+
+ def con (f):
+ @wraps(f)
+ def wrapper (*args, **kwargs):
+ if not "connection" in kwargs:
+ con= sql.connect(os.path.join(SESSION_DIR, "package.db"))
+ con.row_factory = sql.Row
+ kwargs["connection"] = con
+
+ return f(*args, **kwargs)
+
+ return wrapper
+
+ @lock
+ @con
+ def populate (self, category = None, connection = None):
+ def _get():
+ # get the lists
+ inst = system.find_packages(pkgSet = system.SET_INSTALLED, key=category, with_version = False)
+ for p in system.find_packages(key = category, with_version = False):
+ cat, pkg = p.split("/")
+
+ yield (cat, pkg, p in inst)
+
+ connection.executemany("INSERT INTO packages (cat, name, inst) VALUES (?, ?, ?)", _get())
+ connection.commit()
+
+ @lock
+ @con
+ def get_cat (self, category = None, byName = True, connection = None):
+ sort = "ORDER BY name"
+ if not byName:
+ sort = "ORDER BY inst DESC, name"
+
+ if not category or category == self.ALL:
+ c = connection.execute("SELECT cat, name, inst FROM packages WHERE 1=1 %s %s" % (self.restrict, sort))
+ else:
+ c = connection.execute("SELECT cat, name, inst FROM packages WHERE cat = ? %s %s" % (self.restrict ,sort), (category,))
+
+ for pkg in c:
+ yield PkgData(pkg["cat"], pkg["name"], pkg["inst"])
+ c.close()
+
+ @lock
+ @con
+ def get_categories (self, installed = False, connection = None):
+
+ if installed:
+ where = "inst = 1"
+ else:
+ where = "1 = 1"
+
+ c = connection.execute("SELECT cat FROM packages WHERE %s %s GROUP BY cat" % (where, self.restrict))
+
+ l = c.fetchall()
+ c.close()
+
+ if len(l) > 1:
+ yield self.ALL
+
+ for cat in l:
+ yield cat["cat"]
+
+ @lock
+ @con
+ def reload (self, cat = None, connection = None):
+ if cat:
+ connection.execute("DELETE FROM packages WHERE cat = ?", (cat,))
+ connection.commit()
+ self.populate(cat+"/", connection = connection)
+ else:
+ connection.execute("DELETE FROM packages")
+ connection.commit()
+ self.populate(connection = connection)
+
+ def get_restrict (self):
+ return self._restrict
+
+ @lock
+ def set_restrict (self, restrict):
+ if not restrict:
+ self._restrict = ""
+ else:
+ self._restrict = "AND name LIKE '%%%s%%'" % restrict
+
+ restrict = property(get_restrict, set_restrict)
diff --git a/portato/gui/utils.py b/portato/gui/utils.py
index 2f30946..c9eae69 100644
--- a/portato/gui/utils.py
+++ b/portato/gui/utils.py
@@ -13,28 +13,17 @@
from __future__ import absolute_import, with_statement
# some stuff needed
-import re
-import sys, os
+import sys
import logging
import gettext
-from threading import Thread, RLock
-from functools import wraps
+from threading import Thread
import gtk
# some backend things
-from ..backend import flags, system, set_system
+from ..backend import flags, set_system
from ..helper import debug, info, set_log_level
-from ..constants import APP, LOCALE_DIR, USE_SQL, SESSION_DIR
-
-if USE_SQL:
- try:
- import sqlite3 as sql
- except ImportError:
- from pysqlite2 import dbapi2 as sql
-
- import anydbm
- import hashlib
+from ..constants import APP, LOCALE_DIR
# parser
from ..config_parser import ConfigParser
@@ -155,236 +144,3 @@ class Config (ConfigParser):
"""Writes to the config file and modify any external configs."""
ConfigParser.write(self)
self.modify_external_configs()
-
-class SQLDatabase (object):
-
- ALL = _("ALL")
- FORBIDDEN = (".bzr", ".svn", ".git", "CVS", ".hg", "_darcs")
-
- def __init__ (self):
- """Constructor."""
- self._restrict = ""
- self._lock = RLock()
-
- pkgdb = os.path.join(SESSION_DIR, "package.db")
- pkgdb_existed = os.path.exists(pkgdb)
-
- if pkgdb_existed:
- debug("package.db already existant")
- else:
- debug("package.db not existant")
-
- pkg_conn = sql.connect(os.path.join(SESSION_DIR, "package.db"))
- pkg_conn.row_factory = sql.Row
- pkg_conn.execute("""
- CREATE TABLE IF NOT EXISTS packages
- (
- name TEXT,
- cat TEXT,
- inst INTEGER
- )""")
-
- pkg_conn.commit()
-
- self.was_updated = self.updated()
- if self.was_updated or not pkgdb_existed:
- info(_("Cleaning database..."))
- pkg_conn.execute("DELETE FROM packages") # empty db at beginning
- info(_("Populating database..."))
- self.populate(connection = pkg_conn)
-
- pkg_conn.close()
-
- descr_conn = sql.connect(os.path.join(SESSION_DIR, "descr.db"))
- descr_conn.execute("""
- CREATE TABLE IF NOT EXISTS descriptions
- (
- cp TEXT,
- descr TEXT
- )""")
- descr_conn.close()
-
- def updated (self):
- changed = False
-
- def walk (path):
- debug("Walking %s", path)
-
- for root, dirs, files in os.walk(path):
- for f in files:
- path = os.path.join(root, f)
- yield "%s %s" % (f, os.stat(path).st_mtime)
-
- for forbidden in self.FORBIDDEN:
- if forbidden in dirs:
- dirs.remove(forbidden)
-
- overlays = system.get_global_settings("PORTDIR_OVERLAY").split()
- hashes = {}
- for overlay in overlays:
- hashes[overlay] = hashlib.md5("".join(walk(overlay))).hexdigest()
-
- timestamp = os.path.join(system.get_global_settings("PORTDIR"), "metadata/timestamp")
- hashes["ROOT"] = hashlib.md5("%s %s" % (timestamp, os.stat(timestamp).st_mtime)).hexdigest()
-
- dbpath = os.path.join(SESSION_DIR, "portdirs.db")
- db_existed = os.path.exists(dbpath)
- db = anydbm.open(dbpath, "c")
- try:
- if db_existed:
- debug("portdirs.db already existant")
- for key in set(db.keys())- set(hashes.keys()):
- debug("Overlay '%s' has been removed", key)
- del db[key]
- changed = True
-
- for key in hashes.iterkeys():
-
- if key not in db.keys():
- debug("Overlay '%s' has been added.", key)
- changed = True
-
- elif db[key] != hashes[key]:
- debug("Overlay '%s' has been changed.", key)
- changed = True
-
- db[key] = hashes[key]
- else:
- debug("portdirs.db not existant")
- for key in hashes.iterkeys():
- db[key] = hashes[key]
-
- finally:
- db.close()
-
- return changed
-
- def lock (f):
- @wraps(f)
- def wrapper (self, *args, **kwargs):
- with self._lock:
- r = f(self, *args, **kwargs)
-
- return r
-
- return wrapper
-
- def con (f):
- @wraps(f)
- def wrapper (*args, **kwargs):
- if not "connection" in kwargs:
- con= sql.connect(os.path.join(SESSION_DIR, "package.db"))
- con.row_factory = sql.Row
- kwargs["connection"] = con
-
- return f(*args, **kwargs)
-
- return wrapper
-
- @lock
- @con
- def populate (self, category = None, connection = None):
- """Populates the database.
-
- @param category: An optional category - so only packages of this category are inserted.
- @type category: string
- """
-
- def _get():
- # get the lists
- inst = system.find_packages(pkgSet = system.SET_INSTALLED, key=category, with_version = False)
- for p in system.find_packages(key = category, with_version = False):
- cat, pkg = p.split("/")
-
- yield (cat, pkg, p in inst)
-
- connection.executemany("INSERT INTO packages (cat, name, inst) VALUES (?, ?, ?)", _get())
- connection.commit()
-
- @lock
- @con
- def get_cat (self, category = None, byName = True, connection = None):
- """Returns the packages in the category.
-
- @param cat: category to return the packages from; if None it defaults to "ALL"
- @type cat: string
- @param byName: selects whether to return the list sorted by name or by installation
- @type byName: boolean
- @return: an iterator over a list of tuples: (category, name, is_installed) or []
- @rtype: L{PkgData}<iterator>
- """
-
- sort = "ORDER BY name"
- if not byName:
- sort = "ORDER BY inst DESC, name"
-
- if not category or category == self.ALL:
- c = connection.execute("SELECT cat, name, inst FROM packages WHERE 1=1 %s %s" % (self.restrict, sort))
- else:
- c = connection.execute("SELECT cat, name, inst FROM packages WHERE cat = ? %s %s" % (self.restrict ,sort), (category,))
-
- for pkg in c:
- yield PkgData(pkg["cat"], pkg["name"], pkg["inst"])
- c.close()
-
- @lock
- @con
- def get_categories (self, installed = False, connection = None):
- """Returns all categories.
-
- @param installed: Only return these with at least one installed package.
- @type installed: boolean
- @returns: the list of categories
- @rtype: string<iterator>
- """
-
- if installed:
- where = "inst = 1"
- else:
- where = "1 = 1"
-
- c = connection.execute("SELECT cat FROM packages WHERE %s %s GROUP BY cat" % (where, self.restrict))
-
- l = c.fetchall()
- c.close()
-
- if len(l) > 1:
- yield self.ALL
-
- for cat in l:
- yield cat["cat"]
-
- @lock
- @con
- def reload (self, cat = None, connection = None):
- """Reloads the given category.
-
- @param cat: category
- @type cat: string
- """
-
- if cat:
- connection.execute("DELETE FROM packages WHERE cat = ?", (cat,))
- connection.commit()
- self.populate(cat+"/", connection = connection)
- else:
- connection.execute("DELETE FROM packages")
- connection.commit()
- self.populate(connection = connection)
-
- def get_restrict (self):
- return self._restrict
-
- @lock
- def set_restrict (self, restrict):
- if not restrict:
- self._restrict = ""
- else:
- self._restrict = "AND name LIKE '%%%s%%'" % restrict
-
- restrict = property(get_restrict, set_restrict)
-
-if USE_SQL:
- Database = SQLDatabase
-else:
- Database = DictDatabase