/[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 6 by dpavlin, Thu Jun 23 09:47:59 2005 UTC revision 30 by dpavlin, Sun Jul 31 15:59:19 2005 UTC
# Line 1  Line 1 
1  #!/usr/local/bin/perl -w  #!/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  print Dumper(\%Conf);  my $dsn = "dbi:SQLite:dbname=$TopDir/$Conf{SearchDB}";
22    
23  my $dbh = DBI->connect("dbi:SQLite:dbname=$TopDir/$Conf{SearchDB}", "", "", { RaiseError => 1, AutoCommit => 0 });  my $dbh = DBI->connect($dsn, "", "", { RaiseError => 1, AutoCommit => 0 });
24    
25  my %opt;  my %opt;
26    
27  if ( !getopts("cdu", \%opt ) ) {  if ( !getopts("cdm:", \%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  #################################INSERT VALUES#############################  #################################INSERT VALUES#############################
127    
128  # get hosts  # get hosts
129  $hosts = $bpc->HostInfoRead("localhost");  $hosts = $bpc->HostInfoRead();
 my $host_key;  
130  my $hostID;  my $hostID;
131  my $shareID;  my $shareID;
132  foreach $host_key (keys %{$hosts})  
133  {  my $sth;
134    my $hostname = $hosts->{$host_key}->{'host'};  
135    my $backups;  $sth->{insert_hosts} = $dbh->prepare(qq{
136    my $sql;  INSERT INTO hosts (name, IP) VALUES (?,?)
137    });
138    $sql = q{ SELECT ID FROM hosts WHERE name=? };  
139    my $st = $dbh->prepare($sql);  $sth->{hosts_by_name} = $dbh->prepare(qq{
140    $st->bind_param(1,$hosts->{$host_key}->{'host'});  SELECT ID FROM hosts WHERE name=?
141    $st->execute();  });
142    my $tmp = $st->fetchrow_hashref();  
143    if ($tmp->{'ID'} ne "")  $sth->{backups_broj} = $dbh->prepare(qq{
144        {  SELECT COUNT(*)
145            $hostID = $tmp->{'ID'};  FROM backups
146        }  WHERE hostID=? AND num=?
147      else  });
148        {  
149            $sql = q{ INSERT INTO hosts ( ID, name, IP) VALUES (NULL,"}.  $sth->{insert_backups} = $dbh->prepare(qq{
150                      $hosts->{$host_key}->{'host'}."\", \"".  INSERT INTO backups (hostID, num, date, type)
151                     $hosts->{$host_key}->{'ip'}."\");";  VALUES (?,?,?,?)
152    });
153            $dbh->do($sql);  
154            $hostID = $dbh->func('last_insert_rowid');  $sth->{insert_files} = $dbh->prepare(qq{
155    INSERT INTO files
156        }          (shareID, backupNum, name, path, fullpath, date, type, size)
157    $st->finish();          VALUES (?,?,?,?,?,?,?,?)
158    print("processing host ".$hosts->{$host_key}->{'host'}.":\n");  });
159    
160    foreach my $host_key (keys %{$hosts}) {
161    
162            my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";
163    
164            $sth->{hosts_by_name}->execute($hosts->{$host_key}->{'host'});
165    
166            unless (($hostID) = $sth->{hosts_by_name}->fetchrow_array()) {
167                    $sth->{insert_hosts}->execute(
168                            $hosts->{$host_key}->{'host'},
169                            $hosts->{$host_key}->{'ip'}
170                    );
171    
172                    $hostID = $dbh->func('last_insert_rowid');
173            }
174    
175            print("host ".$hosts->{$host_key}->{'host'}.": ");
176    
177    # get backups for a host          # get backups for a host
178    my @backups = $bpc->BackupInfoRead($hostname);          my @backups = $bpc->BackupInfoRead($hostname);
179    foreach my $backup (@backups)          print scalar @backups, " increments\n";
180    {  
181      my $backupNum = $backup->{'num'};          my $inc_nr = 0;
182      my @backupShares = ();  
183            foreach my $backup (@backups) {
184                    $inc_nr++;
185                    last if ($opt{m} && $inc_nr > $opt{m});
186    
187                    my $backupNum = $backup->{'num'};
188                    my @backupShares = ();
189    
190                    print $hosts->{$host_key}->{'host'},"\t#$backupNum\n";
191    
192                    $sth->{backups_broj}->execute($hostID, $backupNum);
193                    my ($broj) = $sth->{backups_broj}->fetchrow_array();
194                    next if ($broj > 0);
195    
196                    my $files = BackupPC::View->new($bpc, $hostname, \@backups);
197                    foreach my $share ($files->shareList($backupNum)) {
198    
199                            print "\t$share";
200                            $shareID = getShareID($share, $hostID, $hostname);
201                    
202                            my ($f, $nf, $d, $nd) = recurseDir($bpc, $hostname, \@backups, $backupNum, $share, "", $shareID);
203                            print " $nf/$f files $nd/$d dirs\n";
204                            $dbh->commit();
205                    }
206    
207                    $sth->{insert_backups}->execute(
208                            $hostID,
209                            $backupNum,
210                            $backup->{'endTime'},
211                            $backup->{'type'}
212                    );
213                    $dbh->commit();
214    
         
     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;  
               }  
215          }          }
         
     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";  
216  }  }
217    undef $sth;
218  $dbh->commit();  $dbh->commit();
219  $dbh->disconnect();  $dbh->disconnect();
220    
221    sub getShareID() {
222    
223  sub haveBeenThere          my ($share, $hostID, $hostname) = @_;
224  {  
225    my ($where) = @_;          $sth->{share_id} ||= $dbh->prepare(qq{
226                      SELECT ID FROM shares WHERE hostID=? AND name=?
227    foreach my $st (@beenThere)          });
228    {  
229      if ($where eq $st)          $sth->{share_id}->execute($hostID,$share);
230      {  
231        return 1;          my ($id) = $sth->{share_id}->fetchrow_array();
232      }  
233    }          return $id if (defined($id));
     
   push(@beenThere, $where);  
   return 0;  
 }  
234    
235  sub clearBeenThereCache          $sth->{insert_share} ||= $dbh->prepare(qq{
236  {                  INSERT INTO shares
237    @beenThere = ();                          (hostID,name,share,localpath)
238                    VALUES (?,?,?,?)
239            });
240    
241            my $drop_down = $hostname . '/' . $share;
242            $drop_down =~ s#//+#/#g;
243    
244            $sth->{insert_share}->execute($hostID,$share, $drop_down ,undef);
245            return $dbh->func('last_insert_rowid');        
246  }  }
247    
248  sub getShareID()  sub found_in_db {
249    {  
250        my ($share, $hostID, $hostname) = @_;          my ($shareID,undef,$name,$path,undef,$date,undef,$size) = @_;
251        my $tmp;  
252                  $sth->{file_in_db} ||= $dbh->prepare(qq{
253        my $st = $dbh -> prepare(" SELECT shares.ID AS ID FROM shares WHERE hostID=? AND name=?");                  SELECT count(*) FROM files
254        $st -> execute($hostID,$share);                  WHERE shareID = ? and
255        my $tmp = $st->fetchrow_hashref();                          path = ? and
256        $st->finish();                          name = ? and
257        if ($tmp)                          date = ? and
258          {                          size = ?
259              return $tmp->{'ID'};          });
260          }  
261        my $sql =          my @param = ($shareID,$path,$name,$date,$size);
262            q{          $sth->{file_in_db}->execute(@param);
263                INSERT INTO shares(ID,hostID,name,share,localpath)          my ($rows) = $sth->{file_in_db}->fetchrow_array();
264                  VALUES    #       print STDERR ( $rows ? '+' : '-' ), join(" ",@param), "\n";
265                 (NULL,}.                            return $rows;
266                "$hostID,\"$share\",\"//$hostname$share\",NULL);";                }
       $dbh->do($sql);  
       return $dbh->func('last_insert_rowid');            
   }  
267    
268  ####################################################  ####################################################
269  # recursing through filesystem structure and       #  # recursing through filesystem structure and       #
270  # and returning flattened files list               #  # and returning flattened files list               #
271  ####################################################  ####################################################
272  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 = "";  
273    
274            my ($bpc, $hostname, $backups, $backupNum, $share, $dir, $shareID) = @_;
275    # first, add all the entries in current directory  
276    foreach $file_key (keys %{$filesInBackup})          print STDERR "recurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
277    {  
278      push(@ret, {          my ($nr_files, $new_files, $nr_dirs, $new_dirs) = (0,0,0,0);
279                   'fileName' => $file_key,  
280                   'relPath'  => $filesInBackup->{$file_key}->{'relPath'},          { # scope
281                   'fullPath' => $filesInBackup->{$file_key}->{'fullPath'},                  my @stack;
282                   'sharePath'=> $filesInBackup->{$file_key}->{'sharePathM'},  
283                   'size'     => $filesInBackup->{$file_key}->{'size'},                  my $files = BackupPC::View->new($bpc, $hostname, $backups);            
284                   'mtime'    => $filesInBackup->{$file_key}->{'mtime'},                  my $filesInBackup = $files->dirAttrib($backupNum, $share, $dir);
285                   'type'     => $filesInBackup->{$file_key}->{'type'}  
286                 });                    # first, add all the entries in current directory
287    }                  foreach my $path_key (keys %{$filesInBackup}) {
288                                my @data = (
289    # then, recurse thru subfolders                                  $shareID,
290    foreach my $fold (@ret)                                  $backupNum,
291    {                                  $path_key,
292     if ($fold->{'type'} == BPC_FTYPE_DIR &&                                  $filesInBackup->{$path_key}->{'relPath'},
293         haveBeenThere($fold->{'relPath'}) != 1                                  $filesInBackup->{$path_key}->{'fullPath'},
294        )          #                       $filesInBackup->{$path_key}->{'sharePathM'},
295      {                                  $filesInBackup->{$path_key}->{'mtime'},
296                                          $filesInBackup->{$path_key}->{'type'},
297        push(@ret,                                  $filesInBackup->{$path_key}->{'size'}
298             recurseDir($bpc, $hostname, $backups, $backupNo, $share, $fold->{'relPath'})                          );
299            );  
300      }                          my $key = join(" ", (
301    }                                  $shareID,
302    return @ret;                                  $dir,
303                                    $path_key,
304                                    $filesInBackup->{$path_key}->{'mtime'},
305                                    $filesInBackup->{$path_key}->{'size'}
306                            ));
307    
308    
309                            if (! $beenThere->{$key} && ! found_in_db(@data)) {
310                                    print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
311                                    $sth->{'insert_files'}->execute(@data);
312                                    if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
313                                            $new_dirs++;
314                                            print STDERR " dir\n" if ($debug >= 2);
315                                    } else {
316                                            $new_files++;
317                                            print STDERR " file\n" if ($debug >= 2);
318                                    }
319                            }
320                            $beenThere->{$key}++;
321    
322                            if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
323                                    $nr_dirs++;
324    
325                                    my $full_path = $dir . '/' . $path_key;
326                                    push @stack, $full_path;
327                                    print STDERR "### store to stack: $full_path\n" if ($debug >= 3);
328    
329    #                               my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $path_key, $shareID) unless ($beenThere->{$key});
330    #
331    #                               $nr_files += $f;
332    #                               $new_files += $nf;
333    #                               $nr_dirs += $d;
334    #                               $new_dirs += $nd;
335    
336                            } else {
337                                    $nr_files++;
338                            }
339                    }
340    
341                    print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
342    
343                    while ( my $dir = shift @stack ) {
344                            my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $dir, $shareID);
345                            print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
346                            $nr_files += $f;
347                            $new_files += $nf;
348                            $nr_dirs += $d;
349                            $new_dirs += $nd;
350                    }
351            }
352    
353            return ($nr_files, $new_files, $nr_dirs, $new_dirs);
354  }  }
355    

Legend:
Removed from v.6  
changed lines
  Added in v.30

  ViewVC Help
Powered by ViewVC 1.1.26