/[collab-qa]/udd/udd/bugs_gatherer.pl
ViewVC logotype

Diff of /udd/udd/bugs_gatherer.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

udd/src/udd/bugs_gatherer.pl revision 999 by neronus-guest, Fri Aug 8 13:53:23 2008 UTC udd/udd/bugs_gatherer.pl revision 1217 by lucas, Sun Sep 7 17:28:09 2008 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl  #!/usr/bin/perl -w
2  # Last-Modified: <Fri Aug  8 13:56:31 2008>  # Last-Modified: <Mon Aug 18 14:29:47 2008>
3    
4  use strict;  use strict;
5  use warnings;  use warnings;
# Line 10  use FindBin '$Bin'; Line 10  use FindBin '$Bin';
10  use lib $Bin, qw{/org/udd.debian.net/mirrors/bugs.debian.org/perl};  use lib $Bin, qw{/org/udd.debian.net/mirrors/bugs.debian.org/perl};
11    
12  use DBI;  use DBI;
13    use DBI qw{:sql_types};
14  use YAML::Syck;  use YAML::Syck;
15  use Time::Local;  use Time::Local;
16    
# Line 17  use Debbugs::Bugs qw{get_bugs}; Line 18  use Debbugs::Bugs qw{get_bugs};
18  use Debbugs::Status qw{read_bug get_bug_status bug_presence};  use Debbugs::Status qw{read_bug get_bug_status bug_presence};
19  use Debbugs::Packages qw{binarytosource};  use Debbugs::Packages qw{binarytosource};
20  use Debbugs::Config qw{:globals};  use Debbugs::Config qw{:globals};
21  use Debbugs::User qw{read_usertags};  use Debbugs::User;
22    #use Debbugs::User qw{read_usertags};
23    
24  $YAML::Syck::ImplicitTyping = 1;  $YAML::Syck::ImplicitTyping = 1;
25    
26    #Used for measuring time
27    our $t;
28    our $timing = 0;
29    
30  # Return the list of usernames  # Return the list of usernames
31  sub get_bugs_users {  sub get_bugs_users {
32          my $topdir = "$gSpoolDir/user";          my $topdir = "$gSpoolDir/user";
# Line 86  sub without_duplicates { Line 92  sub without_duplicates {
92          return (grep { ($h{$_}++ == 0) || 0 } @_);          return (grep { ($h{$_}++ == 0) || 0 } @_);
93  }  }
94    
95  sub main {  sub setup {
96          if(@ARGV != 2) {          my ($config, $source, $dbh) = @_;
97                  print STDERR "Usage: $0 <config> <source>";          my $schema = $config->{general}->{'schema-dir'} . '/' . $config->{$source}->{schema};
98                  exit 1;          open SQL, "<",  $schema or die $!;
99            my $command = join "", <SQL>;
100            close SQL;
101            $command =~ s/%\(([^)]+)\)s/$config->{$source}->{$1}/g;
102            $dbh->prepare($command)->execute() or die $!;
103    }
104    
105    sub tables {
106            my ($config, $source, $dbh) = @_;
107            my @ret = ();
108            foreach my $prefix ($config->{$source}->{table}, $config->{$source}->{'archived-table'}) {
109                    foreach my $postfix (qw{_merged_with _found_in _fixed_in _tags}, '') {
110                            push @ret, "$prefix$postfix";
111                    }
112          }          }
113            unshift @ret, $config->{$source}->{'usertags-table'};
114            return @ret;
115    }
116    
         my $config = LoadFile($ARGV[0]) or die "Could not load configuration: $!";  
         my $source = $ARGV[1];  
         my %src_config = %{$config->{$source}};  
