/[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 48 - (show annotations)
Sat Aug 20 14:13:58 2005 UTC (18 years, 8 months ago) by dpavlin
File size: 9207 byte(s)
some speedups, I think this is most I can do without changing database

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26