/[BackupPC]/trunk/bin/BackupPC_updatedb
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/bin/BackupPC_updatedb

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 8 by dpavlin, Thu Jun 23 12:22:21 2005 UTC revision 35 by dpavlin, Sun Jul 31 21:03:36 2005 UTC
# Line 1  Line 1 
1  #!/usr/local/bin/perl  #!/usr/local/bin/perl -w
 $| = 1;  
2    
3  use strict;  use strict;
4  use DBI;  use DBI;
# Line 10  use Data::Dumper; Line 9  use Data::Dumper;
9  use Getopt::Std;  use Getopt::Std;
10  use constant BPC_FTYPE_DIR => 5;  use constant BPC_FTYPE_DIR => 5;
11    
12    my $debug = 0;
13    $|=1;
14    
15  my $hosts;  my $hosts;
16  my $bpc = BackupPC::Lib->new || die;  my $bpc = BackupPC::Lib->new || die;
17  my %Conf = $bpc->Conf();  my %Conf = $bpc->Conf();
18  my $TopDir = $bpc->TopDir();  my $TopDir = $bpc->TopDir();
19  my @beenThere = ();  my $beenThere = {};
20    
21  my $dbh = DBI->connect("dbi:SQLite:dbname=$TopDir/$Conf{SearchDB}", "", "", { RaiseError => 1, AutoCommit => 0 });  my $dsn = "dbi:SQLite:dbname=$TopDir/$Conf{SearchDB}";
22    
23    my $dbh = DBI->connect($dsn, "", "", { RaiseError => 1, AutoCommit => 0 });
24    
25  my %opt;  my %opt;
26    
27  if ( !getopts("cdu", \%opt ) ) {  if ( !getopts("cdm:v", \%opt ) ) {
28          print STDERR <<EOF;          print STDERR <<EOF;
29  usage: $0 (-c|-df|-u)  usage: $0 [-c|-d] [-m num]
30    
31  Options:  Options:
32          -c      Create database on first use          -c      create database on first use
33          -d      Delete database before import          -d      delete database before import
34          -u      Update database (import new revisions)          -m num  import just num increments for one host
35  EOF  EOF
36          exit 1;          exit 1;
37  }  }
38    
39  ###################################create tables############################3  ###################################create tables############################3
40    
41  if ($opt{c})  if ($opt{c}) {
42      {          print "creating tables...\n";
       print "creating database...";  
43                
44        $dbh->do(          $dbh->do(qq{
45            q{                  create table hosts (
46                create table hosts                          ID      INTEGER         PRIMARY KEY,
47                  (   ID             INTEGER              PRIMARY KEY,                          name    VARCHAR(30)     NOT NULL,
48                      name             VARCHAR(30)        NOT NULL,                          IP      VARCHAR(15)
                     IP       VARCHAR(20)        NOT NULL  
49                  );                              );            
50            }          });
       );  
51                                
52        $dbh->do(          $dbh->do(qq{
53            q{                  create table shares (
54                create table shares                          ID      INTEGER         PRIMARY KEY,
55                  (   ID             INTEGER           PRIMARY KEY,                          hostID  INTEGER         NOT NULL references hosts(id),
56                      hostID         INTEGER           NOT NULL,                          name    VARCHAR(30)     NOT NULL,
57                      name           VARCHAR(30)       NOT NULL,                          share   VARCHAR(200)    NOT NULL,
58                      share          VARCHAR(200)      NOT NULL,                          localpath VARCHAR(200)      
                     localpath      VARCHAR(200)        
59                  );                              );            
60            }          });
       );  
61                    
62        $dbh->do(          $dbh->do(qq{
63            q{                  create table backups (
64                create table backups                          hostID  INTEGER         NOT NULL references hosts(id),
65                  ( hostID     INTEGER            NOT NULL,                          num     INTEGER         NOT NULL,
66                      num      INTEGER            NOT NULL,                          date    DATE,
67                      date             DATE,                          type    CHAR(1),
68                      type             CHAR(1),                          PRIMARY KEY(hostID, num)
                     PRIMARY KEY(hostID, num)  
69                  );                              );            
70            }          });
       );  
71    
72        $dbh->do(          $dbh->do(qq{
73            q{                  create table dvds (
74                create table dvds                          ID      INTEGER         PRIMARY KEY,
75                  ( ID         INTEGER            PRIMARY KEY,                          num     INTEGER         NOT NULL,
76                      num      INTEGER            NOT NULL,                          name    VARCHAR(255)    NOT NULL,
77                      name             VARCHAR(255)       NOT NULL,                          mjesto  VARCHAR(255)
                     mjesto     VARCHAR(255)  
78                  );                  );
79            }          });
       );  
80    
81        $dbh->do(          $dbh->do(qq{    
82            q{                      create table files (
83                create table files                          ID      INTEGER         NOT NULL PRIMARY KEY,  
84                  (   ID         INTEGER          NOT NULL PRIMARY KEY,                            shareID INTEGER         NOT NULL references shares(id),
85                      shareID    INTEGER          NOT NULL,                          backupNum  INTEGER      NOT NULL references backups(num),
86                      backupNum  INTEGER          NOT NULL,                          name       VARCHAR(255) NOT NULL,
87                      name       VARCHAR(255)     NOT NULL,                          path       VARCHAR(255) NOT NULL,
88                      path       VARCHAR(255)     NOT NULL,                          fullpath   VARCHAR(255) NOT NULL,
89                      fullpath   VARCHAR(255)     NOT NULL,                          date       TIMESTAMP    NOT NULL,
90                      date       TIMESTAMP        NOT NULL,                          type       INTEGER      NOT NULL,
91                      type       INTEGER          NOT NULL,                          size       INTEGER      NOT NULL,
92                      size       INTEGER          NOT NULL,                          dvdid      INTEGER      references dvds(id)    
                     dvdid      INTEGER            
93                  );                  );
94            }          });
95        );  
96        print "done\n";          print "creating indexes...\n";
97    }  
98            foreach my $index (qw(
99  if ($opt{d})                  hosts_name
100    {                  backups_hostID
101        print("deleting db first...\n");                  backups_num
102                          shares_hostID
103        $dbh->do(                  shares_name
104            q{ DELETE FROM hosts; }                  files_shareID
105            );                  files_path
106        $dbh->do(                  files_name
107            q{ DELETE FROM shares; }                  files_date
108            );                  files_size
109        $dbh->do(          )) {
110            q{ DELETE FROM files;}                  my ($table,$col) = split(/_/, $index);
111            );                  $dbh->do(qq{ create index $index on $table($col) });
112        $dbh->do(          }
113            q{ DELETE FROM dvds;}  
114            );  
115        $dbh->do(  }
116            q{ DELETE FROM backups; }  
117            );  if ($opt{d}) {
118    }          print "deleting ";
119            foreach my $table (qw(hosts shares files dvds backups)) {
120                    print "$table ";
121                    $dbh->do(qq{ DELETE FROM $table });
122            }
123            print " done...\n";
124    }
125    
126    if ($opt{v}) {
127            print "Debug level at $opt{v}\n";
128            $debug = $opt{v};
129    }
130    
131  #################################INSERT VALUES#############################  #################################INSERT VALUES#############################
132    
133  # get hosts  # get hosts
134  $hosts = $bpc->HostInfoRead();  $hosts = $bpc->HostInfoRead();
 print Dumper($hosts);  