117    
118          my $dbname = $config->{general}->{dbname};  sub drop {
119          # Connection to DB          my ($config, $source, $dbh) = @_;
120          my $dbh = DBI->connect("dbi:Pg:dbname=$dbname");          map {
121          # We want to commit the transaction as a hole at the end                  $dbh->prepare("DROP VIEW $_")->execute() or die $!;
122          $dbh->{AutoCommit} = 0;          }
123            qw{bugs_rt_affects_stable bugs_rt_affects_testing_and_unstable bugs_rt_affects_unstable bugs_rt_affects_testing};
124    
125            foreach my $table (tables($config, $source, $dbh)) {
126                    $dbh->prepare("DROP TABLE $table")->execute() or die $!;
127            }
128    }
129    
130    sub run_usertags {
131            my ($config, $source, $dbh) = @_;
132            my %src_config = %{$config->{$source}};
133            my $table = $src_config{'usertags-table'} or die "usertags-table not specified for source $source";
134            our $timing;
135            our $t;
136    
         # Free usertags table  
         $dbh->prepare("DELETE FROM bug_user_tags")->execute() or die  
                 "Couldn't empty bug_user_tags: $!";  
137    
138            $t = time();
139            # Free usertags table
140            $dbh->do("DELETE FROM $table") or die
141                    "Couldn't empty $table: $!";
142            print "Deleting usertags: ",(time() - $t),"s\n" if $timing;
143            $t = time();
144          # read and insert user tags          # read and insert user tags
145          my @users = get_bugs_users();          my @users = get_bugs_users();
146          foreach my $user (@users) {          foreach my $user (@users) {
147                  my %tags = ();                  #read_usertags(\%tags, $user);
148                  read_usertags(\%tags, $user);                  my $u = Debbugs::User->new($user);
149                    my %tags = %{$u->{tags}};
150                  $user = $dbh->quote($user);                  $user = $dbh->quote($user);
151                  foreach my $tag (keys %tags) {                  foreach my $tag (keys %tags) {
152                          my $qtag = $dbh->quote($tag);                          my $qtag = $dbh->quote($tag);
153                          map { $dbh->prepare("INSERT INTO bug_user_tags VALUES ($user, $qtag, $_)")->execute() or die $! } @{$tags{$tag}};                          map { $dbh->do("INSERT INTO $table VALUES ($user, $qtag, $_)") or die $! } @{$tags{$tag}};
154                  }                  }
155          }          }
156    }
157    
158    sub run {
159            my ($config, $source, $dbh) = @_;
160    
161            our $t;
162            our $timing;
163            print "Inserting usertags: ",(time() - $t),"s\n" if $timing;
164            $t = time();
165            run_usertags($config, $source, $dbh);
166    
167            my %src_config = %{$config->{$source}};
168            my $table = $src_config{table};
169            my $archived_table = $src_config{'archived-table'};
170    
171            my @modified_bugs;
172          ####### XXX EXPERIMENT          ####### XXX EXPERIMENT
173          ####### XXX What to do with bugs both archived and unarchived          ####### XXX What to do with bugs both archived and unarchived
174          #my $max_last_modified = get_db_max_last_modified($dbh);          #my $max_last_modified = get_db_max_last_modified($dbh);
# Line 136  sub main { Line 185  sub main {
185                  #       @modified_bugs = get_bugs(archive => 'both');                  #       @modified_bugs = get_bugs(archive => 'both');
186                  #}                  #}
187                  #@modified_bugs = without_duplicates(@modified_bugs);                  #@modified_bugs = without_duplicates(@modified_bugs);
         my @modified_bugs;  
188          if($src_config{archived}) {          if($src_config{archived}) {
189                  @modified_bugs = get_bugs(archive => 1);                  @modified_bugs = get_bugs(archive => 1);
190          } else {          } else {
191                  @modified_bugs = get_bugs();                  @modified_bugs = get_bugs();
192          }          }
193    
194          print scalar(@modified_bugs), " modified bugs\n";          my @modified_bugs2;
195          ####### XXX EXPERIMENT          if ($src_config{debug}) {
196                    foreach $b (@modified_bugs) {
197                            push(@modified_bugs2, $b) if ($b =~ /0$/);
198                    }
199                    @modified_bugs = @modified_bugs2;
200            }
201    
202          # Get the bugs we want to import          print "Fetching list of ",scalar(@modified_bugs), " bugs to insert: ",(time() - $t),"s\n" if $timing;
203          # my @bugs = $src_config{archived} ? get_bugs(archive => 1) : get_bugs();          $t = time();
204    
205          # Delete all bugs we are going to import          foreach my $prefix ($table, $archived_table) {
206          for my $bug (@modified_bugs) {                  foreach my $postfix ('', qw{_merged_with _found_in _fixed_in _tags}) {
207                  map {                          my $sth = $dbh->prepare("DELETE FROM $prefix$postfix WHERE id = \$1");
208                          $dbh->prepare("DELETE FROM $_ WHERE id = $bug")->execute() or die $!                          map {
209                  } qw{bugs_archived bugs_unarchived bug_merged_with bug_found_in bug_fixed_in bug_tags};                                  $sth->execute($_) or die $!;
210                            } @modified_bugs;
211                    }
212          }          }
213          print "Bugs deleted\n";          print "Deleting bugs: ",(time() - $t),"s\n" if $timing;
214            $t = time();
215    
216          # Used to chache binary to source mappings          # Used to chache binary to source mappings
217          my %binarytosource = ();          my %binarytosource = ();
   
