[Secure-testing-commits] r1983 - / bin lib/python

Florian Weimer fw at costa.debian.org
Wed Sep 14 20:48:55 UTC 2005


Author: fw
Date: 2005-09-14 20:48:54 +0000 (Wed, 14 Sep 2005)
New Revision: 1983

Modified:
   Makefile
   bin/update-packages
   lib/python/bugs.py
   lib/python/security_db.py
Log:
This change groups binary packages for different architectures, as long
as they have the same version.  Synthesis of testing/stable/oldstable
has been disabled (and will be replaced with new code).

lib/python/security_db.py (mergeLists):
  New helper functions to deal with architecture lists.
(DB.initSchema):
  Add parsed column to inodeprints table.
  Update source_packages and binary_packages table.
  Split package_status into source_package_status and
  binary_package_status.
(DB.updateSources, DB.updatePackages):
  Remove and replace with ...
(DB.readPackages):
  ... new method.
(DB.availableReleases, DB._updateVersions):
  Adjust to new schema.
(DB.calculateVulnerabilities):
  Disable synthesis of testing etc.
  Adjust to new schema.
  Fix bug in large INSERT INTO statements: Need t.release = p.release
  instead of t.release = n.release.
  Add return to disable bug-specific rating code.
(test):
  Update.

lib/python/bugs.py (PackageNote.releaseStatus):
  Rename ...
(PackageNote.sourceStatus):
  ... and make it specific to source packages.
(BugFromDB.getDebianBugs):
  New method to get a list of Debian bug numbers.

bin/update-packages (import):
  Automatically reads the correct directory.

Makefile (stamps/packages-imported):
  Update accordingly.


Modified: Makefile
===================================================================
--- Makefile	2005-09-14 19:20:56 UTC (rev 1982)
+++ Makefile	2005-09-14 20:48:54 UTC (rev 1983)
@@ -27,8 +27,7 @@
 # update-packages" has been invoked before.
 stamps/packages-imported: $(PACKAGE_FILES)
 	if test -e stamps/packages-downloaded ; then \
-		$(PYTHON) bin/update-packages import \
-			$(RELEASES) $(SECURITY_RELEASES) ; \
+		$(PYTHON) bin/update-packages import ; \
 	fi
 	touch $@
 

Modified: bin/update-packages
===================================================================
--- bin/update-packages	2005-09-14 19:20:56 UTC (rev 1982)
+++ bin/update-packages	2005-09-14 20:48:54 UTC (rev 1983)
@@ -70,35 +70,21 @@
 
 def cmd_import(args):
     db_file = root_path + '/data/security.db'
+    new_file = not os.path.exists(db_file)
     db = security_db.DB(db_file, verbose=True)
-    try:
-        for release, archs in explodeReleases(args):
-            for archive in archives:
-                c = db.writeTxn()
-                db.maybeUpdateSources(c, release, archive,
-                                      nameSources(release, archive))
-                db.commit(c)
-                for arch in archs:
-                    c = db.writeTxn()
-                    db.maybeUpdatePackages(c, release, archive, arch,
-                                           namePackages(release,
-                                                        archive, arch))
-                    db.commit(c)
-    except IOError, e:
-        if e.errno == errno.ENOENT:
-            sys.stderr.write(
-"""error: could not open a file
-error: please run 'update-packages download' first
-""")
-            sys.exit(1)
+    if new_file:
+        db.initSchema()
+    c = db.writeTxn()
+    db.readPackages(c, root_path + '/data/packages')
+    db.commit(c)
 
 cmds = {"download" : cmd_download,
         "import" : cmd_import}
 
-if len(sys.argv) < 3 or not cmds.has_key(sys.argv[1]):
+if len(sys.argv) < 2 or not cmds.has_key(sys.argv[1]):
     sys.stderr.write(\
 """usage: update-packages download URL-BASE RELEASE=ARCH...
-       update-packages import RELEASE=ARCH...
+       update-packages import
 """)
     sys.exit(1)
 try:

