|
1 use strict; |
|
2 use Date::Calc qw{Delta_DHMS This_Year}; |
|
3 use DBI; |
|
4 |
|
5 use Getopt::Long; |
|
6 |
|
7 my $help = 0; |
|
8 my $create = 0; |
|
9 my $id = ''; |
|
10 my $file = ''; |
|
11 my $verbose = 0; |
|
12 GetOptions(( |
|
13 'create!' => \$create, |
|
14 'file=s' => \$file, |
|
15 'id=s' => \$id, |
|
16 'help!' => \$help, |
|
17 'verbose!' => \$verbose |
|
18 )); |
|
19 |
|
20 if ($help||!$file) |
|
21 { |
|
22 print <<_EOH; |
|
23 bitops |
|
24 Executes operations on the BIT db |
|
25 |
|
26 Usage: bitops.pl [-c|-i ID] -f FILE |
|
27 |
|
28 Options: |
|
29 -h, --help Show this help message and exit |
|
30 -c, --create Create entry for a new build then set the attributes to |
|
31 the values provided in FILE. Returns the build id for |
|
32 the newly created build. |
|
33 -i ID, --id ID Update entry for build number ID with the values |
|
34 provided in FILE. |
|
35 -f FILE, --file FILE Use attributes in FILE to create/update the build info |
|
36 See below for file format. |
|
37 |
|
38 File format: |
|
39 File must be a list of attribute-value-pairs. One avp per line, on each line |
|
40 attribute and value are separated by a tab. |
|
41 These are the supported attributes (in brackets the syntax of the value): |
|
42 - build_id_string |
|
43 - package (VALUE) |
|
44 - platform (VALUE) |
|
45 - started (VALUE) |
|
46 - finished (VALUE) |
|
47 - creator (VALUE) |
|
48 - machine (VALUE) |
|
49 - build_brag (VALUE) |
|
50 - test_brag (VALUE) |
|
51 - baseline_short (VALUE) |
|
52 - sources_short (VALUE) |
|
53 - envinfo (TOOL,VERSION) |
|
54 - failure (CATEGORY,COUNT) |
|
55 - report (NAME,URL,TYPE) |
|
56 - content (NAME,URL,REVISION) |
|
57 - label (VALUE) |
|
58 _EOH |
|
59 exit(0); |
|
60 } |
|
61 |
|
62 my $db = undef; |
|
63 |
|
64 my $builds_entry = {}; |
|
65 my $envinfo = []; |
|
66 my $failures = []; |
|
67 my $reports = []; |
|
68 my $content = []; |
|
69 my $labels = []; |
|
70 my $testing_entry = {}; |
|
71 |
|
72 sub ConnectToDB() |
|
73 { |
|
74 $db = DBI->connect('DBI:mysql:bit:v800016:3306','fbf','mysql') |
|
75 or die("Couldn't connect to database: " . DBI->errstr()); |
|
76 } |
|
77 |
|
78 sub DisconnectFromDB() |
|
79 { |
|
80 $db->disconnect(); |
|
81 } |
|
82 |
|
83 sub parse_file |
|
84 { |
|
85 my ($file) = @_; |
|
86 |
|
87 open(FILE, $file) or die "Can't open file $file"; |
|
88 |
|
89 while (<FILE>) |
|
90 { |
|
91 my $line = $_; |
|
92 chomp $line; |
|
93 $line =~ s/^\s//g; |
|
94 $line =~ s/\s$//g; |
|
95 next if ($line !~ /[^\s]/); |
|
96 |
|
97 if ($line =~ /([^\t]+)\t([^\t]+)/) |
|
98 { |
|
99 my $attr = $1; |
|
100 my $value = $2; |
|
101 |
|
102 if ($attr =~ /^(build_id_string|package|platform|started|finished|creator|machine|build_brag|test_brag|baseline_short|sources_short)$/i) |
|
103 { |
|
104 $attr = lc($attr); |
|
105 print " found ($attr,$value) for table 'build'\n" if ($verbose); |
|
106 $builds_entry->{$attr}=$value; |
|
107 } |
|
108 elsif ($attr =~ /^(envinfo)$/i) |
|
109 { |
|
110 $attr = lc($attr); |
|
111 if ($value =~ /([^,]*),([^,]*)/) |
|
112 { |
|
113 my $tool = $1; |
|
114 my $version = $2; |
|
115 |
|
116 if (!$tool || !$version) |
|
117 { |
|
118 print "ERROR: Tool or version empty: \"$value\"\n"; |
|
119 return 1; |
|
120 } |
|
121 print " found ($tool,$version) for table 'envinfo'\n" if ($verbose); |
|
122 push(@{$envinfo}, {tool=>$tool, version=>$version}); |
|
123 } |
|
124 else |
|
125 { |
|
126 print "ERROR: Could not understand value of envinfo: \"$value\"\n"; |
|
127 return 1; |
|
128 } |
|
129 } |
|
130 elsif ($attr =~ /^(failure)$/i) |
|
131 { |
|
132 $attr = lc($attr); |
|
133 if ($value =~ /([^,]*),([^,]*)/) |
|
134 { |
|
135 my $category = $1; |
|
136 my $count = $2; |
|
137 |
|
138 if (!$category || !$count) |
|
139 { |
|
140 print "ERROR: Category or count empty: \"$value\"\n"; |
|
141 return 1; |
|
142 } |
|
143 print " found ($category,$count) for table 'failures'\n" if ($verbose); |
|
144 push(@{$failures}, {category=>$category, count=>$count}); |
|
145 } |
|
146 else |
|
147 { |
|
148 print "ERROR: Could not understand value of failure: \"$value\"\n"; |
|
149 return 1; |
|
150 } |
|
151 } |
|
152 elsif ($attr =~ /^(report)$/i) |
|
153 { |
|
154 $attr = lc($attr); |
|
155 if ($value =~ /([^,]*),([^,]*),([^,]*)/) |
|
156 { |
|
157 my $name = $1; |
|
158 my $url = $2; |
|
159 my $type = $3; |
|
160 |
|
161 if (!$name || !$url || !$type) |
|
162 { |
|
163 print "ERROR: Name, url or type empty: \"$value\"\n"; |
|
164 return 1; |
|
165 } |
|
166 print " found ($name,$url,$type) for table 'reports'\n" if ($verbose); |
|
167 push(@{$reports}, {name=>$name, url=>$url, type=>$type}); |
|
168 } |
|
169 else |
|
170 { |
|
171 print "ERROR: Could not understand value of report: \"$value\"\n"; |
|
172 return 1; |
|
173 } |
|
174 } |
|
175 elsif ($attr =~ /^(content)$/i) |
|
176 { |
|
177 $attr = lc($attr); |
|
178 if ($value =~ /([^,]*),([^,]*),([^,]*)/) |
|
179 { |
|
180 my $name = $1; |
|
181 my $url = $2; |
|
182 my $revision = $3; |
|
183 |
|
184 if (!$name || !$url || !$revision) |
|
185 { |
|
186 print "ERROR: Name, url or revision empty: \"$value\"\n"; |
|
187 return 1; |
|
188 } |
|
189 print " found ($name,$url,$revision) for table 'content'\n" if ($verbose); |
|
190 push(@{$reports}, {name=>$name, url=>$url, revision=>$revision}); |
|
191 } |
|
192 else |
|
193 { |
|
194 print "ERROR: Could not understand value of content: \"$value\"\n"; |
|
195 return 1; |
|
196 } |
|
197 } |
|
198 elsif ($attr =~ /^(label)$/i) |
|
199 { |
|
200 print " found ($attr,$value) for table 'labels'\n" if ($verbose); |
|
201 push(@{$labels}, {label=>$value}); |
|
202 } |
|
203 else |
|
204 { |
|
205 print "ERROR: Could not understand avp: \"$line\"\n"; |
|
206 return 1; |
|
207 } |
|
208 |
|
209 } |
|
210 else |
|
211 { |
|
212 print "WARNING: line \"$line\" does not seem a correctly formed attribute-value-pair (tab-separated)\n"; |
|
213 return 1; |
|
214 } |
|
215 } |
|
216 |
|
217 close(FILE); |
|
218 return 0; |
|
219 } |
|
220 |
|
221 # MAIN PROGRAM |
|
222 |
|
223 my $r=parse_file($file); |
|
224 if ($r) |
|
225 { |
|
226 print "Error while parsing file $file\n"; |
|
227 exit(1); |
|
228 } |
|
229 |
|
230 ConnectToDB(); |
|
231 my $newbuildid = -1; |
|
232 if ($create) |
|
233 { |
|
234 if (keys %{$builds_entry}) |
|
235 { |
|
236 my $field_list = ''; |
|
237 my $qm_list = ''; |
|
238 my @fields = (); |
|
239 for my $field (keys %{$builds_entry}) |
|
240 { |
|
241 $field_list .= "$field,"; |
|
242 $qm_list .= "?,"; |
|
243 push(@fields,$builds_entry->{$field}); |
|
244 } |
|
245 $field_list =~ s/,$//; |
|
246 $qm_list =~ s/,$//; |
|
247 |
|
248 my $query = $db->prepare("insert into builds ($field_list) values ($qm_list)") |
|
249 or die("Couldn't prepare query insert into builds: " . $db->errstr()); |
|
250 |
|
251 $query->execute(@fields) |
|
252 or print "WARNING: Couldn't execute insert into builds (@fields): " . $db->errstr() . "\n"; |
|
253 |
|
254 $newbuildid = $db->last_insert_id(undef, undef, undef, undef); |
|
255 } |
|
256 if (@{$envinfo}) |
|
257 { |
|
258 my $query = $db->prepare_cached("insert into envinfo (build_id,tool,version) values ($newbuildid,?,?)") |
|
259 or die("Couldn't prepare query insert into envinfo: " . $db->errstr()); |
|
260 |
|
261 for my $entry (@{$envinfo}) |
|
262 { |
|
263 my $tool = $entry->{tool}; |
|
264 my $version = $entry->{version}; |
|
265 |
|
266 $query->execute($tool, $version) |
|
267 or print "WARNING: Couldn't execute insert into envinfo ($tool,$version): " . $db->errstr() . "\n"; |
|
268 } |
|
269 } |
|
270 if (@{$failures}) |
|
271 { |
|
272 print " prepare_cached 'insert into failures (build_id,category,count) values ($newbuildid,?,?)'\n" if ($verbose); |
|
273 my $query = $db->prepare_cached("insert into failures (build_id,category,count) values ($newbuildid,?,?)") |
|
274 or die("Couldn't prepare query insert into failures: " . $db->errstr()); |
|
275 |
|
276 for my $entry (@{$failures}) |
|
277 { |
|
278 my $category = $entry->{category}; |
|
279 my $count = $entry->{count}; |
|
280 |
|
281 print " execute '$category, $count'\n" if ($verbose); |
|
282 $query->execute($category, $count) |
|
283 or print "WARNING: Couldn't execute insert into failures ($category,$count): " . $db->errstr() . "\n"; |
|
284 } |
|
285 } |
|
286 if (@{$reports}) |
|
287 { |
|
288 print " prepare_cached 'insert into reports (build_id,name,url,type) values ($newbuildid,?,?,?)'\n" if ($verbose); |
|
289 my $query = $db->prepare_cached("insert into reports (build_id,name,url,type) values ($newbuildid,?,?,?)") |
|
290 or die("Couldn't prepare query insert into reports: " . $db->errstr()); |
|
291 |
|
292 for my $entry (@{$reports}) |
|
293 { |
|
294 my $name = $entry->{name}; |
|
295 my $url = $entry->{url}; |
|
296 my $type = $entry->{type}; |
|
297 |
|
298 print " execute '$name, $url, $type'\n" if ($verbose); |
|
299 $query->execute($name, $url, $type) |
|
300 or print "WARNING: Couldn't execute insert into reports ($name,$url,$type): " . $db->errstr() . "\n"; |
|
301 } |
|
302 } |
|
303 if (@{$content}) |
|
304 { |
|
305 print " prepare_cached 'insert into content (build_id,name,url,revision) values ($newbuildid,?,?,?)'\n" if ($verbose); |
|
306 my $query = $db->prepare_cached("insert into content (build_id,name,url,revision) values ($newbuildid,?,?,?)") |
|
307 or die("Couldn't prepare query insert into content: " . $db->errstr()); |
|
308 |
|
309 for my $entry (@{$content}) |
|
310 { |
|
311 my $name = $entry->{name}; |
|
312 my $url = $entry->{url}; |
|
313 my $revision = $entry->{revision}; |
|
314 |
|
315 print " execute '$name, $url, $revision'\n" if ($verbose); |
|
316 $query->execute($name, $url, $revision) |
|
317 or print "WARNING: Couldn't execute insert into content ($name,$url,$revision): " . $db->errstr() . "\n"; |
|
318 } |
|
319 } |
|
320 if (@{$labels}) |
|
321 { |
|
322 print " prepare_cached 'insert into labels (build_id,label) values ($newbuildid,?)'\n" if ($verbose); |
|
323 my $query = $db->prepare_cached("insert into labels (build_id,label) values ($newbuildid,?)") |
|
324 or die("Couldn't prepare query insert into labels: " . $db->errstr()); |
|
325 |
|
326 for my $entry (@{$labels}) |
|
327 { |
|
328 my $label = $entry->{label}; |
|
329 |
|
330 print " execute '$label'\n" if ($verbose); |
|
331 $query->execute($label) |
|
332 or print "WARNING: Couldn't execute insert into revision ($label): " . $db->errstr() . "\n"; |
|
333 } |
|
334 } |
|
335 print "new build id: $newbuildid\n"; |
|
336 } |
|
337 else |
|
338 { |
|
339 print "Updating build $id\n"; |
|
340 |
|
341 if (keys %{$builds_entry}) |
|
342 { |
|
343 my $field_list = ''; |
|
344 my @fields = (); |
|
345 for my $field (keys %{$builds_entry}) |
|
346 { |
|
347 $field_list .= "$field=?,"; |
|
348 push(@fields,$builds_entry->{$field}); |
|
349 } |
|
350 $field_list =~ s/,$//; |
|
351 |
|
352 print " prepare 'update builds set $field_list where id=$id'\n" if ($verbose); |
|
353 my $query = $db->prepare("update builds set $field_list where id=$id") |
|
354 or die("Couldn't prepare query update builds: " . $db->errstr()); |
|
355 |
|
356 print " execute '@fields'\n" if ($verbose); |
|
357 $query->execute(@fields) |
|
358 or print "WARNING: Couldn't execute update builds (@fields): " . $db->errstr() . "\n"; |
|
359 } |
|
360 if (@{$envinfo}) |
|
361 { |
|
362 print " prepare 'delete from envinfo where build_id=$id'\n" if ($verbose); |
|
363 my $delete_query = $db->prepare("delete from envinfo where build_id=$id") |
|
364 or die("Couldn't prepare query delete from envinfo: " . $db->errstr()); |
|
365 |
|
366 print " execute ''\n" if ($verbose); |
|
367 $delete_query->execute() |
|
368 or print "WARNING: Couldn't execute delete from envinfo: " . $db->errstr() . "\n"; |
|
369 |
|
370 print " prepare 'insert into envinfo (build_id,tool,version) values ($id,?,?)'\n" if ($verbose); |
|
371 my $query = $db->prepare_cached("insert into envinfo (build_id,tool,version) values ($id,?,?)") |
|
372 or die("Couldn't prepare query insert into envinfo: " . $db->errstr()); |
|
373 |
|
374 for my $entry (@{$envinfo}) |
|
375 { |
|
376 my $tool = $entry->{tool}; |
|
377 my $version = $entry->{version}; |
|
378 |
|
379 print " execute '$tool,$version'\n" if ($verbose); |
|
380 $query->execute($tool, $version) |
|
381 or print "WARNING: Couldn't execute insert into envinfo ($tool,$version): " . $db->errstr() . "\n"; |
|
382 } |
|
383 } |
|
384 if (@{$failures}) |
|
385 { |
|
386 print " prepare 'delete from failures where build_id=$id'\n" if ($verbose); |
|
387 my $delete_query = $db->prepare("delete from failures where build_id=$id") |
|
388 or die("Couldn't prepare query delete from failures: " . $db->errstr()); |
|
389 |
|
390 print " execute ''\n" if ($verbose); |
|
391 $delete_query->execute() |
|
392 or print "WARNING: Couldn't execute delete from failures: " . $db->errstr() . "\n"; |
|
393 |
|
394 print " prepare 'insert into failures (build_id,category,count) values ($id,?,?)'\n" if ($verbose); |
|
395 my $query = $db->prepare_cached("insert into failures (build_id,category,count) values ($id,?,?)") |
|
396 or die("Couldn't prepare query insert into failures: " . $db->errstr()); |
|
397 |
|
398 for my $entry (@{$failures}) |
|
399 { |
|
400 my $category = $entry->{category}; |
|
401 my $count = $entry->{count}; |
|
402 |
|
403 print " execute '$category,$count'\n" if ($verbose); |
|
404 $query->execute($category, $count) |
|
405 or print "WARNING: Couldn't execute insert into failures ($category,$count): " . $db->errstr() . "\n"; |
|
406 } |
|
407 } |
|
408 if (@{$reports}) |
|
409 { |
|
410 print " prepare 'delete from reports where build_id=$id'\n" if ($verbose); |
|
411 my $delete_query = $db->prepare("delete from reports where build_id=$id") |
|
412 or die("Couldn't prepare query delete from reports: " . $db->errstr()); |
|
413 |
|
414 print " execute ''\n" if ($verbose); |
|
415 $delete_query->execute() |
|
416 or print "WARNING: Couldn't execute delete from reports: " . $db->errstr() . "\n"; |
|
417 |
|
418 print " prepare 'insert into reports (build_id,name,url,type) values ($id,?,?,?)'\n" if ($verbose); |
|
419 my $query = $db->prepare_cached("insert into reports (build_id,name,url,type) values ($id,?,?,?)") |
|
420 or die("Couldn't prepare query insert into failures: " . $db->errstr()); |
|
421 |
|
422 for my $entry (@{$reports}) |
|
423 { |
|
424 my $name = $entry->{name}; |
|
425 my $url = $entry->{url}; |
|
426 my $type = $entry->{type}; |
|
427 |
|
428 print " execute '$name,$url,$type'\n" if ($verbose); |
|
429 $query->execute($name, $url, $type) |
|
430 or print "WARNING: Couldn't execute insert into reports ($name,$url,$type): " . $db->errstr() . "\n"; |
|
431 } |
|
432 } |
|
433 if (@{$content}) |
|
434 { |
|
435 print " prepare 'delete from content where build_id=$id'\n" if ($verbose); |
|
436 my $delete_query = $db->prepare("delete from content where build_id=$id") |
|
437 or die("Couldn't prepare query delete from content: " . $db->errstr()); |
|
438 |
|
439 print " execute ''\n" if ($verbose); |
|
440 $delete_query->execute() |
|
441 or print "WARNING: Couldn't execute delete from content: " . $db->errstr() . "\n"; |
|
442 |
|
443 print " prepare 'insert into content (build_id,name,url,revision) values ($id,?,?,?)'\n" if ($verbose); |
|
444 my $query = $db->prepare_cached("insert into content (build_id,name,url,revision) values ($id,?,?,?)") |
|
445 or die("Couldn't prepare query insert into content: " . $db->errstr()); |
|
446 |
|
447 for my $entry (@{$content}) |
|
448 { |
|
449 my $name = $entry->{name}; |
|
450 my $url = $entry->{url}; |
|
451 my $revision = $entry->{revision}; |
|
452 |
|
453 print " execute '$name,$url,$revision'\n" if ($verbose); |
|
454 $query->execute($name, $url, $revision) |
|
455 or print "WARNING: Couldn't execute insert into content ($name,$url,$revision): " . $db->errstr() . "\n"; |
|
456 } |
|
457 } |
|
458 if (@{$labels}) |
|
459 { |
|
460 print " prepare 'delete from labels where build_id=$id'\n" if ($verbose); |
|
461 my $delete_query = $db->prepare("delete from labels where build_id=$id") |
|
462 or die("Couldn't prepare query delete from labels: " . $db->errstr()); |
|
463 |
|
464 print " execute ''\n" if ($verbose); |
|
465 $delete_query->execute() |
|
466 or print "WARNING: Couldn't execute delete from labels: " . $db->errstr() . "\n"; |
|
467 |
|
468 print " prepare 'insert into labels (build_id,label) values ($id,?)'\n" if ($verbose); |
|
469 my $query = $db->prepare_cached("insert into label (build_id,label) values ($id,?)") |
|
470 or die("Couldn't prepare query insert into label: " . $db->errstr()); |
|
471 |
|
472 for my $entry (@{$labels}) |
|
473 { |
|
474 my $label = $entry->{label}; |
|
475 |
|
476 print " execute '$label'\n" if ($verbose); |
|
477 $query->execute($label) |
|
478 or print "WARNING: Couldn't execute insert into labels ($label): " . $db->errstr() . "\n"; |
|
479 } |
|
480 } |
|
481 } |
|
482 DisconnectFromDB(); |
|
483 |
|
484 |