218          # XXX What if a bug is in location 'db' (which currently doesn't exist)          # XXX What if a bug is in location 'db' (which currently doesn't exist)
219          my $location = $src_config{archived} ? 'archive' : 'db_h';          my $location = $src_config{archived} ? 'archive' : 'db_h';
220          my $table = $src_config{archived} ? 'bugs_archived' : 'bugs_unarchived';          #my $table = $src_config{archived} ? 'bugs_archived' : 'bugs';
221            $table = $src_config{archived} ? $archived_table : $table;
222          # Read all bugs          # Read all bugs
223            my $insert_bugs_handle = $dbh->prepare("INSERT INTO $table VALUES (\$1, \$2, \$3, \$4::abstime, \$5, \$6, \$7, \$8, \$9, \$10::abstime, \$11, \$12, \$13)");
224            my $insert_bugs_found_handle = $dbh->prepare("INSERT INTO ${table}_found_in VALUES (\$1, \$2)");
225            my $insert_bugs_fixed_handle = $dbh->prepare("INSERT INTO ${table}_fixed_in VALUES (\$1, \$2)");
226            my $insert_bugs_merged_handle = $dbh->prepare("INSERT INTO ${table}_merged_with VALUES (\$1, \$2)");
227            my $insert_bugs_tags_handle = $dbh->prepare("INSERT INTO ${table}_tags VALUES (\$1, \$2)");
228            $insert_bugs_handle->bind_param(4, undef, SQL_INTEGER);
229            $insert_bugs_handle->bind_param(10, undef, SQL_INTEGER);
230    
231            print "Inserting bugs: ",(time() - $t),"s\n" if $timing;
232            $t = time();
233          foreach my $bug_nr (@modified_bugs) {          foreach my $bug_nr (@modified_bugs) {
234                  # Fetch bug using Debbugs                  # Fetch bug using Debbugs
235                  # Bugs which were once archived and have been unarchived again will appear in get_bugs(archive => 1).                  # Bugs which were once archived and have been unarchived again will appear in get_bugs(archive => 1).
# Line 173  sub main { Line 239  sub main {
239                  my %bug = %{get_bug_status(bug => $bug_nr, status => $bug_ref)};                  my %bug = %{get_bug_status(bug => $bug_nr, status => $bug_ref)};
240    
241                  # Convert data where necessary                  # Convert data where necessary
242                  map { $bug{$_} = $dbh->quote($bug{$_}) } qw(subject originator owner pending);                  my @found_versions = @{$bug{found_versions}};
243                  my @found_versions = map { $dbh->quote($_) } @{$bug{found_versions}};                  my @fixed_versions = @{$bug{fixed_versions}};
244                  my @fixed_versions = map { $dbh->quote($_) } @{$bug{fixed_versions}};                  my @tags = split / /, $bug{keywords};
                 my @tags = map {$dbh->quote($_) } split / /, $bug{keywords};  
245    
246                  # log_modified and date are not necessarily set. If they are not available, they                  # log_modified and date are not necessarily set. If they are not available, they
247                  # are assumed to be epoch (i.e. bug #4170)                  # are assumed to be epoch (i.e. bug #4170)
248                  map {                  map {
249                          if($bug{$_}) {                          if($bug{$_}) {
250                                  $bug{$_} = "$bug{$_}::abstime";                                  #$bug{$_} = "$bug{$_}::abstime";
251                                    $bug{$_} = int($bug{$_});
252                          } else {                          } else {
253                                  $bug{$_} = '0::abstime';                                  $bug{$_} = 0;
254                          }                          }
255                  } qw{date log_modified};                  } qw{date log_modified};
256    
# Line 195  sub main { Line 261  sub main {
261                  my $source = $binarytosource{$bug{package}};                  my $source = $binarytosource{$bug{package}};
262    
263                  if(not defined $source) {                  if(not defined $source) {
264                          $source = 'NULL';                  # if source is not defined, then we $bug{package} is likely to
265                  } else {                  # be a source package name (or the source package has the same
266                          $source = $dbh->quote($source);                  # name as the binary package). See #480818 for ex.
267                            $source = $bug{package};
268                  }                  }
269    
270                  #Calculate bug presence in distributions                  #Calculate bug presence in distributions
271                  my $present_in_stable =                  my ($present_in_stable, $present_in_testing, $present_in_unstable);
272                          bug_presence(bug => $bug_nr, status => \%bug,                  if($src_config{archived}) {
273                                           dist => 'stable');                          $present_in_stable = $present_in_testing = $present_in_unstable = 'FALSE';
                 my $present_in_testing =  
                         bug_presence(bug => $bug_nr, status => \%bug,  
                                          dist => 'testing');  
                 my $present_in_unstable =  
                         bug_presence(bug => $bug_nr, status => \%bug,  
                                          dist => 'unstable');  
                 if(!defined($present_in_stable) or !defined($present_in_unstable) or !defined($present_in_testing)) {  
                         print "NUMBER: $bug_nr\n";  
                 }  
                 if(defined($present_in_stable) and ($present_in_stable eq 'absent' or $present_in_stable eq 'fixed')) {  
                         $present_in_stable = 'FALSE';  
274                  } else {                  } else {
275                          $present_in_stable = 'TRUE';                          $present_in_stable =
276                  }                                  bug_presence(bug => $bug_nr, status => \%bug,
277                  if(defined($present_in_testing) and ($present_in_testing eq 'absent' or $present_in_testing eq 'fixed')) {                                                           dist => 'stable');
278                          $present_in_testing = 'FALSE';                          $present_in_testing =
279                  } else {                                  bug_presence(bug => $bug_nr, status => \%bug,
280                          $present_in_testing = 'TRUE';                                                           dist => 'testing');
281                  }                          $present_in_unstable =
282                  if(defined($present_in_unstable) and ($present_in_unstable eq 'absent' or $present_in_unstable eq 'fixed')) {                                  bug_presence(bug => $bug_nr, status => \%bug,
283                          $present_in_unstable = 'FALSE';                                                           dist => 'unstable');
284                  } else {                          if(!defined($present_in_stable) or !defined($present_in_unstable) or !defined($present_in_testing)) {
285                          $present_in_unstable = 'TRUE';                                  print "NUMBER: $bug_nr\n";
286                            }
287    
288                            if(defined($present_in_stable) and ($present_in_stable eq 'absent' or $present_in_stable eq 'fixed')) {
289                                    $present_in_stable = 'FALSE';
290                            } else {
291                                    $present_in_stable = 'TRUE';
292                            }
293                            if(defined($present_in_testing) and ($present_in_testing eq 'absent' or $present_in_testing eq 'fixed')) {
294                                    $present_in_testing = 'FALSE';
295                            } else {
296                                    $present_in_testing = 'TRUE';
297                            }
298                            if(defined($present_in_unstable) and ($present_in_unstable eq 'absent' or $present_in_unstable eq 'fixed')) {
299                                    $present_in_unstable = 'FALSE';
300                            } else {
301                                    $present_in_unstable = 'TRUE';
302                            }
303                  }                  }
304    
   
305                  # Insert data into bugs table                  # Insert data into bugs table
306                  my $query = "INSERT INTO $table VALUES ($bug_nr, '$bug{package}', $source, $bug{date}, \                  $insert_bugs_handle->execute($bug_nr, $bug{package}, $source, $bug{date}, $bug{pending},
307                               E$bug{pending}, '$bug{severity}', E$bug{originator}, E$bug{owner}, \                          $bug{severity}, $bug{originator}, $bug{owner}, $bug{subject}, $bug{log_modified},
308                                           E$bug{subject}, $bug{log_modified}, $present_in_stable,                          $present_in_stable, $present_in_testing, $present_in_unstable) or die $!;
                                          $present_in_testing, $present_in_unstable)";  
                 # Execute insertion  
                 my $sth = $dbh->prepare($query);  
                 $sth->execute() or die $!;  
