4 # Debian Archive Kit Database Update Script
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 the PL/Perl (plperl) procedural language must be enabled first."
30 print "Run 'createlang plpgsql projectb' to add it."
35 print "Adding debversion type to database."
37 # Not present in all databases, maybe PL/Perl version-dependent?
38 # c.execute("SET SESSION plperl.use_strict TO 't';")
40 c.execute("CREATE DOMAIN debversion AS TEXT;")
41 c.execute("COMMENT ON DOMAIN debversion IS 'Debian package version number';")
43 c.execute("""ALTER DOMAIN debversion
44 ADD CONSTRAINT debversion_syntax
45 CHECK (VALUE !~ '[^-+:.0-9a-zA-Z~]');""")
47 # From Dpkg::Version::parseversion
48 c.execute("""CREATE OR REPLACE FUNCTION debversion_split (debversion)
54 $ver =~ /^(\d+):(.+)/ or die "bad version number '$ver'";
62 if ($ver =~ /(.+)-(.*)$/)
64 $verhash{version} = $1;
65 $verhash{revision} = $2;
69 $verhash{version} = $ver;
70 $verhash{revision} = 0;
73 return [$verhash{'epoch'}, $verhash{'version'}, $verhash{'revision'}];
77 c.execute("""COMMENT ON FUNCTION debversion_split (debversion)
78 IS 'Split debian version into epoch, upstream version and revision';""")
80 c.execute("""CREATE OR REPLACE FUNCTION debversion_epoch (version debversion)
85 split := debversion_split(version);
91 COMMENT ON FUNCTION debversion_epoch (debversion)
92 IS 'Get debian version epoch';
94 CREATE OR REPLACE FUNCTION debversion_version (version debversion)
99 split := debversion_split(version);
104 IMMUTABLE STRICT;""")
105 c.execute("""COMMENT ON FUNCTION debversion_version (debversion)
106 IS 'Get debian version upstream version';""")
108 c.execute("""CREATE OR REPLACE FUNCTION debversion_revision (version debversion)
113 split := debversion_split(version);
118 IMMUTABLE STRICT;""")
119 c.execute("""COMMENT ON FUNCTION debversion_revision (debversion)
120 IS 'Get debian version revision';""")
122 # From Dpkg::Version::parseversion
123 c.execute("""CREATE OR REPLACE FUNCTION debversion_compare_single (version1 text, version2 text)
124 RETURNS integer AS $$
127 ##define order(x) ((x) == '~' ? -1 \
128 # : cisdigit((x)) ? 0 \
130 # : cisalpha((x)) ? (x) \
132 # This comparison is out of dpkg's order to avoid
133 # comparing things to undef and triggering warnings.
134 if (not defined $x or not length $x) {
140 elsif ($x =~ /^\d$/) {
143 elsif ($x =~ /^[A-Z]$/i) {
147 return ord($x) + 256;
153 return @{$a} ? shift @{$a} : undef;
155 my ($val, $ref) = @_;
156 $val = "" if not defined $val;
157 $ref = "" if not defined $ref;
158 my @val = split //,$val;
159 my @ref = split //,$ref;
160 my $vc = next_elem @val;
161 my $rc = next_elem @ref;
162 while (defined $vc or defined $rc) {
164 while ((defined $vc and $vc !~ /^\d$/) or
165 (defined $rc and $rc !~ /^\d$/)) {
166 my $vo = order($vc); my $ro = order($rc);
167 # Unlike dpkg's verrevcmp, we only return 1 or -1 here.
168 return (($vo - $ro > 0) ? 1 : -1) if $vo != $ro;
169 $vc = next_elem @val; $rc = next_elem @ref;
171 while (defined $vc and $vc eq '0') {
172 $vc = next_elem @val;
174 while (defined $rc and $rc eq '0') {
175 $rc = next_elem @ref;
177 while (defined $vc and $vc =~ /^\d$/ and
178 defined $rc and $rc =~ /^\d$/) {
179 $first_diff = ord($vc) - ord($rc) if !$first_diff;
180 $vc = next_elem @val; $rc = next_elem @ref;
182 return 1 if defined $vc and $vc =~ /^\d$/;
183 return -1 if defined $rc and $rc =~ /^\d$/;
184 return (($first_diff > 0) ? 1 : -1) if $first_diff;
189 IMMUTABLE STRICT;""")
190 c.execute("""COMMENT ON FUNCTION debversion_compare_single (text, text)
191 IS 'Compare upstream or revision parts of Debian versions';""")
193 # Logic only derived from Dpkg::Version::parseversion
194 c.execute("""CREATE OR REPLACE FUNCTION debversion_compare (version1 debversion, version2 debversion)
195 RETURNS integer AS $$
202 split1 := debversion_split(version1);
203 split2 := debversion_split(version2);
205 -- RAISE NOTICE 'Version 1: %', version1;
206 -- RAISE NOTICE 'Version 2: %', version2;
207 -- RAISE NOTICE 'Split 1: %', split1;
208 -- RAISE NOTICE 'Split 2: %', split2;
210 IF split1[1] > split2[1] THEN
212 ELSIF split1[1] < split2[1] THEN
215 result := debversion_compare_single(split1[2], split2[2]);
217 result := debversion_compare_single(split1[3], split2[3]);
225 IMMUTABLE STRICT;""")
226 c.execute("""COMMENT ON FUNCTION debversion_compare (debversion, debversion)
227 IS 'Compare Debian versions';""")
229 c.execute("""CREATE OR REPLACE FUNCTION debversion_eq (version1 debversion, version2 debversion)
230 RETURNS boolean AS $$
235 comp := debversion_compare(version1, version2);
241 IMMUTABLE STRICT;""")
242 c.execute("""COMMENT ON FUNCTION debversion_eq (debversion, debversion)
243 IS 'debversion equal';""")
245 c.execute("""CREATE OR REPLACE FUNCTION debversion_ne (version1 debversion, version2 debversion)
246 RETURNS boolean AS $$
251 comp := debversion_compare(version1, version2);
257 IMMUTABLE STRICT;""")
258 c.execute("""COMMENT ON FUNCTION debversion_ne (debversion, debversion)
259 IS 'debversion not equal';""")
261 c.execute("""CREATE OR REPLACE FUNCTION debversion_lt (version1 debversion, version2 debversion)
262 RETURNS boolean AS $$
267 comp := debversion_compare(version1, version2);
273 IMMUTABLE STRICT;""")
274 c.execute("""COMMENT ON FUNCTION debversion_lt (debversion, debversion)
275 IS 'debversion less-than';""")
277 c.execute("""CREATE OR REPLACE FUNCTION debversion_gt (version1 debversion, version2 debversion) RETURNS boolean AS $$
282 comp := debversion_compare(version1, version2);
288 IMMUTABLE STRICT;""")
289 c.execute("""COMMENT ON FUNCTION debversion_gt (debversion, debversion)
290 IS 'debversion greater-than';""")
292 c.execute("""CREATE OR REPLACE FUNCTION debversion_le (version1 debversion, version2 debversion)
293 RETURNS boolean AS $$
298 comp := debversion_compare(version1, version2);
304 IMMUTABLE STRICT;""")
305 c.execute("""COMMENT ON FUNCTION debversion_le (debversion, debversion)
306 IS 'debversion less-than-or-equal';""")
308 c.execute("""CREATE OR REPLACE FUNCTION debversion_ge (version1 debversion, version2 debversion)
309 RETURNS boolean AS $$
314 comp := debversion_compare(version1, version2);
320 IMMUTABLE STRICT;""")
321 c.execute("""COMMENT ON FUNCTION debversion_ge (debversion, debversion)
322 IS 'debversion greater-than-or-equal';""")
324 c.execute("""CREATE OPERATOR = (
325 PROCEDURE = debversion_eq,
326 LEFTARG = debversion,
327 RIGHTARG = debversion,
330 c.execute("""COMMENT ON OPERATOR = (debversion, debversion)
331 IS 'debversion equal';""")
333 c.execute("""CREATE OPERATOR != (
334 PROCEDURE = debversion_eq,
335 LEFTARG = debversion,
336 RIGHTARG = debversion,
339 c.execute("""COMMENT ON OPERATOR != (debversion, debversion)
340 IS 'debversion not equal';""")
342 c.execute("""CREATE OPERATOR < (
343 PROCEDURE = debversion_lt,
344 LEFTARG = debversion,
345 RIGHTARG = debversion,
348 c.execute("""COMMENT ON OPERATOR < (debversion, debversion)
349 IS 'debversion less-than';""")
351 c.execute("""CREATE OPERATOR > (
352 PROCEDURE = debversion_gt,
353 LEFTARG = debversion,
354 RIGHTARG = debversion,
357 c.execute("""COMMENT ON OPERATOR > (debversion, debversion)
358 IS 'debversion greater-than';""")
360 c.execute("""CREATE OPERATOR <= (
361 PROCEDURE = debversion_le,
362 LEFTARG = debversion,
363 RIGHTARG = debversion,
366 c.execute("""COMMENT ON OPERATOR <= (debversion, debversion)
367 IS 'debversion less-than-or-equal';""")
369 c.execute("""CREATE OPERATOR >= (
370 PROCEDURE = debversion_ge,
371 LEFTARG = debversion,
372 RIGHTARG = debversion,
375 c.execute("""COMMENT ON OPERATOR >= (debversion, debversion)
376 IS 'debversion greater-than-or-equal';""")
378 c.execute("ALTER TABLE source ALTER COLUMN version TYPE debversion;")
379 c.execute("ALTER TABLE binaries ALTER COLUMN version TYPE debversion;")
381 c.execute("UPDATE config SET value = '1' WHERE name = 'db_revision'")
385 except psycopg2.ProgrammingError, msg:
387 print "FATAL: Unable to apply debversion table update 2!"
388 print "Error Message: " + str(msg)
389 print "Database changes have been rolled back."