diff --git a/pisi/api.py b/pisi/api.py index 0bb8f25e..77ea7d1a 100644 --- a/pisi/api.py +++ b/pisi/api.py @@ -26,11 +26,13 @@ import pisi.uri import pisi.util import pisi.dependency as dependency import pisi.pgraph as pgraph -import pisi.packagedb -import pisi.repodb -import pisi.installdb -import pisi.sourcedb -import pisi.lockeddbshelve as shelve +import pisi.db.packagedb +import pisi.db.repodb +import pisi.db.filesdb +import pisi.db.installdb +import pisi.db.sourcedb +import pisi.db.componentdb +import pisi.db.lockeddbshelve as shelve import pisi.index import pisi.config import pisi.metadata @@ -105,12 +107,12 @@ def init(database = True, write = True, ctx.database = database if database: shelve.init_dbenv(write=write) - ctx.repodb = pisi.repodb.init() - ctx.installdb = pisi.installdb.init() - ctx.filesdb = pisi.files.FilesDB() - ctx.componentdb = pisi.component.ComponentDB() - ctx.packagedb = pisi.packagedb.init_db() - ctx.sourcedb = pisi.sourcedb.init() + ctx.repodb = pisi.db.repodb.init() + ctx.installdb = pisi.db.installdb.init() + ctx.filesdb = pisi.db.filesdb.init() + ctx.componentdb = pisi.db.componentdb.init() + ctx.packagedb = pisi.db.packagedb.init() + ctx.sourcedb = pisi.db.sourcedb.init() else: ctx.repodb = None ctx.installdb = None @@ -129,20 +131,14 @@ def finalize(): ctx.loghandler.flush() ctx.log.removeHandler(ctx.loghandler) - pisi.repodb.finalize() - pisi.installdb.finalize() - if ctx.filesdb != None: - ctx.filesdb.close() - ctx.filesdb = None - if ctx.componentdb != None: - ctx.componentdb.close() - ctx.componentdb = None - if ctx.packagedb: - pisi.packagedb.finalize_db() - ctx.packagedb = None - if ctx.sourcedb: - pisi.sourcedb.finalize() - ctx.sourcedb = None + + pisi.db.repodb.finalize() + pisi.db.installdb.finalize() + pisi.db.filesdb.finalize() + pisi.db.componentdb.finalize() + pisi.db.packagedb.finalize() + pisi.db.sourcedb.finalize() + if ctx.dbenv: ctx.dbenv.close() ctx.dbenv_lock.close() @@ -169,7 +165,7 @@ def list_available(repo = None): def list_upgradable(): return filter(pisi.operations.is_upgradable, ctx.installdb.list_installed()) + ctx.packagedb.get_replaces().keys() -def package_graph(A, repo = pisi.itembyrepodb.installed, ignore_installed = False): +def package_graph(A, repo = pisi.db.itembyrepodb.installed, ignore_installed = False): """Construct a package relations graph. Graph will contain all dependencies of packages A, if ignore_installed @@ -242,14 +238,14 @@ def generate_conflicts(A): def generate_pending_order(A): # returns pending package list in reverse topological order of dependency - G_f = pgraph.PGraph(ctx.packagedb, pisi.itembyrepodb.installed) # construct G_f + G_f = pgraph.PGraph(ctx.packagedb, pisi.db.itembyrepodb.installed) # construct G_f for x in A.keys(): G_f.add_package(x) B = A while len(B) > 0: Bp = set() for x in B.keys(): - pkg = ctx.packagedb.get_package(x, pisi.itembyrepodb.installed) + pkg = ctx.packagedb.get_package(x, pisi.db.itembyrepodb.installed) for dep in pkg.runtimeDependencies(): if dep.package in G_f.vertices(): G_f.add_dep(x, dep) @@ -317,10 +313,10 @@ def info_file(package_fn): def info_name(package_name, installed=False): """Fetch package information for the given package.""" if installed: - package = ctx.packagedb.get_package(package_name, pisi.itembyrepodb.installed) + package = ctx.packagedb.get_package(package_name, pisi.db.itembyrepodb.installed) repo = None else: - package, repo = ctx.packagedb.get_package_repo(package_name, pisi.itembyrepodb.repos) + package, repo = ctx.packagedb.get_package_repo(package_name, pisi.db.itembyrepodb.repos) metadata = pisi.metadata.MetaData() metadata.package = package @@ -337,10 +333,10 @@ def info_name(package_name, installed=False): files = None return metadata, files, repo -def search_package_terms(terms, repo = pisi.itembyrepodb.all): +def search_package_terms(terms, repo = pisi.db.itembyrepodb.all): return search_in_packages(terms, ctx.packagedb.list_packages(repo), repo) -def search_in_packages(terms, packages, repo = pisi.itembyrepodb.all): +def search_in_packages(terms, packages, repo = pisi.db.itembyrepodb.all): def search(package, term): term = unicode(term).lower() @@ -395,7 +391,7 @@ def add_repo(name, indexuri, at = None): if ctx.repodb.has_repo(name): raise Error(_('Repo %s already present.') % name) else: - repo = pisi.repodb.Repo(pisi.uri.URI(indexuri)) + repo = pisi.db.repodb.Repo(pisi.uri.URI(indexuri)) ctx.repodb.add_repo(name, repo, at = at) ctx.ui.info(_('Repo %s added to system.') % name) diff --git a/pisi/atomicoperations.py b/pisi/atomicoperations.py index a68f87d9..441e6d6a 100644 --- a/pisi/atomicoperations.py +++ b/pisi/atomicoperations.py @@ -29,7 +29,7 @@ import pisi.uri import pisi.ui import pisi.version import pisi.delta -import pisi.packagedb +import pisi.db.packagedb class Error(pisi.Error): pass @@ -159,7 +159,7 @@ class Install(AtomicOperation): # check if package is in database # If it is not, put it into 3rd party packagedb if not ctx.packagedb.has_package(self.pkginfo.name): - ctx.packagedb.add_package(self.pkginfo, pisi.itembyrepodb.thirdparty) + ctx.packagedb.add_package(self.pkginfo, pisi.db.itembyrepodb.thirdparty) # If it is explicitly specified that package conflicts with this package and also # we passed check_conflicts tests in operations.py than this means a non-conflicting @@ -199,7 +199,7 @@ class Install(AtomicOperation): if ctx.installdb.is_installed(pkg.name): # is this a reinstallation? #FIXME: consider REPOSITORY instead of DISTRIBUTION -- exa - #ipackage = ctx.packagedb.get_package(pkg.name, pisi.itembyrepodb.installed) + #ipackage = ctx.packagedb.get_package(pkg.name, pisi.db.itembyrepodb.installed) ipkg = ctx.installdb.get_info(pkg.name) repomismatch = ipkg.distribution != pkg.distribution @@ -424,7 +424,7 @@ class Install(AtomicOperation): ctx.filesdb.add_files(self.metadata.package.name, self.files, txn=txn) # installed packages - ctx.packagedb.add_package(self.pkginfo, pisi.itembyrepodb.installed, txn=txn) + ctx.packagedb.add_package(self.pkginfo, pisi.db.itembyrepodb.installed, txn=txn) def install_single(pkg, upgrade = False): @@ -453,7 +453,7 @@ class Remove(AtomicOperation): def __init__(self, package_name, ignore_dep = None): super(Remove, self).__init__(ignore_dep) self.package_name = package_name - self.package = ctx.packagedb.get_package(self.package_name, pisi.itembyrepodb.installed) + self.package = ctx.packagedb.get_package(self.package_name, pisi.db.itembyrepodb.installed) try: self.files = ctx.installdb.files(self.package_name) except pisi.Error, e: @@ -552,7 +552,7 @@ class Remove(AtomicOperation): ctx.installdb.remove(self.package_name, txn) ctx.filesdb.remove_files(self.files, txn) # FIXME: something goes wrong here, if we use ctx operations ends up with segmentation fault! - pisi.packagedb.remove_tracking_package(self.package_name, txn) + pisi.db.packagedb.remove_tracking_package(self.package_name, txn) def remove_single(package_name): @@ -579,7 +579,7 @@ def virtual_install(metadata, files, txn): ctx.filesdb.add_files(metadata.package.name, files, txn=txn) # installed packages - ctx.packagedb.add_package(metadata.package, pisi.itembyrepodb.installed, txn=txn) + ctx.packagedb.add_package(metadata.package, pisi.db.itembyrepodb.installed, txn=txn) def resurrect_package(package_fn, write_files, txn = None): """Resurrect the package from xml files""" diff --git a/pisi/cli/commands.py b/pisi/cli/commands.py index ba6ff349..22702a5c 100644 --- a/pisi/cli/commands.py +++ b/pisi/cli/commands.py @@ -374,7 +374,7 @@ the package in graphviz format to 'pgraph.dot'. repo = ctx.get_option('repository') ctx.ui.info(_('Plotting packages in repository %s') % repo) else: - repo = pisi.itembyrepodb.repos + repo = pisi.db.itembyrepodb.repos if self.args: a = self.args else: @@ -387,7 +387,7 @@ the package in graphviz format to 'pgraph.dot'. # if A is empty, then graph all packages ctx.ui.info(_('Plotting a graph of relations among all installed packages')) a = ctx.installdb.list_installed() - repo = pisi.itembyrepodb.installed + repo = pisi.db.itembyrepodb.installed g = pisi.api.package_graph(a, repo = repo, ignore_installed = ctx.get_option('ignore_installed')) g.write_graphviz(file(ctx.get_option('output'), 'w')) @@ -953,7 +953,7 @@ Usage: info ... ctx.ui.info(_('[inst] '), noln=True) else: ctx.ui.info(_('Installed package:')) - self.print_pkginfo(metadata, files,pisi.itembyrepodb.installed) + self.print_pkginfo(metadata, files,pisi.db.itembyrepodb.installed) if ctx.packagedb.has_package(arg): metadata, files, repo = pisi.api.info_name(arg, False) @@ -961,7 +961,7 @@ Usage: info ... ctx.ui.info(_('[repo] '), noln=True) else: ctx.ui.info(_('Package found in %s repository:') % repo) - self.print_pkginfo(metadata, files, pisi.itembyrepodb.repos) + self.print_pkginfo(metadata, files, pisi.db.itembyrepodb.repos) if not ctx.packagedb.has_package(arg): ctx.ui.info(_("%s is not found in repositories") % arg) @@ -1146,7 +1146,7 @@ Usage: list-installed ctx.ui.info(_('Package Name |St| Version| Rel.| Build| Distro| Date')) print '========================================================================' for pkg in installed: - package = ctx.packagedb.get_package(pkg, pisi.itembyrepodb.installed) + package = ctx.packagedb.get_package(pkg, pisi.db.itembyrepodb.installed) inst_info = ctx.installdb.get_info(pkg) if self.options.long: ctx.ui.info(unicode(package)) @@ -1524,7 +1524,7 @@ Lists the packages that will be upgraded. ctx.ui.info(_('Package Name |St| Version| Rel.| Build| Distro| Date')) print '========================================================================' for pkg in upgradable_pkgs: - package = ctx.packagedb.get_package(pkg, pisi.itembyrepodb.installed) + package = ctx.packagedb.get_package(pkg, pisi.db.itembyrepodb.installed) inst_info = ctx.installdb.get_info(pkg) if self.options.long: ctx.ui.info(package) diff --git a/pisi/component.py b/pisi/component.py index f1c4adcc..64d5ff6f 100644 --- a/pisi/component.py +++ b/pisi/component.py @@ -18,8 +18,8 @@ import pisi import pisi.context as ctx import pisi.pxml.xmlfile as xmlfile import pisi.pxml.autoxml as autoxml -import pisi.lockeddbshelve as shelve -import pisi.itembyrepodb +import pisi.db.lockeddbshelve as shelve +import pisi.db.itembyrepodb class Error(pisi.Error): pass @@ -81,171 +81,3 @@ class Component(xmlfile.XmlFile): t_Packages = [ [autoxml.String], autoxml.optional, "Parts/Package"] t_Sources = [ [autoxml.String], autoxml.optional, "Parts/Source"] - -class ComponentDB(object): - """a database of components""" - - def __init__(self): - self.d = pisi.itembyrepodb.ItemByRepoDB('component') - - def close(self): - self.d.close() - - def destroy(self): - self.d.destroy() - - def has_component(self, name, repo = pisi.itembyrepodb.repos, txn = None): - name = str(name) - return self.d.has_key(name, repo, txn) - - def get_component(self, name, repo=None, txn = None): - try: - return self.d.get_item(name, repo, txn=txn) - except pisi.itembyrepodb.NotfoundError, e: - raise Error(_('Component %s not found') % name) - - def get_component_repo(self, name, repo=None, txn = None): - try: - return self.d.get_item_repo(name, repo, txn=txn) - except pisi.itembyrepodb.NotfoundError, e: - raise Error(_('Component %s not found') % name) - - def get_union_comp(self, name, txn = None, repo = pisi.itembyrepodb.repos ): - """get a union of all repository components packages, not just the first repo in order. - get only basic repo info from the first repo""" - def proc(txn): - s = self.d.d.get(name, txn=txn) - pkgs = set() - srcs = set() - for repostr in self.d.order(repo = repo): - if s.has_key(repostr): - pkgs |= set(s[repostr].packages) - srcs |= set(s[repostr].sources) - comp = self.get_component(name) - comp.packages = list(pkgs) - comp.sources = list(srcs) - return comp - return self.d.txn_proc(proc, txn) - - def list_components(self, repo=None): - return self.d.list(repo) - - # walk: walks through the underlying components' packages - def get_union_packages(self, component_name, walk=False, repo=pisi.itembyrepodb.repos, txn = None): - """returns union of all repository component's packages, not just the first repo's - component's in order""" - - component = self.get_union_comp(component_name, txn, repo) - if not walk: - return component.packages - - packages = [] - packages.extend(component.packages) - for dep in component.dependencies: - packages.extend(self.get_union_packages(dep, walk, repo, txn)) - - return packages - - # walk: walks through the underlying components' packages - def get_packages(self, component_name, walk=False, repo=None, txn = None): - """returns the given component's and underlying recursive components' packages""" - - component = self.get_component(component_name, repo, txn) - if not walk: - return component.packages - - packages = [] - packages.extend(component.packages) - for dep in component.dependencies: - packages.extend(self.get_packages(dep, walk, repo, txn)) - - return packages - - def add_child(self, component, repo, txn = None): - """update component tree""" - parent_name = ".".join(component.name.split(".")[:-1]) - if not parent_name: # root component - return - - if self.has_component(parent_name, repo, txn): - parent = self.get_component(parent_name, repo, txn) - else: - parent = Component(name = parent_name) - - if component.name not in parent.dependencies: - parent.dependencies.append(component.name) - self.d.add_item(parent_name, parent, repo, txn) - - def update_component(self, component, repo, txn = None): - def proc(txn): - if self.has_component(component.name, repo, txn): - # preserve list of sources, packages and dependencies - current = self.d.get_item(component.name, repo, txn) - component.packages = current.packages - component.sources = current.sources - component.dependencies = current.dependencies - self.d.add_item(component.name, component, repo, txn) - self.add_child(component, repo, txn) - self.d.txn_proc(proc, txn) - - def add_package(self, component_name, package, repo, txn = None): - def proc(txn): - assert component_name - if self.has_component(component_name, repo, txn): - component = self.get_component(component_name, repo, txn) - else: - component = Component( name = component_name ) - if not package in component.packages: - component.packages.append(package) - self.d.add_item(component_name, component, repo, txn) # update - self.add_child(component, repo, txn) - self.d.txn_proc(proc, txn) - - def remove_package(self, component_name, package, repo = None, txn = None): - def proc(txn, repo): - if not self.has_component(component_name, repo, txn): - raise Error(_('Information for component %s not available') % component_name) - if not repo: - repo = self.d.which_repo(component_name, txn=txn) # get default repo then - component = self.get_component(component_name, repo, txn) - if package in component.packages: - component.packages.remove(package) - self.d.add_item(component_name, component, repo, txn) # update - - ctx.txn_proc(lambda x: proc(txn, repo), txn) - - def add_spec(self, component_name, spec, repo, txn = None): - def proc(txn): - assert component_name - if self.has_component(component_name, repo, txn): - component = self.get_component(component_name, repo, txn) - else: - component = Component( name = component_name ) - if not spec in component.sources: - component.sources.append(spec) - self.d.add_item(component_name, component, repo, txn) # update - self.add_child(component, repo, txn) - self.d.txn_proc(proc, txn) - - def remove_spec(self, component_name, spec, repo = None, txn = None): - def proc(txn, repo): - if not self.has_component(component_name, repo, txn): - raise Error(_('Information for component %s not available') % component_name) - if not repo: - repo = self.d.which_repo(component_name, txn=txn) # get default repo then - component = self.get_component(component_name, repo, txn) - if spec in component.sources: - component.sources.remove(spec) - self.d.add_item(component_name, component, repo, txn) # update - - ctx.txn_proc(lambda x: proc(txn, repo), txn) - - def clear(self, txn = None): - self.d.clear(txn) - - def remove_component(self, name, repo = None, txn = None): - name = str(name) - self.d.remove_item(name, repo, txn) - - def remove_repo(self, repo, txn = None): - self.d.remove_repo(repo, txn=txn) diff --git a/pisi/db/__init__.py b/pisi/db/__init__.py new file mode 100644 index 00000000..31121064 --- /dev/null +++ b/pisi/db/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2005 - 2007, TUBITAK/UEKAE +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# Please read the COPYING file. +# diff --git a/pisi/db/componentdb.py b/pisi/db/componentdb.py new file mode 100644 index 00000000..7cf91d7f --- /dev/null +++ b/pisi/db/componentdb.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2005 - 2007, TUBITAK/UEKAE +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# Please read the COPYING file. +# + +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + +import pisi +import pisi.db.lockeddbshelve as shelve +import pisi.context as ctx + +class Error(pisi.Error): + pass + +class ComponentDB(object): + """a database of components""" + + def __init__(self): + self.d = pisi.db.itembyrepodb.ItemByRepoDB('component') + + def close(self): + self.d.close() + + def destroy(self): + self.d.destroy() + + def has_component(self, name, repo = pisi.db.itembyrepodb.repos, txn = None): + name = str(name) + return self.d.has_key(name, repo, txn) + + def get_component(self, name, repo=None, txn = None): + try: + return self.d.get_item(name, repo, txn=txn) + except pisi.db.itembyrepodb.NotfoundError, e: + raise Error(_('Component %s not found') % name) + + def get_component_repo(self, name, repo=None, txn = None): + try: + return self.d.get_item_repo(name, repo, txn=txn) + except pisi.db.itembyrepodb.NotfoundError, e: + raise Error(_('Component %s not found') % name) + + def get_union_comp(self, name, txn = None, repo = pisi.db.itembyrepodb.repos ): + """get a union of all repository components packages, not just the first repo in order. + get only basic repo info from the first repo""" + def proc(txn): + s = self.d.d.get(name, txn=txn) + pkgs = set() + srcs = set() + for repostr in self.d.order(repo = repo): + if s.has_key(repostr): + pkgs |= set(s[repostr].packages) + srcs |= set(s[repostr].sources) + comp = self.get_component(name) + comp.packages = list(pkgs) + comp.sources = list(srcs) + return comp + return self.d.txn_proc(proc, txn) + + def list_components(self, repo=None): + return self.d.list(repo) + + # walk: walks through the underlying components' packages + def get_union_packages(self, component_name, walk=False, repo=pisi.db.itembyrepodb.repos, txn = None): + """returns union of all repository component's packages, not just the first repo's + component's in order""" + + component = self.get_union_comp(component_name, txn, repo) + if not walk: + return component.packages + + packages = [] + packages.extend(component.packages) + for dep in component.dependencies: + packages.extend(self.get_union_packages(dep, walk, repo, txn)) + + return packages + + # walk: walks through the underlying components' packages + def get_packages(self, component_name, walk=False, repo=None, txn = None): + """returns the given component's and underlying recursive components' packages""" + + component = self.get_component(component_name, repo, txn) + if not walk: + return component.packages + + packages = [] + packages.extend(component.packages) + for dep in component.dependencies: + packages.extend(self.get_packages(dep, walk, repo, txn)) + + return packages + + def add_child(self, component, repo, txn = None): + """update component tree""" + parent_name = ".".join(component.name.split(".")[:-1]) + if not parent_name: # root component + return + + if self.has_component(parent_name, repo, txn): + parent = self.get_component(parent_name, repo, txn) + else: + parent = Component(name = parent_name) + + if component.name not in parent.dependencies: + parent.dependencies.append(component.name) + self.d.add_item(parent_name, parent, repo, txn) + + def update_component(self, component, repo, txn = None): + def proc(txn): + if self.has_component(component.name, repo, txn): + # preserve list of sources, packages and dependencies + current = self.d.get_item(component.name, repo, txn) + component.packages = current.packages + component.sources = current.sources + component.dependencies = current.dependencies + self.d.add_item(component.name, component, repo, txn) + self.add_child(component, repo, txn) + self.d.txn_proc(proc, txn) + + def add_package(self, component_name, package, repo, txn = None): + def proc(txn): + assert component_name + if self.has_component(component_name, repo, txn): + component = self.get_component(component_name, repo, txn) + else: + component = Component( name = component_name ) + if not package in component.packages: + component.packages.append(package) + self.d.add_item(component_name, component, repo, txn) # update + self.add_child(component, repo, txn) + self.d.txn_proc(proc, txn) + + def remove_package(self, component_name, package, repo = None, txn = None): + def proc(txn, repo): + if not self.has_component(component_name, repo, txn): + raise Error(_('Information for component %s not available') % component_name) + if not repo: + repo = self.d.which_repo(component_name, txn=txn) # get default repo then + component = self.get_component(component_name, repo, txn) + if package in component.packages: + component.packages.remove(package) + self.d.add_item(component_name, component, repo, txn) # update + + ctx.txn_proc(lambda x: proc(txn, repo), txn) + + def add_spec(self, component_name, spec, repo, txn = None): + def proc(txn): + assert component_name + if self.has_component(component_name, repo, txn): + component = self.get_component(component_name, repo, txn) + else: + component = Component( name = component_name ) + if not spec in component.sources: + component.sources.append(spec) + self.d.add_item(component_name, component, repo, txn) # update + self.add_child(component, repo, txn) + self.d.txn_proc(proc, txn) + + def remove_spec(self, component_name, spec, repo = None, txn = None): + def proc(txn, repo): + if not self.has_component(component_name, repo, txn): + raise Error(_('Information for component %s not available') % component_name) + if not repo: + repo = self.d.which_repo(component_name, txn=txn) # get default repo then + component = self.get_component(component_name, repo, txn) + if spec in component.sources: + component.sources.remove(spec) + self.d.add_item(component_name, component, repo, txn) # update + + ctx.txn_proc(lambda x: proc(txn, repo), txn) + + def clear(self, txn = None): + self.d.clear(txn) + + def remove_component(self, name, repo = None, txn = None): + name = str(name) + self.d.remove_item(name, repo, txn) + + def remove_repo(self, repo, txn = None): + self.d.remove_repo(repo, txn=txn) + +componentdb = None + +def init(): + global componentdb + if componentdb: + return componentdb + + componentdb = ComponentDB() + return componentdb + +def finalize(): + global componentdb + if componentdb: + componentdb.close() + componentdb = None diff --git a/pisi/dbshelve.py b/pisi/db/dbshelve.py similarity index 100% rename from pisi/dbshelve.py rename to pisi/db/dbshelve.py diff --git a/pisi/db/filesdb.py b/pisi/db/filesdb.py new file mode 100644 index 00000000..b9ac0bf7 --- /dev/null +++ b/pisi/db/filesdb.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2005 - 2007, TUBITAK/UEKAE +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# Please read the COPYING file. +# + +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + +import pisi +import pisi.db.lockeddbshelve as shelve + +class Error(pisi.Error): + pass + +class FilesDB(shelve.LockedDBShelf): + + def __init__(self): + shelve.LockedDBShelf.__init__(self, 'files') + + def add_files(self, pkg_name, files, txn = None): + def proc(txn): + for x in files.list: + path = x.path + del x.path # don't store redundant attribute in db + self.put(path, (pkg_name, x), txn) + x.path = path # store it back in + self.txn_proc(proc, txn) + + def remove_files(self, files, txn = None): + def proc(txn): + for x in files.list: + if self.has_key(x.path): + self.delete(x.path, txn) + self.txn_proc(proc, txn) + + def has_file(self, path, txn = None): + return self.has_key(str(path), txn) + + def get_file(self, path, txn = None): + path = str(path) + def proc(txn): + if not self.has_key(path, txn): + return None + else: + (name, fileinfo) = self.get(path, txn) + fileinfo.path = path + return (name, fileinfo) + return self.txn_proc(proc, txn) + + def match_files(self, glob): + # NB: avoid using, this reads the entire db + import fnmatch + glob = str(glob) + infos = [] + for key in self.keys(): + if fnmatch.fnmatch(key, glob): + + # FIXME: Why should we assign path attribute manually + # in fileinfo? This is also done in get_file(), seems + # like a dirty workaround... - baris + name = self[key][0] + fileinfo = self[key][1] + fileinfo.path = key + infos.append((name, fileinfo)) + return infos + +filesdb = None + +def init(): + global filesdb + if filesdb: + return filesdb + + filesdb = FilesDB() + return filesdb + +def finalize(): + global filesdb + if filesdb: + filesdb.close() + filesdb = None diff --git a/pisi/installdb.py b/pisi/db/installdb.py similarity index 99% rename from pisi/installdb.py rename to pisi/db/installdb.py index 6ef21efa..7551fb57 100644 --- a/pisi/installdb.py +++ b/pisi/db/installdb.py @@ -20,7 +20,7 @@ _ = __trans.ugettext # PiSi import pisi import pisi.context as ctx -import pisi.lockeddbshelve as shelve +import pisi.db.lockeddbshelve as shelve import pisi.files import pisi.util diff --git a/pisi/itembyrepodb.py b/pisi/db/itembyrepodb.py similarity index 99% rename from pisi/itembyrepodb.py rename to pisi/db/itembyrepodb.py index ed59b29b..7ac7bd3c 100644 --- a/pisi/itembyrepodb.py +++ b/pisi/db/itembyrepodb.py @@ -16,7 +16,7 @@ _ = __trans.ugettext import pisi import pisi.context as ctx -import pisi.lockeddbshelve as shelve +import pisi.db.lockeddbshelve as shelve installed, thirdparty, repos, all = range(1, 5) diff --git a/pisi/lockeddbshelve.py b/pisi/db/lockeddbshelve.py similarity index 99% rename from pisi/lockeddbshelve.py rename to pisi/db/lockeddbshelve.py index cde9e5a9..83db0339 100644 --- a/pisi/lockeddbshelve.py +++ b/pisi/db/lockeddbshelve.py @@ -16,7 +16,7 @@ import types import bsddb3.db as db import bsddb3.dbobj as dbobj -import pisi.dbshelve as shelve +import pisi.db.dbshelve as shelve import gettext __trans = gettext.translation('pisi', fallback=True) diff --git a/pisi/packagedb.py b/pisi/db/packagedb.py similarity index 89% rename from pisi/packagedb.py rename to pisi/db/packagedb.py index 072af94c..9086a445 100644 --- a/pisi/packagedb.py +++ b/pisi/db/packagedb.py @@ -23,7 +23,7 @@ _ = __trans.ugettext import pisi import pisi.context as ctx -import pisi.itembyrepodb +import pisi.db.itembyrepodb class Error(pisi.Error): pass @@ -38,10 +38,10 @@ class PackageDB(object): using shelf objects""" def __init__(self): - self.d = pisi.itembyrepodb.ItemByRepoDB('package') - self.dr = pisi.itembyrepodb.ItemByRepoDB('revdep') - self.do = pisi.itembyrepodb.ItemByRepoDB('obsoleted') - self.drp = pisi.itembyrepodb.ItemByRepoDB('replaces') + self.d = pisi.db.itembyrepodb.ItemByRepoDB('package') + self.dr = pisi.db.itembyrepodb.ItemByRepoDB('revdep') + self.do = pisi.db.itembyrepodb.ItemByRepoDB('obsoleted') + self.drp = pisi.db.itembyrepodb.ItemByRepoDB('replaces') def close(self): self.d.close() @@ -61,7 +61,7 @@ class PackageDB(object): def get_package(self, name, repo=None, txn = None): try: return self.d.get_item(name, repo, txn=txn) - except pisi.itembyrepodb.NotfoundError: + except pisi.db.itembyrepodb.NotfoundError: raise Error(_('Package %s not found') % name) def get_package_repo(self, name, repo=None, txn = None): @@ -172,21 +172,22 @@ class PackageDB(object): self.drp.remove_repo(repo, txn=txn) self.d.txn_proc(proc, txn) -pkgdb = None - def remove_tracking_package(name, txn = None): # remove the guy from the tracking databases - if pkgdb.has_package(name, pisi.itembyrepodb.installed, txn=txn): - pkgdb.remove_package(name, pisi.itembyrepodb.installed, txn=txn) - if pkgdb.has_package(name, pisi.itembyrepodb.thirdparty, txn=txn): - pkgdb.remove_package(name, pisi.itembyrepodb.thirdparty, txn=txn) + if pkgdb.has_package(name, pisi.db.itembyrepodb.installed, txn=txn): + pkgdb.remove_package(name, pisi.db.itembyrepodb.installed, txn=txn) + if pkgdb.has_package(name, pisi.db.itembyrepodb.thirdparty, txn=txn): + pkgdb.remove_package(name, pisi.db.itembyrepodb.thirdparty, txn=txn) -def init_db(): +pkgdb = None + +def init(): global pkgdb pkgdb = PackageDB() return pkgdb -def finalize_db(): +def finalize(): global pkgdb if pkgdb: pkgdb.close() + pkgdb = None diff --git a/pisi/repodb.py b/pisi/db/repodb.py similarity index 98% rename from pisi/repodb.py rename to pisi/db/repodb.py index f6676115..17d23456 100644 --- a/pisi/repodb.py +++ b/pisi/db/repodb.py @@ -15,7 +15,7 @@ __trans = gettext.translation('pisi', fallback=True) _ = __trans.ugettext import pisi -import pisi.lockeddbshelve as shelve +import pisi.db.lockeddbshelve as shelve import pisi.context as ctx class Error(pisi.Error): diff --git a/pisi/sourcedb.py b/pisi/db/sourcedb.py similarity index 85% rename from pisi/sourcedb.py rename to pisi/db/sourcedb.py index 3c6e1fcf..e85931b2 100644 --- a/pisi/sourcedb.py +++ b/pisi/db/sourcedb.py @@ -25,8 +25,7 @@ __trans = gettext.translation('pisi', fallback=True) _ = __trans.ugettext import pisi.context as ctx -import pisi.repodb -import pisi.itembyrepodb +import pisi.db.itembyrepodb class NotfoundError(pisi.Error): pass @@ -34,8 +33,8 @@ class NotfoundError(pisi.Error): class SourceDB(object): def __init__(self): - self.d = pisi.itembyrepodb.ItemByRepoDB('source') - self.dpkgtosrc = pisi.itembyrepodb.ItemByRepoDB('pkgtosrc') + self.d = pisi.db.itembyrepodb.ItemByRepoDB('source') + self.dpkgtosrc = pisi.db.itembyrepodb.ItemByRepoDB('pkgtosrc') def close(self): self.d.close() @@ -50,13 +49,13 @@ class SourceDB(object): def get_spec(self, name, repo=None, txn = None): try: return self.d.get_item(name, repo, txn) - except pisi.itembyrepodb.NotfoundError: + except pisi.db.itembyrepodb.NotfoundError: raise NotfoundError(_("Source package %s not found") % name) def get_spec_repo(self, name, repo=None, txn = None): try: return self.d.get_item_repo(name, repo, txn) - except pisi.itembyrepodb.NotfoundError: + except pisi.db.itembyrepodb.NotfoundError: raise NotfoundError(_("Source package %s not found") % name) def pkgtosrc(self, name, txn = None): @@ -90,18 +89,18 @@ class SourceDB(object): self.dpkgtosrc.remove_repo(repo, txn=txn) self.d.txn_proc(proc, txn) -sourcedb = None +srcdb = None def init(): - global sourcedb - if sourcedb: - return sourcedb + global srcdb + if srcdb: + return srcdb - sourcedb = SourceDB() - return sourcedb + srcdb = SourceDB() + return srcdb def finalize(): - global sourcedb - if sourcedb: - sourcedb.close() - sourcedb = None + global srcdb + if srcdb: + srcdb.close() + srcdb = None diff --git a/pisi/files.py b/pisi/files.py index aed0614d..7af885ca 100644 --- a/pisi/files.py +++ b/pisi/files.py @@ -15,7 +15,7 @@ during the build process of a package and used in installation.''' import pisi.pxml.autoxml as autoxml -import pisi.lockeddbshelve as shelve +import pisi.db.lockeddbshelve as shelve class FileInfo: @@ -50,54 +50,3 @@ class Files(autoxml.xmlfile.XmlFile): self.list.append(fileinfo) -class FilesDB(shelve.LockedDBShelf): - - def __init__(self): - shelve.LockedDBShelf.__init__(self, 'files') - - def add_files(self, pkg_name, files, txn = None): - def proc(txn): - for x in files.list: - path = x.path - del x.path # don't store redundant attribute in db - self.put(path, (pkg_name, x), txn) - x.path = path # store it back in - self.txn_proc(proc, txn) - - def remove_files(self, files, txn = None): - def proc(txn): - for x in files.list: - if self.has_key(x.path): - self.delete(x.path, txn) - self.txn_proc(proc, txn) - - def has_file(self, path, txn = None): - return self.has_key(str(path), txn) - - def get_file(self, path, txn = None): - path = str(path) - def proc(txn): - if not self.has_key(path, txn): - return None - else: - (name, fileinfo) = self.get(path, txn) - fileinfo.path = path - return (name, fileinfo) - return self.txn_proc(proc, txn) - - def match_files(self, glob): - # NB: avoid using, this reads the entire db - import fnmatch - glob = str(glob) - infos = [] - for key in self.keys(): - if fnmatch.fnmatch(key, glob): - - # FIXME: Why should we assign path attribute manually - # in fileinfo? This is also done in get_file(), seems - # like a dirty workaround... - baris - name = self[key][0] - fileinfo = self[key][1] - fileinfo.path = key - infos.append((name, fileinfo)) - return infos diff --git a/pisi/operations.py b/pisi/operations.py index cbd41026..1dbbf1cc 100644 --- a/pisi/operations.py +++ b/pisi/operations.py @@ -632,7 +632,7 @@ def plan_remove(A): # try to construct a pisi graph of packages to # install / reinstall - G_f = pgraph.PGraph(ctx.packagedb, pisi.itembyrepodb.installed) # construct G_f + G_f = pgraph.PGraph(ctx.packagedb, pisi.db.itembyrepodb.installed) # construct G_f # find the (install closure) graph of G_f by package # set A using packagedb @@ -642,11 +642,11 @@ def plan_remove(A): while len(B) > 0: Bp = set() for x in B: - rev_deps = ctx.packagedb.get_rev_deps(x, pisi.itembyrepodb.installed) + rev_deps = ctx.packagedb.get_rev_deps(x, pisi.db.itembyrepodb.installed) for (rev_dep, depinfo) in rev_deps: # we don't deal with uninstalled rev deps # and unsatisfied dependencies (this is important, too) - if ctx.packagedb.has_package(rev_dep, pisi.itembyrepodb.installed) and \ + if ctx.packagedb.has_package(rev_dep, pisi.db.itembyrepodb.installed) and \ dependency.installed_satisfies_dep(depinfo): if not rev_dep in G_f.vertices(): Bp.add(rev_dep) diff --git a/pisi/pgraph.py b/pisi/pgraph.py index 05181e46..352fa58b 100644 --- a/pisi/pgraph.py +++ b/pisi/pgraph.py @@ -21,7 +21,7 @@ import graph class PGraph(graph.Digraph): - def __init__(self, packagedb, repo = pisi.itembyrepodb.repos): + def __init__(self, packagedb, repo = pisi.db.itembyrepodb.repos): super(PGraph, self).__init__() self.packagedb = packagedb self.repo = repo diff --git a/pisi/relation.py b/pisi/relation.py index 8a478076..c2e09cee 100644 --- a/pisi/relation.py +++ b/pisi/relation.py @@ -17,7 +17,7 @@ _ = __trans.ugettext import pisi.context as ctx import pisi.version import pisi.pxml.autoxml as autoxml -import pisi.itembyrepodb +import pisi.db.itembyrepodb class Relation: @@ -54,6 +54,6 @@ def installed_package_satisfies(relation): if not ctx.installdb.is_installed(pkg_name): return False else: - pkg = ctx.packagedb.get_package(pkg_name, pisi.itembyrepodb.installed) + pkg = ctx.packagedb.get_package(pkg_name, pisi.db.itembyrepodb.installed) (version, release) = (pkg.version, pkg.release) return relation.satisfies_relation(pkg_name, version, release) diff --git a/setup.py b/setup.py index d87e5796..9881a82b 100755 --- a/setup.py +++ b/setup.py @@ -93,7 +93,7 @@ setup(name="pisi", author_email="pisi@pardus.org.tr", url="http://www.pardus.org.tr/eng/pisi/", package_dir = {'': ''}, - packages = ['pisi', 'pisi.cli', 'pisi.actionsapi', 'pisi.pxml', 'pisi.scenarioapi'], + packages = ['pisi', 'pisi.cli', 'pisi.actionsapi', 'pisi.pxml', 'pisi.scenarioapi', 'pisi.db'], scripts = ['pisi-cli', 'scripts/lspisi', 'scripts/unpisi', 'scripts/check-newconfigs.py', 'scripts/revdep-rebuild'], cmdclass = {'install' : Install} )