simplify (not to say refactor ;-) code. Also, make it actually work.
authordpavlin <dpavlin@8392b6e1-25fa-0310-8288-cc32f8e212ea>
Thu, 1 Sep 2005 20:24:13 +0000 (20:24 +0000)
committerdpavlin <dpavlin@8392b6e1-25fa-0310-8288-cc32f8e212ea>
Thu, 1 Sep 2005 20:24:13 +0000 (20:24 +0000)
Now it doesn't require files or dirs as last parametar (because we know
that we want all files in that backup).
So, run this script, pipe it to gzip (or bzip2) and you have compressed
archive of one increment.

git-svn-id: svn+ssh://llin/home/dpavlin/private/svn/BackupPC/trunk@112 8392b6e1-25fa-0310-8288-cc32f8e212ea

bin/BackupPC_tarIncCreate

index 408cf59..1a53dc6 100755 (executable)
@@ -6,7 +6,7 @@
 #
 # DESCRIPTION
 #  
-#   Usage: BackupPC_tarIncCreate [options] files/directories...
+#   Usage: BackupPC_tarIncCreate [options]
 #
 #   Flags:
 #     Required options:
@@ -31,6 +31,8 @@
 #
 # AUTHOR
 #   Craig Barratt  <cbarratt@users.sourceforge.net>
+#   Ivan Klaric <iklaric@gmail.com>
+#   Dobrica Pavlinusic <dpavlin@rot13.org>
 #
 # COPYRIGHT
 #   Copyright (C) 2001-2003  Craig Barratt
@@ -68,19 +70,21 @@ use BackupPC::Attrib qw(:all);
 use BackupPC::FileZIO;
 use BackupPC::View;
 use BackupPC::SearchLib;
-use Data::Dumper;
+use Time::HiRes qw/time/;
+use POSIX qw/strftime/;
+use Data::Dumper;      ### FIXME
 
 die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
 my $TopDir = $bpc->TopDir();
 my $BinDir = $bpc->BinDir();
 my %Conf   = $bpc->Conf();
-my @DBCache;
-my $db_done = 0;
 my %opts;
+my $in_backup_increment;
 
