]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/dbconn.py
Merge remote-tracking branch 'origin/master' into p-s-from-db
[dak.git] / daklib / dbconn.py
index ae5a9e0d21b6583712fcc5d7fd3578cb55479876..5028b7cdd3015818eea5fe866325e71bd5587205 100755 (executable)
@@ -39,6 +39,7 @@ import re
 import psycopg2
 import traceback
 import commands
+import signal
 
 try:
     # python >= 2.6
@@ -487,6 +488,11 @@ __all__.append('BinContents')
 
 ################################################################################
 
+def subprocess_setup():
+    # Python installs a SIGPIPE handler by default. This is usually not what
+    # non-Python subprocesses expect.
+    signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+
 class DBBinary(ORMObject):
     def __init__(self, package = None, source = None, version = None, \
         maintainer = None, architecture = None, poolfile = None, \
@@ -525,7 +531,8 @@ class DBBinary(ORMObject):
         package does not contain any regular file.
         '''
         fullpath = self.poolfile.fullpath
-        dpkg = Popen(['dpkg-deb', '--fsys-tarfile', fullpath], stdout = PIPE)
+        dpkg = Popen(['dpkg-deb', '--fsys-tarfile', fullpath], stdout = PIPE,
+            preexec_fn = subprocess_setup)
         tar = TarFile.open(fileobj = dpkg.stdout, mode = 'r|')
         for member in tar.getmembers():
             if not member.isdir():
@@ -856,8 +863,8 @@ class BuildQueue(object):
 
         # Check if we have a file of this name or this ID already
         for f in self.queuefiles:
-            if f.fileid is not None and f.fileid == poolfile.file_id or \
-               f.poolfile.filename == poolfile_basename:
+            if (f.fileid is not None and f.fileid == poolfile.file_id) or \
+               (f.poolfile is not None and f.poolfile.filename == poolfile_basename):
                    # In this case, update the BuildQueueFile entry so we
                    # don't remove it too early
                    f.lastused = datetime.now()
@@ -1352,6 +1359,17 @@ __all__.append('get_dscfiles')
 
 ################################################################################
 
+class ExternalOverride(ORMObject):
+    def __init__(self, *args, **kwargs):
+        pass
+
+    def __repr__(self):
+        return '<ExternalOverride %s = %s: %s>' % (self.package, self.key, self.value)
+
+__all__.append('ExternalOverride')
+
+################################################################################
+
 class PoolFile(ORMObject):
     def __init__(self, filename = None, location = None, filesize = -1, \
         md5sum = None):
@@ -2663,6 +2681,8 @@ def add_dsc_to_db(u, filename, session=None):
         session.add(df)
 
     # Add the src_uploaders to the DB
+    session.flush()
+    session.refresh(source)
     source.uploaders = [source.maintainer]
     if u.pkg.dsc.has_key("uploaders"):
         for up in u.pkg.dsc["uploaders"].replace(">, ", ">\t").split("\t"):
@@ -2861,6 +2881,12 @@ class Suite(ORMObject):
         return session.query(DBSource).filter_by(source = source). \
             with_parent(self)
 
+    def get_overridesuite(self):
+        if self.overridesuite is None:
+            return self
+        else:
+            return object_session(self).query(Suite).filter_by(suite_name=self.overridesuite).one()
+
 __all__.append('Suite')
 
 @session_wrapper
@@ -3136,7 +3162,9 @@ __all__.append('VersionCheck')
 def get_version_checks(suite_name, check = None, session = None):
     suite = get_suite(suite_name, session)
     if not suite:
-        return None
+        # Make sure that what we return is iterable so that list comprehensions
+        # involving this don't cause a traceback
+        return []
     q = session.query(VersionCheck).filter_by(suite=suite)
     if check:
         q = q.filter_by(check=check)
@@ -3184,6 +3212,7 @@ class DBConn(object):
             'changes_pending_source_files',
             'changes_pool_files',
             'dsc_files',
+            'external_overrides',
             'extra_src_references',
             'files',
             'fingerprint',
@@ -3219,7 +3248,6 @@ class DBConn(object):
             'almost_obsolete_all_associations',
             'almost_obsolete_src_associations',
             'any_associations_source',
-            'bin_assoc_by_arch',
             'bin_associations_binaries',
             'binaries_suite_arch',
             'binfiles_suite_component_arch',
@@ -3319,6 +3347,13 @@ class DBConn(object):
                                  poolfile_id = self.tbl_dsc_files.c.file,
                                  poolfile = relation(PoolFile)))
 
+        mapper(ExternalOverride, self.tbl_external_overrides,
+                properties = dict(
+                    suite_id = self.tbl_external_overrides.c.suite,
+                    suite = relation(Suite),
+                    component_id = self.tbl_external_overrides.c.component,
+                    component = relation(Component)))
+
         mapper(PoolFile, self.tbl_files,
                properties = dict(file_id = self.tbl_files.c.id,
                                  filesize = self.tbl_files.c.size,
@@ -3591,12 +3626,21 @@ class DBConn(object):
         self.__setupmappers()
         self.pid = os.getpid()
 
-    def session(self):
+    def session(self, work_mem = 0):
+        '''
+        Returns a new session object. If a work_mem parameter is provided a new
+        transaction is started and the work_mem parameter is set for this
+        transaction. The work_mem parameter is measured in MB. A default value
+        will be used if the parameter is not set.
+        '''
         # reinitialize DBConn in new processes
         if self.pid != os.getpid():
             clear_mappers()
             self.__createconn()
-        return self.db_smaker()
+        session = self.db_smaker()
+        if work_mem > 0:
+            session.execute("SET LOCAL work_mem TO '%d MB'" % work_mem)
+        return session
 
 __all__.append('DBConn')