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

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

  ViewVC Help
Powered by ViewVC 1.1.26