[LON-CAPA-cvs] cvs: loncom /debugging_tools rebuild_db_from_hist.pl
matthew
lon-capa-cvs@mail.lon-capa.org
Wed, 08 Dec 2004 22:06:48 -0000
matthew Wed Dec 8 17:06:48 2004 EDT
Added files:
/loncom/debugging_tools rebuild_db_from_hist.pl
Log:
Short script to rebuild a *.db file from a *.hist file.
Index: loncom/debugging_tools/rebuild_db_from_hist.pl
+++ loncom/debugging_tools/rebuild_db_from_hist.pl
#!/usr/bin/perl -w
#
# The LearningOnline Network
#
# rebuild_db_from_hist.pl Rebuild a *.db file from a *.hist file
#
# $Id: rebuild_db_from_hist.pl,v 1.1 2004/12/08 22:06:48 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
#################################################
use strict;
use Getopt::Long;
use GDBM_File;
#
# Options
my ($help,$debug,$test);
GetOptions("help" => \$help,
"debug" => \$debug,
"test" => \$test);
if (! defined($debug)) { $debug = 0; }
if (! defined($test)) { $test = 0; }
#
# Help them out if they ask for it
if ($help) {
print <<'END';
rebuild_db_from_hist.pl - recreate a db file from a hist file.
Options:
-help Display this help.
-debug Output debugging code
-sort Sort the entries by time
-test Do not write the data but verify it was created properly
Examples:
rebuild_db_from_hist.pl $file.hist
END
exit;
}
#
# Loop through ARGV getting files.
while (my $fname = shift) {
my $db_filename = $fname;
$db_filename =~ s/\.hist$/\.db/;
if (-e $db_filename && ! $test) {
print STDERR "Aborting: The target file $db_filename exists.".$/;
next;
}
my ($error,$constructed_hash) = &process_file($fname,$db_filename);
if (! defined($error) || ! $test) {
$error = &write_hash($db_filename,$constructed_hash);
}
if ($test) {
my $error = &test_hash($db_filename,$constructed_hash);
if (defined($error)) {
print "Error processing ".$fname.$/;
print STDERR $error;
} else {
print "Everything looks good for ".$fname.$/;
}
}
if (defined($error)) {
print $error.$/;
}
}
exit;
######################################################
######################################################
sub process_file {
my ($fname,$db_filename,$debug) = @_;
#
open(HISTFILE,$fname);
my %db_to_store;
my $no_action_count = 0;
while (my $command = <HISTFILE>) {
chomp($command);
my $error = undef;
# Each line can begin with:
# P:put
# D:delete
my ($action,$time,$concatenated_data) = split(':',$command,3);
my @data = split('&',$concatenated_data);
foreach my $k_v_pair (@data) {
my ($key,$value) = split('=',$k_v_pair,2);
if (defined($action) && $action eq 'P') {
if (defined($value)) {
$db_to_store{$key}=$value;
} else {
$no_action_count++;
}
} elsif ($action eq 'D') {
delete($db_to_store{$key});
} else {
$error = "Unable to understand action '".$action."'";
}
}
if (defined($error)) {
return ('Error:'.$error.$/,undef);
}
}
if ($no_action_count) {
print $no_action_count.' lines did not require action.'.$/;
}
close(HISTFILE);
return (undef,\%db_to_store);
}
sub write_hash {
my ($db_filename,$db_to_store) = @_;
#
# Write the gdbm file
my %db;
if (! tie(%db,'GDBM_File',$db_filename,&GDBM_WRCREAT(),0640)) {
warn "Unable to tie to $db_filename";
return "Unable to tie to $db_filename";
}
#
while (my ($k,$v) = each(%$db_to_store)) {
$db{$k}=$v;
}
#
untie(%db);
return undef;
}
sub test_hash {
my ($db_filename,$my_db) = @_;
#
my %db;
if (! tie(%db,'GDBM_File',$db_filename,&GDBM_READER(),0640)) {
return "Unable to tie to $db_filename";;
}
my (%key_errors,%value_errors);
while (my ($k,$v) = each(%db)) {
if (exists($my_db->{$k})) {
if ($my_db->{$k} eq $v) {
delete($my_db->{$k});
} else {
$value_errors{$k}=$v;
}
} else {
$key_errors{$k}=$v;
}
}
untie(%db);
#
my $error;
my $extra_count = scalar(keys(%$my_db));
if ($extra_count) {
$error.=$extra_count.' extra key/value pairs found: '.$/;
while (my ($k,$v) = each(%$my_db)) {
$error .= ' "'.$k.'" => "'.$v.'"'.$/;
}
}
my $key_count = scalar(keys(%key_errors));
if ($key_count) {
$error.=$key_count.' missing keys found: '.$/;
while (my ($k,$v) = each(%key_errors)) {
$error .= ' "'.$k.'" => "'.$v.'"'.$/;
}
}
my $value_count = scalar(keys(%value_errors));
if ($value_count) {
$error.=$value_count.' missing values found: '.$/;
while (my ($k,$v) = each(%value_errors)) {
$error .= ' "'.$k.'" => "'.$v.'"'.$/;
}
}
#
return $error;
}