#!/usr/bin/perl -w use strict; use DBI; use Data::Dumper; use Data::TreeDumper; # Define variables my $db; my $user; my $pass; my $host; my $dbh; my $stime; my $etime; my $endtime; my %hash; ## DB data $db = "ofrs"; $user = "ofrs"; $pass = "ofrs"; $host = "localhost"; # Connect to DB $dbh = DBI->connect("DBI:mysql:$db:$host", $user, $pass); # Set time before import $stime = time; # Sync a replication folder on the disk with the database checkFS("/data/test1"); # Set time after import $etime = time; $endtime = ($etime - $stime); # Print needed time print "Needed $endtime seconds ...\n"; # Creates a hash tree for a replication folder using the pathes in the database # Syntax: makeTree($repFolder) # Return Value: hash-tree (hash) sub makeTree { # Set & define the variables my $path = $_[0]; my $tree={}; # Set query my $query = "SELECT path FROM dir WHERE path = '$path';"; # Run query my $sth = $dbh->prepare($query); $sth->execute(); # Use the query results ... while (my @result = $sth->fetchrow_array) { my $path = $result[0]; # ... and add each path to the hash-tree addToTree($tree,$path); } # return the hash-tree return $tree; } # add a Path to the hash-tree # Syntax: addToTree($tree,$path) # Return value: none sub addToTree { # Set & define the variables my $tree = $_[0]; my $path = $_[1]; # Split the path up to its parts my @parts = split('/',$path); # Delete the first (empty) part shift @parts; # Delete the trailing slash at the end of the path if exists my $file=1; unless($parts[-1]) { $file=0; pop(@parts); } # build the hash-tree for this path my $ref=\$tree; $ref=\$$ref->{$_} for(@parts); } # build the pathes from the hash-tree # Syntax: buildPathes($tree) # Return value: path-list (array-reference) sub buildPathes { # Set & define variables my $tree=shift; my $path=shift // ''; my @list; # walk through all levels and sort them for my $name (sort(keys(%$tree))) { my $elm=$tree->{$name}; if($elm && ref($elm) eq 'HASH') { # run the function recursive my $lst=buildPathes($elm,"$path/$name"); push(@list,@$lst); } else { push(@list,"$path/$name"); } } # return the list of pathes from the hash-tree return \@list; } # sync a replication folder on the disk with the database # Syntax: checkFS($repPath) # Return value: none sub checkFS { # Set & define variables my $path = $_[0]; # create the hash-tree for this path / replication folder my $tree = makeTree($path); # check if the folder on the disk exists in the database checkFolder($path, $tree); # build the pathes from the hashes left in the hash-tree my $onlyDB = buildPathes($tree); # print the pathes out print "OnlyDB-Pathes:\n"; print Dumper($onlyDB); # foreach my $path (@$onlyDB) { # DELETE THE MISSING FOLDERS FROM THE DATABASE # } } # check a folder and its subfolder if they exists in the hash-tree # Syntax: checkFolder($path, $tree) # Return value: none sub checkFolder { # Set variables my @subfolders; my $path; my @parts; my $name; my $hash; my $tmphash; my $found; my $childNotFound; # Load arguments into variables if (-d $_[0]) { $path = $_[0]; # Load path into variable } else { # Exit script if no path is specified print "Error: No valid path specified\n"; exit(1); } if (defined($_[1])) { $hash = $_[1]; # Load hash into variable } else { # Exit script if no hash is specified print "Error: No hash specified\n"; exit(1); } # Set variables $childNotFound = 0; # split the path to its parts @parts=split(/\//, $path); shift @parts; $name = $parts[-1]; $found = 0; $tmphash = \%hash; for (my $i = 0; $i < @parts; $i++) { # walk through each part of the path my $part = $parts[$i]; if(defined($tmphash->{$part})) { # Does the part exists in the hash-tree? if($i == @parts-1) { # Is this the last part of the path? $found=1; # Yes, the folder is in the database! } else { # Not the last part of the path $tmphash=$tmphash->{$part}; # Go one level further } } else { last; # The path is not in the database } } if ($found == 0) { # Insert current directory into DB # Set query my $query = "INSERT INTO dir (path) VALUES (\"$path\");"; # Run query $dbh->do($query); } # Open the current directory opendir (DIR, $path) or die "Unable to open $path: $!"; # Exclude "." and ".." my @files = grep { !/^\.{1,2}$/ } readdir (DIR); # Close directory closedir (DIR); # Set the full path for all files @files = map { $path . '/' . $_ } @files; # Write each subfolder into the array @subfolders foreach my $file (@files) { if (-d $file) { push (@subfolders, $file) } } # If there are any subfolders then ... if (@subfolders > 0) { foreach my $subfolder (@subfolders) { # ... put the subfolder into the DB using the subfolder's path and the id of the current directory $childNotFound = checkFolder($subfolder, \%hash); } } # if this directory was found in the path and if it has no subfolders, then delete it from the hash-tree if ($found == 1 && !keys(%{$tmphash->{$name}})) { delete $tmphash->{$name}; return 0; } else { # return 1 if this folder is either not in the hash-tree or if this directory has subfolders return 1; } }