/[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 326 - (hide annotations)
Tue Jan 31 16:37:14 2006 UTC (18 years, 4 months ago) by dpavlin
File size: 17859 byte(s)
 r9166@llin:  dpavlin | 2006-01-31 17:36:56 +0100
 more fixes for operation without Hyper Estraier

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26