7 @contact: Debian FTP Master <ftpmaster@debian.org>
8 @copyright: 2008 Michael Casadevall <mcasadevall@debian.org>
9 @copyright: 2008 Roger Leigh <rleigh@debian.org>
10 @license: GNU General Public License version 2 or later
13 # This program is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation; either version 2 of the License, or
16 # (at your option) any later version.
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 ################################################################################
31 from daklib.dak_exceptions import DBUpdateError
33 ################################################################################
36 print "Note: to be able to enable the the PL/Perl (plperl) procedural language, we do"
37 print "need postgresql-plperl-$postgres-version installed. Make sure that this is the"
38 print "case before you continue. Interrupt if it isn't, sleeping 5 seconds now."
39 print "(We need to be database superuser for this to work!)"
45 print "Enabling PL/Perl language"
46 c.execute("CREATE LANGUAGE plperl;")
47 c.execute("CREATE LANGUAGE plpgsql;")
49 print "Adding debversion type to database."
51 # Not present in all databases, maybe PL/Perl version-dependent?
52 # c.execute("SET SESSION plperl.use_strict TO 't';")
54 c.execute("CREATE DOMAIN debversion AS TEXT;")
55 c.execute("COMMENT ON DOMAIN debversion IS 'Debian package version number';")
57 c.execute("""ALTER DOMAIN debversion
58 ADD CONSTRAINT debversion_syntax
59 CHECK (VALUE !~ '[^-+:.0-9a-zA-Z~]');""")
61 # From Dpkg::Version::parseversion
62 c.execute("""CREATE OR REPLACE FUNCTION debversion_split (debversion)
68 $ver =~ /^(\d+):(.+)/ or die "bad version number '$ver'";
76 if ($ver =~ /(.+)-(.*)$/)
78 $verhash{version} = $1;
79 $verhash{revision} = $2;
83 $verhash{version} = $ver;
84 $verhash{revision} = 0;
87 return [$verhash{'epoch'}, $verhash{'version'}, $verhash{'revision'}];
91 c.execute("""COMMENT ON FUNCTION debversion_split (debversion)
92 IS 'Split debian version into epoch, upstream version and revision';""")
94 c.execute("""CREATE OR REPLACE FUNCTION debversion_epoch (version debversion)
99 split := debversion_split(version);
105 COMMENT ON FUNCTION debversion_epoch (debversion)
106 IS 'Get debian version epoch';
108 CREATE OR REPLACE FUNCTION debversion_version (version debversion)
113 split := debversion_split(version);
118 IMMUTABLE STRICT;""")
119 c.execute("""COMMENT ON FUNCTION debversion_version (debversion)
120 IS 'Get debian version upstream version';""")
122 c.execute("""CREATE OR REPLACE FUNCTION debversion_revision (version debversion)
127 split := debversion_split(version);
132 IMMUTABLE STRICT;""")
133 c.execute("""COMMENT ON FUNCTION debversion_revision (debversion)
134 IS 'Get debian version revision';""")
136 # From Dpkg::Version::parseversion
137 c.execute("""CREATE OR REPLACE FUNCTION debversion_compare_single (version1 text, version2 text)
138 RETURNS integer AS $$
141 ##define order(x) ((x) == '~' ? -1 \
142 # : cisdigit((x)) ? 0 \
144 # : cisalpha((x)) ? (x) \
146 # This comparison is out of dpkg's order to avoid
147 # comparing things to undef and triggering warnings.
148 if (not defined $x or not length $x) {
154 elsif ($x =~ /^\d$/) {
157 elsif ($x =~ /^[A-Z]$/i) {
161 return ord($x) + 256;
167 return @{$a} ? shift @{$a} : undef;
169 my ($val, $ref) = @_;
170 $val = "" if not defined $val;
171 $ref = "" if not defined $ref;
172 my @val = split //,$val;
173 my @ref = split //,$ref;
174 my $vc = next_elem @val;
175 my $rc = next_elem @ref;
176 while (defined $vc or defined $rc) {
178 while ((defined $vc and $vc !~ /^\d$/) or
179 (defined $rc and $rc !~ /^\d$/)) {
180 my $vo = order($vc); my $ro = order($rc);
181 # Unlike dpkg's verrevcmp, we only return 1 or -1 here.
182 return (($vo - $ro > 0) ? 1 : -1) if $vo != $ro;
183 $vc = next_elem @val; $rc = next_elem @ref;
185 while (defined $vc and $vc eq '0') {
186 $vc = next_elem @val;
188 while (defined $rc and $rc eq '0') {
189 $rc = next_elem @ref;
191 while (defined $vc and $vc =~ /^\d$/ and
192 defined $rc and $rc =~ /^\d$/) {
193 $first_diff = ord($vc) - ord($rc) if !$first_diff;
194 $vc = next_elem @val; $rc = next_elem @ref;
196 return 1 if defined $vc and $vc =~ /^\d$/;
197 return -1 if defined $rc and $rc =~ /^\d$/;
198 return (($first_diff > 0) ? 1 : -1) if $first_diff;
203 IMMUTABLE STRICT;""")
204 c.execute("""COMMENT ON FUNCTION debversion_compare_single (text, text)
205 IS 'Compare upstream or revision parts of Debian versions';""")
207 # Logic only derived from Dpkg::Version::parseversion
208 c.execute("""CREATE OR REPLACE FUNCTION debversion_compare (version1 debversion, version2 debversion)
209 RETURNS integer AS $$
216 split1 := debversion_split(version1);
217 split2 := debversion_split(version2);
219 -- RAISE NOTICE 'Version 1: %', version1;
220 -- RAISE NOTICE 'Version 2: %', version2;
221 -- RAISE NOTICE 'Split 1: %', split1;
222 -- RAISE NOTICE 'Split 2: %', split2;
224 IF split1[1] > split2[1] THEN
226 ELSIF split1[1] < split2[1] THEN
229 result := debversion_compare_single(split1[2], split2[2]);
231 result := debversion_compare_single(split1[3], split2[3]);
239 IMMUTABLE STRICT;""")
240 c.execute("""COMMENT ON FUNCTION debversion_compare (debversion, debversion)
241 IS 'Compare Debian versions';""")
243 c.execute("""CREATE OR REPLACE FUNCTION debversion_eq (version1 debversion, version2 debversion)
244 RETURNS boolean AS $$
249 comp := debversion_compare(version1, version2);
255 IMMUTABLE STRICT;""")
256 c.execute("""COMMENT ON FUNCTION debversion_eq (debversion, debversion)
257 IS 'debversion equal';""")
259 c.execute("""CREATE OR REPLACE FUNCTION debversion_ne (version1 debversion, version2 debversion)
260 RETURNS boolean AS $$
265 comp := debversion_compare(version1, version2);
271 IMMUTABLE STRICT;""")
272 c.execute("""COMMENT ON FUNCTION debversion_ne (debversion, debversion)
273 IS 'debversion not equal';""")
275 c.execute("""CREATE OR REPLACE FUNCTION debversion_lt (version1 debversion, version2 debversion)
276 RETURNS boolean AS $$
281 comp := debversion_compare(version1, version2);
287 IMMUTABLE STRICT;""")
288 c.execute("""COMMENT ON FUNCTION debversion_lt (debversion, debversion)
289 IS 'debversion less-than';""")
291 c.execute("""CREATE OR REPLACE FUNCTION debversion_gt (version1 debversion, version2 debversion) RETURNS boolean AS $$
296 comp := debversion_compare(version1, version2);
302 IMMUTABLE STRICT;""")
303 c.execute("""COMMENT ON FUNCTION debversion_gt (debversion, debversion)
304 IS 'debversion greater-than';""")
306 c.execute("""CREATE OR REPLACE FUNCTION debversion_le (version1 debversion, version2 debversion)
307 RETURNS boolean AS $$
312 comp := debversion_compare(version1, version2);
318 IMMUTABLE STRICT;""")
319 c.execute("""COMMENT ON FUNCTION debversion_le (debversion, debversion)
320 IS 'debversion less-than-or-equal';""")
322 c.execute("""CREATE OR REPLACE FUNCTION debversion_ge (version1 debversion, version2 debversion)
323 RETURNS boolean AS $$
328 comp := debversion_compare(version1, version2);
334 IMMUTABLE STRICT;""")
335 c.execute("""COMMENT ON FUNCTION debversion_ge (debversion, debversion)
336 IS 'debversion greater-than-or-equal';""")
338 c.execute("""CREATE OPERATOR = (
339 PROCEDURE = debversion_eq,
340 LEFTARG = debversion,
341 RIGHTARG = debversion,
344 c.execute("""COMMENT ON OPERATOR = (debversion, debversion)
345 IS 'debversion equal';""")
347 c.execute("""CREATE OPERATOR != (
348 PROCEDURE = debversion_eq,
349 LEFTARG = debversion,
350 RIGHTARG = debversion,
353 c.execute("""COMMENT ON OPERATOR != (debversion, debversion)
354 IS 'debversion not equal';""")
356 c.execute("""CREATE OPERATOR < (
357 PROCEDURE = debversion_lt,
358 LEFTARG = debversion,
359 RIGHTARG = debversion,
362 c.execute("""COMMENT ON OPERATOR < (debversion, debversion)
363 IS 'debversion less-than';""")
365 c.execute("""CREATE OPERATOR > (
366 PROCEDURE = debversion_gt,
367 LEFTARG = debversion,
368 RIGHTARG = debversion,
371 c.execute("""COMMENT ON OPERATOR > (debversion, debversion)
372 IS 'debversion greater-than';""")
374 c.execute("""CREATE OPERATOR <= (
375 PROCEDURE = debversion_le,
376 LEFTARG = debversion,
377 RIGHTARG = debversion,
380 c.execute("""COMMENT ON OPERATOR <= (debversion, debversion)
381 IS 'debversion less-than-or-equal';""")
383 c.execute("""CREATE OPERATOR >= (
384 PROCEDURE = debversion_ge,
385 LEFTARG = debversion,
386 RIGHTARG = debversion,
389 c.execute("""COMMENT ON OPERATOR >= (debversion, debversion)
390 IS 'debversion greater-than-or-equal';""")
392 c.execute("ALTER TABLE source ALTER COLUMN version TYPE debversion;")
393 c.execute("ALTER TABLE binaries ALTER COLUMN version TYPE debversion;")
395 c.execute("UPDATE config SET value = '2' WHERE name = 'db_revision'")
399 except psycopg2.ProgrammingError, msg:
401 raise DBUpdateError, "Unable to appy debversion updates, rollback issued. Error message : %s" % (str(msg))