135  my $hostID;  my $hostID;
136  my $shareID;  my $shareID;
137  foreach my $host_key (keys %{$hosts})  
138  {  my $sth;
139    my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";  
140    my $backups;  $sth->{insert_hosts} = $dbh->prepare(qq{
141    my $sql;  INSERT INTO hosts (name, IP) VALUES (?,?)
142    });
143    $sql = q{ SELECT ID FROM hosts WHERE name=? };  
144    my $st = $dbh->prepare($sql);  $sth->{hosts_by_name} = $dbh->prepare(qq{
145    $st->bind_param(1,$hosts->{$host_key}->{'host'});  SELECT ID FROM hosts WHERE name=?
146    $st->execute();  });
147    if (my $tmp = $st->fetchrow_hashref())  
148        {  $sth->{backups_broj} = $dbh->prepare(qq{
149            $hostID = $tmp->{'ID'};  SELECT COUNT(*)
150        }  FROM backups
151      else  WHERE hostID=? AND num=?
152        {  });
153            $sql = q{ INSERT INTO hosts ( ID, name, IP) VALUES (NULL,"}.  
154                      $hosts->{$host_key}->{'host'}."\", \"".  $sth->{insert_backups} = $dbh->prepare(qq{
155                     $hosts->{$host_key}->{'ip'}."\");";  INSERT INTO backups (hostID, num, date, type)
156    VALUES (?,?,?,?)
157            $dbh->do($sql);  });
158            $hostID = $dbh->func('last_insert_rowid');  
159    $sth->{insert_files} = $dbh->prepare(qq{
160        }  INSERT INTO files
161    $st->finish();          (shareID, backupNum, name, path, fullpath, date, type, size)
162    print("processing host ".$hosts->{$host_key}->{'host'}.":\n");          VALUES (?,?,?,?,?,?,?,?)
163    });
164    
165    foreach my $host_key (keys %{$hosts}) {
166    
167            my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";
168    
169            $sth->{hosts_by_name}->execute($hosts->{$host_key}->{'host'});
170    
171            unless (($hostID) = $sth->{hosts_by_name}->fetchrow_array()) {
172                    $sth->{insert_hosts}->execute(
173                            $hosts->{$host_key}->{'host'},
174                            $hosts->{$host_key}->{'ip'}
175                    );
176    
177                    $hostID = $dbh->func('last_insert_rowid');
178            }
179    
180            print("host ".$hosts->{$host_key}->{'host'}.": ");
181    
182    # get backups for a host          # get backups for a host
183    my @backups = $bpc->BackupInfoRead($hostname);          my @backups = $bpc->BackupInfoRead($hostname);
184    foreach my $backup (@backups)          print scalar @backups, " increments\n";
185    {  
186      my $backupNum = $backup->{'num'};          my $inc_nr = 0;
187      my @backupShares = ();  
188            foreach my $backup (@backups) {
189                    $inc_nr++;
190                    last if ($opt{m} && $inc_nr > $opt{m});
191    
192                    my $backupNum = $backup->{'num'};
193                    my @backupShares = ();
194    
195                    print $hosts->{$host_key}->{'host'},"\t#$backupNum\n";
196    
197                    $sth->{backups_broj}->execute($hostID, $backupNum);
198                    my ($broj) = $sth->{backups_broj}->fetchrow_array();
199                    next if ($broj > 0);
200    
201                    my $files = BackupPC::View->new($bpc, $hostname, \@backups, 1);
202                    foreach my $share ($files->shareList($backupNum)) {
203    
204                            print "\t$share";
205                            $shareID = getShareID($share, $hostID, $hostname);
206                    
207                            my ($f, $nf, $d, $nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);
208                            print " $nf/$f files $nd/$d dirs\n";
209                            $dbh->commit();
210                    }
211    
212                    $sth->{insert_backups}->execute(
213                            $hostID,
214                            $backupNum,
215                            $backup->{'endTime'},
216                            $backup->{'type'}
217                    );
218                    $dbh->commit();
219    
         
     if ($opt{u})  
         {  
             my $sql = q{  
                   SELECT COUNT(*) AS broj  
                   FROM backups  
                   WHERE hostID=? AND  
                         num=?  
                 };  
               
             my $st  = $dbh->prepare($sql);  
             $st->bind_param(1,$hostID);  
             $st->bind_param(2,$backupNum);  
             $st->execute();  
             my $tmp = $st->fetchrow_hashref();  
             $st->finish();  
             if ($tmp->{'broj'} > 0)  
               {  
                   next;  
               }  
220          }          }
         
     print "\tprocessing backup no. $backupNum...";  
     my $sql =      
         q{  
             INSERT INTO backups (hostID, num, date, type)  
               VALUES  
               (}.$hostID.",". $backupNum.q{, }.$backup->{'endTime'}.",\"". $backup->{'type'}.q{");  
          };  
     $dbh->do($sql);  
   
     my $files = BackupPC::View->new($bpc, $hostname, \@backups);  
     @backupShares = $files->shareList($backupNum);  
     foreach my $share (@backupShares)  
     {        
       my @flattenedFiles = ();  
       clearBeenThereCache();  
       print "\n\t\tprocessing share ".$share."...";  
       $shareID = getShareID($share, $hostID, $hostname);  
           
       @flattenedFiles = recurseDir($bpc, $hostname, \@backups, $backupNum, $share, "");  
       print "done\n";  
       print "\t\tinserting data into db...";  
       foreach my $file (@flattenedFiles)  
           {  
               $dbh->do("INSERT INTO files(ID, shareID, backupNum, name, path, fullpath, date, type, size) VALUES "  
                   ."( NULL, $shareID, "  
                   .$backupNum.", \""  
                   .$file->{'fileName'}."\", \""  
                   .$file->{'relPath'}. "\", \""  
                   .$file->{'fullPath'}."\", "  
                   .$file->{'mtime'}.", "  
                   .$file->{'type'}.", "  
                   .$file->{'size'}.")"  
                   );  
           }  
       print "done\n";  
     }  
   }  
   print "done.\n";  
221  }  }
222    undef $sth;
223  $dbh->commit();  $dbh->commit();
224  $dbh->disconnect();  $dbh->disconnect();
225    
226    sub getShareID() {
227    
228  sub haveBeenThere          my ($share, $hostID, $hostname) = @_;
229  {  
230    my ($where) = @_;          $sth->{share_id} ||= $dbh->prepare(qq{
231                      SELECT ID FROM shares WHERE hostID=? AND name=?
232    foreach my $st (@beenThere)          });
233    {  
234      if ($where eq $st)          $sth->{share_id}->execute($hostID,$share);
235      {  
236        return 1;          my ($id) = $sth->{share_id}->fetchrow_array();
     }  
   }  
     
   push(@beenThere, $where);  
   return 0;  
 }  
237    
238  sub clearBeenThereCache          return $id if (defined($id));
239  {  
240    @beenThere = ();          $sth->{insert_share} ||= $dbh->prepare(qq{
241                    INSERT INTO shares
242                            (hostID,name,share,localpath)
243                    VALUES (?,?,?,?)
244            });
245    
246            my $drop_down = $hostname . '/' . $share;
247            $drop_down =~ s#//+#/#g;
248    
249            $sth->{insert_share}->execute($hostID,$share, $drop_down ,undef);
250            return $dbh->func('last_insert_rowid');        
251  }  }
252    
253  sub getShareID()  sub found_in_db {
254    {  
255        my ($share, $hostID, $hostname) = @_;          my ($shareID,undef,$name,$path,undef,$date,undef,$size) = @_;
256        my $tmp;  
257                  $sth->{file_in_db} ||= $dbh->prepare(qq{
258        my $st = $dbh -> prepare(" SELECT shares.ID AS ID FROM shares WHERE hostID=? AND name=?");                  SELECT count(*) FROM files
259        $st -> execute($hostID,$share);                  WHERE shareID = ? and
260        my $tmp = $st->fetchrow_hashref();                          path = ? and
261        $st->finish();                          name = ? and
262        if ($tmp)                          date = ? and
263          {                          size = ?
264              return $tmp->{'ID'};          });
265          }  
266        my $sql =          my @param = ($shareID,$path,$name,$date,$size);
267            q{          $sth->{file_in_db}->execute(@param);
268                INSERT INTO shares(ID,hostID,name,share,localpath)          my ($rows) = $sth->{file_in_db}->fetchrow_array();
269                  VALUES    #       print STDERR ( $rows ? '+' : '-' ), join(" ",@param), "\n";
270                 (NULL,}.                            return $rows;
271                "$hostID,\"$share\",\"//$hostname$share\",NULL);";                }
       $dbh->do($sql);  
       return $dbh->func('last_insert_rowid');            
   }  
272    
273  ####################################################  ####################################################
274  # recursing through filesystem structure and       #  # recursing through filesystem structure and       #
275  # and returning flattened files list               #  # and returning flattened files list               #
276  ####################################################  ####################################################
277  sub recurseDir  sub recurseDir($$$$$$$$) {
 {  
   my ($bpc, $hostname, $backups, $backupNo, $share, $dir) = @_;  
   my @ret = ();  
   my $files = BackupPC::View->new($bpc, $hostname, $backups);              
   my $filesInBackup = $files->dirAttrib($backupNo, $share, $dir);  
   my $file_key = "";  
278    
279            my ($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID) = @_;
280    # first, add all the entries in current directory  
281    foreach $file_key (keys %{$filesInBackup})          print STDERR "recurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
282    {  
283      push(@ret, {          my ($nr_files, $new_files, $nr_dirs, $new_dirs) = (0,0,0,0);
284                   'fileName' => $file_key,  
285                   'relPath'  => $filesInBackup->{$file_key}->{'relPath'},          { # scope
286                   'fullPath' => $filesInBackup->{$file_key}->{'fullPath'},                  my @stack;
287                   'sharePath'=> $filesInBackup->{$file_key}->{'sharePathM'},  
288                   'size'     => $filesInBackup->{$file_key}->{'size'},                  my $filesInBackup = $files->dirAttrib($backupNum, $share, $dir);
289                   'mtime'    => $filesInBackup->{$file_key}->{'mtime'},  
290                   'type'     => $filesInBackup->{$file_key}->{'type'}                  # first, add all the entries in current directory
291                 });                    foreach my $path_key (keys %{$filesInBackup}) {
292    }                          my @data = (
293                                        $shareID,
294    # then, recurse thru subfolders                                  $backupNum,
295    foreach my $fold (@ret)                                  $path_key,
296    {                                  $filesInBackup->{$path_key}->{'relPath'},
297     if ($fold->{'type'} == BPC_FTYPE_DIR &&                                  $filesInBackup->{$path_key}->{'fullPath'},
298         haveBeenThere($fold->{'relPath'}) != 1          #                       $filesInBackup->{$path_key}->{'sharePathM'},
299        )                                  $filesInBackup->{$path_key}->{'mtime'},
300      {                                  $filesInBackup->{$path_key}->{'type'},
301                                          $filesInBackup->{$path_key}->{'size'}
302        push(@ret,                          );
303             recurseDir($bpc, $hostname, $backups, $backupNo, $share, $fold->{'relPath'})  
304            );                          my $key = join(" ", (
305      }                                  $shareID,
306    }                                  $dir,
307    return @ret;                                  $path_key,
308                                    $filesInBackup->{$path_key}->{'mtime'},
309                                    $filesInBackup->{$path_key}->{'size'}
310                            ));
311    
312    
313                            if (! $beenThere->{$key} && ! found_in_db(@data)) {
314                                    print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
315                                    $sth->{'insert_files'}->execute(@data);
316                                    if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
317                                            $new_dirs++;
318                                            print STDERR " dir\n" if ($debug >= 2);
319                                    } else {
320                                            $new_files++;
321                                            print STDERR " file\n" if ($debug >= 2);
322                                    }
323                            }
324                            $beenThere->{$key}++;
325    
326                            if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
327                                    $nr_dirs++;
328    
329                                    my $full_path = $dir . '/' . $path_key;
330                                    push @stack, $full_path;
331                                    print STDERR "### store to stack: $full_path\n" if ($debug >= 3);
332    
333    #                               my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $path_key, $shareID) unless ($beenThere->{$key});
334    #
335    #                               $nr_files += $f;
336    #                               $new_files += $nf;
337    #                               $nr_dirs += $d;
338    #                               $new_dirs += $nd;
339    
340                            } else {
341                                    $nr_files++;
342                            }
343                    }
344    
345                    print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
346    
347                    while ( my $dir = shift @stack ) {
348                            my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID);
349                            print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
350                            $nr_files += $f;
351                            $new_files += $nf;
352                            $nr_dirs += $d;
353                            $new_dirs += $nd;
354                    }
355            }
356    
357            return ($nr_files, $new_files, $nr_dirs, $new_dirs);
358  }  }
359    

Legend:
Removed from v.8  
changed lines
  Added in v.35

  ViewVC Help
Powered by ViewVC 1.1.26