/[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 52 - (hide annotations)
Sat Aug 20 16:45:02 2005 UTC (18 years, 9 months ago) by dpavlin
File size: 9797 byte(s)
schema fix

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     " files\n";
245 dpavlin 14
246     $sth->{backups_broj}->execute($hostID, $backupNum);
247     my ($broj) = $sth->{backups_broj}->fetchrow_array();
248     next if ($broj > 0);
249    
250 dpavlin 49 $sth->{insert_backups}->execute(
251     $hostID,
252     $backupNum,
253     $backup->{'endTime'},
254     $backup->{'type'}
255     );
256     $dbh->commit();
257    
258 dpavlin 34 my $files = BackupPC::View->new($bpc, $hostname, \@backups, 1);
259 dpavlin 14 foreach my $share ($files->shareList($backupNum)) {
260    
261 dpavlin 37 my $t = time();
262    
263     print strftime($t_fmt,localtime())," ", $share;
264 dpavlin 14 $shareID = getShareID($share, $hostID, $hostname);
265    
266 dpavlin 35 my ($f, $nf, $d, $nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);
267 dpavlin 50 my $dur = (time() - $t) || 1;
268     printf(" %d/%d files %d/%d dirs [%.2f/s dur: %s]\n",
269 dpavlin 37 $nf, $f, $nd, $d,
270 dpavlin 50 ( ($f+$d) / $dur ),
271     fmt_time($dur)
272 dpavlin 37 );
273 dpavlin 14 $dbh->commit();
274     }
275 dpavlin 29
276 dpavlin 6 }
277     }
278 dpavlin 14 undef $sth;
279 dpavlin 6 $dbh->commit();
280     $dbh->disconnect();
281    
282 dpavlin 51 print "total duration: ",fmt_time(time() - $start_t),"\n";
283    
284 dpavlin 38 $pidfile->remove;
285    
286 dpavlin 14 sub getShareID() {
287 dpavlin 6
288 dpavlin 14 my ($share, $hostID, $hostname) = @_;
289    
290     $sth->{share_id} ||= $dbh->prepare(qq{
291     SELECT ID FROM shares WHERE hostID=? AND name=?
292     });
293    
294     $sth->{share_id}->execute($hostID,$share);
295    
296     my ($id) = $sth->{share_id}->fetchrow_array();
297    
298     return $id if (defined($id));
299    
300     $sth->{insert_share} ||= $dbh->prepare(qq{
301     INSERT INTO shares
302     (hostID,name,share,localpath)
303     VALUES (?,?,?,?)
304     });
305    
306 dpavlin 25 my $drop_down = $hostname . '/' . $share;
307     $drop_down =~ s#//+#/#g;
308    
309     $sth->{insert_share}->execute($hostID,$share, $drop_down ,undef);
310 dpavlin 49 return $dbh->last_insert_id(undef,undef,'shares',undef);
311 dpavlin 6 }
312    
313 dpavlin 14 sub found_in_db {
314    
315 dpavlin 48 my @data = @_;
316     shift @data;
317 dpavlin 14
318 dpavlin 48 my ($key, $shareID,undef,$name,$path,undef,$date,undef,$size) = @_;
319    
320     return $beenThere->{$key} if (defined($beenThere->{$key}));
321    
322 dpavlin 14 $sth->{file_in_db} ||= $dbh->prepare(qq{
323 dpavlin 48 SELECT 1 FROM files
324 dpavlin 14 WHERE shareID = ? and
325     path = ? and
326     name = ? and
327     date = ? and
328     size = ?
329     });
330    
331     my @param = ($shareID,$path,$name,$date,$size);
332     $sth->{file_in_db}->execute(@param);
333 dpavlin 48 my $rows = $sth->{file_in_db}->rows;
334 dpavlin 45 print STDERR "## found_in_db ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);
335 dpavlin 48
336     $beenThere->{$key}++;
337    
338     $sth->{'insert_files'}->execute(@data) unless ($rows);
339 dpavlin 14 return $rows;
340 dpavlin 6 }
341    
342     ####################################################
343     # recursing through filesystem structure and #
344     # and returning flattened files list #
345     ####################################################
346 dpavlin 14 sub recurseDir($$$$$$$$) {
347 dpavlin 6
348 dpavlin 35 my ($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID) = @_;
349 dpavlin 14
350 dpavlin 44 print STDERR "\nrecurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
351 dpavlin 29
352 dpavlin 14 my ($nr_files, $new_files, $nr_dirs, $new_dirs) = (0,0,0,0);
353    
354 dpavlin 27 { # scope
355 dpavlin 29 my @stack;
356 dpavlin 14
357 dpavlin 45 print STDERR "# dirAttrib($backupNum, $share, $dir)\n" if ($debug >= 2);
358 dpavlin 27 my $filesInBackup = $files->dirAttrib($backupNum, $share, $dir);
359 dpavlin 14
360 dpavlin 27 # first, add all the entries in current directory
361     foreach my $path_key (keys %{$filesInBackup}) {
362     my @data = (
363     $shareID,
364     $backupNum,
365     $path_key,
366     $filesInBackup->{$path_key}->{'relPath'},
367     $filesInBackup->{$path_key}->{'fullPath'},
368     # $filesInBackup->{$path_key}->{'sharePathM'},
369     $filesInBackup->{$path_key}->{'mtime'},
370     $filesInBackup->{$path_key}->{'type'},
371     $filesInBackup->{$path_key}->{'size'}
372     );
373    
374     my $key = join(" ", (
375     $shareID,
376     $dir,
377     $path_key,
378     $filesInBackup->{$path_key}->{'mtime'},
379     $filesInBackup->{$path_key}->{'size'}
380     ));
381    
382    
383 dpavlin 48 if (! defined($beenThere->{$key}) && ! found_in_db($key, @data)) {
384 dpavlin 30 print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
385 dpavlin 48
386 dpavlin 27 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
387     $new_dirs++;
388 dpavlin 30 print STDERR " dir\n" if ($debug >= 2);
389 dpavlin 27 } else {
390     $new_files++;
391 dpavlin 30 print STDERR " file\n" if ($debug >= 2);
392 dpavlin 27 }
393     }
394    
395 dpavlin 14 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
396 dpavlin 27 $nr_dirs++;
397    
398 dpavlin 29 my $full_path = $dir . '/' . $path_key;
399     push @stack, $full_path;
400 dpavlin 30 print STDERR "### store to stack: $full_path\n" if ($debug >= 3);
401 dpavlin 29
402 dpavlin 27 # my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $path_key, $shareID) unless ($beenThere->{$key});
403     #
404     # $nr_files += $f;
405     # $new_files += $nf;
406     # $nr_dirs += $d;
407     # $new_dirs += $nd;
408    
409 dpavlin 14 } else {
410 dpavlin 27 $nr_files++;
411 dpavlin 14 }
412     }
413    
414 dpavlin 30 print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
415 dpavlin 14
416 dpavlin 29 while ( my $dir = shift @stack ) {
417 dpavlin 35 my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $files, $backupNum, $share, $dir, $shareID);
418 dpavlin 30 print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
419 dpavlin 29 $nr_files += $f;
420     $new_files += $nf;
421     $nr_dirs += $d;
422     $new_dirs += $nd;
423     }
424 dpavlin 14 }
425    
426     return ($nr_files, $new_files, $nr_dirs, $new_dirs);
427 dpavlin 6 }
428    

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26