Modified: lib/python/bugs.py
===================================================================
--- lib/python/bugs.py	2005-09-14 19:20:56 UTC (rev 1982)
+++ lib/python/bugs.py	2005-09-14 20:48:54 UTC (rev 1983)
@@ -103,25 +103,32 @@
         else:
             return "unfixed"
 
-    def releaseStatus(self, cursor):
-        """Returns a pair of lists (VULNERABLE, NON-VULNERABLE).
+    def sourceStatus(self, cursor):
+        """Returns a pair of lists (VERSION, RELEASE-LIST).
 
-        The lists consits of triples (release, archive, architecture).
+        The first one is the list with the vulnerable versions, the
+        second one contains fixed versions.
         """
 
-        vulnerable = []
-        non_vulnerable  = []
-        
-        for (release, archive, architecture, vuln) in cursor.execute(
-            """SELECT release, archive, architecture, vulnerable
-            FROM package_status WHERE note = ?""", (self.id,)):
-            t = (release, archive,architecture)
-            if vuln:
-                vulnerable.append(t)
+        vulnerable_versions = {}
+        fixed_versions = {}
+        for (release, archive, version, vulnerable) in cursor.execute(
+            """SELECT p.release, p.archive, p.version, s.vulnerable
+            FROM source_package_status AS s, source_packages AS p
+            WHERE s.note = ? AND p.rowid = s.package""", (self.id,)):
+            if vulnerable:
+                versions = vulnerable_versions
             else:
-                non_vulnerable.append(t)
+                versions = fixed_versions
+            if not versions.has_key(version):
+                versions[version] = []
+            versions[version].append((release, archive))
 
-        return (vulnerable, non_vulnerable)
+        def sort(versions):
+            l = map(debian_support.Version, versions.keys())
+            l.sort()
+            return map(lambda ver: (ver, versions[str(ver)]), l)
+        return (sort(vulnerable_versions), sort(fixed_versions))
         
     def writeDB(self, cursor, bug_name):
         """Writes the object to an SQLite database.
@@ -342,6 +349,14 @@
             return
         raise ValueError, "unknown bug " + `name`
 
+    def getDebianBugs(self, cursor):
+        """Returns a list of Debian bugs to which the bug report refers."""
+        return map(lambda (x,): x, cursor.execute(
+            """SELECT DISTINCT bug FROM debian_bugs, package_notes
+            WHERE package_notes.bug_name = ?
+            AND debian_bugs.note = package_notes.id
+            ORDER BY bug""", (self.name,)))
+
 class BugReservedCVE(BugBase):
     """Class for reserved CVE entries."""
     def __init__(self, fname, lineno, name, comments=None):

Modified: lib/python/security_db.py
===================================================================
--- lib/python/security_db.py	2005-09-14 19:20:56 UTC (rev 1982)
+++ lib/python/security_db.py	2005-09-14 20:48:54 UTC (rev 1983)
@@ -28,7 +28,10 @@
 
 import apsw
 import bugs
+import cPickle
+import cStringIO
 import debian_support
+import glob
 import os
 import re
 import sys
@@ -49,6 +52,27 @@
     def __str__(self):
         return self.errors[0] + ' [more...]'
 
+def mergeLists(a, b):
+    """Merges two lists."""
+    if type(a) == types.StringType:
+        if a == "":
+            a = []
+        else:
+            a = a.split(',')
+    if type(b) == types.StringType:
+        if b == "":
+            b = []
+        else:
+            b = b.split(',')
+    result = {}
+    for x in a:
+        result[x] = 1
+    for x in b:
+        result[x] = 1
+    result = result.keys()
+    result.sort()
+    return result
+
 class DB:
     """Access to the security database.
 
@@ -98,7 +122,8 @@
 
         cursor.execute("""CREATE TABLE inodeprints
         (file TEXT NOT NULL PRIMARY KEY,
-         inodeprint TEXT NOT NULL)""")
+         inodeprint TEXT NOT NULL,
+         parsed BLOB)""")
 
         cursor.execute(
             """CREATE TABLE nicknames
@@ -111,23 +136,30 @@
         (id INTEGER NOT NULL PRIMARY KEY,
          version TEXT NOT NULL UNIQUE)""")
 
