Upgradescript, das die Eindeutigkeit von acc_trans.acc_trans_id sicherstellt
[kivitendo-erp.git] / sql / Pg-upgrade2 / acc_trans_id_uniqueness.pl
1 # @tag: acc_trans_id_uniqueness
2 # @description: Sorgt dafür, dass acc_trans.acc_trans_id eindeutig ist
3 # @depends: release_2_6_1
4 # @charset: utf-8
5
6 use utf8;
7 use strict;
8 use Data::Dumper;
9
10 die "This script cannot be run from the command line." unless $::form;
11
12 sub mydberror {
13   my ($msg) = @_;
14   die $dbup_locale->text("Database update error:") . "<br>$msg<br>" . $DBI::errstr;
15 }
16
17 sub do_query {
18   my ($query, $may_fail) = @_;
19
20   return if $dbh->do($query);
21
22   mydberror($query) unless ($may_fail);
23   $dbh->rollback();
24   $dbh->begin_work();
25 }
26
27 sub do_update {
28   my $query = <<SQL;
29     SELECT acc_trans_id, trans_id, itime, mtime
30     FROM acc_trans
31     WHERE acc_trans_id IN (
32       SELECT acc_trans_id FROM acc_trans GROUP BY acc_trans_id HAVING COUNT(*) > 1
33     )
34     ORDER BY trans_id, itime, mtime NULLS FIRST
35 SQL
36
37   my @entries = selectall_hashref_query($form, $dbh, $query);
38
39   return 1 unless @entries;
40
41   $query = <<SQL;
42     SELECT setval('acc_trans_id_seq', (
43       SELECT COALESCE(MAX(acc_trans_id), 0) + 1
44       FROM acc_trans
45     ))
46 SQL
47
48   do_query($query, 0);
49
50   my %entries_by_trans_id;
51   foreach my $entry (@entries) {
52     if (!$entries_by_trans_id{ $entry->{trans_id} }) {
53       $entries_by_trans_id{ $entry->{trans_id} } = [];
54     } else {
55       my $mtime = $entry->{mtime} ? "= '$entry->{mtime}'" : 'IS NULL';
56       $query    = <<SQL;
57         UPDATE acc_trans
58         SET acc_trans_id = nextval('acc_trans_id_seq')
59         WHERE (acc_trans_id = $entry->{acc_trans_id})
60           AND (trans_id     = $entry->{trans_id})
61           AND (itime        = '$entry->{itime}')
62           AND (mtime $mtime)
63 SQL
64
65       do_query($query, 0);
66     }
67   }
68
69   return 1;
70 }
71
72 return do_update();