/[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

Annotation of /trunk/bin/BackupPC_updatedb

Parent Directory Parent Directory | Revision Log Revision Log


Revision 246 - (hide annotations)
Fri Dec 9 12:49:55 2005 UTC (18 years, 5 months ago) by dpavlin
File size: 17234 byte(s)
check daylight saving time offset when reading from database too.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26