From d17e60a6087a9b140599d59aa747139b03c7207c Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Mon, 24 Oct 2022 12:01:28 +0200 Subject: [PATCH] Add another table to store linked_revs We need to create fake revisions when packages were touched that are linked themselves --- lib/db.py | 11 ++++++++++- lib/db_revision.py | 6 +++++- lib/importer.py | 41 +++++++++++++++++++++++++++++++++++++++-- lib/tree_builder.py | 5 +++-- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/lib/db.py b/lib/db.py index 7958c50..87acbe8 100644 --- a/lib/db.py +++ b/lib/db.py @@ -163,8 +163,17 @@ class DB: ) """, "UPDATE scheme SET version=13", + ), + schemes[14] = ( + """ + CREATE TABLE linked_revs ( + id SERIAL PRIMARY KEY, + revision_id INTEGER NOT NULL, + linked_id INTEGER NOT NULL + ) + """, + "UPDATE scheme SET version=14", ) - schema_version = self.schema_version() if (schema_version + 1) not in schemes: return diff --git a/lib/db_revision.py b/lib/db_revision.py index 11dfecb..c8065e8 100644 --- a/lib/db_revision.py +++ b/lib/db_revision.py @@ -25,7 +25,7 @@ class DBRevision: self._hash = None def __str__(self): - return f"Rev {self.project}/{self.rev} Md5 {self.unexpanded_srcmd5} {self.commit_time} {self.userid} {self.request_number}" + return f"Rev {self.project}/{self.package}/{self.rev} Md5 {self.unexpanded_srcmd5} {self.commit_time} {self.userid} {self.request_number}" def __repr__(self): return f"[{self.__str__()}]" @@ -119,6 +119,8 @@ class DBRevision: return ret def linked_rev(self, db): + if self.broken: + return None with db.cursor() as cur: cur.execute( "SELECT project,package FROM links where revision_id=%s", (self.dbid,) @@ -134,6 +136,8 @@ class DBRevision: revisions = [DBRevision(row) for row in cur.fetchall()] if revisions: return revisions[0] + else: + self.set_broken(db) return None def set_broken(self, db): diff --git a/lib/importer.py b/lib/importer.py index 8bd08bf..011da01 100644 --- a/lib/importer.py +++ b/lib/importer.py @@ -1,5 +1,6 @@ import functools import logging +import xml.etree.ElementTree as ET from lib.binary import is_binary_or_large from lib.db import DB @@ -145,6 +146,36 @@ class Importer: dbrev.links_to(db, tprj, tpkg) db.conn.commit() + def find_linked_revs(self, db): + cur = db.cursor() + cur.execute( + """SELECT * from revisions WHERE id in (SELECT l.revision_id FROM links l + LEFT JOIN linked_revs lrevs ON lrevs.revision_id=l.revision_id + WHERE lrevs.id IS NULL) and broken is FALSE;""" + ) + for row in cur.fetchall(): + rev = DBRevision(row) + linked_rev = rev.linked_rev(db) + if not linked_rev: + logging.debug("No link", rev) + continue + cur.execute( + """INSERT INTO linked_revs (revision_id, linked_id) + VALUES (%s,%s)""", + (rev.dbid, linked_rev.dbid), + ) + + def fetch_all_linked_packages(self, db, project, package): + cur = db.cursor() + cur.execute( + """SELECT DISTINCT l.project, l.package from links l JOIN revisions r + on r.id=l.revision_id WHERE r.project=%s AND r.package=%s""", + (project, package), + ) + for row in cur.fetchall(): + (lproject, lpackage) = row + self.update_db_package(db, lproject, lpackage) + def import_into_db(self): db = DB() for project, _, api_url in self.projects: @@ -169,9 +200,15 @@ class Importer: # TODO move into SELECT if rev.broken or rev.expanded_srcmd5: continue - linked_rev = rev.linked_rev(db) + with db.cursor() as cur: + cur.execute( + """SELECT unexpanded_srcmd5 from revisions WHERE + id=(SELECT linked_id FROM linked_revs WHERE revision_id=%s""", + (rev.dbid,), + ) + linked_rev = cur.fetchone() if linked_rev: - linked_rev = linked_rev.unexpanded_srcmd5 + linked_rev = linked_rev[0] list = self.obs.list( project, self.package, rev.unexpanded_srcmd5, linked_rev ) diff --git a/lib/tree_builder.py b/lib/tree_builder.py index 69d260d..af74331 100644 --- a/lib/tree_builder.py +++ b/lib/tree_builder.py @@ -12,14 +12,15 @@ class TreeBuilder: ret = [] prev = None for rev in revisions: - if rev.broken: continue + print(rev, rev.files_hash(self.db)) + if rev.broken: + continue if prev and prev.files_hash(self.db) == rev.files_hash(self.db): continue ret.append(rev) prev = rev return ret - def build(self, package): factory_revisions = self.filtered_revisions("openSUSE:Factory", package) source_revisions = dict()