-        cursor.execute("""CREATE TABLE source_packages
-        (package TEXT NOT NULL,
-         release TEXT NOT NULL, archive TEXT NOT NULL,
-         version TEXT NOT NULL,
-         version_id INTEGER NOT NULL DEFAULT 0,
-         PRIMARY KEY (package, release, archive));""")
+        cursor.execute(
+            """CREATE TABLE source_packages
+            (name TEXT NOT NULL,
+            release TEXT NOT NULL,
+            archive TEXT NOT NULL,
+            version TEXT NOT NULL,
+            version_id INTEGER NOT NULL DEFAULT 0,
+            PRIMARY KEY (name, release, archive))""")
 
-        cursor.execute("""CREATE TABLE binary_packages
-        (package TEXT NOT NULL,
-         release TEXT NOT NULL, archive TEXT NOT NULL,
-         architecture TEXT NOT NULL,
-         version TEXT NOT NULL,
-         version_id INTEGER NOT NULL DEFAULT 0,
-         source TEXT NOT NULL, source_version TEXT NOT NULL,
-         PRIMARY KEY (package, release, archive, architecture));""")
-        cursor.execute("""CREATE INDEX binary_packages_source
-        ON binary_packages(source)""")
+        cursor.execute(
+            """CREATE TABLE binary_packages
+            (name TEXT NOT NULL,
+            release TEXT NOT NULL,
+            archive TEXT NOT NULL,
+            version TEXT NOT NULL,
+            source TEXT NOT NULL,
+            source_version TEXT NOT NULL,
+            archs TEXT NOT NULL,
+            version_id INTEGER NOT NULL DEFAULT 0,
+            PRIMARY KEY (name, release, archive, version, source,
+            source_version))""")
+        cursor.execute(
+            """CREATE INDEX binary_packages_source
+            ON binary_packages(source)""")
 
         cursor.execute("""CREATE TABLE package_notes
         (id INTEGER NOT NULL PRIMARY KEY,
@@ -175,161 +207,189 @@
          reason TEXT NOT NULL,
          PRIMARY KEY (bug_name, release, note))""")
          
-        cursor.execute("""CREATE TABLE package_status
+        cursor.execute("""CREATE TABLE source_package_status
         (note INTEGER NOT NULL,
-        release TEXT NOT NULL,
-        archive TEXT NOT NULL,
-        architecture TEXT NOT NULL,
-        vulnerable INTEGER NOT NULL,
-        bug_name TEXT NOT NULL,
-        package TEXT NOT NULL,
-        source TEXT NOT NULL,
-        PRIMARY KEY (note, release, archive, architecture))""")
+         package INTEGER NOT NULL,
+         vulnerable INTEGER NOT NULL,
+         PRIMARY KEY (note, package))""")
         cursor.execute(
-            "CREATE INDEX package_status_bug ON package_status(bug_name)")
+            """CREATE INDEX source_package_status_package
+            ON source_package_status(package)""")
+
+        cursor.execute("""CREATE TABLE binary_package_status
+        (note INTEGER NOT NULL,
+         package INTEGER NOT NULL,
+         vulnerable INTEGER NOT NULL,
+         PRIMARY KEY (note, package))""")
         cursor.execute(
-            "CREATE INDEX package_status_package ON package_status(package)")
-        cursor.execute(
-            "CREATE INDEX package_status_source ON package_status(source)")
+            """CREATE INDEX binary_package_status_package
+            ON binary_package_status(package)""")
 
