]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/dbconn.py
merge with master
[dak.git] / daklib / dbconn.py
index 5bd1d76595717043fb744d1715d33612e8d9c442..b29137221672d7f698fd7459a1f12c0a2ff1c630 100755 (executable)
@@ -113,6 +113,14 @@ class DBConn(Singleton):
                        'suite_version': Cache(lambda x: '%s_%s' % (x['source'], x['suite'])),
                       }
 
+        self.prepared_statements = {}
+
+    def prepare(self,name,statement):
+        if not self.prepared_statements.has_key(name):
+            c = self.cursor()
+            c.execute(statement)
+            self.prepared_statements[name] = statement
+
     def clear_caches(self):
         self.__init_caches()
 
@@ -160,7 +168,7 @@ class DBConn(Singleton):
         @return: the database id for the given suite
 
         """
-        return self.__get_id('id', 'suite', 'suite_name', suite)
+        return int(self.__get_id('id', 'suite', 'suite_name', suite))
 
     def get_section_id(self, section):
         """
@@ -195,14 +203,14 @@ class DBConn(Singleton):
         Returns database id for given override C{type}.
         Results are kept in a cache during runtime to minimize database queries.
 
-        @type type: string
-        @param type: The name of the override type
+        @type override_type: string
+        @param override_type: The name of the override type
 
         @rtype: int
         @return: the database id for the given override type
 
         """
-        return self.__get_id('id', 'override_type', 'override_type', override_type)
+        return self.__get_id('id', 'override_type', 'type', override_type)
 
     def get_architecture_id(self, architecture):
         """
@@ -390,11 +398,11 @@ class DBConn(Singleton):
             else:
                 row = cursor.fetchone()
 
-                if row[1] != size or row[2] != md5sum:
+                if row[1] != int(size) or row[2] != md5sum:
                     res =  -2
 
                 else:
-                    self.caches[cachename].SetValue(values, row[0])
+                    self.caches['files'].SetValue(values, row[0])
                     res = row[0]
 
         return res
@@ -413,18 +421,22 @@ class DBConn(Singleton):
         @rtype: int
         @return: the database id for the given component
         """
-        values={'value': filename}
-        query = "SELECT id FROM content_file_names WHERE file = %(value)s"
-        id = self.__get_single_id(query, values, cachename='content_file_names')
-        if not id:
-            c = self.db_con.cursor()
-            c.execute( "INSERT INTO content_file_names VALUES (DEFAULT, %(value)s) RETURNING id",
-                       values )
-
-            id = c.fetchone()[0]
-            self.caches['content_file_names'].SetValue(values, id)
-
-        return id
+        try:
+            values={'value': filename}
+            query = "SELECT id FROM content_file_names WHERE file = %(value)s"
+            id = self.__get_single_id(query, values, cachename='content_file_names')
+            if not id:
+                c = self.db_con.cursor()
+                c.execute( "INSERT INTO content_file_names VALUES (DEFAULT, %(value)s) RETURNING id",
+                           values )
+
+                id = c.fetchone()[0]
+                self.caches['content_file_names'].SetValue(values, id)
+
+            return id
+        except:
+            traceback.print_exc()
+            raise
 
     def get_or_set_contents_path_id(self, path):
         """
@@ -439,29 +451,59 @@ class DBConn(Singleton):
         @rtype: int
         @return: the database id for the given component
         """
-        values={'value': path}
-        query = "SELECT id FROM content_file_paths WHERE path = %(value)s"
-        id = self.__get_single_id(query, values, cachename='content_path_names')
-        if not id:
-            c = self.db_con.cursor()
-            c.execute( "INSERT INTO content_file_paths VALUES (DEFAULT, %(value)s) RETURNING id",
-                       values )
+        try:
+            values={'value': path}
+            query = "SELECT id FROM content_file_paths WHERE path = %(value)s"
+            id = self.__get_single_id(query, values, cachename='content_path_names')
+            if not id:
+                c = self.db_con.cursor()
+                c.execute( "INSERT INTO content_file_paths VALUES (DEFAULT, %(value)s) RETURNING id",
+                           values )
+
+                id = c.fetchone()[0]
+                self.caches['content_path_names'].SetValue(values, id)
+
+            return id
+        except:
+            traceback.print_exc()
+            raise
 
-            id = c.fetchone()[0]
-            self.caches['content_path_names'].SetValue(values, id)
+    def get_suite_architectures(self, suite):
+        """
+        Returns list of architectures for C{suite}.
 
