/[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 29 - (show annotations)
Sun Jul 31 12:40:51 2005 UTC (18 years, 9 months ago) by dpavlin
File size: 8154 byte(s)
bug squashing fest: moved stack in recurseDir in proper scope (which will save memory),
recurse always through all directories (unfortunate fact that directory mtime doesn't
track changes in sub-directories), insert invrement after all files are inserted

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26