-    def updateSources(self, cursor, release, archive, packages):
-        """Reads a Sources file and adds it to the database.
+        self.commit(cursor)
 
-        Old records for the same release/archive pair are removed.
+    def filePrint(self, filename):
+        """Returns a fingerprint string for filename."""
 
-        cursor - cursor used to update the database
-        release - Debian release (e.g. sarge)
-        archive - fork of a release (e.g. security)
-        packages - debian_support.PackageFile object with source packages
-        """
-        
-        cursor.execute('DELETE FROM source_packages '
-                       + 'WHERE release = ? AND archive = ?',
-                       (release, archive))
+        st = os.stat(filename)
+        # The "1" is a version number which can be used to trigger a
+        # re-read if the code has changed in an incompatible way.
+        return `(st.st_size, st.st_ino, st.st_mtime, 1)`
 
-        for pkg in packages:
-            pkg_name = None
-            pkg_version = None
-            for (name, contents) in pkg:
-                if name == "Package":
-                    pkg_name = contents
-                elif name == "Version":
-                    pkg_version = debian_support.Version(contents)
-            if pkg_name is None:
-                raise SyntaxError\
-                      ("package record does not contain package name")
-            if pkg_version is None:
-                raise SyntaxError\
-                      ("package record for %s does not contain version"
-                       % pkg_name)
-            cursor.execute('INSERT INTO source_packages '
-                           + '(package, release, archive, version) '
-                           + 'VALUES (?, ?, ?, ?)',
-                           (pkg_name, release, archive, str(pkg_version)))
+    def _parseFile(self, cursor, filename):
+        current_print = self.filePrint(filename)
 
-    def updatePackages(self, cursor,
-                       release, archive, architecture,
-                       packages):
-        """Reads a Packages file and adds it to the database.
+        def do_parse(packages):
+            if self.verbose:
+                print "    parseFile: reading " + `filename`
 
-        Old records for the same release/archive/architecture
-        triple are removed.
+            re_source = re.compile\
+                (r'^([a-zA-Z0-9.+-]+)(?:\s+\(([a-zA-Z0-9.+:-]+)\))?$')
 
-        cursor - cursor used to update the database
-        release - Debian release (e.g. sarge)
-        archive - fork of a release (e.g. security)
-        architecture - architecture of binary packages (e.g. i386)
-        packages - debian_support.PackageFile object with binary packages
-        """
+            data = []
+            for pkg in packages:
+                pkg_name = None
+                pkg_version = None
+                pkg_source = None
+                pkg_source_version = None
+                for (name, contents) in pkg:
+                    if name == "Package":
+                        pkg_name = contents
+                    elif name == "Version":
+                        pkg_version = contents
+                    elif name == "Source":
+                        match = re_source.match(contents)
+                        if match is None:
+                            raise SyntaxError(('package %s references '
+                                               + 'invalid source package %s') %
+                                              (pkg_name, `contents`))
+                        (pkg_source, pkg_source_version) = match.groups()
+                if pkg_name is None:
+                    raise SyntaxError\
+                          ("package record does not contain package name")
+                if pkg_version is None:
+                    raise SyntaxError\
+                          ("package record for %s does not contain version"
+                           % pkg_name)
+                data.append((pkg_name, pkg_version,
+                             pkg_source, pkg_source_version))
 
-        re_source = re.compile\
-                    (r'^([a-zA-Z0-9.+-]+)(?:\s+\(([a-zA-Z0-9.+:-]+)\))?$')
+            return data
 
-        cursor.execute('DELETE FROM binary_packages '
-                + 'WHERE release = ? AND archive = ? AND architecture = ?',
-                       (release, archive, architecture))
+        def toString(data):
+            result = cStringIO.StringIO()
+            cPickle.dump(data, result)
+            return result.getvalue()
+            
+        for (old_print, contents) in cursor.execute(
+            "SELECT inodeprint, parsed FROM inodeprints WHERE file = ?",
+            (filename,)):
+            if old_print == current_print:
+                return cPickle.load(cStringIO.StringIO(contents))
+            result = do_parse(debian_support.PackageFile(filename))
+            cursor.execute("""UPDATE inodeprints SET inodeprint = ?, parsed = ?
+            WHERE file = ?""", (current_print, toString(result), filename))
+            return result
 
