]> git.decadent.org.uk Git - dak.git/blob - dak/dakdb/update23.py
Merge remote branch 'origin/master' into contents
[dak.git] / dak / dakdb / update23.py
1 #!/usr/bin/env python
2 # coding=utf8
3
4 """
5 Adding a trainee field to the process-new notes
6
7 @contact: Debian FTP Master <ftpmaster@debian.org>
8 @copyright: 2009  Mike O'Connor <stew@debian.org>
9 @license: GNU General Public License version 2 or later
10 """
11
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
16
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
26 ################################################################################
27
28
29 ################################################################################
30
31 import psycopg2
32 import time
33 from daklib.dak_exceptions import DBUpdateError
34
35 ################################################################################
36
37 def suites():
38     """
39     return a list of suites to operate on
40     """
41     if Config().has_key( "%s::%s" %(options_prefix,"Suite")):
42         suites = utils.split_args(Config()[ "%s::%s" %(options_prefix,"Suite")])
43     else:
44         suites = [ 'unstable', 'testing' ]
45 #            suites = Config().SubTree("Suite").List()
46
47     return suites
48
49 def arches(cursor, suite):
50     """
51     return a list of archs to operate on
52     """
53     arch_list = []
54     cursor.execute("""SELECT s.architecture, a.arch_string
55     FROM suite_architectures s
56     JOIN architecture a ON (s.architecture=a.id)
57     WHERE suite = :suite""", {'suite' : suite })
58
59     while True:
60         r = cursor.fetchone()
61         if not r:
62             break
63
64         if r[1] != "source" and r[1] != "all":
65             arch_list.append((r[0], r[1]))
66
67     return arch_list
68
69 def do_update(self):
70     """
71     Adding contents table as first step to maybe, finally getting rid
72     of apt-ftparchive
73     """
74
75     print __doc__
76
77     try:
78         c = self.db.cursor()
79
80         c.execute("""CREATE TABLE pending_bin_contents (
81         id serial NOT NULL,
82         package text NOT NULL,
83         version debversion NOT NULL,
84         arch int NOT NULL,
85         filename text NOT NULL,
86         type int NOT NULL,
87         PRIMARY KEY(id))""" );
88
89         c.execute("""CREATE TABLE deb_contents (
90         filename text,
91         section text,
92         package text,
93         binary_id integer,
94         arch integer,
95         suite integer)""" )
96
97         c.execute("""CREATE TABLE udeb_contents (
98         filename text,
99         section text,
100         package text,
101         binary_id integer,
102         suite integer,
103         arch integer)""" )
104
105         c.execute("""ALTER TABLE ONLY deb_contents
106         ADD CONSTRAINT deb_contents_arch_fkey
107         FOREIGN KEY (arch) REFERENCES architecture(id)
108         ON DELETE CASCADE;""")
109
110         c.execute("""ALTER TABLE ONLY udeb_contents
111         ADD CONSTRAINT udeb_contents_arch_fkey
112         FOREIGN KEY (arch) REFERENCES architecture(id)
113         ON DELETE CASCADE;""")
114
115         c.execute("""ALTER TABLE ONLY deb_contents
116         ADD CONSTRAINT deb_contents_pkey
117         PRIMARY KEY (filename,package,arch,suite);""")
118
119         c.execute("""ALTER TABLE ONLY udeb_contents
120         ADD CONSTRAINT udeb_contents_pkey
121         PRIMARY KEY (filename,package,arch,suite);""")
122
123         c.execute("""ALTER TABLE ONLY deb_contents
124         ADD CONSTRAINT deb_contents_suite_fkey
125         FOREIGN KEY (suite) REFERENCES suite(id)
126         ON DELETE CASCADE;""")
127
128         c.execute("""ALTER TABLE ONLY udeb_contents
129         ADD CONSTRAINT udeb_contents_suite_fkey
130         FOREIGN KEY (suite) REFERENCES suite(id)
131         ON DELETE CASCADE;""")
132
133         c.execute("""ALTER TABLE ONLY deb_contents
134         ADD CONSTRAINT deb_contents_binary_fkey
135         FOREIGN KEY (binary_id) REFERENCES binaries(id)
136         ON DELETE CASCADE;""")
137
138         c.execute("""ALTER TABLE ONLY udeb_contents
139         ADD CONSTRAINT udeb_contents_binary_fkey
140         FOREIGN KEY (binary_id) REFERENCES binaries(id)
141         ON DELETE CASCADE;""")
142
143         c.execute("""CREATE INDEX ind_deb_contents_binary ON deb_contents(binary_id);""" )
144
145
146         suites = self.suites()
147
148         for suite in [i.lower() for i in suites]:
149             suite_id = DBConn().get_suite_id(suite)
150             arch_list = arches(c, suite_id)
151             arch_list = arches(c, suite_id)
152
153             for (arch_id,arch_str) in arch_list:
154                 c.execute( "CREATE INDEX ind_deb_contents_%s_%s ON deb_contents (arch,suite) WHERE (arch=2 OR arch=%d) AND suite=$d"%(arch_str,suite,arch_id,suite_id) )
155
156             for section, sname in [("debian-installer","main"),
157                                   ("non-free/debian-installer", "nonfree")]:
158                 c.execute( "CREATE INDEX ind_udeb_contents_%s_%s ON udeb_contents (section,suite) WHERE section=%s AND suite=$d"%(sname,suite,section,suite_id) )
159
160
161         c.execute( """CREATE OR REPLACE FUNCTION update_contents_for_bin_a() RETURNS trigger AS  $$
162     event = TD["event"]
163     if event == "DELETE" or event == "UPDATE":
164
165         plpy.execute(plpy.prepare("DELETE FROM deb_contents WHERE binary_id=$1 and suite=$2",
166                                   ["int","int"]),
167                                   [TD["old"]["bin"], TD["old"]["suite"]])
168
169     if event == "INSERT" or event == "UPDATE":
170
171        content_data = plpy.execute(plpy.prepare(
172             """SELECT s.section, b.package, b.architecture, ot.type
173             FROM override o
174             JOIN override_type ot on o.type=ot.id
175             JOIN binaries b on b.package=o.package
176             JOIN files f on b.file=f.id
177             JOIN location l on l.id=f.location
178             JOIN section s on s.id=o.section
179             WHERE b.id=$1
180             AND o.suite=$2
181             """,
182             ["int", "int"]),
183             [TD["new"]["bin"], TD["new"]["suite"]])[0]
184
185        filenames = plpy.execute(plpy.prepare(
186            "SELECT bc.file FROM bin_contents bc where bc.binary_id=$1",
187            ["int"]),
188            [TD["new"]["bin"]])
189
190        for filename in filenames:
191            plpy.execute(plpy.prepare(
192                """INSERT INTO deb_contents
193                    (filename,section,package,binary_id,arch,suite)
194                    VALUES($1,$2,$3,$4,$5,$6)""",
195                ["text","text","text","int","int","int"]),
196                [filename["file"],
197                 content_data["section"],
198                 content_data["package"],
199                 TD["new"]["bin"],
200                 content_data["architecture"],
201                 TD["new"]["suite"]] )
202 $$ LANGUAGE plpythonu VOLATILE SECURITY DEFINER;
203 """)
204
205
206         c.execute( """CREATE OR REPLACE FUNCTION update_contents_for_override() RETURNS trigger AS  $$
207     event = TD["event"]
208     if event == "UPDATE":
209
210         otype = plpy.execute(plpy.prepare("SELECT type from override_type where id=$1",["int"]),[TD["new"]["type"]] )[0];
211         if otype["type"].endswith("deb"):
212             section = plpy.execute(plpy.prepare("SELECT section from section where id=$1",["int"]),[TD["new"]["section"]] )[0];
213
214             table_name = "%s_contents" % otype["type"]
215             plpy.execute(plpy.prepare("UPDATE %s set section=$1 where package=$2 and suite=$3" % table_name,
216                                       ["text","text","int"]),
217                                       [section["section"],
218                                       TD["new"]["package"],
219                                       TD["new"]["suite"]])
220
221 $$ LANGUAGE plpythonu VOLATILE SECURITY DEFINER;
222 """)
223         c.execute( """CREATE TRIGGER bin_associations_contents_trigger
224                       AFTER INSERT OR UPDATE OR DELETE ON bin_associations
225                       FOR EACH ROW EXECUTE PROCEDURE update_contents_for_bin_a();""")
226         c.execute("""CREATE TRIGGER override_contents_trigger
227                       AFTER UPDATE ON override
228                       FOR EACH ROW EXECUTE PROCEDURE update_contents_for_override();""")
229
230
231         c.execute( "CREATE INDEX ind_deb_contents_name ON deb_contents(package);");
232         c.execute( "CREATE INDEX ind_udeb_contents_name ON udeb_contents(package);");
233
234         self.db.commit()
235
236     except psycopg2.ProgrammingError, msg:
237         self.db.rollback()
238         raise DBUpdateError, "Unable to apply process-new update 14, rollback issued. Error message : %s" % (str(msg))
239