/[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 51 - (show annotations)
Sat Aug 20 16:40:11 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 9793 byte(s)
added SearchDSN and SearchUser configuration directives. Defaults are
probably useful only to me :-)
Added total duration display to BackupPC_updatedb

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26