#!/usr/bin/perl
#
# Удаляет старые данные о трафике из базы.
#

use warnings;
use strict;

use DBI;
use Sys::Syslog qw(:standard :macros);
use File::Basename;
use Getopt::Long;

# используемые константы
my $config = "/etc/trafstat/trafstat.conf";
our $daemon = '';
my $help = '';

# получим параметры командной строки
GetOptions("config=s" => \$config, "help" => \$help, "daemon" => \$daemon);
if ($help) {help(); exit;}

# получим пользователя и пароль для доступа к базе
my ($db_name, $db_user, $db_pass) = ("", "", "");
open(CONFIG, $config) or error("Failed open cofig file: $config");
while (<CONFIG>) {
	next if /^#|^$|^\[/;
	SWITCH: {
		/^db_name\s*=\s*(\w+)/ && do {$db_name = $1; last SWITCH;};
		/^db_user\s*=\s*(\w+)/ && do {$db_user = $1; last SWITCH;};
		/^db_pass\s*=\s*(\w+)/ && do {$db_pass = $1; last SWITCH;};
	}
}
close(CONFIG);

# подключимся к базе
my $dbh = DBI->connect("DBI:mysql:database=$db_name", $db_user, $db_pass,
	{PrintError => 0}) or error("Connect to database failed: $DBI::errstr");

#
# Удалим старый трафик из таблицы текущего трафика 'traffic_cur'.
#

# получим количество дней хранения трафика в таблице 'traffic_cur'
my $query = "select value from config where name = 'storage_current_traf'";
my $strgCurrTraf = $dbh->selectrow_array($query);
error("Failed execute query '$query': " . $dbh->errstr) if $dbh->err;

# удалим устаревший трафик из таблицы 'traffic_cur'
$strgCurrTraf += 0;  # необходим числовой контекст
if ($strgCurrTraf) {
	# Так как столбец 'data' имеет формат 'YYYY-MM-DD HH:MM:SS' а сравнение
	# выполняется с форматом 'YYYY-MM-DD' при удалении, что равносильно сравнению с
	# 'YYYY-MM-DD 00:00:00'. По это причине крайний день удаляться не будет.
	# Что бы данные в крайнем дне так же удалялись, уменьшим количество
	# удаляемых дней на 1.
	my $day = $strgCurrTraf - 1;
	$query = "delete from traffic_cur where date <= subdate(curdate(), interval $day day)";
	$dbh->do($query) or error("Failed execute query '$query': " . $dbh->errstr);
} else {
	warning("Missing the 'storage_current_traf'.");
}

#
# Удалим старый трафик из таблиц архивного трафика 'traffic_YEAR'.
#

# получим количество лет хранения архивного трафика
$query = "select value from config where name = 'storage_annual_traf'";
my $strgAnTraf = $dbh->selectrow_array($query);
error("Failed execute query '$query': " . $dbh->errstr) if $dbh->err;

# удалим старые таблицы с трафиком
$strgAnTraf += 0;  # необходим числовой контекст
if ($strgAnTraf) {
	# получим список хранимых таблиц архивного трафика
	my @years;
	$query = "select year from list_traffic order by year desc";
	my $sth = $dbh->prepare($query) or error("Failed prepare query '$query': " . $dbh->errstr);
	$sth->execute() or error("Failed execute query '$query': " . $dbh->errstr);
	while (my ($year) = $sth->fetchrow_array()) {push(@years, $year);}
	$sth->finish();

	# удалим старый архивный трафик
	for (my $i = $strgAnTraf; $i < @years; $i++) {
		my $year = $years[$i];

		$query = "delete from list_traffic where year = $year";
		$dbh->do($query) or error("Failed execute query '$query': " . $dbh->errstr);

		$query = "drop table traffic_$year";
		$dbh->do($query) or error("Failed execute query '$query': " . $dbh->errstr);
	}
} else {
	warning("Missing the 'storage_annual_traf'.");
}

$dbh->disconnect();
exit(0);

# вывод сообщения об ошибке
sub warning {
	my $str = shift;
	my $msg = "WARNING: $str";

	if ($daemon) {
		openlog(basename($0), "ndelay,pid", LOG_LOCAL0);
		syslog(LOG_WARNING, $msg);
		closelog();
	} else {
		warn("$msg\n");
	}
}

# вывод сообщения об ошибке и завершение работы
sub error {
	my $str = shift;
	my $msg = "ERROR: $str";

	if ($daemon) {
		openlog(basename($0), "ndelay,pid", LOG_LOCAL0);
		syslog(LOG_ERR, $msg);
		closelog();
		exit(1);
	} else {
		die("$msg\n");
	}
}

# отображает справку
sub help {
	my $progName = basename($0);
	print("Usage: $progName [OPTIONS]...\n" .
		"Deletes old data from the database.\n" .
		"\n" .
		"  --config=NAME  use a configuration file\n" .
		"  --daemon       run in daemon mode\n" .
		"  --help         display this help and exit\n" .
		"\n");
}
