#!/dataserfs/libs-2024-01-11/bin/perl -w

use strict;

	#
	# ddu-purge-old-scans
	#
	# spd+svc
	# driven by root crontab
	#
	#





delete @ENV{'PATH','IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
$ENV{'PATH'} = '/bin:/usr/bin';

use DBI;
use File::FcntlLock;
use Carp::Assert;


my $SCAN_MAX_DAYS	= 30; 	# for scans
my $OLD_TREES_MAX_DAYS	= 15; 	# for old_trees

my $db  	= "ddu";
my $db_host  	= "localhost";
my $db_user  	= "ddu";
my $db_pw  	= "ddu";

my $lockfile	= "/var/run/ddu-purge-old-scans.lock";
my $logfile	= "/var/log/ddu-purge-old-scans.log";

my $TIMEOUT = 12 * 3600;	# 12 hours

my @MysqlOptions = qw(  DBI:MariaDB:
                        mariadb_server_prepare=0
                        mariadb_read_default_file=/etc/my.cnf );





# #####################################################################
sub CloseDB{ my( $dbh ) = @_;
# #####################################################################
	assert($dbh);
        $dbh->disconnect();
} # CloseDB



# #####################################################################
# $port is optional
sub OpenDB{my($host,$database,$db_user,$db_pass, $port) = @_;
# #####################################################################
	assert($host);
	assert($database);
	assert($db_user);
	assert($db_pass);
	# port may be NULL

my $dsn = join(';', @MysqlOptions, "host=$host", "database=$database");
        if ( defined $port ) {
                $dsn .= ";port=$port";          # add port if defined
        } # if

        my $dbh = DBI->connect($dsn, $db_user, $db_pass);

 return($dbh);
} # OpenDB
# #####################################################################



# #####################################################################
sub purge_old{my($dbh) = @_;
# #####################################################################
	assert($dbh);

my $cutoff = time() - ($OLD_TREES_MAX_DAYS * 24 * 3600);
	$dbh->do(qq{
		DELETE FROM old_trees
		WHERE	begutc < ?
		},undef,
		$cutoff);
} # purge_old



# #####################################################################
sub delete_scans{my($dbh) = @_;
# #####################################################################
	assert($dbh);

my $cutoff = time() - ($OLD_TREES_MAX_DAYS * 24 * 3600);
#print STDERR "cutoff ",scalar localtime($cutoff),"\n";

	my $oldies = $dbh->selectall_arrayref(qq{
				SELECT	scanno,root_sha1,site,begutc
				FROM	scans
				WHERE	begutc < ?
				ORDER BY begutc
				},  {Slice => {}},
				$cutoff);


	foreach my $r (@$oldies ) {
		print "dropping scanno $$r{scanno}, $$r{root_sha1}, $$r{site}, ", scalar localtime($$r{begutc}),"\n";
		$dbh->do(qq{ DROP TABLE IF EXISTS tree_$$r{root_sha1} });
		$dbh->do(qq{ DELETE FROM scans where scanno = ? LIMIT 1},
			undef,$$r{scanno});
		$dbh->do(qq{ DELETE FROM old_trees where scanno = ? LIMIT 1},
			undef,$$r{scanno});
	}
} # delete_scans










# #####################################################################
sub main_thing{my($scan_max_days) =@_;
# #####################################################################

	$scan_max_days = $SCAN_MAX_DAYS if( !$scan_max_days);


	#open(STDOUT,">>$logfile") || die( "logfile $!");
	#open(STDERR,">>$logfile") || die( "logfile $!");

	# lock to make sure we run only once
	# open for append ( i.e. create if needed )
	open(LOCK, ">>$lockfile" ) || die( "lockfile $!");
	my $fs = new File::FcntlLock( l_type => F_WRLCK);
	if ( ! defined $fs->lock(\*LOCK, F_SETLK) ) {
		#unable to lock
		exit (0) if ( $fs->error =~ /already locked/ );
		die("unable to lock: $!, " . $fs->error);
	} # if


my $dbh = OpenDB($db_host,$db,$db_user,$db_pw) ||
		die("cannot connect to db '$db' on '$db_host' as '$db_user'");

	$dbh->{RaiseError} = 1;
	$dbh->{AutoCommit} = 1;

	delete_scans($dbh);
	purge_old($dbh);

	CloseDB($dbh);
	close(LOCK);


} # main_thing



main_thing(@ARGV);
