/[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 325 - (hide annotations)
Tue Jan 31 16:29:30 2006 UTC (18 years, 4 months ago) by dpavlin
File size: 17866 byte(s)
 r9164@llin:  dpavlin | 2006-01-31 17:29:14 +0100
 create trigger, small fixes for deployment without HyperEstraier

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 303 unless (defined($index_node_url)) {
117 dpavlin 116 print STDERR "HyperEstraier support not enabled in configuration\n";
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 325 unless ($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 303 if ($hest_node) {
228 dpavlin 116 $hest_node->put_doc($doc);
229     } else {
230     die "not supported";
231     }
232 dpavlin 98 $added++;
233 dpavlin 81 }
234    
235 dpavlin 315 print "$added";
236 dpavlin 81
237 dpavlin 98 $offset += EST_CHUNK;
238 dpavlin 81
239 dpavlin 98 } while ($results == EST_CHUNK);
240 dpavlin 81
241 dpavlin 86 my $dur = (time() - $t) || 1;
242 dpavlin 98 printf(" [%.2f/s dur: %s]\n",
243 dpavlin 89 ( $added / $dur ),
244 dpavlin 86 fmt_time($dur)
245     );
246 dpavlin 89 }
247 dpavlin 86
248 dpavlin 89 #---- /subs ----
249    
250    
251     ## update index ##
252 dpavlin 303 if ( ( $opt{i} || $opt{j} ) && !$opt{c} ) {
253 dpavlin 89 # update all
254 dpavlin 303 print "force update of Hyper Estraier index ";
255 dpavlin 89 print "by -i flag" if ($opt{i});
256 dpavlin 131 print "by -j flag" if ($opt{j});
257 dpavlin 89 print "\n";
258     hest_update();
259 dpavlin 81 }
260    
261 dpavlin 89 ## create tables ##
262 dpavlin 14 if ($opt{c}) {
263 dpavlin 49 sub do_index {
264     my $index = shift || return;
265 dpavlin 152 my ($table,$col,$unique) = split(/:/, $index);
266 dpavlin 49 $unique ||= '';
267 dpavlin 152 $index =~ s/\W+/_/g;
268     print "$index on $table($col)" . ( $unique ? "u" : "" ) . " ";
269 dpavlin 49 $dbh->do(qq{ create $unique index $index on $table($col) });
270     }
271    
272 dpavlin 14 print "creating tables...\n";
273 dpavlin 183
274     $dbh->do( qq{
275 dpavlin 14 create table hosts (
276 dpavlin 49 ID SERIAL PRIMARY KEY,
277 dpavlin 14 name VARCHAR(30) NOT NULL,
278     IP VARCHAR(15)
279 dpavlin 6 );
280 dpavlin 183
281 dpavlin 14 create table shares (
282 dpavlin 49 ID SERIAL PRIMARY KEY,
283 dpavlin 14 hostID INTEGER NOT NULL references hosts(id),
284     name VARCHAR(30) NOT NULL,
285 dpavlin 152 share VARCHAR(200) NOT NULL
286 dpavlin 6 );
287 dpavlin 130
288     create table dvds (
289     ID SERIAL PRIMARY KEY,
290     num INTEGER NOT NULL,
291     name VARCHAR(255) NOT NULL,
292     mjesto VARCHAR(255)
293     );
294 dpavlin 183
295 dpavlin 14 create table backups (
296 dpavlin 152 id serial,
297 dpavlin 14 hostID INTEGER NOT NULL references hosts(id),
298     num INTEGER NOT NULL,
299 dpavlin 49 date integer NOT NULL,
300     type CHAR(4) not null,
301 dpavlin 65 shareID integer not null references shares(id),
302 dpavlin 136 size bigint not null,
303 dpavlin 152 inc_size bigint not null default -1,
304     inc_deleted boolean default false,
305 dpavlin 325 parts integer not null default 0,
306 dpavlin 152 PRIMARY KEY(id)
307 dpavlin 6 );
308    
309 dpavlin 14 create table files (
310 dpavlin 152 ID SERIAL,
311     shareID INTEGER NOT NULL references shares(id),
312     backupNum INTEGER NOT NULL,
313     name VARCHAR(255) NOT NULL,
314     path VARCHAR(255) NOT NULL,
315     date integer NOT NULL,
316     type INTEGER NOT NULL,
317     size bigint NOT NULL,
318     primary key(id)
319 dpavlin 6 );
320    
321 dpavlin 152 create table archive (
322     id serial,
323 dpavlin 130 dvd_nr int not null,
324 dpavlin 152 total_size bigint default -1,
325 dpavlin 130 note text,
326     username varchar(20) not null,
327 dpavlin 152 date timestamp default now(),
328 dpavlin 130 primary key(id)
329     );
330    
331 dpavlin 183 create table archive_backup (
332 dpavlin 160 archive_id int not null references archive(id) on delete cascade,
333 dpavlin 152 backup_id int not null references backups(id),
334 dpavlin 130 primary key(archive_id, backup_id)
335     );
336 dpavlin 183
337     create table archive_burned (
338 dpavlin 199 archive_id int references archive(id),
339 dpavlin 202 date timestamp default now(),
340 dpavlin 199 part int not null default 1,
341 dpavlin 202 copy int not null default 1,
342 dpavlin 196 iso_size bigint default -1
343 dpavlin 183 );
344    
345 dpavlin 235 create table backup_parts (
346     id serial,
347     backup_id int references backups(id),
348     part_nr int not null check (part_nr > 0),
349     tar_size bigint not null check (tar_size > 0),
350     size bigint not null check (size > 0),
351     md5 text not null,
352     items int not null check (items > 0),
353     date timestamp default now(),
354     primary key(id)
355     );
356 dpavlin 130 });
357    
358 dpavlin 153 print "creating indexes: ";
359 dpavlin 6
360 dpavlin 14 foreach my $index (qw(
361 dpavlin 152 hosts:name
362     backups:hostID
363     backups:num
364     backups:shareID
365     shares:hostID
366     shares:name
367     files:shareID
368     files:path
369     files:name
370     files:date
371     files:size
372     archive:dvd_nr
373 dpavlin 183 archive_burned:archive_id
374 dpavlin 235 backup_parts:backup_id,part_nr
375 dpavlin 14 )) {
376 dpavlin 49 do_index($index);
377 dpavlin 14 }
378 dpavlin 153
379     print " creating sequence: ";
380     foreach my $seq (qw/dvd_nr/) {
381     print "$seq ";
382     $dbh->do( qq{ CREATE SEQUENCE $seq } );
383     }
384    
385 dpavlin 325 print " creating triggers ";
386     $dbh->do( qq{
387     create or replace function backup_parts_check() returns trigger as '
388     declare
389     b_parts integer;
390     b_counted integer;
391     b_id integer;
392     begin
393     if (TG_OP=''UPDATE'') then
394     b_id := old.id;
395     b_parts := old.parts;
396     elsif (TG_OP = ''INSERT'') then
397     b_id := new.id;
398     b_parts := new.parts;
399     end if;
400     b_counted := (select count(*) from backup_parts where backup_id = b_id);
401     if ( b_parts != b_counted ) then
402     raise exception ''Update of backup % aborted, requested % parts and there are really % parts'', b_id, b_parts, b_counted;
403     end if;
404     return null;
405     end;
406     ' language plpgsql;
407 dpavlin 153
408 dpavlin 325 create trigger do_backup_parts_check
409     after insert or update or delete on backups
410     for each row execute procedure backup_parts_check();
411     });
412    
413 dpavlin 49 print "...\n";
414 dpavlin 14
415 dpavlin 49 $dbh->commit;
416 dpavlin 14
417     }
418    
419 dpavlin 89 ## delete data before inseting ##
420 dpavlin 14 if ($opt{d}) {
421     print "deleting ";
422 dpavlin 49 foreach my $table (qw(files dvds backups shares hosts)) {
423 dpavlin 14 print "$table ";
424     $dbh->do(qq{ DELETE FROM $table });
425     }
426     print " done...\n";
427 dpavlin 49
428 dpavlin 51 $dbh->commit;
429 dpavlin 14 }
430    
431 dpavlin 89 ## insert new values ##
432 dpavlin 6
433     # get hosts
434 dpavlin 8 $hosts = $bpc->HostInfoRead();
435 dpavlin 6 my $hostID;
436     my $shareID;
437    
438 dpavlin 14 my $sth;
439 dpavlin 6
440 dpavlin 14 $sth->{insert_hosts} = $dbh->prepare(qq{
441     INSERT INTO hosts (name, IP) VALUES (?,?)
442     });
443 dpavlin 6
444 dpavlin 14 $sth->{hosts_by_name} = $dbh->prepare(qq{
445     SELECT ID FROM hosts WHERE name=?
446     });
447    
448 dpavlin 65 $sth->{backups_count} = $dbh->prepare(qq{
449 dpavlin 14 SELECT COUNT(*)
450     FROM backups
451 dpavlin 65 WHERE hostID=? AND num=? AND shareid=?
452 dpavlin 14 });
453    
454     $sth->{insert_backups} = $dbh->prepare(qq{
455 dpavlin 66 INSERT INTO backups (hostID, num, date, type, shareid, size)
456 dpavlin 242 VALUES (?,?,?,?,?,-1)
457 dpavlin 14 });
458    
459 dpavlin 242 $sth->{update_backups_size} = $dbh->prepare(qq{
460     UPDATE backups SET size = ?
461     WHERE hostID = ? and num = ? and date = ? and type =? and shareid = ?
462     });
463    
464 dpavlin 14 $sth->{insert_files} = $dbh->prepare(qq{
465     INSERT INTO files
466 dpavlin 62 (shareID, backupNum, name, path, date, type, size)
467     VALUES (?,?,?,?,?,?,?)
468 dpavlin 14 });
469    
470 dpavlin 248 my @hosts = keys %{$hosts};
471     my $host_nr = 0;
472 dpavlin 14
473 dpavlin 248 foreach my $host_key (@hosts) {
474    
475 dpavlin 14 my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";
476    
477     $sth->{hosts_by_name}->execute($hosts->{$host_key}->{'host'});
478    
479     unless (($hostID) = $sth->{hosts_by_name}->fetchrow_array()) {
480     $sth->{insert_hosts}->execute(
481     $hosts->{$host_key}->{'host'},
482     $hosts->{$host_key}->{'ip'}
483     );
484    
485 dpavlin 49 $hostID = $dbh->last_insert_id(undef,undef,'hosts',undef);
486 dpavlin 14 }
487    
488 dpavlin 248 $host_nr++;
489 dpavlin 14 # get backups for a host
490     my @backups = $bpc->BackupInfoRead($hostname);
491 dpavlin 67 my $incs = scalar @backups;
492 dpavlin 6
493 dpavlin 311 my $host_header = sprintf("host %s [%d/%d]: %d increments\n",
494     $hosts->{$host_key}->{'host'},
495     $host_nr,
496     ($#hosts + 1),
497     $incs
498     );
499     print $host_header unless ($opt{q});
500    
501 dpavlin 14 my $inc_nr = 0;
502 dpavlin 67 $beenThere = {};
503 dpavlin 14
504     foreach my $backup (@backups) {
505 dpavlin 40
506 dpavlin 14 $inc_nr++;
507     last if ($opt{m} && $inc_nr > $opt{m});
508    
509     my $backupNum = $backup->{'num'};
510     my @backupShares = ();
511    
512 dpavlin 311 my $share_header = sprintf("%-10s %2d/%-2d #%-2d %s %5s/%5s files (date: %s dur: %s)\n",
513 dpavlin 67 $hosts->{$host_key}->{'host'},
514     $inc_nr, $incs, $backupNum,
515     $backup->{type} || '?',
516     $backup->{nFilesNew} || '?', $backup->{nFiles} || '?',
517 dpavlin 57 strftime($t_fmt,localtime($backup->{startTime})),
518 dpavlin 67 fmt_time($backup->{endTime} - $backup->{startTime})
519     );
520 dpavlin 311 print $share_header unless ($opt{q});
521 dpavlin 14
522 dpavlin 34 my $files = BackupPC::View->new($bpc, $hostname, \@backups, 1);
523 dpavlin 14 foreach my $share ($files->shareList($backupNum)) {
524    
525 dpavlin 37 my $t = time();
526    
527 dpavlin 14 $shareID = getShareID($share, $hostID, $hostname);
528    
529 dpavlin 65 $sth->{backups_count}->execute($hostID, $backupNum, $shareID);
530     my ($count) = $sth->{backups_count}->fetchrow_array();
531     # skip if allready in database!
532     next if ($count > 0);
533    
534 dpavlin 311 # dump host and share header for -q
535     if ($opt{q}) {
536     if ($host_header) {
537     print $host_header;
538     $host_header = undef;
539     }
540     print $share_header;
541     }
542    
543 dpavlin 65 # dump some log
544 dpavlin 86 print curr_time," ", $share;
545 dpavlin 65
546 dpavlin 242 $sth->{insert_backups}->execute(
547     $hostID,
548     $backupNum,
549     $backup->{'endTime'},
550     substr($backup->{'type'},0,4),
551     $shareID,
552     );
553    
554 dpavlin 66 my ($f, $nf, $d, $nd, $size) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);
555 dpavlin 65
556 dpavlin 250 eval {
557     $sth->{update_backups_size}->execute(
558     $size,
559     $hostID,
560     $backupNum,
561     $backup->{'endTime'},
562     substr($backup->{'type'},0,4),
563     $shareID,
564     );
565     print " commit";
566     $dbh->commit();
567     };
568     if ($@) {
569     print " rollback";
570     $dbh->rollback();
571     }
572 dpavlin 65
573 dpavlin 50 my $dur = (time() - $t) || 1;
574 dpavlin 66 printf(" %d/%d files %d/%d dirs %0.2f MB [%.2f/s dur: %s]\n",
575 dpavlin 37 $nf, $f, $nd, $d,
576 dpavlin 66 ($size / 1024 / 1024),
577 dpavlin 50 ( ($f+$d) / $dur ),
578     fmt_time($dur)
579 dpavlin 37 );
580 dpavlin 89
581 dpavlin 107 hest_update($hostID, $shareID, $backupNum) if ($nf + $nd > 0);
582 dpavlin 14 }
583 dpavlin 29
584 dpavlin 6 }
585     }
586 dpavlin 14 undef $sth;
587 dpavlin 6 $dbh->commit();
588     $dbh->disconnect();
589    
590 dpavlin 51 print "total duration: ",fmt_time(time() - $start_t),"\n";
591    
592 dpavlin 38 $pidfile->remove;
593    
594 dpavlin 14 sub getShareID() {
595 dpavlin 6
596 dpavlin 14 my ($share, $hostID, $hostname) = @_;
597    
598     $sth->{share_id} ||= $dbh->prepare(qq{
599     SELECT ID FROM shares WHERE hostID=? AND name=?
600     });
601    
602     $sth->{share_id}->execute($hostID,$share);
603    
604     my ($id) = $sth->{share_id}->fetchrow_array();
605    
606     return $id if (defined($id));
607    
608     $sth->{insert_share} ||= $dbh->prepare(qq{
609     INSERT INTO shares
610 dpavlin 152 (hostID,name,share)
611     VALUES (?,?,?)
612 dpavlin 14 });
613    
614 dpavlin 25 my $drop_down = $hostname . '/' . $share;
615     $drop_down =~ s#//+#/#g;
616    
617 dpavlin 152 $sth->{insert_share}->execute($hostID,$share, $drop_down);
618 dpavlin 49 return $dbh->last_insert_id(undef,undef,'shares',undef);
619 dpavlin 6 }
620    
621 dpavlin 14 sub found_in_db {
622    
623 dpavlin 48 my @data = @_;
624     shift @data;
625 dpavlin 14
626 dpavlin 74 my ($key, $shareID,undef,$name,$path,$date,undef,$size) = @_;
627 dpavlin 48
628     return $beenThere->{$key} if (defined($beenThere->{$key}));
629    
630 dpavlin 14 $sth->{file_in_db} ||= $dbh->prepare(qq{
631 dpavlin 48 SELECT 1 FROM files
632 dpavlin 14 WHERE shareID = ? and
633     path = ? and
634 dpavlin 246 size = ? and
635     ( date = ? or date = ? or date = ? )
636 dpavlin 74 LIMIT 1
637 dpavlin 14 });
638    
639 dpavlin 246 my @param = ($shareID,$path,$size,$date, $date-$dst_offset, $date+$dst_offset);
640 dpavlin 14 $sth->{file_in_db}->execute(@param);
641 dpavlin 48 my $rows = $sth->{file_in_db}->rows;
642 dpavlin 74 print STDERR "## found_in_db($shareID,$path,$date,$size) ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);
643 dpavlin 48
644     $beenThere->{$key}++;
645    
646     $sth->{'insert_files'}->execute(@data) unless ($rows);
647 dpavlin 14 return $rows;
648 dpavlin 6 }
649    
650     ####################################################
651     # recursing through filesystem structure and #
652     # and returning flattened files list #
653     ####################################################
654 dpavlin 14 sub recurseDir($$$$$$$$) {
655 dpavlin 6
656 dpavlin 35 my ($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID) = @_;
657 dpavlin 14
658 dpavlin 44 print STDERR "\nrecurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
659 dpavlin 29
660 dpavlin 66 my ($nr_files, $new_files, $nr_dirs, $new_dirs, $size) = (0,0,0,0,0);
661 dpavlin 14
662 dpavlin 27 { # scope
663 dpavlin 29 my @stack;
664 dpavlin 14
665 dpavlin 45 print STDERR "# dirAttrib($backupNum, $share, $dir)\n" if ($debug >= 2);
666 dpavlin 27 my $filesInBackup = $files->dirAttrib($backupNum, $share, $dir);
667 dpavlin 14
668 dpavlin 27 # first, add all the entries in current directory
669     foreach my $path_key (keys %{$filesInBackup}) {
670 dpavlin 66 print STDERR "# file ",Dumper($filesInBackup->{$path_key}),"\n" if ($debug >= 3);
671 dpavlin 27 my @data = (
672     $shareID,
673     $backupNum,
674     $path_key,
675     $filesInBackup->{$path_key}->{'relPath'},
676     $filesInBackup->{$path_key}->{'mtime'},
677     $filesInBackup->{$path_key}->{'type'},
678     $filesInBackup->{$path_key}->{'size'}
679     );
680    
681     my $key = join(" ", (
682     $shareID,
683     $dir,
684     $path_key,
685     $filesInBackup->{$path_key}->{'mtime'},
686     $filesInBackup->{$path_key}->{'size'}
687     ));
688    
689 dpavlin 242 my $key_dst_prev = join(" ", (
690 dpavlin 240 $shareID,
691     $dir,
692     $path_key,
693     $filesInBackup->{$path_key}->{'mtime'} - $dst_offset,
694     $filesInBackup->{$path_key}->{'size'}
695     ));
696    
697 dpavlin 242 my $key_dst_next = join(" ", (
698 dpavlin 240 $shareID,
699     $dir,
700     $path_key,
701     $filesInBackup->{$path_key}->{'mtime'} + $dst_offset,
702     $filesInBackup->{$path_key}->{'size'}
703     ));
704    
705 dpavlin 70 my $found;
706 dpavlin 240 if (
707     ! defined($beenThere->{$key}) &&
708 dpavlin 242 ! defined($beenThere->{$key_dst_prev}) &&
709     ! defined($beenThere->{$key_dst_next}) &&
710 dpavlin 240 ! ($found = found_in_db($key, @data))
711     ) {
712 dpavlin 30 print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
713 dpavlin 48
714 dpavlin 27 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
715 dpavlin 70 $new_dirs++ unless ($found);
716 dpavlin 30 print STDERR " dir\n" if ($debug >= 2);
717 dpavlin 27 } else {
718 dpavlin 70 $new_files++ unless ($found);
719 dpavlin 30 print STDERR " file\n" if ($debug >= 2);
720 dpavlin 27 }
721 dpavlin 66 $size += $filesInBackup->{$path_key}->{'size'} || 0;
722 dpavlin 27 }
723    
724 dpavlin 14 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
725 dpavlin 27 $nr_dirs++;
726    
727 dpavlin 29 my $full_path = $dir . '/' . $path_key;
728     push @stack, $full_path;
729 dpavlin 30 print STDERR "### store to stack: $full_path\n" if ($debug >= 3);
730 dpavlin 29
731 dpavlin 27 # my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $path_key, $shareID) unless ($beenThere->{$key});
732     #
733     # $nr_files += $f;
734     # $new_files += $nf;
735     # $nr_dirs += $d;
736     # $new_dirs += $nd;
737    
738 dpavlin 14 } else {
739 dpavlin 27 $nr_files++;
740 dpavlin 14 }
741     }
742    
743 dpavlin 30 print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
744 dpavlin 14
745 dpavlin 29 while ( my $dir = shift @stack ) {
746 dpavlin 66 my ($f,$nf,$d,$nd, $s) = recurseDir($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID);
747 dpavlin 30 print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
748 dpavlin 29 $nr_files += $f;
749     $new_files += $nf;
750     $nr_dirs += $d;
751     $new_dirs += $nd;
752 dpavlin 66 $size += $s;
753 dpavlin 29 }
754 dpavlin 14 }
755    
756 dpavlin 66 return ($nr_files, $new_files, $nr_dirs, $new_dirs, $size);
757 dpavlin 6 }
758    

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26