-if ( !getopts("th:n:p:r:s:b:w:", \%opts) || @ARGV < 1 ) {
+
+if ( !getopts("th:n:p:r:s:b:w:", \%opts) ) {
     print STDERR <<EOF;
-usage: $0 [options] files/directories...
+usage: $0 [options]
   Required options:
      -h host         host from which the tar archive is created
      -n dumpNum      dump number from which the tar archive is created
@@ -160,23 +164,12 @@ my(%HardLinkExtraFiles, @HardLinks);
 #
 binmode(STDOUT);
 my $fh = *STDOUT;
-if ( $ShareName eq "*" ) {
-    my $PathRemoveOrig = $PathRemove;
-    my $PathAddOrig    = $PathAdd;
-    foreach $ShareName ( $view->shareList($Num) ) {
-        #print(STDERR "Doing share ($ShareName)\n");
-        $PathRemove = "/" if ( !defined($PathRemoveOrig) );
-        ($PathAdd = "/$ShareName/$PathAddOrig") =~ s{//+}{/}g;
-        foreach my $dir ( @ARGV ) {
-            archiveWrite($fh, $dir);
-        }
-        archiveWriteHardLinks($fh);
-    }
+
+if (seedCache($Host, $ShareName, $Num)) {
+       archiveWrite($fh, '/');
+       archiveWriteHardLinks($fh);
 } else {
-    foreach my $dir ( @ARGV ) {
-        archiveWrite($fh, $dir);
-    }
-    archiveWriteHardLinks($fh);
+       print STDERR "NOTE: no files found for $Host:$ShareName, increment $Num\n";
 }
 
 #
@@ -390,80 +383,37 @@ sub TarWriteFileInfo
 }
 
 #
-# returns 1 if a given directory has files somewhere under it 
-# in a given dump of a given share
+# seed cache of files in this increment
 #
-sub checkSubDirs($$$$) {
-       my ($dir, $share, $host, $dumpNo) = @_;
-       my $ret;
+sub seedCache($$$) {
+       my ($host, $share, $dumpNo) = @_;
+
        my $dsn = $Conf{SearchDSN};
        my $db_user = $Conf{SearchUser} || '';
-       my $search_sql;
        
-       print(STDERR $dir);
-       # erase first dot
-       if (substr($dir, 0, 1) == '.')
-       {
-               $dir = substr($dir, 1, length($dir));
-       }
-       # erase first slash
-       if (substr($dir, 0, 1) == '/') 
-       {
-               $dir = substr($dir, 1, length($dir));           
-       }
-       # erase last slash
-       if (substr($dir, length($dir)-1, 1) == '/')
-       {
-               $dir = substr($dir, 0, length($dir)-1);
-       }
-
-       if (! $db_done)
-       {
-               print STDERR "doing db...";
-               my $search_sql = q{
-                               SELECT hosts.name, shares.name, startfiles.name, COUNT(files.*) AS subfiles
-                               FROM files startfiles 
-                                        INNER JOIN shares ON (shares.id=startfiles.shareid) 
-                                        INNER JOIN hosts ON  (hosts.id=shares.hostid) 
-                                        INNER JOIN backups ON (
-                                               backups.num=startfiles.backupnum AND 
-                                               backups.hostid=hosts.id AND backups.shareid=shares.id
-                                        )
-                                        LEFT JOIN files ON  (
-                                               files.backupnum=startfiles.backupnum AND
-                                               files.shareid=startfiles.shareid AND
-                                               files.path LIKE startfiles.path || '/%' AND              
-                                               files.type<>startfiles.type AND                 
-                                               files.id <> startfiles.id
-                                       )               
-                               WHERE                           
-                                       hosts.name=? AND                
-                                       shares.name=? AND           
-                                       startfiles.type=? AND           
-                                       startfiles.backupnum=?
-                               GROUP BY hosts.name, shares.name, startfiles.name, startfiles.backupnum;
-                       };      
-               my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1} );       
-               my $sth = $dbh->prepare($search_sql);   
-               $sth->execute($host, $share, BPC_FTYPE_DIR, $dumpNo);
-               print STDERR "done\n";
-               while (my @r_data = $sth->fetchrow_array())
-               {
-                       $DBCache[$r_data[0]][$r_data[1]][$r_data[2]] = 1;
-               }
-               
-               $sth->finish();
-
-               $DBCache[$host][$share][$dir] = $ret;           
-               $dbh->disconnect();     
-               $db_done = 1;
+       print STDERR curr_time(), "getting files for $host:$share increment $dumpNo...";
+       my $sql = q{
+               SELECT path
+               FROM files
+                       JOIN shares on shares.id = shareid
+                       JOIN hosts on hosts.id = shares.hostid
+               WHERE hosts.name = ? and shares.name = ? and backupnum = ?
+       };
+
+       my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1} );       
+       my $sth = $dbh->prepare($sql);  
+       $sth->execute($host, $share, $dumpNo);
+       my $count = $sth->rows;
+       print STDERR " found $count items\n";
+       while (my $row = $sth->fetchrow_arrayref) {
+print STDERR "+ ", $row->[0],"\n";
+               $in_backup_increment->{ $row->[0] }++;
        }
+       
+       $sth->finish();
+       $dbh->disconnect();
 
-       if ($DBCache[$host][$share][$dir] != undef && $DBCache[$host][$share][$dir] == 1)
-       {
-               return 1;
-       }
-       return 0;
+       return $count;
 }
 
 my $Attr;
@@ -473,11 +423,15 @@ sub TarWriteFile
 {
     my($hdr, $fh, $tarPathOverride) = @_;
 
-
     my $tarPath = $hdr->{relPath};
     $tarPath = $tarPathOverride if ( defined($tarPathOverride) );
 
     $tarPath =~ s{//+}{/}g;
+
+#print STDERR "? $tarPath\n";
+    return unless ($in_backup_increment->{$tarPath});
+print STDERR "A $tarPath\n";
+
     if ( defined($PathRemove)
             && substr($tarPath, 0, length($PathRemove)) eq $PathRemove ) {
         substr($tarPath, 0, length($PathRemove)) = $PathAdd;
@@ -493,12 +447,8 @@ sub TarWriteFile
         
                 
         $hdr->{name} .= "/" if ( $hdr->{name} !~ m{/$} );
-        # check if it has files under it in the database        
-               if ( checkSubDirs($hdr->{path}, $ShareName, $Host, $Num) != 0 )
-               {
-               TarWriteFileInfo($fh, $hdr);
-                       $DirCnt++;
-               }
+        TarWriteFileInfo($fh, $hdr);
+       $DirCnt++;
     } elsif ( $hdr->{type} == BPC_FTYPE_FILE ) {
         #
         # Regular file: write the header and file
@@ -538,23 +488,10 @@ sub TarWriteFile
             $hdr->{linkname} .= $data;
         }
                $f->close;
-               #
-               # Check @ARGV and the list of hardlinked files we have explicity
-               # dumped to see if we have dumped this file or not
-               #
                my $done = 0;
                my $name = $hdr->{linkname};
                $name =~ s{^\./}{/};
                if ( $HardLinkExtraFiles{$name} ) {
-                   $done = 1;
-               } else {
-                   foreach my $arg ( @ARGV ) {
-                       $arg =~ s{^\./+}{/};
-                       $arg =~ s{/+$}{};
-                       $done = 1 if ( $name eq $arg || $name =~ /^\Q$arg\// );
-                   }
-               }
-               if ( $done ) {
                    #
                    # Target file will be or was written, so just remember
                    # the hardlink so we can dump it later.
@@ -621,4 +558,8 @@ sub TarWriteFile
        $ErrorCnt++;
     }
 }
-       
+
+my $t_fmt = '%Y-%m-%d %H:%M:%S';
+sub curr_time {
+       return strftime($t_fmt,localtime());
+}