309    
310                  # insert data into bug_fixed_in and bug_found_in tables                  # insert data into bug_fixed_in and bug_found_in tables
311                  foreach my $version (without_duplicates(@found_versions)) {                  foreach my $version (without_duplicates(@found_versions)) {
312                          $query = "INSERT INTO bug_found_in VALUES ($bug_nr, $version)";                          $insert_bugs_found_handle->execute($bug_nr, $version) or die $!;
                         $dbh->prepare($query)->execute() or die $!;  
313                  }                  }
314                  foreach my $version (without_duplicates(@fixed_versions)) {                  foreach my $version (without_duplicates(@fixed_versions)) {
315                          $query = "INSERT INTO bug_fixed_in VALUES ($bug_nr, $version)";                          $insert_bugs_fixed_handle->execute($bug_nr, $version) or die $!;
                         $dbh->prepare($query)->execute() or die $!;  
316                  }                  }
317                  foreach my $mergee (without_duplicates(split / /, $bug{mergedwith})) {                  foreach my $mergee (without_duplicates(split / /, $bug{mergedwith})) {
318                          $query = "INSERT INTO bug_merged_with VALUES ($bug_nr, $mergee)";                          $insert_bugs_merged_handle->execute($bug_nr, $mergee) or die $!;
                         $dbh->prepare($query)->execute() or die $!;  
319                  }                  }
320                  foreach my $tag (without_duplicates(@tags)) {                  foreach my $tag (without_duplicates(@tags)) {
321                          $query = "INSERT INTO bug_tags VALUES ($bug_nr, $tag)";                          $insert_bugs_tags_handle->execute($bug_nr, $tag) or die $!;
                         $dbh->prepare($query)->execute() or die $!;  
322                  }                  }
323          }          }
324    }
325    
326    sub main {
327            if(@ARGV != 3) {
328                    print STDERR "Usage: $0 <config> <command> <source>\n";
329                    exit 1;
330            }
331    
332            our $t = time();
333            our $timing;
334    
335            my $config = LoadFile($ARGV[0]) or die "Could not load configuration: $!";
336            my $command = $ARGV[1];
337            my $source = $ARGV[2];
338    
339            my $dbname = $config->{general}->{dbname};
340            # Connection to DB
341            my $dbh = DBI->connect("dbi:Pg:dbname=$dbname");
342            # We want to commit the transaction as a hole at the end
343            $dbh->{AutoCommit} = 0;
344    
345            if($command eq 'run') {
346                    run($config, $source, $dbh);
347            } elsif ($command eq 'setup') {
348                    setup($config, $source, $dbh);
349            } elsif ($command eq 'drop') {
350                    drop($config, $source, $dbh);
351            } elsif ($command eq 'tables') {
352                    print join "\n", tables($config, $source, $dbh)
353            } else {
354                    print STDERR "<command> has to be one of run, drop and setup\n";
355                    exit(1)
356            }
357    
358          $dbh->commit();          $dbh->commit();
359            print "Committing bugs: ",(time() - $t),"s\n" if $timing;
360  }  }
361    
362  main();  main();

Legend:
Removed from v.999  
changed lines
  Added in v.1217

  ViewVC Help
Powered by ViewVC 1.1.5