-# TODO : bsr must use only good backup or not (see use_ok_bkp_only)
-# This sub creates a BSR from the information in the restore_list
-# Returns the BSR as a string
-sub create_filelist
-{
- my $self = shift;
- my $dbh = $self->{dbh};
- my %mediainfos;
- # This query gets all jobid/jobmedia/media combination.
- my $query = "
-SELECT Job.JobId, Job.VolsessionId, Job.VolsessionTime, JobMedia.StartFile,
- JobMedia.EndFile, JobMedia.FirstIndex, JobMedia.LastIndex,
- JobMedia.StartBlock, JobMedia.EndBlock, JobMedia.VolIndex,
- Media.Volumename, Media.MediaType
-FROM Job, JobMedia, Media
-WHERE Job.JobId = JobMedia.JobId
- AND JobMedia.MediaId = Media.MediaId
- ORDER BY JobMedia.FirstIndex, JobMedia.LastIndex";
-
-
- my $result = $dbh->selectall_arrayref($query);
-
- # We will store everything hashed by jobid.
-
- foreach my $refrow (@$result)
- {
- my ($jobid, $volsessionid, $volsessiontime, $startfile, $endfile,
- $firstindex, $lastindex, $startblock, $endblock,
- $volindex, $volumename, $mediatype) = @{$refrow};
-
- # We just have to deal with the case where starfile != endfile
- # In this case, we concatenate both, for the bsr
- if ($startfile != $endfile) {
- $startfile = $startfile . '-' . $endfile;
- }
-
- my @tmparray =
- ($jobid, $volsessionid, $volsessiontime, $startfile,
- $firstindex, $lastindex, $startblock .'-'. $endblock,
- $volindex, $volumename, $mediatype);
-
- push @{$mediainfos{$refrow->[0]}},(\@tmparray);
- }
-
-
- # reminder : restore_list looks like this :
- # ($name,$jobid,'file',$curjobids, undef, undef, undef, $dirfileindex);
-
- # Here, we retrieve every file/dir that could be in the restore
- # We do as simple as possible for the SQL engine (no crazy joins,
- # no pseudo join (>= FirstIndex ...), etc ...
- # We do a SQL union of all the files/dirs specified in the restore_list
- my @select_queries;
- foreach my $entry (@{$self->{restore_list}->{data}})
- {
- if ($entry->[2] eq 'dir')
- {
- my $dir = unpack('u', $entry->[0]);
- my $inclause = $entry->[3]; #curjobids
-
- my $query =
-"(SELECT Path.Path, Filename.Name, File.FileIndex, File.JobId
- FROM File, Path, Filename
- WHERE Path.PathId = File.PathId
- AND File.FilenameId = Filename.FilenameId
- AND Path.Path LIKE '$dir%'
- AND File.JobId IN ($inclause) )";
- push @select_queries,($query);
- }
- else
- {
- # It's a file. Great, we allready have most
- # of what is needed. Simple and efficient query
- my $file = unpack('u', $entry->[0]);
- my @file = split '/',$file;
- $file = pop @file;
- my $dir = join('/',@file);
-
- my $jobid = $entry->[1];
- my $fileindex = $entry->[7];
- my $inclause = $entry->[3]; # curjobids
- my $query =
-"(SELECT Path.Path, Filename.Name, File.FileIndex, File.JobId
- FROM File, Path, Filename
- WHERE Path.PathId = File.PathId
- AND File.FilenameId = Filename.FilenameId
- AND Path.Path = '$dir/'
- AND Filename.Name = '$file'
- AND File.JobId = $jobid)";
- push @select_queries,($query);
- }
- }
- $query = join("\nUNION ALL\n",@select_queries) . "\nORDER BY FileIndex\n";
-
- print $query,"\n" if $debug;
-
- #Now we run the query and parse the result...
- # there may be a lot of records, so we better be efficient
- # We use the bind column method, working with references...
-
- my $sth = $dbh->prepare($query);
- $sth->execute;
-
- my ($path,$name,$fileindex,$jobid);
- $sth->bind_columns(\$path,\$name,\$fileindex,\$jobid);
-
- # The temp place we're going to save all file
- # list to before the real list
- my @temp_list;
-
- RECORD_LOOP:
- while ($sth->fetchrow_arrayref())
- {
- # This may look dumb, but we're going to do a join by ourselves,
- # to save memory and avoid sending a complex query to mysql
- my $complete_path = $path . $name;
- my $is_dir = 0;
-
- if ( $name eq '')
- {
- $is_dir = 1;
- }
-
- # Remove trailing slash (normalize file and dir name)
- $complete_path =~ s/\/$//;
-
- # Let's find the ref(s) for the %mediainfo element(s)
- # containing the data for this file
- # There can be several matches. It is the pseudo join.
- my $med_idx=0;
- my $max_elt=@{$mediainfos{$jobid}}-1;
- MEDIA_LOOP:
- while($med_idx <= $max_elt)
- {
- my $ref = $mediainfos{$jobid}->[$med_idx];
- # First, can we get rid of the first elements of the
- # array ? (if they don't contain valuable records
- # anymore
- if ($fileindex > $ref->[5])
- {
- # It seems we don't need anymore
- # this entry in %mediainfo (the input data
- # is sorted...)
- # We get rid of it.
- shift @{$mediainfos{$jobid}};
- $max_elt--;
- next MEDIA_LOOP;
- }
- # We will do work on this elt. We can ++
- # $med_idx for next loop
- $med_idx++;