+        # No inodeprints entry, load file and add one.
+        result = do_parse(debian_support.PackageFile(filename))
+        cursor.execute("""INSERT INTO inodeprints (file, inodeprint, parsed)
+        VALUES (?, ?, ?)""", (filename, current_print, toString(result)))
+        return result
 
-        for pkg in packages:
-            pkg_name = None
-            pkg_version = None
-            pkg_source = None
-            pkg_source_version = None
-            for (name, contents) in pkg:
-                if name == "Package":
-                    pkg_name = contents
-                elif name == "Version":
-                    pkg_version = debian_support.Version(contents)
-                elif name == "Source":
-                    match = re_source.match(contents)
-                    if match is None:
-                        raise SyntaxError(('binary package %s references '
-                                           + 'invalid source package %s') %
-                                          (pkg_name, `contents`))
-                    (pkg_source, pkg_source_version) = match.groups()
+    def readPackages(self, cursor, directory):
+        """Reads a directory of package files."""
 
-            if pkg_name is None:
-                raise SyntaxError\
-                      ("binary package record does not contain package name")
-            if pkg_version is None:
-                raise SyntaxError\
-                      ("binary record for %s does not contain version"
-                       % pkg_name)
-            if pkg_source is None:
-                pkg_source = pkg_name
-            if pkg_source_version is None:
-                pkg_source_version = pkg_version
+        if self.verbose:
+            print "readPackages:"
+            print "  deleting old data"
+        cursor.execute("DELETE FROM source_packages")
+        cursor.execute("DELETE FROM binary_packages")
 
-            cursor.execute('INSERT INTO binary_packages '
-                           + '(package, release, archive, architecture,'
-                           + 'version, source, source_version) '
-                           + 'VALUES (?, ?, ?, ?, ?, ?, ?)',
-                           (pkg_name, release, archive, architecture,
-                            str(pkg_version),
-                            pkg_source, str(pkg_source_version)))
+        self._readSourcePackages(cursor, directory)
+        self._readBinaryPackages(cursor, directory)
 
-    def filePrint(self, filename):
-        """Returns a fingerprint string for filename."""
+        if self.verbose:
+            print "  finished"
+            
+    def _readSourcePackages(self, cursor, directory):
+        """Reads from directory with source package files."""
 
-        st = os.stat(filename)
-        # The "1" is a version number which can be used to trigger a
-        # re-read if the code has changed in an incompatible way.
-        return `(st.st_size, st.st_ino, st.st_mtime, 1)`
+        re_sources = re.compile(r'.*/([a-z-]+)_([a-z-]+)_Sources$')
 
-    def _maybeUpdate(self, cursor, args, filename, action):
-        """Internal routine used for conditional update."""
+
+        if self.verbose:
+            print "  reading source packages"
+
+        for filename in glob.glob(directory + '/*_Sources'):
+            match = re_sources.match(filename)
+            if match is None:
+                raise ValueError, "invalid file name: " + `filename`
+
+            (release, archive) = match.groups()
+            parsed = self._parseFile(cursor, filename)
+
+            def gen():
+                for (name, version, source, source_version) in parsed:
+                    assert source is None
+                    assert source_version is None
+                    yield name, release, archive, version
+            cursor.executemany(
+                """INSERT INTO source_packages
+               (name, release, archive, version) VALUES (?, ?, ?, ?)""",
+                gen())
         
-        current_print = self.filePrint(filename)
+    def _readBinaryPackages(self, cursor, directory):
+        """Reads from a directory with binary package files."""
 
