package Util::ShortTermRepository;
##############################################################################
#
# DESCRIPTION:
#
# HISTORY
# HISTORY: $Log: ShortTermRepository.pm,v $
# HISTORY: Revision 1.7 2014/02/27 07:01:07 apsop
# HISTORY: VERSION header now shows CVS Revision
# HISTORY:
# HISTORY: Revision 1.6 2007/11/30 16:34:22 apsop
# HISTORY: Check for existence of fetched repository file before using it.
# HISTORY:
# HISTORY: Revision 1.5 2007/06/29 15:25:21 apsop
# HISTORY: Set SEARCH_RANGE to 2. Only wait if checksum is wrong, not if no file is found.
# HISTORY:
# HISTORY: Revision 1.4 2006/12/20 14:20:19 apsop
# HISTORY: Bug fix the previous changes.
# HISTORY:
# HISTORY: Revision 1.3 2006/12/19 15:23:37 apsop
# HISTORY: Use time indexed directories for storing repository files.
# HISTORY:
# HISTORY: Revision 1.2 2006/08/01 20:35:34 apsop
# HISTORY: Add in CVS history indicator.
# HISTORY:
# HISTORY:
#
# VERSION: $Revision: 1.7 $
#
##############################################################################
use strict;
#########################
# constructor
#########################
sub new { #(directory)
my $proto = shift;
my $class = ref($proto) || $proto;
#####################################
# initialize some variables
#####################################
my $self={};
$self->{DIR}=shift;
$self->{FILENAME}=shift;
$self->{FILES}={};
$self->{WAIT}=60;
$self->{SEARCH_RANGE}=2;
$self->{MAX_COUNT}=5;
bless($self,$class);
return $self;
} # end of constructor
#########################
# accessors
#########################
##############################################################################
#
##############################################################################
sub log {
my $self = shift;
return $self->{FILENAME}->log();
}
#########################
# methods
#########################
##############################################################################
#
##############################################################################
sub export {
my $self = shift;
my $type = shift;
my $log = $self->log();
my @files = @_;
unless(@files) {
#########################################
# export all the files of the given type
#########################################
@files = $self->{FILENAME}->any($type);
}
########################################
# copy all the files to the repository
########################################
my $file;
foreach $file (@files) {
$file =~ /_(\d+)\./;
my $index = int($1/1000000)*1000000;
my $dir = "$self->{DIR}/$type/$index";
mkdir $dir;
my $checksum = "$dir/.$file.sha1";
unlink $checksum;
system("sha1sum $file > $checksum");
system("cp $file $dir");
}
} # end of export method
##############################################################################
#
##############################################################################
sub fetch {
my $self = shift;
my $type = shift;
my @args = @_;
my $log = $self->log();
my $filename = $self->{FILENAME};
my $dir;
my $file;
my $okaysum = 0;
my $count = 0;
until($okaysum){
##############################################
# locate the file in the repository directory
##############################################
my $subdir = int($args[2]/1000000)*1000000;
for(my $idir = 0; $idir < $self->{SEARCH_RANGE}; $idir++){
$dir = "$self->{DIR}/$type/" . ($subdir - 1000000*$idir);
$filename->glob_dir($dir);
$file = $filename->get($type, @args);
################################################################
# if we located the file, copy it into the working directory
################################################################
if($file && $self->{FILENAME}->fetch($file, $dir) && -f $file) {
my $checksum = "$dir/.$file.sha1";
if( -f $checksum){
open SUM, $checksum;
my $sum = (split ' ', <SUM>)[0];
close SUM;
open SUM, "sha1sum $file |";
my $check = (split ' ', <SUM>)[0];
close SUM;
$okaysum = 1 if $sum eq $check;
last;
}
}
}
if($okaysum){
###########################################################
# we got a file, so remember its name for cataloging later
###########################################################
$self->remember($type, $file);
}elsif(!$file){
######################
# no file, so give up
######################
return $file;
}else{
######################################################
# Got a file, but bad checksum, so wait and try again
######################################################
unlink $file;
unless($count){
$log->entry("Waiting for repository while fetching $file.");
}
last if $count++ > $self->{MAX_COUNT};
sleep $self->{WAIT};
}
}
unless($okaysum){
$log->error(1, "Repository timeout while file fetching $file.");
}
return $file;
} # end of fetch method
##############################################################################
# store a file name and type internally so that it can be included in a catalog
# of all fetched files later.
##############################################################################
sub remember {
my $self = shift;
my $type = shift;
my $file = shift;
unless($self->{FILES}->{$type}) {
$self->{FILES}->{$type} = {};
}
$self->{FILES}->{$type}->{$file} =1;
} # end of remember method
1;