/[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 49 by dpavlin, Sat Aug 20 15:01:48 2005 UTC revision 117 by dpavlin, Sun Sep 11 13:05:06 2005 UTC
# Line 13  use File::Pid; Line 13  use File::Pid;
13  use POSIX qw/strftime/;  use POSIX qw/strftime/;
14    
15  use constant BPC_FTYPE_DIR => 5;  use constant BPC_FTYPE_DIR => 5;
16    use constant EST_CHUNK => 100000;
17    
18  my $debug = 0;  my $debug = 0;
19  $|=1;  $|=1;
20    
21    my $start_t = time();
22    
23  my $pidfile = new File::Pid;  my $pidfile = new File::Pid;
24    
25  if (my $pid = $pidfile->running ) {  if (my $pid = $pidfile->running ) {
# Line 36  my %Conf = $bpc->Conf(); Line 39  my %Conf = $bpc->Conf();
39  my $TopDir = $bpc->TopDir();  my $TopDir = $bpc->TopDir();
40  my $beenThere = {};  my $beenThere = {};
41    
42  my $dsn = "dbi:SQLite:dbname=$TopDir/$Conf{SearchDB}";  my $dsn = $Conf{SearchDSN} || die "Need SearchDSN in config.pl\n";
43  my $user = '';  my $user = $Conf{SearchUser} || '';
44    
45  # DEBUG option!  my $use_hest = $Conf{HyperEstraierIndex};
46  ($dsn,$user) = qw/dbi:Pg:dbname=backuppc dpavlin/;  my ($index_path, $index_node_url) = getHyperEstraier_url($use_hest);
47    
48  my $dbh = DBI->connect($dsn, $user, "", { RaiseError => 1, AutoCommit => 0 });  my $dbh = DBI->connect($dsn, $user, "", { RaiseError => 1, AutoCommit => 0 });
49    
50  my %opt;  my %opt;
51    
52  if ( !getopts("cdm:v:", \%opt ) ) {  if ( !getopts("cdm:v:i", \%opt ) ) {
53          print STDERR <<EOF;          print STDERR <<EOF;
54  usage: $0 [-c|-d] [-m num] [-v|-v level]  usage: $0 [-c|-d] [-m num] [-v|-v level] [-i]
55    
56  Options:  Options:
57          -c      create database on first use          -c      create database on first use
58          -d      delete database before import          -d      delete database before import
59          -m num  import just num increments for one host          -m num  import just num increments for one host
60          -v num  set verbosity (debug) level (default $debug)          -v num  set verbosity (debug) level (default $debug)
61            -i      update HyperEstraier full text index
62  EOF  EOF
63          exit 1;          exit 1;
64  }  }
65    
66  ###################################create tables############################3  if ($opt{v}) {
67            print "Debug level at $opt{v}\n";
68            $debug = $opt{v};
69    }
70    
71    #---- subs ----
72    
73    sub fmt_time {
74            my $t = shift || return;
75            my $out = "";
76            my ($ss,$mm,$hh) = gmtime($t);
77            $out .= "${hh}h" if ($hh);
78            $out .= sprintf("%02d:%02d", $mm,$ss);
79            return $out;
80    }
81    
82    sub curr_time {
83            return strftime($t_fmt,localtime());
84    }
85    
86    my $hest_db;
87    my $hest_node;
88    
89    sub signal {
90            my($sig) = @_;
91            if ($hest_db) {
92                    print "\nCaught a SIG$sig--syncing database and shutting down\n";
93                    $hest_db->sync();
94                    $hest_db->close();
95            }
96            exit(0);
97    }
98    
99    $SIG{'INT'}  = \&signal;
100    $SIG{'QUIT'} = \&signal;
101    
102    sub hest_update {
103    
104            my ($host_id, $share_id, $num) = @_;
105    
106            unless ($use_hest) {
107                    print STDERR "HyperEstraier support not enabled in configuration\n";
108                    return;
109            }
110    
111            print curr_time," updating HyperEstraier:";
112    
113            my $t = time();
114    
115            my $offset = 0;
116            my $added = 0;
117    
118            print " opening index $use_hest";
119            if ($index_path) {
120                    $hest_db = HyperEstraier::Database->new();
121                    $hest_db->open($index_path, $HyperEstraier::Database::DBWRITER | $HyperEstraier::Database::DBCREAT);
122                    print " directly";
123            } elsif ($index_node_url) {
124                    $hest_node ||= HyperEstraier::Node->new($index_node_url);
125                    $hest_node->set_auth('admin', 'admin');
126                    print " via node URL";
127            } else {
128                    die "don't know how to use HyperEstraier Index $use_hest";
129            }
130            print " increment is " . EST_CHUNK . " files:";
131    
132            my $results = 0;
133    
134            do {
135    
136                    my $where = '';
137                    my @data;
138                    if ($host_id && $share_id && $num) {
139                            $where = qq{
140                            WHERE
141                                    hosts.id = ? AND
142                                    shares.id = ? AND
143                                    files.backupnum = ?
144                            };
145                            @data = ( $host_id, $share_id, $num );
146                    }
147    
148                    my $limit = sprintf('LIMIT '.EST_CHUNK.' OFFSET %d', $offset);
149    
150                    my $sth = $dbh->prepare(qq{
151                            SELECT
152                                    files.id                        AS fid,
153                                    hosts.name                      AS hname,
154                                    shares.name                     AS sname,
155                                    -- shares.share                 AS sharename,
156                                    files.backupnum                 AS backupnum,
157                                    -- files.name                   AS filename,
158                                    files.path                      AS filepath,
159                                    files.date                      AS date,
160                                    files.type                      AS type,
161                                    files.size                      AS size,
162                                    files.shareid                   AS shareid,
163                                    backups.date                    AS backup_date
164                            FROM files
165                                    INNER JOIN shares       ON files.shareID=shares.ID
166                                    INNER JOIN hosts        ON hosts.ID = shares.hostID
167                                    INNER JOIN backups      ON backups.num = files.backupNum and backups.hostID = hosts.ID AND backups.shareID = shares.ID
168                            $where
169                            $limit
170                    });
171    
172                    $sth->execute(@data);
173                    $results = $sth->rows;
174    
175                    if ($results == 0) {
176                            print " - no new files\n";
177                            last;
178                    }
179    
180                    sub fmt_date {
181                            my $t = shift || return;
182                            my $iso = BackupPC::Lib::timeStamp($t);
183                            $iso =~ s/\s/T/;
184                            return $iso;
185                    }
186    
187                    while (my $row = $sth->fetchrow_hashref()) {
188    
189                            my $fid = $row->{'fid'} || die "no fid?";
190                            my $uri = 'file:///' . $fid;
191    
192                            my $id = ($hest_db || $hest_node)->uri_to_id($uri);
193                            next unless ($id == -1);
194    
195                            # create a document object
196                            my $doc = HyperEstraier::Document->new;
197    
198                            # add attributes to the document object
199                            $doc->add_attr('@uri', $uri);
200    
201                            foreach my $c (@{ $sth->{NAME} }) {
202                                    $doc->add_attr($c, $row->{$c}) if ($row->{$c});
203                            }
204    
205                            #$doc->add_attr('@cdate', fmt_date($row->{'date'}));
206    
207                            # add the body text to the document object
208                            my $path = $row->{'filepath'};
209                            $doc->add_text($path);
210                            $path =~ s/(.)/$1 /g;
211                            $doc->add_hidden_text($path);
212    
213                            print STDERR $doc->dump_draft,"\n" if ($debug > 1);
214    
215                            # register the document object to the database
216                            if ($hest_db) {
217                                    $hest_db->put_doc($doc, $HyperEstraier::Database::PDCLEAN);
218                            } elsif ($hest_node) {
219                                    $hest_node->put_doc($doc);
220                            } else {
221                                    die "not supported";
222                            }
223                            $added++;
224                    }
225    
226                    print " $added";
227                    $hest_db->sync() if ($index_path);
228    
229                    $offset += EST_CHUNK;
230    
231            } while ($results == EST_CHUNK);
232    
233            if ($index_path) {
234                    print ", close";
235                    $hest_db->close();
236            }
237    
238            my $dur = (time() - $t) || 1;
239            printf(" [%.2f/s dur: %s]\n",
240                    ( $added / $dur ),
241                    fmt_time($dur)
242            );
243    }
244    
245    #---- /subs ----
246    
247    
248    ## update index ##
249    if (($opt{i} || ($index_path && ! -e $index_path)) && !$opt{c}) {
250            # update all
251            print "force update of HyperEstraier index ";
252            print "importing existing data" unless (-e $index_path);
253            print "by -i flag" if ($opt{i});
254            print "\n";
255            hest_update();
256    }
257    
258    ## create tables ##
259  if ($opt{c}) {  if ($opt{c}) {
260          sub do_index {          sub do_index {
261                  my $index = shift || return;                  my $index = shift || return;
262                  my ($table,$col,$unique) = split(/_/, $index);                  my ($table,$col,$unique) = split(/_/, $index);
263                  $unique ||= '';                  $unique ||= '';
264                    $index =~ s/,/_/g;
265                  $dbh->do(qq{ create $unique index $index on $table($col) });                  $dbh->do(qq{ create $unique index $index on $table($col) });
266          }          }
267    
# Line 95  if ($opt{c}) { Line 291  if ($opt{c}) {
291                          num     INTEGER         NOT NULL,                          num     INTEGER         NOT NULL,
292                          date    integer         NOT NULL,                          date    integer         NOT NULL,
293                          type    CHAR(4)         not null,                          type    CHAR(4)         not null,
294                          PRIMARY KEY(hostID, num)                          shareID integer         not null references shares(id),
295                            size    integer         not null,
296                            PRIMARY KEY(hostID, num, shareID)
297                  );                              );            
298          });          });
299    
300          do_index('backups_num_unique');          #do_index('backups_hostid,num_unique');
301    
302          $dbh->do(qq{          $dbh->do(qq{
303                  create table dvds (                  create table dvds (
# Line 114  if ($opt{c}) { Line 312  if ($opt{c}) {
312                  create table files (                  create table files (
313                          ID      SERIAL          PRIMARY KEY,                            ID      SERIAL          PRIMARY KEY,  
314                          shareID INTEGER         NOT NULL references shares(id),                          shareID INTEGER         NOT NULL references shares(id),
315                          backupNum  INTEGER      NOT NULL references backups(num),                          backupNum  INTEGER      NOT NULL,
316                          name       VARCHAR(255) NOT NULL,                          name       VARCHAR(255) NOT NULL,
317                          path       VARCHAR(255) NOT NULL,                          path       VARCHAR(255) NOT NULL,
                         fullpath   VARCHAR(255) NOT NULL,  
318                          date       integer      NOT NULL,                          date       integer      NOT NULL,
319                          type       INTEGER      NOT NULL,                          type       INTEGER      NOT NULL,
320                          size       INTEGER      NOT NULL,                          size       INTEGER      NOT NULL,
# Line 148  if ($opt{c}) { Line 345  if ($opt{c}) {
345    
346  }  }
347    
348    ## delete data before inseting ##
349  if ($opt{d}) {  if ($opt{d}) {
350          print "deleting ";          print "deleting ";
351          foreach my $table (qw(files dvds backups shares hosts)) {          foreach my $table (qw(files dvds backups shares hosts)) {
# Line 156  if ($opt{d}) { Line 354  if ($opt{d}) {
354          }          }
355          print " done...\n";          print " done...\n";
356    
357          eval { $dbh->commit; };          $dbh->commit;
 }  
   
 if ($opt{v}) {  
         print "Debug level at $opt{v}\n";  
         $debug = $opt{v};  
358  }  }
359    
360  #################################INSERT VALUES#############################  ## insert new values ##
361    
362  # get hosts  # get hosts
363  $hosts = $bpc->HostInfoRead();  $hosts = $bpc->HostInfoRead();
# Line 181  $sth->{hosts_by_name} = $dbh->prepare(qq Line 374  $sth->{hosts_by_name} = $dbh->prepare(qq
374  SELECT ID FROM hosts WHERE name=?  SELECT ID FROM hosts WHERE name=?
375  });  });
376    
377  $sth->{backups_broj} = $dbh->prepare(qq{  $sth->{backups_count} = $dbh->prepare(qq{
378  SELECT COUNT(*)  SELECT COUNT(*)
379  FROM backups  FROM backups
380  WHERE hostID=? AND num=?  WHERE hostID=? AND num=? AND shareid=?
381  });  });
382    
383  $sth->{insert_backups} = $dbh->prepare(qq{  $sth->{insert_backups} = $dbh->prepare(qq{
384  INSERT INTO backups (hostID, num, date, type)  INSERT INTO backups (hostID, num, date, type, shareid, size)
385  VALUES (?,?,?,?)  VALUES (?,?,?,?,?,?)
386  });  });
387    
388  $sth->{insert_files} = $dbh->prepare(qq{  $sth->{insert_files} = $dbh->prepare(qq{
389  INSERT INTO files  INSERT INTO files
390          (shareID, backupNum, name, path, fullpath, date, type, size)          (shareID, backupNum, name, path, date, type, size)
391          VALUES (?,?,?,?,?,?,?,?)          VALUES (?,?,?,?,?,?,?)
392  });  });
393    
394  foreach my $host_key (keys %{$hosts}) {  foreach my $host_key (keys %{$hosts}) {
# Line 213  foreach my $host_key (keys %{$hosts}) { Line 406  foreach my $host_key (keys %{$hosts}) {
406                  $hostID = $dbh->last_insert_id(undef,undef,'hosts',undef);                  $hostID = $dbh->last_insert_id(undef,undef,'hosts',undef);
407          }          }
408    
409          print("host ".$hosts->{$host_key}->{'host'}.": ");          print "host ".$hosts->{$host_key}->{'host'}.": ";
410    
411          # get backups for a host          # get backups for a host
412          my @backups = $bpc->BackupInfoRead($hostname);          my @backups = $bpc->BackupInfoRead($hostname);
413          print scalar @backups, " increments\n";          my $incs = scalar @backups;
414            print  "$incs increments\n";
415    
416          my $inc_nr = 0;          my $inc_nr = 0;
417            $beenThere = {};
418    
419          foreach my $backup (@backups) {          foreach my $backup (@backups) {
420    
# Line 229  foreach my $host_key (keys %{$hosts}) { Line 424  foreach my $host_key (keys %{$hosts}) {
424                  my $backupNum = $backup->{'num'};                  my $backupNum = $backup->{'num'};
425                  my @backupShares = ();                  my @backupShares = ();
426    
427                  print $hosts->{$host_key}->{'host'},                  printf("%-10s %2d/%-2d #%-2d %s %5s/%5s files (date: %s dur: %s)\n",
428                          "\t#$backupNum\t", $backup->{type} || '?', " ",                          $hosts->{$host_key}->{'host'},
429                          $backup->{nFilesNew} || '?', "/", $backup->{nFiles} || '?',                          $inc_nr, $incs, $backupNum,
430                          " files\n";                          $backup->{type} || '?',
431                            $backup->{nFilesNew} || '?', $backup->{nFiles} || '?',
432                  $sth->{backups_broj}->execute($hostID, $backupNum);                          strftime($t_fmt,localtime($backup->{startTime})),
433                  my ($broj) = $sth->{backups_broj}->fetchrow_array();                          fmt_time($backup->{endTime} - $backup->{startTime})
                 next if ($broj > 0);  
   
                 $sth->{insert_backups}->execute(  
                         $hostID,  
                         $backupNum,  
                         $backup->{'endTime'},  
                         $backup->{'type'}  
434                  );                  );
                 $dbh->commit();  
435    
436                  my $files = BackupPC::View->new($bpc, $hostname, \@backups, 1);                  my $files = BackupPC::View->new($bpc, $hostname, \@backups, 1);
437                  foreach my $share ($files->shareList($backupNum)) {                  foreach my $share ($files->shareList($backupNum)) {
438    
439                          my $t = time();                          my $t = time();
440    
                         print strftime($t_fmt,localtime())," ", $share;  
441                          $shareID = getShareID($share, $hostID, $hostname);                          $shareID = getShareID($share, $hostID, $hostname);
442                                    
443                          my ($f, $nf, $d, $nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);                          $sth->{backups_count}->execute($hostID, $backupNum, $shareID);
444                          printf(" %d/%d files %d/%d dirs [%.2f/s]\n",                          my ($count) = $sth->{backups_count}->fetchrow_array();
445                                  $nf, $f, $nd, $d,                          # skip if allready in database!
446                                  ( ($f+$d) / ((time() - $t) || 1) )                          next if ($count > 0);
447    
448                            # dump some log
449                            print curr_time," ", $share;
450    
451                            my ($f, $nf, $d, $nd, $size) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);
452    
453                            $sth->{insert_backups}->execute(
454                                    $hostID,
455                                    $backupNum,
456                                    $backup->{'endTime'},
457                                    $backup->{'type'},
458                                    $shareID,
459                                    $size,
460                          );                          );
461    
462                            print " commit";
463                          $dbh->commit();                          $dbh->commit();
464    
465                            my $dur = (time() - $t) || 1;
466                            printf(" %d/%d files %d/%d dirs %0.2f MB [%.2f/s dur: %s]\n",
467                                    $nf, $f, $nd, $d,
468                                    ($size / 1024 / 1024),
469                                    ( ($f+$d) / $dur ),
470                                    fmt_time($dur)
471                            );
472    
473                            hest_update($hostID, $shareID, $backupNum) if ($nf + $nd > 0);
474                  }                  }
475    
476          }          }
# Line 268  undef $sth; Line 479  undef $sth;
479  $dbh->commit();  $dbh->commit();
480  $dbh->disconnect();  $dbh->disconnect();
481    
482    print "total duration: ",fmt_time(time() - $start_t),"\n";
483    
484  $pidfile->remove;  $pidfile->remove;
485    
486  sub getShareID() {  sub getShareID() {
# Line 302  sub found_in_db { Line 515  sub found_in_db {
515          my @data = @_;          my @data = @_;
516          shift @data;          shift @data;
517    
518          my ($key, $shareID,undef,$name,$path,undef,$date,undef,$size) = @_;          my ($key, $shareID,undef,$name,$path,$date,undef,$size) = @_;
519    
520          return $beenThere->{$key} if (defined($beenThere->{$key}));          return $beenThere->{$key} if (defined($beenThere->{$key}));
521    
# Line 310  sub found_in_db { Line 523  sub found_in_db {
523                  SELECT 1 FROM files                  SELECT 1 FROM files
524                  WHERE shareID = ? and                  WHERE shareID = ? and
525                          path = ? and                          path = ? and
                         name = ? and  
526                          date = ? and                          date = ? and
527                          size = ?                          size = ?
528                    LIMIT 1
529          });          });
530    
531          my @param = ($shareID,$path,$name,$date,$size);          my @param = ($shareID,$path,$date,$size);
532          $sth->{file_in_db}->execute(@param);          $sth->{file_in_db}->execute(@param);
533          my $rows = $sth->{file_in_db}->rows;          my $rows = $sth->{file_in_db}->rows;
534          print STDERR "## found_in_db ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);          print STDERR "## found_in_db($shareID,$path,$date,$size) ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);
535    
536          $beenThere->{$key}++;          $beenThere->{$key}++;
537    
# Line 336  sub recurseDir($$$$$$$$) { Line 549  sub recurseDir($$$$$$$$) {
549    
550          print STDERR "\nrecurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);          print STDERR "\nrecurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
551    
552          my ($nr_files, $new_files, $nr_dirs, $new_dirs) = (0,0,0,0);          my ($nr_files, $new_files, $nr_dirs, $new_dirs, $size) = (0,0,0,0,0);
553    
554          { # scope          { # scope
555                  my @stack;                  my @stack;
# Line 346  sub recurseDir($$$$$$$$) { Line 559  sub recurseDir($$$$$$$$) {
559    
560                  # first, add all the entries in current directory                  # first, add all the entries in current directory
561                  foreach my $path_key (keys %{$filesInBackup}) {                  foreach my $path_key (keys %{$filesInBackup}) {
562                            print STDERR "# file ",Dumper($filesInBackup->{$path_key}),"\n" if ($debug >= 3);
563                          my @data = (                          my @data = (
564                                  $shareID,                                  $shareID,
565                                  $backupNum,                                  $backupNum,
566                                  $path_key,                                  $path_key,
567                                  $filesInBackup->{$path_key}->{'relPath'},                                  $filesInBackup->{$path_key}->{'relPath'},
                                 $filesInBackup->{$path_key}->{'fullPath'},  
         #                       $filesInBackup->{$path_key}->{'sharePathM'},  
568                                  $filesInBackup->{$path_key}->{'mtime'},                                  $filesInBackup->{$path_key}->{'mtime'},
569                                  $filesInBackup->{$path_key}->{'type'},                                  $filesInBackup->{$path_key}->{'type'},
570                                  $filesInBackup->{$path_key}->{'size'}                                  $filesInBackup->{$path_key}->{'size'}
# Line 366  sub recurseDir($$$$$$$$) { Line 578  sub recurseDir($$$$$$$$) {
578                                  $filesInBackup->{$path_key}->{'size'}                                  $filesInBackup->{$path_key}->{'size'}
579                          ));                          ));
580    
581                            my $found;
582                          if (! defined($beenThere->{$key}) && ! found_in_db($key, @data)) {                          if (! defined($beenThere->{$key}) && ! ($found = found_in_db($key, @data)) ) {
583                                  print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);                                  print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
584    
585                                  if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {                                  if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
586                                          $new_dirs++;                                          $new_dirs++ unless ($found);
587                                          print STDERR " dir\n" if ($debug >= 2);                                          print STDERR " dir\n" if ($debug >= 2);
588                                  } else {                                  } else {
589                                          $new_files++;                                          $new_files++ unless ($found);
590                                          print STDERR " file\n" if ($debug >= 2);                                          print STDERR " file\n" if ($debug >= 2);
591                                  }                                  }
592                                    $size += $filesInBackup->{$path_key}->{'size'} || 0;
593                          }                          }
594    
595                          if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {                          if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
# Line 401  sub recurseDir($$$$$$$$) { Line 614  sub recurseDir($$$$$$$$) {
614                  print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);                  print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
615    
616                  while ( my $dir = shift @stack ) {                  while ( my $dir = shift @stack ) {
617                          my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID);                          my ($f,$nf,$d,$nd, $s) = recurseDir($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID);
618                          print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);                          print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
619                          $nr_files += $f;                          $nr_files += $f;
620                          $new_files += $nf;                          $new_files += $nf;
621                          $nr_dirs += $d;                          $nr_dirs += $d;
622                          $new_dirs += $nd;                          $new_dirs += $nd;
623                            $size += $s;
624                  }                  }
625          }          }
626    
627          return ($nr_files, $new_files, $nr_dirs, $new_dirs);          return ($nr_files, $new_files, $nr_dirs, $new_dirs, $size);
628  }  }
629    

Legend:
Removed from v.49  
changed lines
  Added in v.117

  ViewVC Help
Powered by ViewVC 1.1.26