/[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 57 - (hide annotations)
Sun Aug 21 14:25:46 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 9935 byte(s)
print start time and duration of each backup

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 48
15 dpavlin 6 use constant BPC_FTYPE_DIR => 5;
16    
17 dpavlin 30 my $debug = 0;
18 dpavlin 14 $|=1;
19 dpavlin 6
20 dpavlin 51 my $start_t = time();
21    
22 dpavlin 38 my $pidfile = new File::Pid;
23    
24     if (my $pid = $pidfile->running ) {
25     die "$0 already running: $pid\n";
26     } elsif ($pidfile->pid ne $$) {
27     $pidfile->remove;
28     $pidfile = new File::Pid;
29     }
30 dpavlin 39 $pidfile->write;
31     print STDERR "$0 using pid ",$pidfile->pid," file ",$pidfile->file,"\n";
32 dpavlin 38
33 dpavlin 37 my $t_fmt = '%Y-%m-%d %H:%M:%S';
34    
35 dpavlin 6 my $hosts;
36     my $bpc = BackupPC::Lib->new || die;
37     my %Conf = $bpc->Conf();
38     my $TopDir = $bpc->TopDir();
39 dpavlin 14 my $beenThere = {};
40 dpavlin 6
41 dpavlin 51 my $dsn = $Conf{SearchDSN} || die "Need SearchDSN in config.pl\n";
42     my $user = $Conf{SearchUser} || '';
43 dpavlin 6
44 dpavlin 49 my $dbh = DBI->connect($dsn, $user, "", { RaiseError => 1, AutoCommit => 0 });
45    
46 dpavlin 6 my %opt;
47    
48 dpavlin 44 if ( !getopts("cdm:v:", \%opt ) ) {
49 dpavlin 6 print STDERR <<EOF;
50 dpavlin 44 usage: $0 [-c|-d] [-m num] [-v|-v level]
51 dpavlin 6
52     Options:
53 dpavlin 14 -c create database on first use
54     -d delete database before import
55     -m num import just num increments for one host
56 dpavlin 44 -v num set verbosity (debug) level (default $debug)
57 dpavlin 6 EOF
58     exit 1;
59     }
60    
61     ###################################create tables############################3
62    
63 dpavlin 14 if ($opt{c}) {
64 dpavlin 49 sub do_index {
65     my $index = shift || return;
66     my ($table,$col,$unique) = split(/_/, $index);
67     $unique ||= '';
68 dpavlin 52 $index =~ s/,/_/g;
69 dpavlin 49 $dbh->do(qq{ create $unique index $index on $table($col) });
70     }
71    
72 dpavlin 14 print "creating tables...\n";
73 dpavlin 6
74 dpavlin 14 $dbh->do(qq{
75     create table hosts (
76 dpavlin 49 ID SERIAL PRIMARY KEY,
77 dpavlin 14 name VARCHAR(30) NOT NULL,
78     IP VARCHAR(15)
79 dpavlin 6 );
80 dpavlin 14 });
81 dpavlin 6
82 dpavlin 14 $dbh->do(qq{
83     create table shares (
84 dpavlin 49 ID SERIAL PRIMARY KEY,
85 dpavlin 14 hostID INTEGER NOT NULL references hosts(id),
86     name VARCHAR(30) NOT NULL,
87     share VARCHAR(200) NOT NULL,
88     localpath VARCHAR(200)
89 dpavlin 6 );
90 dpavlin 14 });
91 dpavlin 6
92 dpavlin 14 $dbh->do(qq{
93     create table backups (
94     hostID INTEGER NOT NULL references hosts(id),
95     num INTEGER NOT NULL,
96 dpavlin 49 date integer NOT NULL,
97     type CHAR(4) not null,
98 dpavlin 14 PRIMARY KEY(hostID, num)
99 dpavlin 6 );
100 dpavlin 14 });
101 dpavlin 6
102 dpavlin 52 do_index('backups_hostid,num_unique');
103 dpavlin 49
104 dpavlin 14 $dbh->do(qq{
105     create table dvds (
106 dpavlin 49 ID SERIAL PRIMARY KEY,
107 dpavlin 14 num INTEGER NOT NULL,
108     name VARCHAR(255) NOT NULL,
109     mjesto VARCHAR(255)
110 dpavlin 6 );
111 dpavlin 14 });
112 dpavlin 6
113 dpavlin 14 $dbh->do(qq{
114     create table files (
115 dpavlin 49 ID SERIAL PRIMARY KEY,
116 dpavlin 14 shareID INTEGER NOT NULL references shares(id),
117 dpavlin 52 backupNum INTEGER NOT NULL,
118 dpavlin 14 name VARCHAR(255) NOT NULL,
119     path VARCHAR(255) NOT NULL,
120     fullpath VARCHAR(255) NOT NULL,
121 dpavlin 49 date integer NOT NULL,
122 dpavlin 14 type INTEGER NOT NULL,
123     size INTEGER NOT NULL,
124     dvdid INTEGER references dvds(id)
125 dpavlin 6 );
126 dpavlin 14 });
127 dpavlin 6
128 dpavlin 49 print "creating indexes:";
129 dpavlin 6
130 dpavlin 14 foreach my $index (qw(
131     hosts_name
132     backups_hostID
133     backups_num
134     shares_hostID
135     shares_name
136     files_shareID
137     files_path
138     files_name
139     files_date
140     files_size
141     )) {
142 dpavlin 49 print " $index";
143     do_index($index);
144 dpavlin 14 }
145 dpavlin 49 print "...\n";
146 dpavlin 14
147 dpavlin 49 $dbh->commit;
148 dpavlin 14
149     }
150    
151     if ($opt{d}) {
152     print "deleting ";
153 dpavlin 49 foreach my $table (qw(files dvds backups shares hosts)) {
154 dpavlin 14 print "$table ";
155     $dbh->do(qq{ DELETE FROM $table });
156     }
157     print " done...\n";
158 dpavlin 49
159 dpavlin 51 $dbh->commit;
160 dpavlin 14 }
161    
162 dpavlin 32 if ($opt{v}) {
163     print "Debug level at $opt{v}\n";
164     $debug = $opt{v};
165     }
166    
167 dpavlin 6 #################################INSERT VALUES#############################
168    
169     # get hosts
170 dpavlin 8 $hosts = $bpc->HostInfoRead();
171 dpavlin 6 my $hostID;
172     my $shareID;
173    
174 dpavlin 14 my $sth;
175 dpavlin 6
176 dpavlin 14 $sth->{insert_hosts} = $dbh->prepare(qq{
177     INSERT INTO hosts (name, IP) VALUES (?,?)
178     });
179 dpavlin 6
180 dpavlin 14 $sth->{hosts_by_name} = $dbh->prepare(qq{
181     SELECT ID FROM hosts WHERE name=?
182     });
183    
184     $sth->{backups_broj} = $dbh->prepare(qq{
185     SELECT COUNT(*)
186     FROM backups
187     WHERE hostID=? AND num=?
188     });
189    
190     $sth->{insert_backups} = $dbh->prepare(qq{
191     INSERT INTO backups (hostID, num, date, type)
192     VALUES (?,?,?,?)
193     });
194    
195     $sth->{insert_files} = $dbh->prepare(qq{
196     INSERT INTO files
197     (shareID, backupNum, name, path, fullpath, date, type, size)
198     VALUES (?,?,?,?,?,?,?,?)
199     });
200    
201 dpavlin 50 sub fmt_time {
202     my $t = shift || return;
203     my $out = "";
204     my ($ss,$mm,$hh) = gmtime($t);
205     $out .= "${hh}h" if ($hh);
206     $out .= sprintf("%02d:%02d", $mm,$ss);
207     return $out;
208     }
209    
210 dpavlin 14 foreach my $host_key (keys %{$hosts}) {
211    
212     my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";
213    
214     $sth->{hosts_by_name}->execute($hosts->{$host_key}->{'host'});
215    
216     unless (($hostID) = $sth->{hosts_by_name}->fetchrow_array()) {
217     $sth->{insert_hosts}->execute(
218     $hosts->{$host_key}->{'host'},
219     $hosts->{$host_key}->{'ip'}
220     );
221    
222 dpavlin 49 $hostID = $dbh->last_insert_id(undef,undef,'hosts',undef);
223 dpavlin 14 }
224    
225     print("host ".$hosts->{$host_key}->{'host'}.": ");
226 dpavlin 6
227 dpavlin 14 # get backups for a host
228     my @backups = $bpc->BackupInfoRead($hostname);
229     print scalar @backups, " increments\n";
230 dpavlin 6
231 dpavlin 14 my $inc_nr = 0;
232    
233     foreach my $backup (@backups) {
234 dpavlin 40
235 dpavlin 14 $inc_nr++;
236     last if ($opt{m} && $inc_nr > $opt{m});
237    
238     my $backupNum = $backup->{'num'};
239     my @backupShares = ();
240    
241 dpavlin 40 print $hosts->{$host_key}->{'host'},
242 dpavlin 44 "\t#$backupNum\t", $backup->{type} || '?', " ",
243 dpavlin 40 $backup->{nFilesNew} || '?', "/", $backup->{nFiles} || '?',
244 dpavlin 57 " files (date: ",
245     strftime($t_fmt,localtime($backup->{startTime})),
246     " dur: ",
247     fmt_time($backup->{endTime} - $backup->{startTime}),
248     ")\n";
249 dpavlin 14
250     $sth->{backups_broj}->execute($hostID, $backupNum);
251     my ($broj) = $sth->{backups_broj}->fetchrow_array();
252     next if ($broj > 0);
253    
254 dpavlin 49 $sth->{insert_backups}->execute(
255     $hostID,
256     $backupNum,
257     $backup->{'endTime'},
258     $backup->{'type'}
259     );
260     $dbh->commit();
261    
262 dpavlin 34 my $files = BackupPC::View->new($bpc, $hostname, \@backups, 1);
263 dpavlin 14 foreach my $share ($files->shareList($backupNum)) {
264    
265 dpavlin 37 my $t = time();
266    
267     print strftime($t_fmt,localtime())," ", $share;
268 dpavlin 14 $shareID = getShareID($share, $hostID, $hostname);
269    
270 dpavlin 35 my ($f, $nf, $d, $nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);
271 dpavlin 50 my $dur = (time() - $t) || 1;
272     printf(" %d/%d files %d/%d dirs [%.2f/s dur: %s]\n",
273 dpavlin 37 $nf, $f, $nd, $d,
274 dpavlin 50 ( ($f+$d) / $dur ),
275     fmt_time($dur)
276 dpavlin 37 );
277 dpavlin 14 $dbh->commit();
278     }
279 dpavlin 29
280 dpavlin 6 }
281     }
282 dpavlin 14 undef $sth;
283 dpavlin 6 $dbh->commit();
284     $dbh->disconnect();
285    
286 dpavlin 51 print "total duration: ",fmt_time(time() - $start_t),"\n";
287    
288 dpavlin 38 $pidfile->remove;
289    
290 dpavlin 14 sub getShareID() {
291 dpavlin 6
292 dpavlin 14 my ($share, $hostID, $hostname) = @_;
293    
294     $sth->{share_id} ||= $dbh->prepare(qq{
295     SELECT ID FROM shares WHERE hostID=? AND name=?
296     });
297    
298     $sth->{share_id}->execute($hostID,$share);
299    
300     my ($id) = $sth->{share_id}->fetchrow_array();
301    
302     return $id if (defined($id));
303    
304     $sth->{insert_share} ||= $dbh->prepare(qq{
305     INSERT INTO shares
306     (hostID,name,share,localpath)
307     VALUES (?,?,?,?)
308     });
309    
310 dpavlin 25 my $drop_down = $hostname . '/' . $share;
311     $drop_down =~ s#//+#/#g;
312    
313     $sth->{insert_share}->execute($hostID,$share, $drop_down ,undef);
314 dpavlin 49 return $dbh->last_insert_id(undef,undef,'shares',undef);
315 dpavlin 6 }
316    
317 dpavlin 14 sub found_in_db {
318    
319 dpavlin 48 my @data = @_;
320     shift @data;
321 dpavlin 14
322 dpavlin 48 my ($key, $shareID,undef,$name,$path,undef,$date,undef,$size) = @_;
323    
324     return $beenThere->{$key} if (defined($beenThere->{$key}));
325    
326 dpavlin 14 $sth->{file_in_db} ||= $dbh->prepare(qq{
327 dpavlin 48 SELECT 1 FROM files
328 dpavlin 14 WHERE shareID = ? and
329     path = ? and
330     name = ? and
331     date = ? and
332     size = ?
333     });
334    
335     my @param = ($shareID,$path,$name,$date,$size);
336     $sth->{file_in_db}->execute(@param);
337 dpavlin 48 my $rows = $sth->{file_in_db}->rows;
338 dpavlin 45 print STDERR "## found_in_db ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);
339 dpavlin 48
340     $beenThere->{$key}++;
341    
342     $sth->{'insert_files'}->execute(@data) unless ($rows);
343 dpavlin 14 return $rows;
344 dpavlin 6 }
345    
346     ####################################################
347     # recursing through filesystem structure and #
348     # and returning flattened files list #
349     ####################################################
350 dpavlin 14 sub recurseDir($$$$$$$$) {
351 dpavlin 6
352 dpavlin 35 my ($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID) = @_;
353 dpavlin 14
354 dpavlin 44 print STDERR "\nrecurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
355 dpavlin 29
356 dpavlin 14 my ($nr_files, $new_files, $nr_dirs, $new_dirs) = (0,0,0,0);
357    
358 dpavlin 27 { # scope
359 dpavlin 29 my @stack;
360 dpavlin 14
361 dpavlin 45 print STDERR "# dirAttrib($backupNum, $share, $dir)\n" if ($debug >= 2);
362 dpavlin 27 my $filesInBackup = $files->dirAttrib($backupNum, $share, $dir);
363 dpavlin 14
364 dpavlin 27 # first, add all the entries in current directory
365     foreach my $path_key (keys %{$filesInBackup}) {
366     my @data = (
367     $shareID,
368     $backupNum,
369     $path_key,
370     $filesInBackup->{$path_key}->{'relPath'},
371     $filesInBackup->{$path_key}->{'fullPath'},
372     # $filesInBackup->{$path_key}->{'sharePathM'},
373     $filesInBackup->{$path_key}->{'mtime'},
374     $filesInBackup->{$path_key}->{'type'},
375     $filesInBackup->{$path_key}->{'size'}
376     );
377    
378     my $key = join(" ", (
379     $shareID,
380     $dir,
381     $path_key,
382     $filesInBackup->{$path_key}->{'mtime'},
383     $filesInBackup->{$path_key}->{'size'}
384     ));
385    
386    
387 dpavlin 48 if (! defined($beenThere->{$key}) && ! found_in_db($key, @data)) {
388 dpavlin 30 print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
389 dpavlin 48
390 dpavlin 27 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
391     $new_dirs++;
392 dpavlin 30 print STDERR " dir\n" if ($debug >= 2);
393 dpavlin 27 } else {
394     $new_files++;
395 dpavlin 30 print STDERR " file\n" if ($debug >= 2);
396 dpavlin 27 }
397     }
398    
399 dpavlin 14 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
400 dpavlin 27 $nr_dirs++;
401    
402 dpavlin 29 my $full_path = $dir . '/' . $path_key;
403     push @stack, $full_path;
404 dpavlin 30 print STDERR "### store to stack: $full_path\n" if ($debug >= 3);
405 dpavlin 29
406 dpavlin 27 # my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $path_key, $shareID) unless ($beenThere->{$key});
407     #
408     # $nr_files += $f;
409     # $new_files += $nf;
410     # $nr_dirs += $d;
411     # $new_dirs += $nd;
412    
413 dpavlin 14 } else {
414 dpavlin 27 $nr_files++;
415 dpavlin 14 }
416     }
417    
418 dpavlin 30 print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
419 dpavlin 14
420 dpavlin 29 while ( my $dir = shift @stack ) {
421 dpavlin 35 my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID);
422 dpavlin 30 print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
423 dpavlin 29 $nr_files += $f;
424     $new_files += $nf;
425     $nr_dirs += $d;
426     $new_dirs += $nd;
427     }
428 dpavlin 14 }
429    
430     return ($nr_files, $new_files, $nr_dirs, $new_dirs);
431 dpavlin 6 }
432    

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26