From 0d0ef528c9ede7efbbf4aa6af876047cc7e5043a Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Thu, 10 Sep 2009 22:25:03 +0200 Subject: [PATCH] [entropy.db/entropy.spm] new entropy pkg metadata called "provided_libs" "provided_libs" contains a list of libraries (including elf classes) that package provides. This commit adds complete entropy.spm and entropy.db support. --- libraries/entropy/db.py | 80 ++++++++++++++++++- .../spm/plugins/interfaces/portage_plugin.py | 28 ++++++- 2 files changed, 100 insertions(+), 8 deletions(-) diff --git a/libraries/entropy/db.py b/libraries/entropy/db.py index ee9aa1eab..64a27b1a5 100644 --- a/libraries/entropy/db.py +++ b/libraries/entropy/db.py @@ -400,6 +400,12 @@ class EntropyRepository: elfclass INTEGER ); + CREATE TABLE provided_libs ( + idpackage INTEGER, + library VARCHAR, + elfclass INTEGER + ); + CREATE TABLE treeupdates ( repository VARCHAR PRIMARY KEY, digest VARCHAR @@ -1575,6 +1581,9 @@ class EntropyRepository: for lib in sorted(pkg_data['needed_paths']): self.insertNeededPaths(lib, pkg_data['needed_paths'][lib]) + if pkg_data.get('provided_libs'): + self.insertProvidedLibraries(idpackage, pkg_data['provided_libs']) + # spm phases if pkg_data.get('spm_phases') != None: self.insertSpmPhases(idpackage, pkg_data['spm_phases']) @@ -1791,6 +1800,10 @@ class EntropyRepository: self.removeSpmPhases(idpackage) except self.dbapi2.OperationalError: pass + try: + self.removeProvidedLibraries(idpackage) + except self.dbapi2.OperationalError: + pass # Remove from dependstable if exists self._removePackageFromDependsTable(idpackage) @@ -2323,6 +2336,21 @@ class EntropyRepository: INSERT INTO content VALUES (?,?,?) """, [(idpackage, x, content[x],) for x in content]) + def insertProvidedLibraries(self, idpackage, libs_metadata): + """ + Insert library metadata owned by package. + + @param idpackage: package indentifier + @type idpackage: int + @param libs_metadata: provided library metadata composed by list of + tuples of length 2 containing library name and ELF class. + @type libs_metadata: list + """ + with self.__write_mutex: + self.cursor.executemany(""" + INSERT INTO provided_libs VALUES (?,?,?) + """, [(idpackage, x, y,) for x, y in libs_metadata]) + def insertNeededPaths(self, library, paths): """ Insert paths where given ELF obj (library) name can be located. @@ -2391,6 +2419,19 @@ class EntropyRepository: DELETE FROM packagesignatures WHERE idpackage = (?) """, (idpackage,)) + def removeProvidedLibraries(self, idpackage): + """ + Remove provided libraries metadata from repository for given package + identifier. + + @param idpackage: package indentifier + @type idpackage: int + """ + with self.__write_mutex: + self.cursor.execute(""" + DELETE FROM provided_libs WHERE idpackage = (?) + """, (idpackage,)) + def removeSpmPhases(self, idpackage): """ Remove Source Package Manager phases for package. @@ -3483,6 +3524,7 @@ class EntropyRepository: 'eclasses': self.retrieveEclasses(idpackage), 'needed': self.retrieveNeeded(idpackage, extended = True), 'needed_paths': self.retrieveNeededPaths(idpackage), + 'provided_libs': self.retrieveProvidedLibraries(idpackage), 'provide': self.retrieveProvide(idpackage), 'conflicts': self.retrieveConflicts(idpackage), 'licensedata': self.retrieveLicensedata(idpackage), @@ -3564,6 +3606,7 @@ class EntropyRepository: 'eclasses': self.retrieveEclasses(idpackage), 'needed': self.retrieveNeeded(idpackage, extended = True), 'needed_paths': self.retrieveNeededPaths(idpackage), + 'provided_libs': self.retrieveProvidedLibraries(idpackage), 'provide': self.retrieveProvide(idpackage), 'conflicts': self.retrieveConflicts(idpackage), 'licensedata': self.retrieveLicensedata(idpackage), @@ -4411,7 +4454,7 @@ class EntropyRepository: return self._cur2set(cur) - def retrieveNeededLibraries(self, idpackage): + def retrieveProvidedLibraries(self, idpackage): """ Return list of library names (from NEEDED ELF metadata) provided by given package identifier. @@ -4423,14 +4466,14 @@ class EntropyRepository: @rtype: list """ # FIXME backward compatibility - if not self._doesTableExist('neededlibraryidpackages'): + if not self._doesTableExist('provided_libs'): return set() cur = self.cursor.execute(""" - SELECT library, elfclass FROM neededlibraryidpackages + SELECT library, elfclass FROM provided_libs WHERE idpackage = (?) """, (idpackage,)) - return cur.fetchall() + return set(cur.fetchall()) def retrieveNeededLibraryIdpackages(self): @@ -6501,6 +6544,9 @@ class EntropyRepository: "elfclass"): self._createNeededlibraryidpackagesTable() + if not self._doesTableExist('provided_libs'): + self._createProvidedLibs() + if not self._doesTableExist('dependstable'): self._createDependsTable() @@ -7156,6 +7202,7 @@ class EntropyRepository: self._createAutomergefilesIndex() self._createNeededlibrarypathsIndex() self._createNeededlibraryidpackagesIndex() + self._createProvidedLibsIndex() def _createMirrorlinksIndex(self): if self.indexing: @@ -7174,6 +7221,21 @@ class EntropyRepository: except self.dbapi2.OperationalError: pass + def _createProvidedLibsIndex(self): + if self.indexing: + with self.__write_mutex: + try: + self.cursor.executescript(""" + CREATE INDEX IF NOT EXISTS provided_libs_library + ON provided_libs ( library ); + CREATE INDEX IF NOT EXISTS provided_libs_idpackage + ON provided_libs ( idpackage ); + CREATE INDEX IF NOT EXISTS provided_libs_lib_elf + ON provided_libs ( library, elfclass ); + """) + except self.dbapi2.OperationalError: + pass + def _createNeededlibraryidpackagesIndex(self): if self.indexing: with self.__write_mutex: @@ -7578,6 +7640,16 @@ class EntropyRepository: """) self._setupInitialSettings() + def _createProvidedLibs(self): + with self.__write_mutex: + self.cursor.executescript(""" + CREATE TABLE provided_libs ( + idpackage INTEGER, + library VARCHAR, + elfclass INTEGER + ); + """) + def _createNeededlibrarypathsTable(self): with self.__write_mutex: self.cursor.executescript(""" diff --git a/libraries/entropy/spm/plugins/interfaces/portage_plugin.py b/libraries/entropy/spm/plugins/interfaces/portage_plugin.py index 2c2db56dc..ddef6de61 100644 --- a/libraries/entropy/spm/plugins/interfaces/portage_plugin.py +++ b/libraries/entropy/spm/plugins/interfaces/portage_plugin.py @@ -671,10 +671,8 @@ class PortagePlugin(SpmPlugin): package_file) data['disksize'] = entropy.tools.sum_file_sizes(data['content']) - for obj, ftype in data['content'].items(): - if ftype == "dir": - continue - print obj + data['provided_libs'] = self._extract_pkg_metadata_provided_libs( + data['content']) # [][][] Kernel dependent packages hook [][][] data['versiontag'] = '' @@ -2658,6 +2656,7 @@ class PortagePlugin(SpmPlugin): my_lib = os.path.join(ldpath, needed_lib) if not os.access(my_lib, os.R_OK): continue + # FIXME: this won't work with injected packages myclass = entropy.tools.read_elf_class(my_lib) if myclass != elf_class: continue @@ -2666,6 +2665,27 @@ class PortagePlugin(SpmPlugin): return data + def _extract_pkg_metadata_provided_libs(self, content): + + provided_libs = set() + ldpaths = entropy.tools.collect_linker_paths() + for obj, ftype in content.items(): + + if ftype == "dir": + continue + obj_dir, obj_name = os.path.split(obj) + + if obj_dir not in ldpaths: + continue + # FIXME: this won't work with injected packages + if not entropy.tools.is_elf_file(obj): + continue + + elf_class = entropy.tools.read_elf_class(obj) + provided_libs.add((obj_name, elf_class,)) + + return provided_libs + def _extract_pkg_metadata_messages(self, log_dir, category, name, version): pkg_messages = []