-        for (old_print,) in cursor.execute\
-           ("SELECT inodeprint FROM inodeprints WHERE file = ?", (filename,)):
-            if old_print == current_print:
-                return
-            if self.verbose:
-                print "maybeUpdate: updating", `args`
-            result = apply(action, (cursor,) + args
-                           + (debian_support.PackageFile(filename),))
-            cursor.execute("""UPDATE inodeprints SET inodeprint = ?
-            WHERE file = ?""", (current_print, filename))
-            return result
+        re_packages \
+            = re.compile(r'.*/([a-z-]+)_([a-z-]+)_([a-z0-9]+)_Packages$')
+        
+        if self.verbose:
+            print "  reading binary packages"
 
-        # No inodeprints entry, load file and add one.
-        result = apply(action, (cursor,) + args
-                       + (debian_support.PackageFile(filename),))
-        cursor.execute("""INSERT INTO inodeprints (file, inodeprint)
-        VALUES (?, ?)""", (filename, current_print))
-        return result
+        packages = {}
+        for filename in glob.glob(directory + '/*_Packages'):
+            match = re_packages.match(filename)
+            if match is None:
+                raise ValueError, "invalid file name: " + `filename`
 
-    def maybeUpdateSources(self, cursor, release, archive, filename):
-        """Reads the Sources file filename if it has been modified."""
-        self._maybeUpdate(cursor, (release, archive), filename,
-                          self.updateSources)
+            (release, archive, architecture) = match.groups()
+            parsed = self._parseFile(cursor, filename)
+            for (name, version, source, source_version) in parsed:
+                if source is None:
+                    source = name
+                if source_version is None:
+                    source_version = version
+        
+                key = (name, release, archive, version, source, source_version)
+                if packages.has_key(key):
+                    packages[key][architecture] = 1
+                else:
+                    packages[key] = {architecture : 1}
 
-    def maybeUpdatePackages(self, cursor, release, archive, arch, filename):
-        """Reads the Packages file filename if it has been modified."""
-        self._maybeUpdate(cursor, (release, archive, arch), filename,
-                          self.updatePackages)
+        l = packages.keys()
 
+        if len(l) == 0:
+            raise ValueError, "no binary packages found"
+        
+        l.sort()
+        def gen():
+            for key in l:
+                archs = packages[key].keys()
+                archs.sort()
+                archs = ','.join(archs)
+                yield key + (archs,)
+
+        if self.verbose:
+            print "  storing binary package data"
+
+        cursor.executemany(
+            """INSERT INTO binary_packages
+            (name, release, archive, version,
+            source, source_version, archs)
+            VALUES (?, ?, ?, ?, ?, ?, ?)""",
+            gen())
+            
     def deleteBugs(self, cursor):
         """Deletes all record bug reports from the database."""
         cursor.execute("DELETE FROM package_notes")
@@ -420,27 +480,27 @@
         return warnings
 
     def availableReleases(self, cursor=None):
-        """Returns a list of tuples (RELEASE, ARCHIVE, ARCHITECTURE-LIST)."""
+        """Returns a list of tuples (RELEASE, ARCHIVE,
+        SOURCES-PRESENT, ARCHITECTURE-LIST)."""
         if cursor is None:
             cursor = self.cursor()
 
         releases = {}
         for r in cursor.execute(
             "SELECT DISTINCT release, archive FROM source_packages"):
-            releases[r] = ['(sources)']
+            releases[r] = (True, [])
 
-        for (rel, archive, arch) in cursor.execute(
-            """SELECT DISTINCT release, archive, architecture
+        for (rel, archive, archs) in cursor.execute(
+            """SELECT DISTINCT release, archive, archs
             FROM binary_packages"""):
-            try:
-                releases[(rel, archive)].append(arch)
-            except KeyError:
-                releases[(rel, archive)] = [arch]
+            key = (rel, archive)
+            if not releases.has_key(key):
+                releases[key] = (False, [])
+            releases[key][1][:] = mergeLists(releases[key][1], archs)
 
         result = []
-        for ((rel, archive), archs) in releases.items():
-            archs.sort()
-            result.append((rel, archive, archs))
+        for ((rel, archive), (sources, archs)) in releases.items():
+            result.append((rel, archive, sources, archs))
         result.sort()
 
         return result
@@ -496,12 +556,10 @@
                 WHERE fixed_version IS NOT NULL
             UNION ALL SELECT version FROM source_packages
             UNION ALL SELECT version FROM binary_packages)"""):
