#!/usr/bin/perl -w use strict; use diagnostics # Copyright (c) Cambia Networks 2001 =pod =head1 syncshadowdir.pl This little script will try to recover all changes from the shadow directory to a mysql database. The shadow directory is different than the shadowdb. If you have the shadowdb enabled go use the syncshadowdb script. This script cannot recover what is not in the shadow dir. This includes.. * comments of components * owners of components * the "activity log" This script has not be modified yet to recover... * bug dependencies * cc (carbon copy) recipients. They would not be difficult, but are not used much by our database, and I need to go home. Warning: Don't leave this as executable in the bugzilla directory. You don't want people running it from a browser. =cut require "globals.pl"; my @bugIds = glob("shadow/*"); sub matchProblem { print("match problem\n$_[0]\n\n"); die(); } ConnectToDatabase(); sub GetLongComment { my $fd = $_[0]; my $who; my $description; my $datetime = "0000-00-00 00:00:00"; while(1) { # for every line of the description my $line = <$fd>; last if(!defined($line)); if($line =~ /^------- Additional Comments From (\S+)\s+(\d\d\d\d-\d\d-\d\d \d\d:\d\d) -------/) { $who = $1; $datetime = "$2:00"; last; }; $description .= $line; } return($description,$who,$datetime); } # Incidentally, this will create a product too if needed sub CreateVersionIfMissing { my ($version,$product) = @_; print("Creating Version ($version of $product)\n"); my $query = # check for components "SELECT value FROM versions WHERE\n" . " program = " . SqlQuote($product) . " AND\n" . " value = " . SqlQuote($version) . "\n"; SendSQL($query); my $exists = FetchOneColumn(); if(!$exists) { # this added description $query = # check for components "INSERT into versions (value, program)\n" . " VALUES (" . SqlQuote($version) . ",\n" . " " . SqlQuote($product) . ")\n"; SendSQL($query); }; } # Incidentally, this will create a product too if needed sub CreateComponentIfMissing { my ($component,$product) = @_; print("Creating Component ($component of $product)\n"); my $query = # check for components "SELECT value FROM components WHERE\n" . " program = " . SqlQuote($product) . " AND\n" . " value = " . SqlQuote($component) . "\n"; SendSQL($query); my $exists = FetchOneColumn(); if(!$exists) { # this added description $query = # check for components "INSERT into components (value, program, description)\n" . " VALUES (" . SqlQuote($component) . ",\n" . " " . SqlQuote($product) . ",\n" . " " . SqlQuote($component) . ")\n"; SendSQL($query); }; } # Incidentally, this will create a product too if needed sub CreateMilestoneIfMissing { my ($milestone,$product) = @_; print("Creating Version ($milestone of $product)\n"); my $query = # check for components "SELECT value FROM milestones WHERE\n" . " product = " . SqlQuote($product) . " AND\n" . " value = " . SqlQuote($milestone) . "\n"; SendSQL($query); my $exists = FetchOneColumn(); if(!$exists) { # this added description $query = # check for components "INSERT into milestones (value, product)\n" . " VALUES (" . SqlQuote($milestone) . ",\n" . " " . SqlQuote($product) . ")\n"; SendSQL($query); }; } =pod # This is an example shadow file # Sometimes some of the lines don't exist. +============================================================================+ | test | +----------------------------------------------------------------------------+ | Bug #: 1201 Product: Infomation Services | | Status: RESOLVED Version: unspecified | | Resolution: INVALID Platform: Other | | Severity: normal OS/Version: other | | Priority: P2 Component: Other | +----------------------------------------------------------------------------+ | Assigned To: rdean@cambianetworks.com | | Reported By: pcarnathan@cambianetworks.com | | CC list: Cc: | +----------------------------------------------------------------------------+ | Milestone: TargetMilestone: --- | | URL: | +============================================================================+ | DESCRIPTION | This is a test ------- Additional Comments From rdean@cambianetworks.com 2001-07-19 17:31 ------- This was a test ------- Additional Comments From rdean@cambianetworks.com 2001-07-19 17:35 ------- Another test =cut while(my $bugfile = pop(@bugIds)) { $bugfile =~ m|/([^/]*)$|; # grab the filename (after last slash) my $id = $1; print("processing bug #$id\n"); if($id !~ /^(\d+)$/) { # is it not just numeric print("bug number not numeric?\n"); next; }; if(!open(BF,"<$bugfile")) { # open bugfile used for emails print("could not open \"$bugfile\" file!\n"); next; } my $junk = ; # skip line 1 of equals $junk =~ /^\+\={76}\+$/ or print("bad line 1\n");; my $short_desc = ; # line 2 $short_desc =~ s/^\|\ // or matchProblem($junk); # remove leading characters $short_desc =~ s/\s+\|\s+// or matchProblem($junk); # remove trailing characters print(" short_desc: <<$short_desc>>\n"); $junk = ; # skip line 3 of dashes $junk =~ /^\+\-{76}\+$/ or matchProblem($junk); $junk = ; # line 4 $junk =~ m/Bug #: (\d+)/ or matchProblem($junk); if($1 != $id) { printf(" bug # in shadow file ($1) didn't agree with filename ($id)!\n"); next; }; $junk =~ m/Product: (.+?)\s+\|\s*$/ or matchProblem($junk); my $product = $1; print(" product: <<$product>>\n"); $junk = ; # line 5 $junk =~ m/Status: (\S+)/ or matchProblem($junk); my $bug_status = $1; print(" bug_status: <<$bug_status>>\n"); $junk =~ m/Version: (.+?)\s+\|\s*$/ or matchProblem($junk); my $version = $1; print(" product: <<$version>>\n"); $junk = ; # line 6 $junk =~ m/Resolution:\s+(.*?)\s+Platform/ or matchProblem($junk); my $resolution = $1; print(" resolution: <<$resolution>>\n"); $junk =~ m/Platform: (.+?)\s+\|\s*$/ or matchProblem($junk); my $rep_platform = $1; print(" rep_platform: <<$rep_platform>>\n"); $junk = ; # line 7 $junk =~ m/Severity: (\S+)/ or matchProblem($junk); my $bug_severity = $1; print(" bug_severity: <<$bug_severity>>\n"); $junk =~ m/OS.Version: (.+?)\s+\|\s*$/ or matchProblem($junk); my $op_sys = $1; print(" op_sys: <<$op_sys>>\n"); $junk = ; # line 8 $junk =~ m/Priority: (\S+)/ or matchProblem($junk); my $priority = $1; print(" priority: <<$priority>>\n"); $junk =~ m/Component: (.+?)\s+\|\s*$/ or matchProblem($junk); my $component = $1; print(" component: <<$component>>\n"); $junk = ; # skip line 9 of dashes $junk =~ /^\+\-{76}\+$/ or matchProblem($junk); $junk = ; # line 10 $junk =~ m/Assigned To: (\S+)\s*\|\s*$/ or matchProblem($junk); my $assigned_to = $1; print(" assigned_to: <<$assigned_to>>\n"); $junk = ; # line 11 $junk =~ m/Reported By: (\S+)\s*\|\s*$/ or matchProblem($junk); my $reporter = $1; print(" reporter: <<$reporter>>\n"); $junk = ; # line 12 my $cc = "Cc: "; if($junk =~ m/CC list: (.+?)\s*\|\s*$/) { $cc = $1; print(" cc: <<$cc>>\n"); $junk = ; # skip line 13 of dashes }; $junk =~ /^\+\-{76}\+$/ or matchProblem($junk); $junk = ; # line 14 my $target_milestone = "---"; if($junk =~ m/Milestone: TargetMilestone: (.+?)\s*\|\s*$/) { $target_milestone = $1; print(" target_milestone: <<$target_milestone>>\n"); $junk = ; # line 15 }; $junk =~ m/URL: (.*?)\s*\|\s*$/ or matchProblem($junk); my $url = $1; print(" url: <<$url>>\n"); $junk = ; # line 16? if($junk =~ m/Depend/) { $junk = ; # skip line of equals }; $junk =~ /^\+\={76}\+$/ or matchProblem($junk); $junk = ; # $junk =~ /DESCRIPTION/ or matchProblem($junk); my ($description,$nextwho,$nextdatetime) = GetLongComment(*BF); my ($who, $datetime) = ($reporter,$nextdatetime); # approximate datetime CreateComponentIfMissing($component,$product); CreateVersionIfMissing($version,$product); CreateMilestoneIfMissing($target_milestone,$product); my $query = " SELECT bugs.bug_id\n". "FROM bugs\n". "WHERE bugs.bug_id = $id\n"; SendSQL($query); if (FetchSQLData()) { # if bug exists print(" already exists\n"); $query = "UPDATE bugs SET\n". " product=" . SqlQuote($product) . ",\n" . " version=" . SqlQuote($version) . ",\n" . " bug_status=" . SqlQuote($bug_status) . ",\n" . " resolution=" . SqlQuote($resolution) . ",\n" . " priority=" . SqlQuote($priority) . ",\n" . " component=" . SqlQuote($component) . ",\n" . " bug_severity=" . SqlQuote($bug_severity) . ",\n" . " short_desc=" . SqlQuote($short_desc) . ",\n" . " target_milestone=" . SqlQuote($target_milestone) . ",\n" . " op_sys=" . SqlQuote($op_sys) . ",\n" . " rep_platform=" . SqlQuote($rep_platform) . ",\n" . " assigned_to=" . DBNameToIdAndCheck($assigned_to,"force") . ",\n" . " reporter=" . DBNameToIdAndCheck($reporter,"force") . "\n" . " WHERE bug_id=$id\n"; #print("$query\n\n"); SendSQL($query); while(1) { # for every description (we possibly add) ($who, $datetime) = ($nextwho,$nextdatetime); last if(eof(BF)); ($description,$nextwho,$nextdatetime) = GetLongComment(*BF); $query = "SELECT bug_id FROM longdescs \n". "WHERE (bug_id = $id\n". "AND thetext = ".SqlQuote($description).")\n"; SendSQL($query); my $exists = FetchOneColumn(); if(!$exists) { # this added description $query = "INSERT INTO longdescs (bug_id, who, bug_when, thetext) VALUES \n" . " ($id, ".SqlQuote(DBNameToIdAndCheck($who,"force")).", \n". " '$datetime',\n " . SqlQuote($description) . ")"; SendSQL($query); } }; } else { # else the bug doesn't exist print(" did not exists\n"); my $query = "INSERT INTO bugs (\n" . " bug_id,product,version,bug_status,resolution,priority, \n". " component, bug_severity, assigned_to, reporter, short_desc,\n". " target_milestone, op_sys, rep_platform, creation_ts, groupset) \n". " VALUES (\n". SqlQuote($id) . ",\n" . SqlQuote($product) . ",\n" . SqlQuote($version) . ",\n" . SqlQuote($bug_status) . ",\n" . SqlQuote($resolution) . ",\n" . SqlQuote($priority) . ",\n" . SqlQuote($component) . ",\n" . SqlQuote($bug_severity) . ",\n" . SqlQuote(DBNameToIdAndCheck($assigned_to,"force")) . ",\n" . SqlQuote(DBNameToIdAndCheck($reporter,"force")) . ",\n" . SqlQuote($short_desc) . ",\n" . SqlQuote($target_milestone) . ",\n" . SqlQuote($op_sys) . ",\n" . SqlQuote($rep_platform) . ",\n" . # we should use the $datetime instead of now(), # but need to check for zero "now() , 0)\n"; SendSQL($query); while(1) { # for every description to add $query = "INSERT INTO longdescs (bug_id, who, bug_when, thetext) VALUES \n" . " ($id, ".SqlQuote(DBNameToIdAndCheck($who,"force")).", \n". " '$datetime',\n " . SqlQuote($description) . ")"; SendSQL($query); last if(eof(BF)); ($who, $datetime) = ($nextwho,$nextdatetime); ($description,$nextwho,$nextdatetime) = GetLongComment(*BF); }; }; } print("####### finished\n"); exit(0);