/[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 130 by dpavlin, Fri Sep 23 08:54:10 2005 UTC
# Line 1  Line 1 
1  #!/usr/local/bin/perl  #!/usr/local/bin/perl -w
 $| = 1;  
2    
3  use strict;  use strict;
 use DBI;  
4  use lib "__INSTALLDIR__/lib";  use lib "__INSTALLDIR__/lib";
5    
6    use DBI;
7  use BackupPC::Lib;  use BackupPC::Lib;
8  use BackupPC::View;  use BackupPC::View;
9  use Data::Dumper;  use Data::Dumper;
10  use Getopt::Std;  use Getopt::Std;
11    use Time::HiRes qw/time/;
12    use File::Pid;
13    use POSIX qw/strftime/;
14    use BackupPC::SearchLib;
15    
16  use constant BPC_FTYPE_DIR => 5;  use constant BPC_FTYPE_DIR => 5;
17    use constant EST_CHUNK => 100000;
18    
19    my $debug = 0;
20    $|=1;
21    
22    my $start_t = time();
23    
24    my $pidfile = new File::Pid;
25    
26    if (my $pid = $pidfile->running ) {
27            die "$0 already running: $pid\n";
28    } elsif ($pidfile->pid ne $$) {
29            $pidfile->remove;
30            $pidfile = new File::Pid;
31    }
32    $pidfile->write;
33    print STDERR "$0 using pid ",$pidfile->pid," file ",$pidfile->file,"\n";
34    
35    my $t_fmt = '%Y-%m-%d %H:%M:%S';
36    
37  my $hosts;  my $hosts;
38  my $bpc = BackupPC::Lib->new || die;  my $bpc = BackupPC::Lib->new || die;
39  my %Conf = $bpc->Conf();  my %Conf = $bpc->Conf();
40  my $TopDir = $bpc->TopDir();  my $TopDir = $bpc->TopDir();
41  my @beenThere = ();  my $beenThere = {};
42    
43    my $dsn = $Conf{SearchDSN} || die "Need SearchDSN in config.pl\n";
44    my $user = $Conf{SearchUser} || '';
45    
46    my $use_hest = $Conf{HyperEstraierIndex};
47    my ($index_path, $index_node_url) = BackupPC::SearchLib::getHyperEstraier_url($use_hest);
48    
49  my $dbh = DBI->connect("dbi:SQLite:dbname=$TopDir/$Conf{SearchDB}", "", "", { RaiseError => 1, AutoCommit => 0 });  my $dbh = DBI->connect($dsn, $user, "", { RaiseError => 1, AutoCommit => 0 });
50    
51  my %opt;  my %opt;
52    
53  if ( !getopts("cdu", \%opt ) ) {  if ( !getopts("cdm:v:i", \%opt ) ) {
54          print STDERR <<EOF;          print STDERR <<EOF;
55  usage: $0 (-c|-df|-u)  usage: $0 [-c|-d] [-m num] [-v|-v level] [-i]
56    
57  Options:  Options:
58          -c      Create database on first use          -c      create database on first use
59          -d      Delete database before import          -d      delete database before import
60          -u      Update database (import new revisions)          -m num  import just num increments for one host
61            -v num  set verbosity (debug) level (default $debug)
62            -i      update HyperEstraier full text index
63  EOF  EOF
64          exit 1;          exit 1;
65  }  }
66    
67  ###################################create tables############################3  if ($opt{v}) {
68            print "Debug level at $opt{v}\n";
69            $debug = $opt{v};
70    }
71    
72    #---- subs ----
73    
74    sub fmt_time {
75            my $t = shift || return;
76            my $out = "";
77            my ($ss,$mm,$hh) = gmtime($t);
78            $out .= "${hh}h" if ($hh);
79            $out .= sprintf("%02d:%02d", $mm,$ss);
80            return $out;
81    }
82    
83    sub curr_time {
84            return strftime($t_fmt,localtime());
85    }
86    
87    my $hest_db;
88    my $hest_node;
89    
90    sub signal {
91            my($sig) = @_;
92            if ($hest_db) {
93                    print "\nCaught a SIG$sig--syncing database and shutting down\n";
94                    $hest_db->sync();
95                    $hest_db->close();
96            }
97            exit(0);
98    }
99    
100    $SIG{'INT'}  = \&signal;
101    $SIG{'QUIT'} = \&signal;
102    
103    sub hest_update {
104    
105            my ($host_id, $share_id, $num) = @_;
106    
107            unless ($use_hest) {
108                    print STDERR "HyperEstraier support not enabled in configuration\n";
109                    return;
110            }
111    
112            print curr_time," updating HyperEstraier:";
113    
114            my $t = time();
115    
116  if ($opt{c})          my $offset = 0;
117      {          my $added = 0;
118        print "creating database...";  
119            print " opening index $use_hest";
120            if ($index_path) {
121                    $hest_db = HyperEstraier::Database->new();
122                    $hest_db->open($TopDir . $index_path, $HyperEstraier::Database::DBWRITER | $HyperEstraier::Database::DBCREAT);
123                    print " directly";
124            } elsif ($index_node_url) {
125                    $hest_node ||= HyperEstraier::Node->new($index_node_url);
126                    $hest_node->set_auth('admin', 'admin');
127                    print " via node URL";
128            } else {
129                    die "don't know how to use HyperEstraier Index $use_hest";
130            }
131            print " increment is " . EST_CHUNK . " files:";
132    
133            my $results = 0;
134    
135            do {
136    
137                    my $where = '';
138                    my @data;
139                    if ($host_id && $share_id && $num) {
140                            $where = qq{
141                            WHERE
142                                    hosts.id = ? AND
143                                    shares.id = ? AND
144                                    files.backupnum = ?
145                            };
146                            @data = ( $host_id, $share_id, $num );
147                    }
148    
149                    my $limit = sprintf('LIMIT '.EST_CHUNK.' OFFSET %d', $offset);
150    
151                    my $sth = $dbh->prepare(qq{
152                            SELECT
153                                    files.id                        AS fid,
154                                    hosts.name                      AS hname,
155                                    shares.name                     AS sname,
156                                    -- shares.share                 AS sharename,
157                                    files.backupnum                 AS backupnum,
158                                    -- files.name                   AS filename,
159                                    files.path                      AS filepath,
160                                    files.date                      AS date,
161                                    files.type                      AS type,
162                                    files.size                      AS size,
163                                    files.shareid                   AS shareid,
164                                    backups.date                    AS backup_date
165                            FROM files
166                                    INNER JOIN shares       ON files.shareID=shares.ID
167                                    INNER JOIN hosts        ON hosts.ID = shares.hostID
168                                    INNER JOIN backups      ON backups.num = files.backupNum and backups.hostID = hosts.ID AND backups.shareID = shares.ID
169                            $where
170                            $limit
171                    });
172    
173                    $sth->execute(@data);
174                    $results = $sth->rows;
175    
176                    if ($results == 0) {
177                            print " - no new files\n";
178                            last;
179                    }
180    
181                    sub fmt_date {
182                            my $t = shift || return;
183                            my $iso = BackupPC::Lib::timeStamp($t);
184                            $iso =~ s/\s/T/;
185                            return $iso;
186                    }
187    
188                    while (my $row = $sth->fetchrow_hashref()) {
189    
190                            my $fid = $row->{'fid'} || die "no fid?";
191                            my $uri = 'file:///' . $fid;
192    
193                            my $id = ($hest_db || $hest_node)->uri_to_id($uri);
194                            next unless ($id == -1);
195    
196                            # create a document object
197                            my $doc = HyperEstraier::Document->new;
198    
199                            # add attributes to the document object
200                            $doc->add_attr('@uri', $uri);
201    
202                            foreach my $c (@{ $sth->{NAME} }) {
203                                    $doc->add_attr($c, $row->{$c}) if ($row->{$c});
204                            }
205    
206                            #$doc->add_attr('@cdate', fmt_date($row->{'date'}));
207    
208                            # add the body text to the document object
209                            my $path = $row->{'filepath'};
210                            $doc->add_text($path);
211                            $path =~ s/(.)/$1 /g;
212                            $doc->add_hidden_text($path);
213    
214                            print STDERR $doc->dump_draft,"\n" if ($debug > 1);
215    
216                            # register the document object to the database
217                            if ($hest_db) {
218                                    $hest_db->put_doc($doc, $HyperEstraier::Database::PDCLEAN);
219                            } elsif ($hest_node) {
220                                    $hest_node->put_doc($doc);
221                            } else {
222                                    die "not supported";
223                            }
224                            $added++;
225                    }
226    
227                    print " $added";
228                    $hest_db->sync() if ($index_path);
229    
230                    $offset += EST_CHUNK;
231    
232            } while ($results == EST_CHUNK);
233    
234            if ($index_path) {
235                    print ", close";
236                    $hest_db->close();
237            }
238    
239            my $dur = (time() - $t) || 1;
240            printf(" [%.2f/s dur: %s]\n",
241                    ( $added / $dur ),
242                    fmt_time($dur)
243            );
244    }
245    
246    #---- /subs ----
247    
248    
249    ## update index ##
250    if (($opt{i} || ($index_path && ! -e $index_path)) && !$opt{c}) {
251            # update all
252            print "force update of HyperEstraier index ";
253            print "importing existing data" unless (-e $index_path);
254            print "by -i flag" if ($opt{i});
255            print "\n";
256            hest_update();
257    }
258    
259    ## create tables ##
260    if ($opt{c}) {
261            sub do_index {
262                    my $index = shift || return;
263                    my ($table,$col,$unique) = split(/_/, $index);
264                    $unique ||= '';
265                    $index =~ s/,/_/g;
266                    $dbh->do(qq{ create $unique index $index on $table($col) });
267            }
268    
269            print "creating tables...\n";
270                
271        $dbh->do(          $dbh->do(qq{
272            q{                  create table hosts (
273                create table hosts                          ID      SERIAL          PRIMARY KEY,
274                  (   ID             INTEGER              PRIMARY KEY,                          name    VARCHAR(30)     NOT NULL,
275                      name             VARCHAR(30)        NOT NULL,                          IP      VARCHAR(15)
                     IP       VARCHAR(20)        NOT NULL  
276                  );                              );            
277            }          });
       );  
278                                
279        $dbh->do(          $dbh->do(qq{
280            q{                  create table shares (
281                create table shares                          ID      SERIAL          PRIMARY KEY,
282                  (   ID             INTEGER           PRIMARY KEY,                          hostID  INTEGER         NOT NULL references hosts(id),
283                      hostID         INTEGER           NOT NULL,                          name    VARCHAR(30)     NOT NULL,
284                      name           VARCHAR(30)       NOT NULL,                          share   VARCHAR(200)    NOT NULL,
285                      share          VARCHAR(200)      NOT NULL,                          localpath VARCHAR(200)      
                     localpath      VARCHAR(200)        
286                  );                              );            
287            }          });
288        );  
289            $dbh->do(qq{
290                    create table dvds (
291                            ID      SERIAL          PRIMARY KEY,
292                            num     INTEGER         NOT NULL,
293                            name    VARCHAR(255)    NOT NULL,
294                            mjesto  VARCHAR(255)
295                    );
296            });
297                    
298        $dbh->do(          $dbh->do(qq{
299            q{                  create table backups (
300                create table backups                          hostID  INTEGER         NOT NULL references hosts(id),
301                  ( hostID     INTEGER            NOT NULL,                          num     INTEGER         NOT NULL,
302                      num      INTEGER            NOT NULL,                          date    integer         NOT NULL,
303                      date             DATE,                          type    CHAR(4)         not null,
304                      type             CHAR(1),                          shareID integer         not null references shares(id),
305                      PRIMARY KEY(hostID, num)                          size    integer         not null,
306                            PRIMARY KEY(hostID, num, shareID)
307                  );                              );            
308            }          });
309        );  
310            #do_index('backups_hostid,num_unique');
311    
312        $dbh->do(  
313            q{          $dbh->do(qq{    
314                create table dvds                  create table files (
315                  ( ID         INTEGER            PRIMARY KEY,                          ID      SERIAL          PRIMARY KEY,  
316                      num      INTEGER            NOT NULL,                          shareID INTEGER         NOT NULL references shares(id),
317                      name             VARCHAR(255)       NOT NULL,                          backupNum  INTEGER      NOT NULL,
318                      mjesto     VARCHAR(255)                          name       VARCHAR(255) NOT NULL,
319                            path       VARCHAR(255) NOT NULL,
320                            date       integer      NOT NULL,
321                            type       INTEGER      NOT NULL,
322                            size       INTEGER      NOT NULL
323                  );                  );
324            }          });
325        );  
326    
327        $dbh->do(          $dbh->do( qq{
328            q{                      create table archive
329                create table files                  (
330                  (   ID         INTEGER          NOT NULL PRIMARY KEY,                            id                      int not null,
331                      shareID    INTEGER          NOT NULL,                          dvd_nr          int not null,
332                      backupNum  INTEGER          NOT NULL,                          note            text,
333                      name       VARCHAR(255)     NOT NULL,                          username        varchar(20) not null,
334                      path       VARCHAR(255)     NOT NULL,                          date            timestamp,
335                      fullpath   VARCHAR(255)     NOT NULL,                          primary key(id)
336                      date       TIMESTAMP        NOT NULL,                  );      
337                      type       INTEGER          NOT NULL,          }
338                      size       INTEGER          NOT NULL,          );
339                      dvdid      INTEGER            
340            $dbh->do( qq{
341                    create table archive_backup
342                    (
343                            archive_id      int not null,
344                            backup_id       int not null,
345                            status          text,
346                            primary key(archive_id, backup_id)
347                  );                  );
348            }          });
349        );  
350        print "done\n";          $dbh->do( qq{
351    }                  create table workflows(
352                            id                      int not null,
353  if ($opt{d})                          step_id         int not null,
354    {                          start           timestamp,
355        print("deleting db first...\n");                          stop            timestamp,
356                                  username        varchar(20),
357        $dbh->do(                          archive_id      int not null,
358            q{ DELETE FROM hosts; }                          running         boolean default true,
359            );                          primary key(id)
360        $dbh->do(                  );
361            q{ DELETE FROM shares; }          });
           );  
       $dbh->do(  
           q{ DELETE FROM files;}  
           );  
       $dbh->do(  
           q{ DELETE FROM dvds;}  
           );  
       $dbh->do(  
           q{ DELETE FROM backups; }  
           );  
   }  
362    
363  #################################INSERT VALUES#############################          $dbh->do( qq{
364                    create table workflow_step
365                    (
366                            step_id         int not null,
367                            code            text,
368                            next_step       int,
369                            stop            boolean default false,
370                            primary key(step_id)
371                    );
372            });
373    
374            $dbh->do( qq{
375                            alter table workflow_step
376                                    add constraint fk_workflow_next_step
377                                    foreign key(next_step)
378                                    references workflow_step(step_id);
379            });
380    
381            $dbh->do( qq{
382                    alter table workflows
383                            add constraint fk_workflows_step_id
384                            foreign key(step_id)
385                            references workflow_step(step_id);
386            });
387            
388            $dbh->do( qq{
389                    alter table workflows
390                            add constraint fk_workflows_archive_id
391                            foreign key(archive_id)
392                            references archive(id);
393            });
394    
395            $dbh->do( qq{
396                    create table workflow_log
397                    (
398                            workflow_id             int not null,
399                            step_id                 int not null,
400                            date                    timestamp not null,
401                            status                  text,
402                            primary key(workflow_id, step_id)
403                    );
404            });
405    
406            $dbh->do( qq{
407                    alter table workflow_log
408                            add constraint fk_workflow_log_workflow_id
409                            foreign key (workflow_id)
410                            references workflows(id);
411                    });
412            
413            $dbh->do( qq{
414                    alter table workflow_log
415                            add constraint fk_workflow_log_step_id
416                            foreign key (step_id)
417                            references      workflow_step(step_id);
418                    });
419    
420            print "creating indexes:";
421    
422            foreach my $index (qw(
423                    hosts_name
424                    backups_hostID
425                    backups_num
426                    shares_hostID
427                    shares_name
428                    files_shareID
429                    files_path
430                    files_name
431                    files_date
432                    files_size
433            )) {
434                    print " $index";
435                    do_index($index);
436            }
437            print "...\n";
438    
439            $dbh->commit;
440    
441    }
442    
443    ## delete data before inseting ##
444    if ($opt{d}) {
445            print "deleting ";
446            foreach my $table (qw(files dvds backups shares hosts)) {
447                    print "$table ";
448                    $dbh->do(qq{ DELETE FROM $table });
449            }
450            print " done...\n";
451    
452            $dbh->commit;
453    }
454    
455    ## insert new values ##
456    
457  # get hosts  # get hosts
458  $hosts = $bpc->HostInfoRead();  $hosts = $bpc->HostInfoRead();
 print Dumper($hosts);  