-            if v is None:
-                continue
             versions.append(debian_support.Version(v))
 
         if self.verbose:
-            print "  calculating linear oder"
+            print "  calculating linear order"
         versions.sort()
 
         if self.verbose:
@@ -561,19 +619,20 @@
                 print "    source packages"
             cursor.execute(
                 """INSERT INTO source_packages 
-                SELECT package, ?, archive, '', MAX(version_id) AS vid
+                SELECT name, ?, archive, '', MAX(version_id) AS vid
                 FROM source_packages WHERE release IN (?, ?)
-                GROUP BY package, archive""",
+                GROUP BY name, archive""",
                 (nickname, realname, realname + '-security'))
             
             if self.verbose:
                 print "    binary packages"
             cursor.execute(
-                """INSERT INTO binary_packages 
-                SELECT DISTINCT package, ?, archive, architecture, '',
-                MAX (version_id) AS vid, source, source_version
+                """INSERT INTO binary_packages
+                SELECT DISTINCT name, ?, archive,
+                MAX (version_id) AS vid, source, source_version,
+                ''
                 FROM binary_packages WHERE release IN (?, ?)
-                GROUP BY package, archive, architecture""",
+                GROUP BY name, archive, archs""",
                 (nickname, realname, realname + '-security'))
 
         if self.verbose:
@@ -607,7 +666,7 @@
         result = []
 
         self._updateVersions(cursor)
-        self._synthesizeReleases(cursor)
+        # self._synthesizeReleases(cursor)
 
         if self.verbose:
             print "calculateVulnerabilities:"
@@ -649,7 +708,8 @@
 
         if self.verbose:
             print "  remove old status"
-        cursor.execute("DELETE FROM package_status")
+        cursor.execute("DELETE FROM source_package_status")
+        cursor.execute("DELETE FROM binary_package_status")
         if self.verbose:
             print "  calculate package status"
             print "    source packages (unqualified)"
@@ -660,56 +720,61 @@
         # tmp_bug_releases table.
         
         cursor.execute(
-            """INSERT INTO package_status
-            SELECT n.id, p.release, p.archive, '' AS architecture,
-            p.version_id < n.fixed_version_id,
-            n.bug_name, p.package, p.package AS source
+            """INSERT INTO source_package_status
+            SELECT n.id, p.rowid,
+            p.version_id < n.fixed_version_id
             FROM package_notes AS n, source_packages AS p
-            WHERE n.release = '' AND p.package = n.package
+            WHERE n.release = '' AND p.name = n.package
             AND NOT EXISTS (SELECT * FROM tmp_bug_releases AS t
                             WHERE t.bug_name = n.bug_name
-                            AND t.release = n.release)""")
+                            AND t.release = p.release)""")
         if self.verbose:
             print "    source packages (qualified)"
         cursor.execute(
-            """INSERT INTO package_status
-            SELECT n.id, p.release, p.archive, '' AS architecture,
-            p.version_id < n.fixed_version_id,
-            n.bug_name, p.package, p.package AS source
+            """INSERT INTO source_package_status
+            SELECT n.id, p.rowid,
+            p.version_id < n.fixed_version_id
             FROM package_notes AS n, source_packages AS p
-            WHERE p.package = n.package
+            WHERE p.name = n.package
             AND (p.release = n.release
-                 OR p.release = n.release || '-security'
+                 OR p.release = (n.release || '-security')
                  OR p.release = (SELECT nickname FROM nicknames
                                  WHERE realname = n.release))""")
 
