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

Contents of /udd/udd/bugs_gatherer.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1059 - (show annotations) (download)
Sun Aug 10 15:02:05 2008 UTC (4 years, 9 months ago) by lucas
Original Path: udd/src/udd/bugs_gatherer.pl
File MIME type: text/plain
File size: 8231 byte(s)
use dbh-do instead of dbh->prepare->execute ; added option to only import some bugs (easier to test)
1 #!/usr/bin/perl
2 # Last-Modified: <Sun Aug 10 10:31:57 2008>
3
4 use strict;
5 use warnings;
6
7 use FindBin '$Bin';
8
9 # We need our own copy of Debbugs::Status for now
10 use lib $Bin, qw{/org/udd.debian.net/mirrors/bugs.debian.org/perl};
11
12 use DBI;
13 use YAML::Syck;
14 use Time::Local;
15
16 use Debbugs::Bugs qw{get_bugs};
17 use Debbugs::Status qw{read_bug get_bug_status bug_presence};
18 use Debbugs::Packages qw{binarytosource};
19 use Debbugs::Config qw{:globals};
20 use Debbugs::User;
21 #use Debbugs::User qw{read_usertags};
22
23 $YAML::Syck::ImplicitTyping = 1;
24
25 # Return the list of usernames
26 sub get_bugs_users {
27 my $topdir = "$gSpoolDir/user";
28 my @ret = ();
29 # see Debbugs::User::filefromemail for why 0...6
30 for(my $i = 0; $i < 7; $i++) {
31 my $dir = "$topdir/$i";
32 opendir DIR, $dir or die "Can't open dir $dir: $!";
33 # Replace all occurences of %dd with the corresponding
34 # character represented by dd, where dd is a hexadecimal
35 # number
36 push @ret, map { s/%(..)/chr(hex($1))/ge; $_ } readdir DIR;
37 }
38 return @ret;
39 }
40
41 sub parse_time {
42 if(shift =~ /(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/) {
43 return ($1, $2, $3, $4, $5, $6);
44 }
45 return undef;
46 }
47
48
49 sub get_db_max_last_modified {
50 my $dbh = shift or die "Argument required";
51 my $sth = $dbh->prepare("SELECT MAX (last_modified) FROM bugs");
52 $sth->execute() or die $!;
53 my $date = $sth->fetchrow_array();
54 if(defined $date) {
55 my ($year, $month, $day, $hour, $minute, $second) = parse_time($date);
56 return timelocal($second, $minute, $hour, $day, $month-1, $year);
57 } else {
58 return 0;
59 }
60 }
61
62 sub get_mtime {
63 return ((stat(shift))[9]);
64 }
65
66 sub get_modified_bugs {
67 my $prune_stamp = shift;
68 die "Argument required" unless defined $prune_stamp;
69 my $top_dir = $gSpoolDir;
70 my @result = ();
71 foreach my $sub (qw(archive db-h)) {
72 my $spool = "$top_dir/$sub";
73 foreach my $subsub (glob "$spool/*") {
74 if( -d $subsub and get_mtime($subsub) > $prune_stamp ) {
75 push @result,
76 map { s{.*/(.*)\.log}{$1}; $_ }
77 grep { get_mtime("$_") > $prune_stamp }
78 glob "$subsub/*.log";
79 }
80 }
81 }
82 return \@result;
83 }
84
85 sub without_duplicates {
86 my %h = ();
87 return (grep { ($h{$_}++ == 0) || 0 } @_);
88 }
89
90 sub main {
91 if(@ARGV != 2) {
92 print STDERR "Usage: $0 <config> <source>";
93 exit 1;
94 }
95
96 my $config = LoadFile($ARGV[0]) or die "Could not load configuration: $!";
97 my $source = $ARGV[1];
98 my %src_config = %{$config->{$source}};
99
100 my $dbname = $config->{general}->{dbname};
101 # Connection to DB
102 my $dbh = DBI->connect("dbi:Pg:dbname=$dbname");
103 # We want to commit the transaction as a hole at the end
104 $dbh->{AutoCommit} = 0;
105 my $timing = 1;
106 my $t;
107
108
109 $t = time();
110 # Free usertags table
111 $dbh->do("DELETE FROM bug_user_tags") or die
112 "Couldn't empty bug_user_tags: $!";
113 print "Deleting usertags: ",(time() - $t),"s\n" if $timing;
114 $t = time();
115 # read and insert user tags
116 my @users = get_bugs_users();
117 foreach my $user (@users) {
118 #read_usertags(\%tags, $user);
119 my $u = Debbugs::User->new($user);
120 my %tags = %{$u->{tags}};
121 $user = $dbh->quote($user);
122 foreach my $tag (keys %tags) {
123 my $qtag = $dbh->quote($tag);
124 map { $dbh->do("INSERT INTO bug_user_tags VALUES ($user, $qtag, $_)") or die $! } @{$tags{$tag}};
125 }
126 }
127 print "Inserting usertags: ",(time() - $t),"s\n" if $timing;
128 $t = time();
129 my @modified_bugs;
130 if($src_config{archived}) {
131 @modified_bugs = get_bugs(archive => 1);
132 } else {
133 @modified_bugs = get_bugs();
134 }
135
136 my @modified_bugs2;
137 if ($src_config{debug}) {
138 foreach $b (@modified_bugs) {
139 push(@modified_bugs2, $b) if ($b =~ /0$/);
140 }
141 @modified_bugs = @modified_bugs2;
142 }
143
144 print "Fetching list of ",scalar(@modified_bugs), " bugs to insert: ",(time() - $t),"s\n" if $timing;
145 $t = time();
146
147 # Delete all bugs we are going to import
148 my $modbugs = join(", ", @modified_bugs);
149 for my $table qw{bugs_archived bugs bug_merged_with bug_found_in bug_fixed_in bug_tags} {
150 $dbh->do("DELETE FROM $table WHERE id IN ($modbugs)") or die $!
151 }
152 print "Deleting bugs: ",(time() - $t),"s\n" if $timing;
153 $t = time();
154
155 # Used to chache binary to source mappings
156 my %binarytosource = ();
157 # XXX What if a bug is in location 'db' (which currently doesn't exist)
158 my $location = $src_config{archived} ? 'archive' : 'db_h';
159 my $table = $src_config{archived} ? 'bugs_archived' : 'bugs';
160 # Read all bugs
161 foreach my $bug_nr (@modified_bugs) {
162 # Fetch bug using Debbugs
163 # Bugs which were once archived and have been unarchived again will appear in get_bugs(archive => 1).
164 # However, those bugs are not to be found in location 'archive', so we detect them, and skip them
165 my $bug_ref = read_bug(bug => $bug_nr, location => $location) or (print STDERR "Could not read file for bug $bug_nr; skipping\n" and next);
166 # Yeah, great, why does get_bug_status not accept a location?
167 my %bug = %{get_bug_status(bug => $bug_nr, status => $bug_ref)};
168
169 # Convert data where necessary
170 map { $bug{$_} = $dbh->quote($bug{$_}) } qw(subject originator owner pending);
171 my @found_versions = map { $dbh->quote($_) } @{$bug{found_versions}};
172 my @fixed_versions = map { $dbh->quote($_) } @{$bug{fixed_versions}};
173 my @tags = map {$dbh->quote($_) } split / /, $bug{keywords};
174
175 # log_modified and date are not necessarily set. If they are not available, they
176 # are assumed to be epoch (i.e. bug #4170)
177 map {
178 if($bug{$_}) {
179 $bug{$_} = "$bug{$_}::abstime";
180 } else {
181 $bug{$_} = '0::abstime';
182 }
183 } qw{date log_modified};
184
185
186 if(not exists $binarytosource{$bug{package}}) {
187 $binarytosource{$bug{package}} = (binarytosource($bug{package}))[0];
188 }
189 my $source = $binarytosource{$bug{package}};
190
191 if(not defined $source) {
192 # if source is not defined, then we $bug{package} is likely to
193 # be a source package name (or the source package has the same
194 # name as the binary package). See #480818 for ex.
195 $source = $dbh->quote($bug{package});
196 } else {
197 $source = $dbh->quote($source);
198 }
199
200 #Calculate bug presence in distributions
201 my $present_in_stable =
202 bug_presence(bug => $bug_nr, status => \%bug,
203 dist => 'stable');
204 my $present_in_testing =
205 bug_presence(bug => $bug_nr, status => \%bug,
206 dist => 'testing');
207 my $present_in_unstable =
208 bug_presence(bug => $bug_nr, status => \%bug,
209 dist => 'unstable');
210 if(!defined($present_in_stable) or !defined($present_in_unstable) or !defined($present_in_testing)) {
211 print "NUMBER: $bug_nr\n";
212 }
213 if(defined($present_in_stable) and ($present_in_stable eq 'absent' or $present_in_stable eq 'fixed')) {
214 $present_in_stable = 'FALSE';
215 } else {
216 $present_in_stable = 'TRUE';
217 }
218 if(defined($present_in_testing) and ($present_in_testing eq 'absent' or $present_in_testing eq 'fixed')) {
219 $present_in_testing = 'FALSE';
220 } else {
221 $present_in_testing = 'TRUE';
222 }
223 if(defined($present_in_unstable) and ($present_in_unstable eq 'absent' or $present_in_unstable eq 'fixed')) {
224 $present_in_unstable = 'FALSE';
225 } else {
226 $present_in_unstable = 'TRUE';
227 }
228
229 # Insert data into bugs table
230 my $query = "INSERT INTO $table VALUES ($bug_nr, '$bug{package}', $source, $bug{date}, \
231 E$bug{pending}, '$bug{severity}', E$bug{originator}, E$bug{owner}, \
232 E$bug{subject}, $bug{log_modified}, $present_in_stable,
233 $present_in_testing, $present_in_unstable)";
234 # Execute insertion
235 $dbh->do($query) or die $!;
236
237 # insert data into bug_fixed_in and bug_found_in tables
238 foreach my $version (without_duplicates(@found_versions)) {
239 $query = "INSERT INTO bug_found_in VALUES ($bug_nr, $version)";
240 $dbh->do($query) or die $!;
241 }
242 foreach my $version (without_duplicates(@fixed_versions)) {
243 $query = "INSERT INTO bug_fixed_in VALUES ($bug_nr, $version)";
244 $dbh->do($query) or die $!;
245 }
246 foreach my $mergee (without_duplicates(split / /, $bug{mergedwith})) {
247 $query = "INSERT INTO bug_merged_with VALUES ($bug_nr, $mergee)";
248 $dbh->do($query) or die $!;
249 }
250 foreach my $tag (without_duplicates(@tags)) {
251 $query = "INSERT INTO bug_tags VALUES ($bug_nr, $tag)";
252 $dbh->do($query) or die $!;
253 }
254 }
255
256 print "Inserting bugs: ",(time() - $t),"s\n" if $timing;
257 $t = time();
258 $dbh->commit();
259 print "Committing bugs: ",(time() - $t),"s\n" if $timing;
260 }
261
262 main();

  ViewVC Help
Powered by ViewVC 1.1.5