from constants import *
+class Cursor(sqlite3.Cursor):
+ def execute(self, *args, **kwargs):
+ # For debugging of SQL queries.
+ #print args, kwargs
+
+ return sqlite3.Cursor.execute(self, *args, **kwargs)
+
+
class Database(object):
def __init__(self, pakfire, filename):
self.pakfire = pakfire
self._db.commit()
def cursor(self):
- return self._db.cursor()
+ return self._db.cursor(Cursor)
def save(self, path):
"""
# Fetch all candidates from the repositories and save the
# best one
- candidates = packages.PackageListing(self.repos.get_by_provides(requires))
+ if requires.type == "file":
+ candidates = self.repos.get_by_file(requires.requires)
+ else:
+ candidates = self.repos.get_by_provides(requires)
+
+ # Turn the candidates into a package listing.
+ candidates = packages.PackageListing(candidates)
if not candidates:
logging.debug(" Got no candidates for that")
# Return the last one.
return p[-1]
+ def get_by_file(self, filename):
+ for pkg in self.packages:
+ if filename in pkg.filelist:
+ yield pkg
+
+ def get_by_id(self, id):
+ raise NotImplementedError
+
+ def get_by_uuid(self, uuid):
+ for pkg in self.packages:
+ if pkg.uuid == uuid:
+ return pkg
+
@property
def packages(self):
for pkg in self._packages:
yield pkg
- @property
- def package_names(self):
- names = []
- for name in [p.name for p in self.packages]:
- if not name in names:
- names.append(name)
-
- return sorted(names)
-
def update(self, force=False):
raise NotImplementedError
# Open the database.
self.db = database.LocalPackageDatabase(self.pakfire)
- def __get_from_cache(self, pkg):
+ def _get_from_cache(self, pkg):
"""
Check if package is already in cache and return an instance of
BinaryPackage instead.
return pkg
- def get_all_by_name(self, name):
- c = self.db.cursor()
- c.execute("SELECT * FROM packages WHERE name = ?", name)
-
- for pkg in c:
- pkg = package.DatabasePackage(self.pakfire, self.repo, self.db, pkg)
-
- # Try to get package from cache.
- yield self.__get_from_cache(pkg)
-
- c.close()
+ def add_package(self, pkg, reason=None):
+ return self.db.add_package(pkg, reason)
- @property
- def package_names(self):
+ def get_by_id(self, id):
c = self.db.cursor()
- c.execute("SELECT DISTINCT name FROM packages ORDER BY name")
+ c.execute("SELECT uuid FROM packages WHERE id = ?", (id,))
for pkg in c:
- yield pkg["name"]
+ break
c.close()
- @property
- def packages(self):
- c = self.db.cursor()
- c.execute("SELECT * FROM packages")
+ return self.get_by_uuid(pkg["uuid"])
- for pkg in c:
- pkg = packages.DatabasePackage(self.pakfire, self.repo, self.db, pkg)
+ def get_by_file(self, filename):
+ c = self.db.cursor()
+ c.execute("SELECT pkg FROM files WHERE name = ?", (filename,))
- # Try to get package from cache.
- yield self.__get_from_cache(pkg)
+ for file in c:
+ pkg = self.get_by_id(file["pkg"])
+ if pkg:
+ yield pkg
c.close()
- def add_package(self, pkg, reason=None):
- return self.db.add_package(pkg, reason)
-
class DatabaseIndex(InstalledIndex):
def __init__(self, pakfire, repo):
os.unlink(self.db.filename)
+ def load_database(self):
+ """
+ Read all packages into RAM.
+ """
+ self._packages = []
+
+ c = self.db.cursor()
+ c.execute("SELECT * FROM packages")
+
+ for pkg in c:
+ pkg = packages.DatabasePackage(self.pakfire, self.repo, self.db, pkg)
+
+ # Try to get package from cache.
+ self._packages.append(self._get_from_cache(pkg))
+
+ c.close()
+
def _update_metadata(self, force):
# Shortcut to repository cache.
cache = self.repo.cache
# (Re-)open the database.
self.db = database.RemotePackageDatabase(self.pakfire,
cache.abspath(filename))
+ self.load_database()
def update(self, force=False):
"""
if not isinstance(requires, pakfire.depsolve.Requires):
requires = pakfire.depsolve.Requires(self, requires)
- # If the provides string equals the name of the package, we
- # return true.
- if self.name == requires.requires:
- return True
-
# Get all provide strings from the package data
# and return true if requires is matched.
if requires.requires in self.provides:
@property
def provides(self):
- provides = self.metadata.get("PKG_PROVIDES").split()
+ if not hasattr(self, "__provides"):
+ # Get automatic provides
+ provides = self._provides
- # Add autoprovides
- for prov in self._provides:
- if not prov in provides:
- provides.append(prov)
+ # Add other provides
+ for prov in self.metadata.get("PKG_PROVIDES").split():
+ if not prov in provides:
+ provides.append(prov)
- return provides
+ self.__provides = provides
+
+ return self.__provides
@property
def conflicts(self):
@property
def provides(self):
- provides = self.metadata.get("provides", "").split()
+ if not hasattr(self, "__provides"):
+ # Get automatic provides
+ provides = self._provides
- # Add autoprovides
- for prov in self._provides:
- if not prov in provides:
- provides.append(prov)
+ # Add other provides
+ for prov in self.metadata.get("provides", "").split():
+ if not prov in provides:
+ provides.append(prov)
- return provides
+ self.__provides = provides
+
+ return self.__provides
@property
def requires(self):
@property
def filelist(self):
- c = self.db.cursor()
- c.execute("SELECT name FROM files WHERE pkg = '%s'" % self.id) # XXX?
+ if not hasattr(self, "__filelist"):
+ c = self.db.cursor()
+ c.execute("SELECT name FROM files WHERE pkg = ?", (self.id,))
- for f in c:
- filename = f["name"]
- if not filename.startswith("/"):
- filename = "/%s" % filename
+ self.__filelist = []
+ for f in c:
+ self.__filelist.append(f["name"])
- yield filename
+ c.close()
- c.close()
+ return self.__filelist
def _does_provide_file(self, requires):
"""
self.add_repo(self.local)
# If we running in build mode, we include our local build repository.
- if self.pakfire.builder:
+ #if self.pakfire.builder:
+ if True:
self.local_build = LocalBuildRepository(self.pakfire)
self.add_repo(self.local_build)
for pkg in repo.get_by_provides(requires):
yield pkg
+ def get_by_file(self, filename):
+ for repo in self.enabled:
+ for pkg in repo.get_by_file(filename):
+ yield pkg
+
def search(self, pattern):
pkg_names = []
if pkg.does_provide(requires):
yield pkg
+ def get_by_file(self, filename):
+ for pkg in self.packages:
+ if filename in pkg.filelist:
+ yield pkg
+
def search(self, pattern):
"""
Returns a list of packages, that match the given pattern,
# if pkg.does_provide(requires):
# yield pkg
+ def get_by_file(self, filename):
+ return self.index.get_by_file(filename)
+