4 """ Database Update Script - debversion """
5 # Copyright © 2008 Michael Casadevall <mcasadevall@debian.org>
6 # Copyright © 2008 Roger Leigh <rleigh@debian.org>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 ################################################################################
26 ################################################################################
29 print "Note: to be able to enable the the PL/Perl (plperl) procedural language, we do"
30 print "need postgresql-plperl-$postgres-version installed. Make sure that this is the"
31 print "case before you continue. Interrupt if it isn't, sleeping 5 seconds now."
32 print "(We need to be database superuser for this to work!)"
38 print "Enabling PL/Perl language"
39 c.execute("CREATE LANGUAGE plperl;")
40 c.execute("CREATE LANGUAGE plpgsql;")
42 print "Adding debversion type to database."
44 # Not present in all databases, maybe PL/Perl version-dependent?
45 # c.execute("SET SESSION plperl.use_strict TO 't';")
47 c.execute("CREATE DOMAIN debversion AS TEXT;")
48 c.execute("COMMENT ON DOMAIN debversion IS 'Debian package version number';")
50 c.execute("""ALTER DOMAIN debversion
51 ADD CONSTRAINT debversion_syntax
52 CHECK (VALUE !~ '[^-+:.0-9a-zA-Z~]');""")
54 # From Dpkg::Version::parseversion
55 c.execute("""CREATE OR REPLACE FUNCTION debversion_split (debversion)
61 $ver =~ /^(\d+):(.+)/ or die "bad version number '$ver'";
69 if ($ver =~ /(.+)-(.*)$/)
71 $verhash{version} = $1;
72 $verhash{revision} = $2;
76 $verhash{version} = $ver;
77 $verhash{revision} = 0;
80 return [$verhash{'epoch'}, $verhash{'version'}, $verhash{'revision'}];
84 c.execute("""COMMENT ON FUNCTION debversion_split (debversion)
85 IS 'Split debian version into epoch, upstream version and revision';""")
87 c.execute("""CREATE OR REPLACE FUNCTION debversion_epoch (version debversion)
92 split := debversion_split(version);
98 COMMENT ON FUNCTION debversion_epoch (debversion)
99 IS 'Get debian version epoch';
101 CREATE OR REPLACE FUNCTION debversion_version (version debversion)
106 split := debversion_split(version);
111 IMMUTABLE STRICT;""")
112 c.execute("""COMMENT ON FUNCTION debversion_version (debversion)
113 IS 'Get debian version upstream version';""")
115 c.execute("""CREATE OR REPLACE FUNCTION debversion_revision (version debversion)
120 split := debversion_split(version);
125 IMMUTABLE STRICT;""")
126 c.execute("""COMMENT ON FUNCTION debversion_revision (debversion)
127 IS 'Get debian version revision';""")
129 # From Dpkg::Version::parseversion
130 c.execute("""CREATE OR REPLACE FUNCTION debversion_compare_single (version1 text, version2 text)
131 RETURNS integer AS $$
134 ##define order(x) ((x) == '~' ? -1 \
135 # : cisdigit((x)) ? 0 \
137 # : cisalpha((x)) ? (x) \
139 # This comparison is out of dpkg's order to avoid
140 # comparing things to undef and triggering warnings.
141 if (not defined $x or not length $x) {
147 elsif ($x =~ /^\d$/) {
150 elsif ($x =~ /^[A-Z]$/i) {
154 return ord($x) + 256;
160 return @{$a} ? shift @{$a} : undef;
162 my ($val, $ref) = @_;
163 $val = "" if not defined $val;
164 $ref = "" if not defined $ref;
165 my @val = split //,$val;
166 my @ref = split //,$ref;
167 my $vc = next_elem @val;
168 my $rc = next_elem @ref;
169 while (defined $vc or defined $rc) {
171 while ((defined $vc and $vc !~ /^\d$/) or
172 (defined $rc and $rc !~ /^\d$/)) {
173 my $vo = order($vc); my $ro = order($rc);
174 # Unlike dpkg's verrevcmp, we only return 1 or -1 here.
175 return (($vo - $ro > 0) ? 1 : -1) if $vo != $ro;
176 $vc = next_elem @val; $rc = next_elem @ref;
178 while (defined $vc and $vc eq '0') {
179 $vc = next_elem @val;
181 while (defined $rc and $rc eq '0') {
182 $rc = next_elem @ref;
184 while (defined $vc and $vc =~ /^\d$/ and
185 defined $rc and $rc =~ /^\d$/) {
186 $first_diff = ord($vc) - ord($rc) if !$first_diff;
187 $vc = next_elem @val; $rc = next_elem @ref;
189 return 1 if defined $vc and $vc =~ /^\d$/;
190 return -1 if defined $rc and $rc =~ /^\d$/;
191 return (($first_diff > 0) ? 1 : -1) if $first_diff;
196 IMMUTABLE STRICT;""")
197 c.execute("""COMMENT ON FUNCTION debversion_compare_single (text, text)
198 IS 'Compare upstream or revision parts of Debian versions';""")
200 # Logic only derived from Dpkg::Version::parseversion
201 c.execute("""CREATE OR REPLACE FUNCTION debversion_compare (version1 debversion, version2 debversion)
202 RETURNS integer AS $$
209 split1 := debversion_split(version1);
210 split2 := debversion_split(version2);
212 -- RAISE NOTICE 'Version 1: %', version1;
213 -- RAISE NOTICE 'Version 2: %', version2;
214 -- RAISE NOTICE 'Split 1: %', split1;
215 -- RAISE NOTICE 'Split 2: %', split2;
217 IF split1[1] > split2[1] THEN
219 ELSIF split1[1] < split2[1] THEN
222 result := debversion_compare_single(split1[2], split2[2]);
224 result := debversion_compare_single(split1[3], split2[3]);
232 IMMUTABLE STRICT;""")
233 c.execute("""COMMENT ON FUNCTION debversion_compare (debversion, debversion)
234 IS 'Compare Debian versions';""")
236 c.execute("""CREATE OR REPLACE FUNCTION debversion_eq (version1 debversion, version2 debversion)
237 RETURNS boolean AS $$
242 comp := debversion_compare(version1, version2);
248 IMMUTABLE STRICT;""")
249 c.execute("""COMMENT ON FUNCTION debversion_eq (debversion, debversion)
250 IS 'debversion equal';""")
252 c.execute("""CREATE OR REPLACE FUNCTION debversion_ne (version1 debversion, version2 debversion)
253 RETURNS boolean AS $$
258 comp := debversion_compare(version1, version2);
264 IMMUTABLE STRICT;""")
265 c.execute("""COMMENT ON FUNCTION debversion_ne (debversion, debversion)
266 IS 'debversion not equal';""")
268 c.execute("""CREATE OR REPLACE FUNCTION debversion_lt (version1 debversion, version2 debversion)
269 RETURNS boolean AS $$
274 comp := debversion_compare(version1, version2);
280 IMMUTABLE STRICT;""")
281 c.execute("""COMMENT ON FUNCTION debversion_lt (debversion, debversion)
282 IS 'debversion less-than';""")
284 c.execute("""CREATE OR REPLACE FUNCTION debversion_gt (version1 debversion, version2 debversion) RETURNS boolean AS $$
289 comp := debversion_compare(version1, version2);
295 IMMUTABLE STRICT;""")
296 c.execute("""COMMENT ON FUNCTION debversion_gt (debversion, debversion)
297 IS 'debversion greater-than';""")
299 c.execute("""CREATE OR REPLACE FUNCTION debversion_le (version1 debversion, version2 debversion)
300 RETURNS boolean AS $$
305 comp := debversion_compare(version1, version2);
311 IMMUTABLE STRICT;""")
312 c.execute("""COMMENT ON FUNCTION debversion_le (debversion, debversion)
313 IS 'debversion less-than-or-equal';""")
315 c.execute("""CREATE OR REPLACE FUNCTION debversion_ge (version1 debversion, version2 debversion)
316 RETURNS boolean AS $$
321 comp := debversion_compare(version1, version2);
327 IMMUTABLE STRICT;""")
328 c.execute("""COMMENT ON FUNCTION debversion_ge (debversion, debversion)
329 IS 'debversion greater-than-or-equal';""")
331 c.execute("""CREATE OPERATOR = (
332 PROCEDURE = debversion_eq,
333 LEFTARG = debversion,
334 RIGHTARG = debversion,
337 c.execute("""COMMENT ON OPERATOR = (debversion, debversion)
338 IS 'debversion equal';""")
340 c.execute("""CREATE OPERATOR != (
341 PROCEDURE = debversion_eq,
342 LEFTARG = debversion,
343 RIGHTARG = debversion,
346 c.execute("""COMMENT ON OPERATOR != (debversion, debversion)
347 IS 'debversion not equal';""")
349 c.execute("""CREATE OPERATOR < (
350 PROCEDURE = debversion_lt,
351 LEFTARG = debversion,
352 RIGHTARG = debversion,
355 c.execute("""COMMENT ON OPERATOR < (debversion, debversion)
356 IS 'debversion less-than';""")
358 c.execute("""CREATE OPERATOR > (
359 PROCEDURE = debversion_gt,
360 LEFTARG = debversion,
361 RIGHTARG = debversion,
364 c.execute("""COMMENT ON OPERATOR > (debversion, debversion)
365 IS 'debversion greater-than';""")
367 c.execute("""CREATE OPERATOR <= (
368 PROCEDURE = debversion_le,
369 LEFTARG = debversion,
370 RIGHTARG = debversion,
373 c.execute("""COMMENT ON OPERATOR <= (debversion, debversion)
374 IS 'debversion less-than-or-equal';""")
376 c.execute("""CREATE OPERATOR >= (
377 PROCEDURE = debversion_ge,
378 LEFTARG = debversion,
379 RIGHTARG = debversion,
382 c.execute("""COMMENT ON OPERATOR >= (debversion, debversion)
383 IS 'debversion greater-than-or-equal';""")
385 c.execute("ALTER TABLE source ALTER COLUMN version TYPE debversion;")
386 c.execute("ALTER TABLE binaries ALTER COLUMN version TYPE debversion;")
388 c.execute("UPDATE config SET value = '2' WHERE name = 'db_revision'")
392 except psycopg2.ProgrammingError, msg:
394 print "FATAL: Unable to apply debversion table update 2!"
395 print "Error Message: " + str(msg)
396 print "Database changes have been rolled back."