-        # Same story for binary packages.
+        # Same story for binary packages.  We prefer source packages,
+        # so we skip all notes which have already source packages
+        # attached.
             
         if self.verbose:
-            print "    binary packages"
+            print "    binary packages (unqualified)"
         cursor.execute(
-            """INSERT INTO package_status
-            SELECT n.id, p.release, p.archive, p.architecture,
-            p.version_id < n.fixed_version_id AS fixed,
-            n.bug_name, p.package, p.source
+            """INSERT INTO binary_package_status
+            SELECT n.id, p.rowid,
+            p.version_id < n.fixed_version_id
             FROM package_notes AS n, binary_packages AS p
-            WHERE n.release = '' AND p.package = n.package
-            AND NOT EXISTS (SELECT * FROM tmp_bug_releases AS t
+            WHERE n.release = '' AND p.name = n.package
+            AND (NOT EXISTS (SELECT * FROM tmp_bug_releases AS t
                             WHERE t.bug_name = n.bug_name
-                            AND t.release = n.release)""")
+                            AND t.release = p.release))
+            AND (NOT EXISTS (SELECT * FROM source_package_status AS s
+                             WHERE s.package = p.rowid))""")
+            
         if self.verbose:
             print "    binary packages (qualified)"
         cursor.execute(
-            """INSERT INTO package_status
-            SELECT n.id, p.release, p.archive, p.architecture AS architecture,
-            p.version_id < n.fixed_version_id,
-            n.bug_name, p.package, p.package AS source
+            """INSERT INTO binary_package_status
+            SELECT n.id, p.rowid,
+            p.version_id < n.fixed_version_id
             FROM package_notes AS n, binary_packages AS p
-            WHERE p.package = n.package
+            WHERE p.name = n.package
             AND (p.release = n.release
                  OR p.release = n.release || '-security'
                  OR p.release = (SELECT nickname FROM nicknames
-                                 WHERE realname = n.release))""")
+                                 WHERE realname = n.release))
+            AND (NOT EXISTS (SELECT * FROM source_package_status AS s
+                             WHERE s.package = p.rowid))""")
+
+        return
         
 
         if self.verbose:
@@ -864,31 +929,20 @@
             print "  architecture:", architecture
             
 def test():
+    assert mergeLists('', '') == [], mergeLists('', '')
+    assert mergeLists('', []) == []
+    assert mergeLists('a', 'a') == ['a']
+    assert mergeLists('a', 'b') == ['a', 'b']
+    assert mergeLists('a,c', 'b') == ['a', 'b', 'c']
+    assert mergeLists('a,c', ['b', 'de']) == ['a', 'b', 'c', 'de']
+
     import os
-
     if os.path.exists('test_security.db'):
         os.unlink('test_security.db')
     db = DB('test_security.db')
     db.initSchema()
 
-    data_prefix = '../../data/packages/'
     cursor = db.writeTxn()
-    db.updateSources(cursor, 'sarge', 'main',
-            debian_support.PackageFile(data_prefix + 'sarge_main_Sources'))
-    db.updatePackages(cursor, 'sarge', 'main', 'i386',
-            debian_support.PackageFile(data_prefix
-                                       + 'sarge_main_i386_Packages'))
-    db.updatePackages(cursor, 'sarge', 'main', 'ia64',
-            debian_support.PackageFile(data_prefix
-                                       + 'sarge_main_ia64_Packages'))
-    db.commit(cursor)
-
-    assert str(db.getVersion(cursor, 'sarge', 'ale')) == '0.7.1-1', \
-           db.getVersion(cursor, 'sarge', 'ale')
-
-    # db.check(cursor)
-
-    cursor = db.writeTxn()
     db.deleteBugs(cursor)
     db.insertBugs(cursor, bugs.CVEFile('../../data/CAN/list'))
     db.insertBugs(cursor, bugs.CVEFile('../../data/CVE/list',




More information about the Secure-testing-commits mailing list