-        return id
+        @type suite: string, int
+        @param suite: the suite name or the suite_id
 
-    def insert_content_paths(self, package, fullpaths):
+        @rtype: list
+        @return: the list of architectures for I{suite}
+        """
+
+        suite_id = None
+        if type(suite) == str:
+            suite_id = self.get_suite_id(suite)
+        elif type(suite) == int:
+            suite_id = suite
+        else:
+            return None
+
+        c = self.db_con.cursor()
+        c.execute( """SELECT a.arch_string FROM suite_architectures sa
+                      JOIN architecture a ON (a.id = sa.architecture)
+                      WHERE suite='%s'""" % suite_id )
+
+        return map(lambda x: x[0], c.fetchall())
+
+    def insert_content_paths(self, bin_id, fullpaths):
         """
         Make sure given path is associated with given binary id
 
         @type bin_id: int
         @param bin_id: the id of the binary
-        @type fullpath: string
-        @param fullpath: the path of the file being associated with the binary
+        @type fullpaths: list
+        @param fullpaths: the list of paths of the file being associated with the binary
 
-        @return True upon success
+        @return: True upon success
         """
 
         c = self.db_con.cursor()
@@ -469,22 +511,67 @@ class DBConn(Singleton):
         c.execute("BEGIN WORK")
         try:
 
-                # Remove any already existing recorded files for this package
-            c.execute("""DELETE FROM temp_content_associations
+            for fullpath in fullpaths:
+                (path, file) = os.path.split(fullpath)
+
+                if path.startswith( "./" ):
+                    path = path[2:]
+                # Get the necessary IDs ...
+                file_id = self.get_or_set_contents_file_id(file)
+                path_id = self.get_or_set_contents_path_id(path)
+
+                c.execute("""INSERT INTO content_associations
+                               (binary_pkg, filepath, filename)
+                           VALUES ( '%d', '%d', '%d')""" % (bin_id, path_id, file_id) )
+
+            c.execute("COMMIT")
+            return True
+        except:
+            traceback.print_exc()
+            c.execute("ROLLBACK")
+            return False
+
+    def insert_pending_content_paths(self, package, fullpaths):
+        """
+        Make sure given paths are temporarily associated with given
+        package
+
+        @type package: dict
+        @param package: the package to associate with should have been read in from the binary control file
+        @type fullpaths: list
+        @param fullpaths: the list of paths of the file being associated with the binary
+
+        @return: True upon success
+        """
+
+        c = self.db_con.cursor()
+
+        c.execute("BEGIN WORK")
+        try:
+            arch_id = self.get_architecture_id(package['Architecture'])
+
+            # Remove any already existing recorded files for this package
+            c.execute("""DELETE FROM pending_content_associations
                          WHERE package=%(Package)s
-                         AND version=%(Version)s""", package )
+                         AND version=%(Version)s
+                         AND architecture=%(ArchID)s""", {'Package': package['Package'],
+                                                          'Version': package['Version'],
+                                                          'ArchID':  arch_id})
 
             for fullpath in fullpaths:
                 (path, file) = os.path.split(fullpath)
 
+                if path.startswith( "./" ):
+                    path = path[2:]
                 # Get the necessary IDs ...
                 file_id = self.get_or_set_contents_file_id(file)
                 path_id = self.get_or_set_contents_path_id(path)
 
-                c.execute("""INSERT INTO temp_content_associations
-                               (package, version, filepath, filename)
-                           VALUES (%%(Package)s, %%(Version)s, '%d', '%d')""" % (path_id, file_id),
-                          package )
+                c.execute("""INSERT INTO pending_content_associations
+                               (package, version, architecture, filepath, filename)
+                            VALUES (%%(Package)s, %%(Version)s, '%d', '%d', '%d')"""
+                    % (arch_id, path_id, file_id), package )
+
             c.execute("COMMIT")
             return True
         except: