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

Contents of /trunk/bin/BackupPC_updatedb

Parent Directory Parent Directory | Revision Log Revision Log


Revision 57 - (show annotations)
Sun Aug 21 14:25:46 2005 UTC (18 years, 9 months ago) by dpavlin
File size: 9935 byte(s)
print start time and duration of each backup

1 #!/usr/local/bin/perl -w
2
3 use strict;
4 use lib "__INSTALLDIR__/lib";
5
6 use DBI;
7 use BackupPC::Lib;
8 use BackupPC::View;
9 use Data::Dumper;
10 use Getopt::Std;
11 use Time::HiRes qw/time/;
12 use File::Pid;
13 use POSIX qw/strftime/;
14
15 use constant BPC_FTYPE_DIR => 5;
16
17 my $debug = 0;
18 $|=1;
19
20 my $start_t = time();
21
22 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 $pidfile->write;
31 print STDERR "$0 using pid ",$pidfile->pid," file ",$pidfile->file,"\n";
32
33 my $t_fmt = '%Y-%m-%d %H:%M:%S';
34
35 my $hosts;
36 my $bpc = BackupPC::Lib->new || die;
37 my %Conf = $bpc->Conf();
38 my $TopDir = $bpc->TopDir();
39 my $beenThere = {};
40
41 my $dsn = $Conf{SearchDSN} || die "Need SearchDSN in config.pl\n";
42 my $user = $Conf{SearchUser} || '';
43
44 my $dbh = DBI->connect($dsn, $user, "", { RaiseError => 1, AutoCommit => 0 });
45
46 my %opt;
47
48 if ( !getopts("cdm:v:", \%opt ) ) {
49 print STDERR <<EOF;
50 usage: $0 [-c|-d] [-m num] [-v|-v level]
51
52 Options:
53 -c create database on first use
54 -d delete database before import
55 -m num import just num increments for one host
56 -v num set verbosity (debug) level (default $debug)
57 EOF
58 exit 1;
59 }
60
61 ###################################create tables############################3
62
63 if ($opt{c}) {
64 sub do_index {
65 my $index = shift || return;
66 my ($table,$col,$unique) = split(/_/, $index);
67 $unique ||= '';
68 $index =~ s/,/_/g;
69 $dbh->do(qq{ create $unique index $index on $table($col) });
70 }
71
72 print "creating tables...\n";
73
74 $dbh->do(qq{
75 create table hosts (
76 ID SERIAL PRIMARY KEY,
77 name VARCHAR(30) NOT NULL,
78 IP VARCHAR(15)
79 );
80 });
81
82 $dbh->do(qq{
83 create table shares (
84 ID SERIAL PRIMARY KEY,
85 hostID INTEGER NOT NULL references hosts(id),
86 name VARCHAR(30) NOT NULL,
87 share VARCHAR(200) NOT NULL,
88 localpath VARCHAR(200)
89 );
90 });
91
92 $dbh->do(qq{
93 create table backups (
94 hostID INTEGER NOT NULL references hosts(id),
95 num INTEGER NOT NULL,
96 date integer NOT NULL,
97 type CHAR(4) not null,
98 PRIMARY KEY(hostID, num)
99 );
100 });
101
102 do_index('backups_hostid,num_unique');
103
104 $dbh->do(qq{
105 create table dvds (
106 ID SERIAL PRIMARY KEY,
107 num INTEGER NOT NULL,
108 name VARCHAR(255) NOT NULL,
109 mjesto VARCHAR(255)
110 );
111 });
112
113 $dbh->do(qq{
114 create table files (
115 ID SERIAL PRIMARY KEY,
116 shareID INTEGER NOT NULL references shares(id),
117 backupNum INTEGER NOT NULL,
118 name VARCHAR(255) NOT NULL,
119 path VARCHAR(255) NOT NULL,
120 fullpath VARCHAR(255) NOT NULL,
121 date integer NOT NULL,
122 type INTEGER NOT NULL,
123 size INTEGER NOT NULL,
124 dvdid INTEGER references dvds(id)
125 );
126 });
127
128 print "creating indexes:";
129
130 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 print " $index";
143 do_index($index);
144 }
145 print "...\n";
146
147 $dbh->commit;
148
149 }
150
151 if ($opt{d}) {
152 print "deleting ";
153 foreach my $table (qw(files dvds backups shares hosts)) {
154 print "$table ";
155 $dbh->do(qq{ DELETE FROM $table });
156 }
157 print " done...\n";
158
159 $dbh->commit;
160 }
161
162 if ($opt{v}) {
163 print "Debug level at $opt{v}\n";
164 $debug = $opt{v};
165 }
166
167 #################################INSERT VALUES#############################
168
169 # get hosts
170 $hosts = $bpc->HostInfoRead();
171 my $hostID;
172 my $shareID;
173
174 my $sth;
175
176 $sth->{insert_hosts} = $dbh->prepare(qq{
177 INSERT INTO hosts (name, IP) VALUES (?,?)
178 });
179
180 $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 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 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 $hostID = $dbh->last_insert_id(undef,undef,'hosts',undef);
223 }
224
225 print("host ".$hosts->{$host_key}->{'host'}.": ");
226
227 # get backups for a host
228 my @backups = $bpc->BackupInfoRead($hostname);
229 print scalar @backups, " increments\n";
230
231 my $inc_nr = 0;
232
233 foreach my $backup (@backups) {
234
235 $inc_nr++;
236 last if ($opt{m} && $inc_nr > $opt{m});
237
238 my $backupNum = $backup->{'num'};
239 my @backupShares = ();
240
241 print $hosts->{$host_key}->{'host'},
242 "\t#$backupNum\t", $backup->{type} || '?', " ",
243 $backup->{nFilesNew} || '?', "/", $backup->{nFiles} || '?',
244 " files (date: ",
245 strftime($t_fmt,localtime($backup->{startTime})),
246 " dur: ",
247 fmt_time($backup->{endTime} - $backup->{startTime}),
248 ")\n";
249
250 $sth->{backups_broj}->execute($hostID, $backupNum);
251 my ($broj) = $sth->{backups_broj}->fetchrow_array();
252 next if ($broj > 0);
253
254 $sth->{insert_backups}->execute(
255 $hostID,
256 $backupNum,
257 $backup->{'endTime'},
258 $backup->{'type'}
259 );
260 $dbh->commit();
261
262 my $files = BackupPC::View->new($bpc, $hostname, \@backups, 1);
263 foreach my $share ($files->shareList($backupNum)) {
264
265 my $t = time();
266
267 print strftime($t_fmt,localtime())," ", $share;
268 $shareID = getShareID($share, $hostID, $hostname);
269
270 my ($f, $nf, $d, $nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);
271 my $dur = (time() - $t) || 1;
272 printf(" %d/%d files %d/%d dirs [%.2f/s dur: %s]\n",
273 $nf, $f, $nd, $d,
274 ( ($f+$d) / $dur ),
275 fmt_time($dur)
276 );
277 $dbh->commit();
278 }
279
280 }
281 }
282 undef $sth;
283 $dbh->commit();
284 $dbh->disconnect();
285
286 print "total duration: ",fmt_time(time() - $start_t),"\n";
287
288 $pidfile->remove;
289
290 sub getShareID() {
291
292 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 my $drop_down = $hostname . '/' . $share;
311 $drop_down =~ s#//+#/#g;
312
313 $sth->{insert_share}->execute($hostID,$share, $drop_down ,undef);
314 return $dbh->last_insert_id(undef,undef,'shares',undef);
315 }
316
317 sub found_in_db {
318
319 my @data = @_;
320 shift @data;
321
322 my ($key, $shareID,undef,$name,$path,undef,$date,undef,$size) = @_;
323
324 return $beenThere->{$key} if (defined($beenThere->{$key}));
325
326 $sth->{file_in_db} ||= $dbh->prepare(qq{
327 SELECT 1 FROM files
328 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 my $rows = $sth->{file_in_db}->rows;
338 print STDERR "## found_in_db ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);
339
340 $beenThere->{$key}++;
341
342 $sth->{'insert_files'}->execute(@data) unless ($rows);
343 return $rows;
344 }
345
346 ####################################################
347 # recursing through filesystem structure and #
348 # and returning flattened files list #
349 ####################################################
350 sub recurseDir($$$$$$$$) {
351
352 my ($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID) = @_;
353
354 print STDERR "\nrecurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
355
356 my ($nr_files, $new_files, $nr_dirs, $new_dirs) = (0,0,0,0);
357
358 { # scope
359 my @stack;
360
361 print STDERR "# dirAttrib($backupNum, $share, $dir)\n" if ($debug >= 2);
362 my $filesInBackup = $files->dirAttrib($backupNum, $share, $dir);
363
364 # 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 if (! defined($beenThere->{$key}) && ! found_in_db($key, @data)) {
388 print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
389
390 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
391 $new_dirs++;
392 print STDERR " dir\n" if ($debug >= 2);
393 } else {
394 $new_files++;
395 print STDERR " file\n" if ($debug >= 2);
396 }
397 }
398
399 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
400 $nr_dirs++;
401
402 my $full_path = $dir . '/' . $path_key;
403 push @stack, $full_path;
404 print STDERR "### store to stack: $full_path\n" if ($debug >= 3);
405
406 # 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 } else {
414 $nr_files++;
415 }
416 }
417
418 print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
419
420 while ( my $dir = shift @stack ) {
421 my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID);
422 print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
423 $nr_files += $f;
424 $new_files += $nf;
425 $nr_dirs += $d;
426 $new_dirs += $nd;
427 }
428 }
429
430 return ($nr_files, $new_files, $nr_dirs, $new_dirs);
431 }
432

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26