Imported Upstream version 3.1.0
[debian/amanda] / perl / Amanda / Tapelist.pm
index 40991d0f43dc647e427b5520269aa93382aa184e..b2792b4574befc902276213e1c0e26d333e74ff8 100644 (file)
@@ -49,6 +49,8 @@ sub this {
 
 package Amanda::Tapelist;
 
+*get_last_reusable_tape_label = *Amanda::Tapelistc::get_last_reusable_tape_label;
+*list_new_tapes = *Amanda::Tapelistc::list_new_tapes;
 *C_read_tapelist = *Amanda::Tapelistc::C_read_tapelist;
 *C_clear_tapelist = *Amanda::Tapelistc::C_clear_tapelist;
 
@@ -60,7 +62,6 @@ package Amanda::Tapelist;
 @EXPORT_OK = ();
 %EXPORT_TAGS = ();
 
-use Amanda::Debug qw(:logging);
 
 =head1 NAME
 
@@ -75,32 +76,38 @@ Amanda::Tapelist - manipulate the Amanda tapelist
     $tl->add_tapelabel($datestamp2, $label2, $comment);
     $tl->write("/path/to/tapefile");
 
-=head1 API STATUS
-
-Stable
-
 =head1 OBJECT-ORIENTED INTERFACE
 
-The package-level functions C<read_tapelist($filename)> and C<clear_tapelist()>
-both return a new tapelist object.  C<read_tapelist> returns C<undef> if the
-tapelist does not exist.  Invalid entries are silently ignored.
+The package-level functions C<read_tapelist($filename)> and
+C<clear_tapelist()> both return a new tapelist object.
+C<read_tapelist> returns C<undef> if the tapelist does not exist.
+Invalid entries are silently ignored.
 
-A tapelist object is a sequence of tapelist
-elements (referred to as TLEs in this document).  Each TLE is a hash with the
-following keys:
+A tapelist object is a sequence of tapelist elements (referred to as TLEs in
+this document), sorted by datestamp from newest to oldest.  Each TLE is a hash
+with the following keys:
 
 =over
 
-=item C<position> -- the one-based position of the TLE in the tapelist
+=item C<position>
+
+the one-based position of the TLE in the tapelist
+
+=item C<datestamp>
+
+the datestamp on which this was written, or "0" for an unused tape
 
-=item C<datestamp> -- the datestamp on which this was written, or "0" for an
-unused tape
+=item C<reuse>
 
-=item C<reuse> -- true if this tape can be reused when it is no longer active
+true if this tape can be reused when it is no longer active
 
-=item C<label> -- tape label
+=item C<label>
 
-=item C<comment> -- the comment for this tape, or undef if no comment was given
+tape label
+
+=item C<comment>
+
+the comment for this tape, or undef if no comment was given
 
 =back
 
@@ -108,35 +115,49 @@ The following methods are available on a tapelist object C<$tl>:
 
 =over
 
-=item C<lookup_tapelabel($lbl)> -- look up and return a reference to the TLE
-with the given label
+=item C<lookup_tapelabel($lbl)>
+
+look up and return a reference to the TLE with the given label
+
+=item C<lookup_tapepos($pos)>
+
+look up and return a reference to the TLE in the given position
 
-=item C<lookup_tapepos($pos)> -- look up and return a reference to the TLE in
-the given position
+=item C<lookup_tapedate($date)>
 
-=item C<lookup_tapedate($date)> -- look up and return a reference to the TLE
-with the given datestamp
+look up and return a reference to the TLE with the given datestamp
 
-=item C<remove_tapelabel($lbl)> -- remove the tape with the given label
+=item C<remove_tapelabel($lbl)>
 
-=item C<add_tapelabel($date, $lbl, $comment)> -- add a tape with the given date,
-label, and comment to the end of the tapelist, marking it reusable.
+remove the tape with the given label
 
-=item C<write($filename)> -- write the tapelist out to C<$filename>.
+=item C<add_tapelabel($date, $lbl, $comment)>
+
+add a tape with the given date, label, and comment to the end of the
+tapelist, marking it reusable.
+
+=item C<write($filename)>
+
+write the tapelist out to C<$filename>.
 
 =back
 
 =head1 INTERACTION WITH C CODE
 
-The C portions of Amanda treat the tapelist as a global variable, while this
-package treats it as an object (and can thus handle more than one tapelist
-simultaneously).  Every call to C<read_tapelist> fills this global variable
-with a copy of the tapelist, and likewise C<clear_tapelist> clears the global.
-However, any changes made from Perl are not reflected in the C copy, nor are
-changes made by C modules reflected in the Perl copy.
+The C portions of Amanda treat the tapelist as a global variable,
+while this package treats it as an object (and can thus handle more
+than one tapelist simultaneously).  Every call to C<read_tapelist>
+fills this global variable with a copy of the tapelist, and likewise
+C<clear_tapelist> clears the global.  However, any changes made from
+Perl are not reflected in the C copy, nor are changes made by C
+modules reflected in the Perl copy.
 
 =cut
 
+
+
+use Amanda::Debug qw(:logging);
+
 ## package functions
 
 sub read_tapelist {
@@ -161,8 +182,18 @@ sub read_tapelist {
     }
     close($fh);
 
+    # sort in descending order by datestamp, sorting on position, too, to ensure
+    # that entries with the same datestamp stay in the right order
+    update_positions(\@tles); # call a method with an explicit $self
+    @tles = sort {
+          $b->{'datestamp'} cmp $a->{'datestamp'}
+       || $a->{'position'} <=> $b->{'position'}
+       } @tles;
+
+    # and re-calculate the positions
+    update_positions(\@tles);
+
     my $self = bless \@tles, "Amanda::Tapelist";
-    $self->update_positions();
 
     return $self;
 }
@@ -227,7 +258,8 @@ sub add_tapelabel {
     my $self = shift;
     my ($datestamp, $label, $comment) = @_;
 
-    push @$self, { 
+    # prepend this (presumably new) volume to the beginning of the list
+    unshift @$self, {
        'datestamp' => $datestamp,
        'label' => $label,
        'reuse' => 1,
@@ -254,11 +286,6 @@ sub write {
     C_read_tapelist($filename);
 }
 
-## TODO -- implement this when it's needed
-# =item C<lookup_last_reusable_tape($skip)> -- find the (C<$skip>+1)-th least recent
-# reusable tape.  For example, C<last_reusable_tape(1)> would return the
-# second-oldest reusable tape.
-
 ## private methods
 
 # update the 'position' key for each TLE