1 #!/usr/local/bin/perl -w
5 use lib "__INSTALLDIR__/lib";
10 use constant BPC_FTYPE_DIR => 5;
16 my $bpc = BackupPC::Lib->new || die;
17 my %Conf = $bpc->Conf();
18 my $TopDir = $bpc->TopDir();
21 my $dsn = "dbi:SQLite:dbname=$TopDir/$Conf{SearchDB}";
23 my $dbh = DBI->connect($dsn, "", "", { RaiseError => 1, AutoCommit => 0 });
27 if ( !getopts("cdm:", \%opt ) ) {
29 usage: $0 [-c|-d] [-m num]
32 -c create database on first use
33 -d delete database before import
34 -m num import just num increments for one host
39 ###################################create tables############################3
42 print "creating tables...\n";
46 ID INTEGER PRIMARY KEY,
47 name VARCHAR(30) NOT NULL,
54 ID INTEGER PRIMARY KEY,
55 hostID INTEGER NOT NULL references hosts(id),
56 name VARCHAR(30) NOT NULL,
57 share VARCHAR(200) NOT NULL,
58 localpath VARCHAR(200)
63 create table backups (
64 hostID INTEGER NOT NULL references hosts(id),
68 PRIMARY KEY(hostID, num)
74 ID INTEGER PRIMARY KEY,
76 name VARCHAR(255) NOT NULL,
83 ID INTEGER NOT NULL PRIMARY KEY,
84 shareID INTEGER NOT NULL references shares(id),
85 backupNum INTEGER NOT NULL references backups(num),
86 name VARCHAR(255) NOT NULL,
87 path VARCHAR(255) NOT NULL,
88 fullpath VARCHAR(255) NOT NULL,
89 date TIMESTAMP NOT NULL,
90 type INTEGER NOT NULL,
91 size INTEGER NOT NULL,
92 dvdid INTEGER references dvds(id)
96 print "creating indexes...\n";
98 foreach my $index (qw(
110 my ($table,$col) = split(/_/, $index);
111 $dbh->do(qq{ create index $index on $table($col) });
119 foreach my $table (qw(hosts shares files dvds backups)) {
121 $dbh->do(qq{ DELETE FROM $table });
126 #################################INSERT VALUES#############################
129 $hosts = $bpc->HostInfoRead();
135 $sth->{insert_hosts} = $dbh->prepare(qq{
136 INSERT INTO hosts (name, IP) VALUES (?,?)
139 $sth->{hosts_by_name} = $dbh->prepare(qq{
140 SELECT ID FROM hosts WHERE name=?
143 $sth->{backups_broj} = $dbh->prepare(qq{
146 WHERE hostID=? AND num=?
149 $sth->{insert_backups} = $dbh->prepare(qq{
150 INSERT INTO backups (hostID, num, date, type)
154 $sth->{insert_files} = $dbh->prepare(qq{
156 (shareID, backupNum, name, path, fullpath, date, type, size)
157 VALUES (?,?,?,?,?,?,?,?)
160 foreach my $host_key (keys %{$hosts}) {
162 my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";
164 $sth->{hosts_by_name}->execute($hosts->{$host_key}->{'host'});
166 unless (($hostID) = $sth->{hosts_by_name}->fetchrow_array()) {
167 $sth->{insert_hosts}->execute(
168 $hosts->{$host_key}->{'host'},
169 $hosts->{$host_key}->{'ip'}
172 $hostID = $dbh->func('last_insert_rowid');
175 print("host ".$hosts->{$host_key}->{'host'}.": ");
177 # get backups for a host
178 my @backups = $bpc->BackupInfoRead($hostname);
179 print scalar @backups, " increments\n";
183 foreach my $backup (@backups) {
185 last if ($opt{m} && $inc_nr > $opt{m});
187 my $backupNum = $backup->{'num'};
188 my @backupShares = ();
190 print $hosts->{$host_key}->{'host'},"\t#$backupNum\n";
192 $sth->{backups_broj}->execute($hostID, $backupNum);
193 my ($broj) = $sth->{backups_broj}->fetchrow_array();
196 my $files = BackupPC::View->new($bpc, $hostname, \@backups);
197 foreach my $share ($files->shareList($backupNum)) {
200 $shareID = getShareID($share, $hostID, $hostname);
202 my ($f, $nf, $d, $nd) = recurseDir($bpc, $hostname, \@backups, $backupNum, $share, "", $shareID);
203 print " $nf/$f files $nd/$d dirs\n";
207 $sth->{insert_backups}->execute(
210 $backup->{'endTime'},
223 my ($share, $hostID, $hostname) = @_;
225 $sth->{share_id} ||= $dbh->prepare(qq{
226 SELECT ID FROM shares WHERE hostID=? AND name=?
229 $sth->{share_id}->execute($hostID,$share);
231 my ($id) = $sth->{share_id}->fetchrow_array();
233 return $id if (defined($id));
235 $sth->{insert_share} ||= $dbh->prepare(qq{
237 (hostID,name,share,localpath)
241 my $drop_down = $hostname . '/' . $share;
242 $drop_down =~ s#//+#/#g;
244 $sth->{insert_share}->execute($hostID,$share, $drop_down ,undef);
245 return $dbh->func('last_insert_rowid');
250 my ($shareID,undef,$name,$path,undef,$date,undef,$size) = @_;
252 $sth->{file_in_db} ||= $dbh->prepare(qq{
253 SELECT count(*) FROM files
254 WHERE shareID = ? and
261 my @param = ($shareID,$path,$name,$date,$size);
262 $sth->{file_in_db}->execute(@param);
263 my ($rows) = $sth->{file_in_db}->fetchrow_array();
264 # print STDERR ( $rows ? '+' : '-' ), join(" ",@param), "\n";
268 ####################################################
269 # recursing through filesystem structure and #
270 # and returning flattened files list #
271 ####################################################
272 sub recurseDir($$$$$$$$) {
274 my ($bpc, $hostname, $backups, $backupNum, $share, $dir, $shareID) = @_;
276 print STDERR "recurse($hostname,$backupNum,$share,$dir,$shareID)\n" if ($debug >= 1);
278 my ($nr_files, $new_files, $nr_dirs, $new_dirs) = (0,0,0,0);
283 my $files = BackupPC::View->new($bpc, $hostname, $backups);
284 my $filesInBackup = $files->dirAttrib($backupNum, $share, $dir);
286 # first, add all the entries in current directory
287 foreach my $path_key (keys %{$filesInBackup}) {
292 $filesInBackup->{$path_key}->{'relPath'},
293 $filesInBackup->{$path_key}->{'fullPath'},
294 # $filesInBackup->{$path_key}->{'sharePathM'},
295 $filesInBackup->{$path_key}->{'mtime'},
296 $filesInBackup->{$path_key}->{'type'},
297 $filesInBackup->{$path_key}->{'size'}
300 my $key = join(" ", (
304 $filesInBackup->{$path_key}->{'mtime'},
305 $filesInBackup->{$path_key}->{'size'}
309 if (! $beenThere->{$key} && ! found_in_db(@data)) {
310 print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
311 $sth->{'insert_files'}->execute(@data);
312 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
314 print STDERR " dir\n" if ($debug >= 2);
317 print STDERR " file\n" if ($debug >= 2);
320 $beenThere->{$key}++;
322 if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {
325 my $full_path = $dir . '/' . $path_key;
326 push @stack, $full_path;
327 print STDERR "### store to stack: $full_path\n" if ($debug >= 3);
329 # my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $path_key, $shareID) unless ($beenThere->{$key});
341 print STDERR "## STACK ",join(", ", @stack),"\n" if ($debug >= 2);
343 while ( my $dir = shift @stack ) {
344 my ($f,$nf,$d,$nd) = recurseDir($bpc, $hostname, $backups, $backupNum, $share, $dir, $shareID);
345 print STDERR "# $dir f: $f nf: $nf d: $d nd: $nd\n" if ($debug >= 1);
353 return ($nr_files, $new_files, $nr_dirs, $new_dirs);