/[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 38 - (show annotations)
Fri Aug 19 15:27:27 2005 UTC (18 years, 9 months ago) by dpavlin
File size: 8811 byte(s)
maintain pid file in /tmp/BackuPC_update.pid

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26