[entropy.db] remove reverse dependencies SQL, generate reverse dependencies metadata dynamically (also using on-disk cache)

This avoids repository database write access requirements and
improves reverse dependencies metadata reliability.
This commit is contained in:
Fabio Erculiani
2010-07-29 19:34:04 +02:00
parent 749a1b8263
commit c288cd80b6
8 changed files with 114 additions and 378 deletions
-12
View File
@@ -243,7 +243,6 @@ help_opts_extended = [
(2, 'vacuum', 2, _('remove installed packages repository internal indexes to save disk space')),
(2, 'generate', 1, _('generate installed packages database using Source Package Manager repositories')),
(2, 'resurrect', 1, _('generate installed packages database using files on the system [last hope]')),
(2, 'revdeps', 1, _('regenerate reverse dependencies metadata')),
(2, 'spmuids', 1, _('regenerate SPM UIDs map (SPM <-> Entropy packages)')),
(2, 'spmsync', 1, _('makes Entropy aware of your Source Package Manager updated packages')),
(2, 'backup', 2, _('backup the current Entropy installed packages database')),
@@ -361,7 +360,6 @@ help_opts_extended = [
(2, 'deptest', 2, _('look for unsatisfied dependencies across community repositories')),
(2, 'pkgtest', 2, _('verify the integrity of local package files')),
(2, 'revdeps', 2, _('regenerate the reverse dependencies metadata')),
None,
(1, 'ugc', 2, _('handles User Generated Content features')),
@@ -560,16 +558,6 @@ def _do_text_community(main_cmd, options):
server_reagent.Entropy.close_repositories()
rc = 0
elif sub_cmd == "revdeps":
try:
import server_reagent
except ImportError:
print_error(darkgreen(comm_err_msg))
rc = 1
else:
rc = server_reagent.Entropy.generate_reverse_dependencies_metadata()
server_reagent.Entropy.close_repositories()
return rc
def _do_text_cleanup(main_cmd, options):
-20
View File
@@ -88,9 +88,6 @@ def database(options):
elif cmd == "resurrect":
return _database_resurrect(etp_client)
elif cmd == "revdeps":
return _database_revdeps(etp_client)
elif cmd in ("counters", "spmuids",):
if cmd == "counters":
print_warning("")
@@ -205,18 +202,6 @@ def _database_counters(entropy_client):
_("Counters table regenerated. Look above for errors."),) ))
return 0
def _database_revdeps(entropy_client):
rc = test_clientdb(entropy_client)
if rc is not None:
return rc
print_info(red(" %s..." % (
_("Regenerating reverse dependencies metadata"),) ))
entropy_client.installed_repository().generateReverseDependenciesMetadata()
print_info(red(" %s." % (
_("Reverse dependencies metadata regenerated successfully"),) ))
return 0
def _database_resurrect(entropy_client):
mytxt = "####### %s: %s" % (
@@ -372,8 +357,6 @@ def _database_resurrect(entropy_client):
print_info(red(" %s." % (_("Database resurrected successfully"),)))
print_info(red(" %s..." % (_("Now generating reverse dependencies metadata"),)))
entropy_client.installed_repository().generateReverseDependenciesMetadata()
print_info(red(" %s..." % (_("Now indexing tables"),)))
entropy_client.installed_repository().indexing = True
entropy_client.installed_repository().createAllIndexes()
@@ -718,9 +701,6 @@ def _database_generate(entropy_client):
print_info(red(" %s." % (_("All the Source Package Manager packages have been injected into Entropy database"),) ))
print_info(red(" %s..." % (
_("Now generating reverse dependencies metadata"),) ))
entropy_client.installed_repository().generateReverseDependenciesMetadata()
print_info(red(" %s...") % (_("Now indexing tables"),) )
entropy_client.installed_repository().indexing = True
entropy_client.installed_repository().createAllIndexes()
-5
View File
@@ -2012,7 +2012,6 @@ def remove_packages(entropy_client, packages = None, atomsdata = None,
if rc != 0:
# generate reverse dependencies metadata now that's done
# so we have fresh meat when queried with user privs
installed_repo.generateReverseDependenciesMetadata(verbose = False)
return -1, rc
# update resume cache
@@ -2027,10 +2026,6 @@ def remove_packages(entropy_client, packages = None, atomsdata = None,
del metaopts
del Package
# generate reverse dependencies metadata now that's done
# so we have fresh meat when queried with user privs
installed_repo.generateReverseDependenciesMetadata(verbose = False)
print_info(red(" @@ ")+blue("%s." % (_("All done"),) ))
return 0, 0
-8
View File
@@ -780,10 +780,6 @@ generate installed packages database using Source Package Manager repositories
generate installed packages database using files on the system [last hope]
=item B<revdeps>
regenerate reverse dependencies metadata
=item B<spmuids>
regenerate SPM UIDs map (SPM <-> Entropy packages)
@@ -1254,10 +1250,6 @@ look for unsatisfied dependencies across community repositories
verify the integrity of local package files
=item B<revdeps>
regenerate reverse dependencies metadata
=item B<ugc>
@@ -1574,9 +1574,6 @@ class Package:
if automerge_data:
inst_repo.insertAutomergefiles(idpackage, automerge_data)
# clear depends table, this will make clientdb dependstable to be
# regenerated during the next request (retrieveReverseDependencies)
inst_repo.taintReverseDependenciesMetadata()
return idpackage
def __filter_out_items_not_installed_from_content(self, pkg_data):
+112 -255
View File
@@ -33,6 +33,7 @@ import threading
import subprocess
import warnings
from sqlite3 import dbapi2
from threading import RLock
from entropy.const import etpConst, const_setup_file, \
const_isunicode, const_convert_to_unicode, const_get_buffer, \
@@ -124,12 +125,6 @@ class EntropyRepository(EntropyRepositoryBase):
dependency VARCHAR
);
CREATE TABLE dependstable (
iddependency INTEGER PRIMARY KEY,
idpackage INTEGER,
FOREIGN KEY(idpackage) REFERENCES baseinfo(idpackage) ON DELETE CASCADE
);
CREATE TABLE conflicts (
idpackage INTEGER,
conflict VARCHAR,
@@ -415,6 +410,7 @@ class EntropyRepository(EntropyRepositoryBase):
on closeDB()
@type temporary: bool
"""
self.__live_cache_lock = RLock()
self.__cursor_cache = {}
self.__connection_cache = {}
self._cleanup_stale_cur_conn_t = time.time()
@@ -586,10 +582,11 @@ class EntropyRepository(EntropyRepositoryBase):
self._cursor().execute('PRAGMA default_cache_size = %s' % (size,))
def __clearLiveCache(self, key):
try:
del self.__live_cache[key]
except KeyError:
pass
with self.__live_cache_lock:
try:
del self.__live_cache[key]
except KeyError:
pass
def __del__(self):
self.closeDB()
@@ -2189,7 +2186,8 @@ class EntropyRepository(EntropyRepositoryBase):
"""
super(EntropyRepository, self).clearCache()
self.__live_cache.clear()
with self.__live_cache_lock:
self.__live_cache.clear()
def retrieveRepositoryUpdatesDigest(self, repository):
"""
@@ -3206,52 +3204,51 @@ class EntropyRepository(EntropyRepositoryBase):
"""
Reimplemented from EntropyRepositoryBase.
"""
# WARNING: never remove this, otherwise equo.db
# (client database) dependstable will be always broken (trust me)
# sanity check on the table
c_tup = ("retrieveReverseDependencies_check",)
if not self.__live_cache.get(c_tup):
self.__live_cache[c_tup] = True
if not self._isDependsTableSane(): # is empty, need generation
self.generateReverseDependenciesMetadata(verbose = False)
# always force commit, if possible, otherwise this, for
# read-only repos will be called over and over.
self.commitChanges(force = True)
with self.__live_cache_lock:
if "reverseDependenciesMetadata" not in self.__live_cache:
self.__generateReverseDependenciesMetadata()
excluded_deptypes_query = ""
if exclude_deptypes is not None:
for dep_type in exclude_deptypes:
excluded_deptypes_query += " AND dependencies.type != %d" % (
dep_type,)
excluded_deptypes_query = ""
if exclude_deptypes is not None:
for dep_type in exclude_deptypes:
excluded_deptypes_query += " AND dependencies.type != %d" % (
dep_type,)
rev_deps = self.__live_cache['reverseDependenciesMetadata']
dep_ids = set((k for k, v in rev_deps.items() if package_id in v))
if not dep_ids:
if key_slot:
return []
return set()
dep_ids_str = ', '.join((str(x) for x in dep_ids))
table_name = self._getReverseDependenciesTable()
if atoms:
cur = self._cursor().execute("""
SELECT baseinfo.atom FROM %s,dependencies,baseinfo
WHERE %s.idpackage = (?) AND
%s.iddependency = dependencies.iddependency AND
baseinfo.idpackage = dependencies.idpackage %s""" % (
table_name, table_name, table_name, excluded_deptypes_query,),
(package_id,))
SELECT baseinfo.atom FROM dependencies, baseinfo
WHERE baseinfo.idpackage = dependencies.idpackage %s AND
dependencies.iddependency IN ( %s )""" % (
excluded_deptypes_query, dep_ids_str,))
result = self._cur2set(cur)
elif key_slot:
cur = self._cursor().execute("""
SELECT categories.category || "/" || baseinfo.name,baseinfo.slot
FROM baseinfo,categories,%s,dependencies
WHERE %s.idpackage = (?) AND
%s.iddependency = dependencies.iddependency AND
baseinfo.idpackage = dependencies.idpackage AND
categories.idcategory = baseinfo.idcategory %s""" % (
table_name, table_name, table_name, excluded_deptypes_query,),
(package_id,))
SELECT categories.category || "/" || baseinfo.name,baseinfo.slot
FROM baseinfo, categories, dependencies
WHERE baseinfo.idpackage = dependencies.idpackage AND
categories.idcategory = baseinfo.idcategory %s AND
dependencies.iddependency IN ( %s )""" % (
excluded_deptypes_query, dep_ids_str,))
result = cur.fetchall()
elif excluded_deptypes_query:
cur = self._cursor().execute("""
SELECT dependencies.idpackage FROM dependencies
WHERE %s AND dependencies.iddependency IN ( %s )""" % (
excluded_deptypes_query.lstrip("AND "), dep_ids_str,))
result = self._cur2set(cur)
else:
cur = self._cursor().execute("""
SELECT dependencies.idpackage FROM %s,dependencies
WHERE %s.idpackage = (?) AND
%s.iddependency = dependencies.iddependency %s""" % (
table_name, table_name, table_name, excluded_deptypes_query,),
(package_id,))
SELECT dependencies.idpackage FROM dependencies
WHERE dependencies.iddependency IN ( %s )""" % (dep_ids_str,))
result = self._cur2set(cur)
return result
@@ -3265,24 +3262,23 @@ class EntropyRepository(EntropyRepositoryBase):
"""
Reimplemented from EntropyRepositoryBase.
"""
# WARNING: never remove this, otherwise equo.db (client database)
# dependstable will be always broken (trust me)
# sanity check on the table
c_tup = ("retrieveUnusedPackageIds_check",)
if not self.__live_cache.get(c_tup):
self.__live_cache[c_tup] = True
if not self._isDependsTableSane(): # is empty, need generation
self.generateReverseDependenciesMetadata(verbose = False)
# always force commit, if possible, otherwise this, for
# read-only repos will be called over and over.
self.commitChanges(force = True)
with self.__live_cache_lock:
if "reverseDependenciesMetadata" not in self.__live_cache:
self.__generateReverseDependenciesMetadata()
rev_deps = self.__live_cache['reverseDependenciesMetadata']
pkg_ids = set()
for v in rev_deps.values():
pkg_ids |= v
if not pkg_ids:
return []
pkg_ids_str = ', '.join((str(x) for x in pkg_ids))
table_name = self._getReverseDependenciesTable()
cur = self._cursor().execute("""
SELECT idpackage FROM baseinfo
WHERE idpackage NOT IN (SELECT idpackage FROM %s)
SELECT idpackage FROM baseinfo
WHERE idpackage NOT IN ( %s )
ORDER BY atom
""" % (table_name,))
""" % (pkg_ids_str,))
return self._cur2list(cur)
def _isAtomAvailable(self, atom):
@@ -4312,9 +4308,6 @@ class EntropyRepository(EntropyRepositoryBase):
if not self._doesTableExist("entropy_branch_migration"):
self._createEntropyBranchMigrationTable()
if not self._doesTableExist("dependstable"):
self._createDependsTable()
if not self._doesTableExist("settings"):
self._createSettingsTable()
@@ -4327,11 +4320,12 @@ class EntropyRepository(EntropyRepositoryBase):
"""
Reimplemented from EntropyRepositoryBase.
"""
live_cache_id = ("validateDatabase",)
cached = self.__live_cache.get(live_cache_id)
if cached is not None:
return
self.__live_cache[live_cache_id] = True
with self.__live_cache_lock:
live_cache_id = ("validateDatabase",)
cached = self.__live_cache.get(live_cache_id)
if cached is not None:
return
self.__live_cache[live_cache_id] = True
# use sqlite3 pragma
pingus = MtimePingus()
@@ -4461,7 +4455,6 @@ class EntropyRepository(EntropyRepositoryBase):
# clear caches
self.clearCache()
self.commitChanges()
self.generateReverseDependenciesMetadata(verbose = False)
dbconn.clearCache()
# verify both checksums, if they don't match, bomb out
@@ -4594,37 +4587,41 @@ class EntropyRepository(EntropyRepositoryBase):
return False
return True
# speed up a bit if we already reported a table as existing
c_tup = "_doesTableExist"
cached = self.__live_cache.get(c_tup, {})
if table in cached:
return cached[table]
with self.__live_cache_lock:
# speed up a bit if we already reported a table as existing
c_tup = "_doesTableExist"
cached = self.__live_cache.get(c_tup, {})
if table in cached:
return cached[table]
cur = self._cursor().execute("""
SELECT name FROM SQLITE_MASTER WHERE type = "table" AND name = (?)
LIMIT 1
""", (table,))
rslt = cur.fetchone()
exists = rslt is not None
obj = self.__live_cache.setdefault(c_tup, {})
obj[table] = exists
cur = self._cursor().execute("""
SELECT name FROM SQLITE_MASTER WHERE type = "table" AND name = (?)
LIMIT 1
""", (table,))
rslt = cur.fetchone()
exists = rslt is not None
obj = self.__live_cache.setdefault(c_tup, {})
obj[table] = exists
return exists
def _doesColumnInTableExist(self, table, column):
# speed up a bit if we already reported a column as existing
c_tup = "_doesColumnInTableExist"
d_tup = (table, column,)
cached = self.__live_cache.get(c_tup, {})
if d_tup in cached:
return cached[d_tup]
with self.__live_cache_lock:
# speed up a bit if we already reported a column as existing
c_tup = "_doesColumnInTableExist"
d_tup = (table, column,)
cached = self.__live_cache.get(c_tup, {})
if d_tup in cached:
return cached[d_tup]
cur = self._cursor().execute('PRAGMA table_info( %s )' % (table,))
rslt = (x[1] for x in cur.fetchall())
cur = self._cursor().execute('PRAGMA table_info( %s )' % (table,))
rslt = (x[1] for x in cur.fetchall())
exists = column in rslt
obj = self.__live_cache.setdefault(c_tup, {})
obj[d_tup] = exists
exists = column in rslt
obj = self.__live_cache.setdefault(c_tup, {})
obj[d_tup] = exists
return exists
def checksum(self, do_order = False, strict = True,
@@ -4632,6 +4629,8 @@ class EntropyRepository(EntropyRepositoryBase):
"""
Reimplemented from EntropyRepositoryBase.
"""
# with self.__live_cache_lock:
# Cache usage is thread safe here.
c_tup = ("checksum", do_order, strict, strings, include_signatures,)
cache = self.__live_cache.get(c_tup)
if cache is not None:
@@ -4759,61 +4758,6 @@ class EntropyRepository(EntropyRepositoryBase):
DELETE FROM installedtable
WHERE idpackage = (?)""", (package_id,))
def _createDependsTable(self, temporary = False):
temp_txt = ""
temp_txt_table = "dependstable"
fk_data = """, FOREIGN KEY(idpackage) REFERENCES
baseinfo(idpackage) ON DELETE CASCADE"""
if temporary:
temp_txt = "TEMPORARY"
temp_txt_table = "dependstable_temp"
fk_data = ""
self._cursor().executescript("""
CREATE %s TABLE IF NOT EXISTS %s
( iddependency INTEGER PRIMARY KEY, idpackage INTEGER%s );
INSERT INTO %s VALUES (-1,NULL);
""" % (temp_txt, temp_txt_table, fk_data, temp_txt_table,))
if self.indexing:
self._cursor().execute("""
CREATE INDEX IF NOT EXISTS dependsindex%s_idpackage
ON %s ( idpackage )
""" % (temp_txt_table, temp_txt_table,))
self.commitChanges()
self.__clearLiveCache("_doesTableExist")
def _sanitizeDependsTable(self):
table_name = self._getReverseDependenciesTable()
self._cursor().execute("""
DELETE FROM %s where iddependency = -1
""" % (table_name,))
self.__clearLiveCache("taintReverseDependenciesMetadata")
self.commitChanges()
def _isDependsTableSane(self):
table_name = self._getReverseDependenciesTable()
try:
cur = self._cursor().execute("""
SELECT iddependency FROM %s WHERE iddependency = -1
""" % (table_name,))
except (OperationalError,):
return False # table does not exist, please regenerate and re-run
status = cur.fetchone()
if status:
return False
cur = self._cursor().execute("""
SELECT count(iddependency) FROM %s
""" % (table_name,))
data = cur.fetchone()
count = 0
if data:
count = data[0]
return count > 1
def storeXpakMetadata(self, *args, **kwargs):
""" @deprecated """
warnings.warn("deprecated call!")
@@ -5254,7 +5198,7 @@ class EntropyRepository(EntropyRepositoryBase):
"useflags", "keywords", "content", "counters", "sizes",
"eclasses", "needed", "triggers", "systempackages", "injected",
"installedtable", "automergefiles", "packagesignatures",
"packagespmphases", "provided_libs", "dependstable"
"packagespmphases", "provided_libs"
)
done_something = False
@@ -5578,119 +5522,32 @@ class EntropyRepository(EntropyRepositoryBase):
""")
self.__clearLiveCache("_doesTableExist")
def _addDependsRelationToDependsTable(self, iterable):
# since this is not bulletproof (because user can mess with this
# stuff via SPM), we need to IGNORE IntegrityError exceptions
# caused by foreign constraint violation
try:
self._cursor().executemany("""
INSERT or REPLACE into dependstable VALUES (?,?)""",
iterable)
except IntegrityError:
# ouch, need to cope with that and execute each insert manually
for iddep, package_id in iterable:
try:
self._cursor().execute("""
INSERT or REPLACE into dependstable VALUES (?,?)""",
(iddep, package_id,))
except IntegrityError:
continue
except OperationalError:
# ouch, we cannot write on db file, but still we need to store
# the dep map and make unprivileged uids to get correct information
# out of this, since it's stuff we can give away for free.
# So, let's create a temp table, this will work.
self._createDependsTable(temporary = True)
self._cursor().executemany("""
INSERT or REPLACE into dependstable_temp VALUES (?,?)""",
iterable)
# from now on, reverse dependencies should be considered
# runtime generated only.
self._temp_reverse_deps = True
# no need to execute stuff below this
self.__clearLiveCache("taintReverseDependenciesMetadata")
return
def __generateReverseDependenciesMetadata(self):
"""
Reverse dependencies dynamic metadata generation.
"""
checksum = self.checksum(strict = False)
cache_key = "__generateReverseDependenciesMetadata_%s_%s" % (
self.reponame, checksum,)
rev_deps_data = self._cacher.pop(cache_key)
if rev_deps_data is not None:
self.__live_cache['reverseDependenciesMetadata'] = rev_deps_data
return rev_deps_data
# prune old iddependencies
# NOTE: maybe use ON DELETE CASCADE + foreign key reference?
cur = self._cursor().execute("SELECT iddependency from dependstable")
cur_iddeps = self._cur2set(cur)
my_iddeps = set(x for x, y in iterable)
to_be_pruned = cur_iddeps - my_iddeps
if to_be_pruned:
prune_list = [(x,) for x in to_be_pruned]
self._cursor().executemany("""
DELETE FROM dependstable WHERE iddependency = (?)
""", prune_list)
self.__clearLiveCache("taintReverseDependenciesMetadata")
dep_data = {}
for iddep, atom in self._listAllDependencies():
def _getReverseDependenciesTable(self):
"""
Internal method. When reverse dependencies table is not available
and user has no privileges to make it automatically generated by
the EntropyRepository logic, we need to fallback to a temporary table.
This method just returns the available reverse dependency table that
this instance should use. It does not check if user has write
permissions but rather if the temporary table exists.
"""
if self._temp_reverse_deps:
return "dependstable_temp"
return "dependstable"
def taintReverseDependenciesMetadata(self):
"""
Reimplemented from EntropyRepositoryBase.
"""
cache_id = "taintReverseDependenciesMetadata"
if cache_id in self.__live_cache:
return
table_name = self._getReverseDependenciesTable()
try:
self._cursor().executescript("""
INSERT or IGNORE INTO %s VALUES (-1,NULL);
""" % (table_name,))
except (OperationalError,):
# FIXME: backward compatibility
pass
self.__live_cache[cache_id] = True
def generateReverseDependenciesMetadata(self, verbose = True):
"""
Reimplemented from EntropyRepositoryBase.
"""
depends = self._listAllDependencies()
count = 0
total = len(depends)
mydata = set()
self.taintReverseDependenciesMetadata()
self.commitChanges()
for iddep, atom in depends:
count += 1
if iddep == -1:
continue
if verbose and ((count == 0) or (count % 150 == 0) or \
(count == total)):
self.output( red("Resolving %s") % (atom,), importance = 0,
level = "info", back = True, count = (count, total))
# not safe to use cache here, people messing with multiple
# instances can make this crash
package_id, rc = self.atomMatch(atom, useCache = False)
if package_id != -1:
mydata.add((iddep, package_id,))
obj = dep_data.setdefault(iddep, set())
obj.add(package_id)
# after this step, it'll be sane for sure
if mydata:
# NOTE: no need to call _sanitizeDependsTable()
# _addDependsRelationToDependsTable() already removes
# iddependency = -1
self._addDependsRelationToDependsTable(mydata)
else:
self._sanitizeDependsTable()
super(EntropyRepository, self).generateReverseDependenciesMetadata(
verbose = verbose)
self.__live_cache['reverseDependenciesMetadata'] = dep_data
self._cacher.push(cache_key, dep_data, async = False)
def moveSpmUidsToBranch(self, to_branch):
"""
-42
View File
@@ -349,23 +349,6 @@ class EntropyRepositoryPlugin(object):
"""
return 0
def reverse_dependencies_tree_generation_hook(self,
entropy_repository_instance):
"""
This hook is called inside
EntropyRepository.generateReverseDependenciesMetadata() method at
the very end of the function code.
Every time that repository is "tainted" with new packages, sooner or
later that function is called.
@param entropy_repository_instance: EntropyRepository instance
@type entropy_repository_instance: EntropyRepository
@return: execution status code, return nonzero for errors, this will
raise a RepositoryPluginError exception.
@rtype: int
"""
return 0
class EntropyRepositoryBase(TextInterface, EntropyRepositoryPluginStore, object):
"""
@@ -3482,31 +3465,6 @@ class EntropyRepositoryBase(TextInterface, EntropyRepositoryPluginStore, object)
"""
raise NotImplementedError()
def taintReverseDependenciesMetadata(self):
"""
Taint reverse (or inverse) dependencies metadata so that will be
generated during the next request.
"""
raise NotImplementedError()
def generateReverseDependenciesMetadata(self, verbose = True):
"""
Regenerate reverse (or inverse) dependencies metadata.
Attention: call this method from your subclass (AT THE END), otherwise
EntropyRepositoryPlugins won't be notified.
@keyword verbose: enable verbosity
@type verbose: bool
"""
plugins = self.get_plugins()
for plugin_id in sorted(plugins):
plug_inst = plugins[plugin_id]
exec_rc = plug_inst.reverse_dependencies_tree_generation_hook(self)
if exec_rc:
raise RepositoryPluginError(
"[reverse_dependencies_tree_generation_hook] %s: status: %s" % (
plug_inst.get_id(), exec_rc,))
def moveSpmUidsToBranch(self, to_branch):
"""
Note: this is not intended for general audience.
+2 -33
View File
@@ -409,17 +409,6 @@ class ServerEntropyRepositoryPlugin(EntropyRepositoryPlugin):
return self.treeupdates_move_action_hook(entropy_repository_instance,
package_id)
def reverse_dependencies_tree_generation_hook(self,
entropy_repository_instance):
# force commit even if readonly, this will allow
# to automagically fix dependstable server side
# we don't care much about syncing the
# database since it's a quite trivial change
entropy_repository_instance.commitChanges(force = True,
no_plugins = True)
return 0
class ServerSystemSettingsPlugin(SystemSettingsPlugin):
@@ -4270,7 +4259,6 @@ class ServerRepositoryMixin:
idpackages_added = set()
to_be_injected = set()
my_qa = self.QA()
missing_deps_taint = False
for package_filepath, inject in packages_data:
mycount += 1
@@ -4308,13 +4296,11 @@ class ServerRepositoryMixin:
header = bold(" !!! "),
count = (mycount, maxcount,)
)
# reinit depends table
self.generate_reverse_dependencies_metadata(repo)
# reinit librarypathsidpackage table
if idpackages_added:
dbconn = self.open_server_repository(read_only = False,
no_upload = True, repo = repo)
missing_deps_taint = my_qa.test_missing_dependencies(
my_qa.test_missing_dependencies(
idpackages_added,
dbconn,
ask = ask,
@@ -4331,15 +4317,9 @@ class ServerRepositoryMixin:
if to_be_injected:
self._inject_database_into_packages(to_be_injected,
repo = repo)
# reinit depends table
if missing_deps_taint:
self.generate_reverse_dependencies_metadata(repo)
self.close_repositories()
raise
# reinit depends table
self.generate_reverse_dependencies_metadata(repo)
# make sure packages are really available, it can happen
# after a previous failure to have garbage here
dbconn = self.open_server_repository(just_reading = True, repo = repo)
@@ -4349,7 +4329,7 @@ class ServerRepositoryMixin:
if idpackages_added:
dbconn = self.open_server_repository(read_only = False,
no_upload = True, repo = repo)
missing_deps_taint = my_qa.test_missing_dependencies(
my_qa.test_missing_dependencies(
idpackages_added,
dbconn,
ask = ask,
@@ -4363,10 +4343,6 @@ class ServerRepositoryMixin:
my_qa.test_reverse_dependencies_linking(idpackages_added, dbconn,
repo = repo)
# reinit depends table
if missing_deps_taint:
self.generate_reverse_dependencies_metadata(repo)
# inject database into packages
self._inject_database_into_packages(to_be_injected, repo = repo)
@@ -4475,13 +4451,6 @@ class ServerMiscMixin:
elif isinstance(setting, dict):
self._settings.set_persistent_setting(setting)
def generate_reverse_dependencies_metadata(self, repo = None):
dbconn = self.open_server_repository(read_only = False,
no_upload = True, repo = repo)
dbconn.generateReverseDependenciesMetadata()
self._taint_database(repo = repo)
dbconn.commitChanges()
def _get_gpg_signature(self, repo_sec, repo, pkg_path):
try:
if not repo_sec.is_keypair_available(repo):