/[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 67 - (hide annotations)
Mon Aug 22 08:58:59 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 10284 byte(s)
small speedup and nicer output

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26