/[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 45 - (show annotations)
Sat Aug 20 11:39:05 2005 UTC (18 years, 9 months ago) by dpavlin
File size: 9099 byte(s)
fine-tune debug output, profile target

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26