]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/dbconn.py
Refactor do_newer_version() in cruft_report.py.
[dak.git] / daklib / dbconn.py
index f69fecd16e4e7e43cc3a4182878b51fcc1b9deff..d4b14293161a321a3630acae51e8bbf9c6deb741 100755 (executable)
@@ -53,7 +53,7 @@ from tempfile import mkstemp, mkdtemp
 from inspect import getargspec
 
 import sqlalchemy
-from sqlalchemy import create_engine, Table, MetaData, Column, Integer
+from sqlalchemy import create_engine, Table, MetaData, Column, Integer, desc
 from sqlalchemy.orm import sessionmaker, mapper, relation, object_session, \
     backref, MapperExtension, EXT_CONTINUE
 from sqlalchemy import types as sqltypes
@@ -421,17 +421,6 @@ __all__.append('get_archive')
 
 ################################################################################
 
-class BinAssociation(object):
-    def __init__(self, *args, **kwargs):
-        pass
-
-    def __repr__(self):
-        return '<BinAssociation %s (%s, %s)>' % (self.ba_id, self.binary, self.suite)
-
-__all__.append('BinAssociation')
-
-################################################################################
-
 class BinContents(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -464,6 +453,9 @@ class DBBinary(ORMObject):
         return ['package', 'version', 'maintainer', 'source',  'poolfile', \
             'binarytype']
 
+    def get_component_name(self):
+        return self.poolfile.location.component.component_name
+
 __all__.append('DBBinary')
 
 @session_wrapper
@@ -483,99 +475,37 @@ def get_suites_binary_in(package, session=None):
 __all__.append('get_suites_binary_in')
 
 @session_wrapper
-def get_binaries_from_name(package, version=None, architecture=None, session=None):
-    """
-    Returns list of DBBinary objects for given C{package} name
+def get_component_by_package_suite(package, suite_list, arch_list=[], session=None):
+    '''
+    Returns the component name of the newest binary package in suite_list or
+    None if no package is found. The result can be optionally filtered by a list
+    of architecture names.
 
     @type package: str
     @param package: DBBinary package name to search for
 
-    @type version: str or None
-    @param version: Version to search for (or None)
-
-    @type architecture: str, list or None
-    @param architecture: Architectures to limit to (or None if no limit)
+    @type suite_list: list of str
+    @param suite_list: list of suite_name items
 
-    @type session: Session
-    @param session: Optional SQL session object (a temporary one will be
-    generated if not supplied)
-
-    @rtype: list
-    @return: list of DBBinary objects for the given name (may be empty)
-    """
-
-    q = session.query(DBBinary).filter_by(package=package)
-
-    if version is not None:
-        q = q.filter_by(version=version)
-
-    if architecture is not None:
-        if not isinstance(architecture, list):
-            architecture = [architecture]
-        q = q.join(Architecture).filter(Architecture.arch_string.in_(architecture))
-
-    ret = q.all()
-
-    return ret
-
-__all__.append('get_binaries_from_name')
-
-@session_wrapper
-def get_binaries_from_source_id(source_id, session=None):
-    """
-    Returns list of DBBinary objects for given C{source_id}
+    @type arch_list: list of str
+    @param arch_list: optional list of arch_string items that defaults to []
 
-    @type source_id: int
-    @param source_id: source_id to search for
-
-    @type session: Session
-    @param session: Optional SQL session object (a temporary one will be
-    generated if not supplied)
-
-    @rtype: list
-    @return: list of DBBinary objects for the given name (may be empty)
-    """
-
-    return session.query(DBBinary).filter_by(source_id=source_id).all()
-
-__all__.append('get_binaries_from_source_id')
-
-@session_wrapper
-def get_binary_from_name_suite(package, suitename, session=None):
-    ### For dak examine-package
-    ### XXX: Doesn't use object API yet
-
-    sql = """SELECT DISTINCT(b.package), b.version, c.name, su.suite_name
-             FROM binaries b, files fi, location l, component c, bin_associations ba, suite su
-             WHERE b.package='%(package)s'
-               AND b.file = fi.id
-               AND fi.location = l.id
-               AND l.component = c.id
-               AND ba.bin=b.id
-               AND ba.suite = su.id
-               AND su.suite_name %(suitename)s
-          ORDER BY b.version DESC"""
-
-    return session.execute(sql % {'package': package, 'suitename': suitename})
-
-__all__.append('get_binary_from_name_suite')
-
-@session_wrapper
-def get_binary_components(package, suitename, arch, session=None):
-    # Check for packages that have moved from one component to another
-    query = """SELECT c.name FROM binaries b, bin_associations ba, suite s, location l, component c, architecture a, files f
-    WHERE b.package=:package AND s.suite_name=:suitename
-      AND (a.arch_string = :arch OR a.arch_string = 'all')
-      AND ba.bin = b.id AND ba.suite = s.id AND b.architecture = a.id
-      AND f.location = l.id
-      AND l.component = c.id
-      AND b.file = f.id"""
-
-    vals = {'package': package, 'suitename': suitename, 'arch': arch}
+    @rtype: str or NoneType
+    @return: name of component or None
+    '''
 
-    return session.execute(query, vals)
+    q = session.query(DBBinary).filter_by(package = package). \
+        join(DBBinary.suites).filter(Suite.suite_name.in_(suite_list))
+    if len(arch_list) > 0:
+        q = q.join(DBBinary.architecture). \
+            filter(Architecture.arch_string.in_(arch_list))
+    binary = q.order_by(desc(DBBinary.version)).first()
+    if binary is None:
+        return None
+    else:
+        return binary.get_component_name()
 
-__all__.append('get_binary_components')
+__all__.append('get_component_by_package_suite')
 
 ################################################################################
 
@@ -918,9 +848,9 @@ __all__.append('ChangePendingSource')
 
 ################################################################################
 
-class Component(object):
-    def __init__(self, *args, **kwargs):
-        pass
+class Component(ORMObject):
+    def __init__(self, component_name = None):
+        self.component_name = component_name
 
     def __eq__(self, val):
         if isinstance(val, str):
@@ -934,8 +864,12 @@ class Component(object):
         # This signals to use the normal comparison operator
         return NotImplemented
 
-    def __repr__(self):
-        return '<Component %s>' % self.component_name
+    def properties(self):
+        return ['component_name', 'component_id', 'description', 'location', \
+            'meets_dfsg']
+
+    def not_null_constraints(self):
+        return ['component_name']
 
 
 __all__.append('Component')
@@ -1642,8 +1576,9 @@ __all__.append('get_dbchange')
 ################################################################################
 
 class Location(ORMObject):
-    def __init__(self, path = None):
+    def __init__(self, path = None, component = None):
         self.path = path
+        self.component = component
         # the column 'type' should go away, see comment at mapper
         self.archive_type = 'pool'
 
@@ -2997,13 +2932,6 @@ class DBConn(object):
                properties = dict(archive_id = self.tbl_archive.c.id,
                                  archive_name = self.tbl_archive.c.name))
 
-        mapper(BinAssociation, self.tbl_bin_associations,
-               properties = dict(ba_id = self.tbl_bin_associations.c.id,
-                                 suite_id = self.tbl_bin_associations.c.suite,
-                                 suite = relation(Suite),
-                                 binary_id = self.tbl_bin_associations.c.bin,
-                                 binary = relation(DBBinary)))
-
         mapper(PendingBinContents, self.tbl_pending_bin_contents,
                properties = dict(contents_id =self.tbl_pending_bin_contents.c.id,
                                  filename = self.tbl_pending_bin_contents.c.filename,
@@ -3052,9 +2980,7 @@ class DBConn(object):
                                  fingerprint = relation(Fingerprint),
                                  install_date = self.tbl_binaries.c.install_date,
                                  suites = relation(Suite, secondary=self.tbl_bin_associations,
-                                     backref=backref('binaries', lazy='dynamic')),
-                                 binassociations = relation(BinAssociation,
-                                                            primaryjoin=(self.tbl_binaries.c.id==self.tbl_bin_associations.c.bin))),
+                                     backref=backref('binaries', lazy='dynamic'))),
                 extension = validator)
 
         mapper(BinaryACL, self.tbl_binary_acl,
@@ -3067,7 +2993,8 @@ class DBConn(object):
 
         mapper(Component, self.tbl_component,
                properties = dict(component_id = self.tbl_component.c.id,
-                                 component_name = self.tbl_component.c.name))
+                                 component_name = self.tbl_component.c.name),
+               extension = validator)
 
         mapper(DBConfig, self.tbl_config,
                properties = dict(config_id = self.tbl_config.c.id))
@@ -3159,7 +3086,8 @@ class DBConn(object):
         mapper(Location, self.tbl_location,
                properties = dict(location_id = self.tbl_location.c.id,
                                  component_id = self.tbl_location.c.component,
-                                 component = relation(Component),
+                                 component = relation(Component, \
+                                     backref=backref('location', uselist = False)),
                                  archive_id = self.tbl_location.c.archive,
                                  archive = relation(Archive),
                                  # FIXME: the 'type' column is old cruft and