459  my $hostID;  my $hostID;
460  my $shareID;  my $shareID;
461  foreach my $host_key (keys %{$hosts})  
462  {  my $sth;
463    my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";  
464    my $backups;  $sth->{insert_hosts} = $dbh->prepare(qq{
465    my $sql;  INSERT INTO hosts (name, IP) VALUES (?,?)
466    });
467    $sql = q{ SELECT ID FROM hosts WHERE name=? };  
468    my $st = $dbh->prepare($sql);  $sth->{hosts_by_name} = $dbh->prepare(qq{
469    $st->bind_param(1,$hosts->{$host_key}->{'host'});  SELECT ID FROM hosts WHERE name=?
470    $st->execute();  });
471    if (my $tmp = $st->fetchrow_hashref())  
472        {  $sth->{backups_count} = $dbh->prepare(qq{
473            $hostID = $tmp->{'ID'};  SELECT COUNT(*)
474        }  FROM backups
475      else  WHERE hostID=? AND num=? AND shareid=?
476        {  });
477            $sql = q{ INSERT INTO hosts ( ID, name, IP) VALUES (NULL,"}.  
478                      $hosts->{$host_key}->{'host'}."\", \"".  $sth->{insert_backups} = $dbh->prepare(qq{
479                     $hosts->{$host_key}->{'ip'}."\");";  INSERT INTO backups (hostID, num, date, type, shareid, size)
480    VALUES (?,?,?,?,?,?)
481            $dbh->do($sql);  });
482            $hostID = $dbh->func('last_insert_rowid');  
483    $sth->{insert_files} = $dbh->prepare(qq{
484        }  INSERT INTO files
485    $st->finish();          (shareID, backupNum, name, path, date, type, size)
486    print("processing host ".$hosts->{$host_key}->{'host'}.":\n");          VALUES (?,?,?,?,?,?,?)
487    });
488    
489    foreach my $host_key (keys %{$hosts}) {
490    
491            my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";
492    
493            $sth->{hosts_by_name}->execute($hosts->{$host_key}->{'host'});
494    
495            unless (($hostID) = $sth->{hosts_by_name}->fetchrow_array()) {
496                    $sth->{insert_hosts}->execute(
497                            $hosts->{$host_key}->{'host'},
498                            $hosts->{$host_key}->{'ip'}
499                    );
500    
501                    $hostID = $dbh->last_insert_id(undef,undef,'hosts',undef);
502            }
503    
504            print "host ".$hosts->{$host_key}->{'host'}.": ";
505    
506    # get backups for a host          # get backups for a host
507    my @backups = $bpc->BackupInfoRead($hostname);          my @backups = $bpc->BackupInfoRead($hostname);
508    foreach my $backup (@backups)          my $incs = scalar @backups;
509    {          print  "$incs increments\n";
510      my $backupNum = $backup->{'num'};  
511      my @backupShares = ();          my $inc_nr = 0;
512            $beenThere = {};
513    
514            foreach my $backup (@backups) {
515    
516                    $inc_nr++;
517                    last if ($opt{m} && $inc_nr > $opt{m});
518    
519                    my $backupNum = $backup->{'num'};
520                    my @backupShares = ();
521    
522                    printf("%-10s %2d/%-2d #%-2d %s %5s/%5s files (date: %s dur: %s)\n",
523                            $hosts->{$host_key}->{'host'},
524                            $inc_nr, $incs, $backupNum,
525                            $backup->{type} || '?',
526                            $backup->{nFilesNew} || '?', $backup->{nFiles} || '?',
527                            strftime($t_fmt,localtime($backup->{startTime})),
528                            fmt_time($backup->{endTime} - $backup->{startTime})
529                    );
530    
531                    my $files = BackupPC::View->new($bpc, $hostname, \@backups, 1);
532                    foreach my $share ($files->shareList($backupNum)) {
533    
534                            my $t = time();
535    
536                            $shareID = getShareID($share, $hostID, $hostname);
537                    
538                            $sth->{backups_count}->execute($hostID, $backupNum, $shareID);
539                            my ($count) = $sth->{backups_count}->fetchrow_array();
540                            # skip if allready in database!
541                            next if ($count > 0);
542    
543                            # dump some log
544                            print curr_time," ", $share;
545    
546                            my ($f, $nf, $d, $nd, $size) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);
547    
548                            $sth->{insert_backups}->execute(
549                                    $hostID,
550                                    $backupNum,
551                                    $backup->{'endTime'},
552                                    substr($backup->{'type'},0,4),
553                                    $shareID,
554                                    $size,
555                            );
556    
557                            print " commit";
558                            $dbh->commit();
559    
560                            my $dur = (time() - $t) || 1;
561                            printf(" %d/%d files %d/%d dirs %0.2f MB [%.2f/s dur: %s]\n",
562                                    $nf, $f, $nd, $d,
563                                    ($size / 1024 / 1024),
564                                    ( ($f+$d) / $dur ),
565                                    fmt_time($dur)
566                            );
567    
568                            hest_update($hostID, $shareID, $backupNum) if ($nf + $nd > 0);
569                    }
570    
         
     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;  
               }  
571          }          }
         
     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";  
572  }  }
573    undef $sth;
574  $dbh->commit();  $dbh->commit();
575  $dbh->disconnect();  $dbh->disconnect();
576    
577    print "total duration: ",fmt_time(time() - $start_t),"\n";
578    
579  sub haveBeenThere  $pidfile->remove;
580  {  
581    my ($where) = @_;  sub getShareID() {
582      
583    foreach my $st (@beenThere)          my ($share, $hostID, $hostname) = @_;
584    {  
585      if ($where eq $st)          $sth->{share_id} ||= $dbh->prepare(qq{
586      {                  SELECT ID FROM shares WHERE hostID=? AND name=?
587        return 1;          });
588      }  
589    }          $sth->{share_id}->execute($hostID,$share);
590      
591    push(@beenThere, $where);          my ($id) = $sth->{share_id}->fetchrow_array();
592    return 0;  
593  }          return $id if (defined($id));
594    
595  sub clearBeenThereCache          $sth->{insert_share} ||= $dbh->prepare(qq{
596  {                  INSERT INTO shares
597    @beenThere = ();                          (hostID,name,share,localpath)
598  }                  VALUES (?,?,?,?)
599            });
600  sub getShareID()  
601    {          my $drop_down = $hostname . '/' . $share;
602        my ($share, $hostID, $hostname) = @_;          $drop_down =~ s#//+#/#g;
603        my $tmp;  
604                  $sth->{insert_share}->execute($hostID,$share, $drop_down ,undef);
605        my $st = $dbh -> prepare(" SELECT shares.ID AS ID FROM shares WHERE hostID=? AND name=?");          return $dbh->last_insert_id(undef,undef,'shares',undef);
606        $st -> execute($hostID,$share);  }
607        my $tmp = $st->fetchrow_hashref();  
608        $st->finish();  sub found_in_db {
609        if ($tmp)  
610          {          my @data = @_;
611              return $tmp->{'ID'};          shift @data;
612          }  
613        my $sql =          my ($key, $shareID,undef,$name,$path,$date,undef,$size) = @_;
614            q{  
615                INSERT INTO shares(ID,hostID,name,share,localpath)          return $beenThere->{$key} if (defined($beenThere->{$key}));
616                  VALUES    
617                 (NULL,}.                            $sth->{file_in_db} ||= $dbh->prepare(qq{
618                "$hostID,\"$share\",\"//$hostname$share\",NULL);";                                SELECT 1 FROM files
619        $dbh->do($sql);                  WHERE shareID = ? and
620        return $dbh->func('last_insert_rowid');                                    path = ? and
621    }                          date = ? and
622                            size = ?
623                    LIMIT 1
624            });
625    
626            my @param = ($shareID,$path,$date,$size);
627            $sth->{file_in_db}->execute(@param);
628            my $rows = $sth->{file_in_db}->rows;
629            print STDERR "## found_in_db($shareID,$path,$date,$size) ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);
630    
631            $beenThere->{$key}++;
632    
633            $sth->{'insert_files'}->execute(@data) unless ($rows);
634            return $rows;
635    }
636    
637  ####################################################  ####################################################
638  # recursing through filesystem structure and       #  # recursing through filesystem structure and       #
639  # and returning flattened files list               #  # and returning flattened files list               #
640  ####################################################  ####################################################
641  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 = "";  
642    
643            my ($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID) = @_;
644    # first, add all the entries in current directory  
645    foreach $file_key (keys %{$filesInBackup})          print STDERR "\nrecurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
646    {  
647      push(@ret, {          my ($nr_files, $new_files, $nr_dirs, $new_dirs, $size) = (0,0,0,0,0);
648                   'fileName' => $file_key,  
649                   'relPath'  => $filesInBackup->{$file_key}->{'relPath'},          { # scope
650                   'fullPath' => $filesInBackup->{$file_key}->{'fullPath'},                  my @stack;
651                   'sharePath'=> $filesInBackup->{$file_key}->{'sharePathM'},  
652                   'size'     => $filesInBackup->{$file_key}->{'size'},                  print STDERR "# dirAttrib($backupNum, $share, $dir)\n" if ($debug >= 2);
653                   'mtime'    => $filesInBackup->{$file_key}->{'mtime'},                  my $filesInBackup = $files->dirAttrib($backupNum, $share, $dir);
654                   'type'     => $filesInBackup->{$file_key}->{'type'}  
655                 });                    # first, add all the entries in current directory
656    }                  foreach my $path_key (keys %{$filesInBackup}) {
657                                print STDERR "# file ",Dumper($filesInBackup->{$path_key}),"\n" if ($debug >= 3);
658    # then, recurse thru subfolders                          my @data = (
659    foreach my $fold (@ret)                                  $shareID,
660    {                                  $backupNum,
661     if ($fold->{'type'} == BPC_FTYPE_DIR &&                                  $path_key,
662         haveBeenThere($fold->{'relPath'}) != 1                                  $filesInBackup->{$path_key}->{'relPath'},
663        )                                  $filesInBackup->{$path_key}->{'mtime'},
664      {                                  $filesInBackup->{$path_key}->{'type'},
665                                          $filesInBackup->{$path_key}->{'size'}
666        push(@ret,                          );
667             recurseDir($bpc, $hostname, $backups, $backupNo, $share, $fold->{'relPath'})  
668            );                          my $key = join(" ", (
669      }                                  $shareID,
670    }                                  $dir,
671    return @ret;                                  $path_key,
672                                    $filesInBackup->{$path_key}->{'mtime'},
673                                    $filesInBackup->{$path_key}->{'size'}
674                            ));
675    
676                            my $found;
677                            if (! defined($beenThere->{$key}) && ! ($found = found_in_db($key, @data)) ) {
678                                    print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
679    
680                                    if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
681                                            $new_dirs++ unless ($found);
682                                            print STDERR " dir\n" if ($debug >= 2);
683                                    } else {
684                                            $new_files++ unless ($found);
685                                            print STDERR " file\n" if ($debug >= 2);
686                                    }
687                                    $size += $filesInBackup->{$path_key}->{'size'} || 0;
688                            }
689    
690                            if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
691                                    $nr_dirs++;
692    
693                                    my $full_path = $dir . '/' . $path_key;
694                                    push @stack, $full_path;
695                                    print STDERR "### store to stack: $full_path\n" if ($debug >= 3);
696    
697    #                               my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $path_key, $shareID) unless ($beenThere->{$key});
698    #
699    #                               $nr_files += $f;
700    #                               $new_files += $nf;
701    #                               $nr_dirs += $d;
702    #                               $new_dirs += $nd;
703    
704                            } else {
705                                    $nr_files++;
706                            }
707                    }
708    
709                    print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
710    
711                    while ( my $dir = shift @stack ) {
712                            my ($f,$nf,$d,$nd, $s) = recurseDir($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID);
713                            print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
714                            $nr_files += $f;
715                            $new_files += $nf;
716                            $nr_dirs += $d;
717                            $new_dirs += $nd;
718                            $size += $s;
719                    }
720            }
721    
722            return ($nr_files, $new_files, $nr_dirs, $new_dirs, $size);
723  }  }
724    

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

  ViewVC Help
Powered by ViewVC 1.1.26