#!/usr/bin/perl

use warnings;
use strict;
use DBI;

my $inBase = "traffic";
my $outBase = "test1";

my ($user, $passwd) = ("root", "");
my ($inDbh, $inSth, $outDbh, $outSth);

$inDbh = DBI->connect("DBI:mysql:host=localhost;database=$inBase",
	$user, $passwd, {PrintError => 0, RaiseError => 1}) or
		die("Connect to database '$inBase' failed: $DBI::errstr");
$outDbh = DBI->connect("DBI:mysql:host=localhost;database=$outBase",
	$user, $passwd, {PrintError => 0, RaiseError => 1}) or
		die("Connect to database '$outBase' failed: $DBI::errstr");

my $inQuery = 'select date, srcIp, dstIp, srcPort, dstPort, pId, bytes, psize ' .
	'from traffic;';
my $outQuery = 'insert into traffic ' .
	'(date, srcIp, dstIp, dstPort, pId, inBytes, outBytes) ' .
	'values(?, ?, ?, ?, ?, ?, ?)';

$inSth = $inDbh->prepare($inQuery) or
	die("Failed 'prepare' query '$inQuery': " . $inDbh->errstr);
$outSth = $outDbh->prepare($outQuery) or
	die("Failed 'prepare' query '$outQuery': " . $outDbh->errstr);

$inSth->execute() or
	die("Failed 'execute' query '$inQuery': " . $inDbh->errstr);

my $count = 0;         # количество обработанных записей
my $countAdd = 0;      # количество перенесенных записей
my $proto = 0;         # протокол не обслуживается
my $portEqual = 0;     # порты равны, не понятно кто источник пакета
my $portNoClient = 0;  # нет нулевого порта, не понятно кто источник пакета

my ($inBytes, $outBytes);

while (my ($date, $srcIp, $dstIp, $srcPort, $dstPort, $pId, $bytes, $psize) = $inSth->fetchrow_array()) {
	# проверим полученную запись
	$count++;
	if ($pId != 1 && $pId != 2) {
		$proto++;
		next;
	} elsif ($dstPort == $srcPort) {
		$portEqual++;
		next;
	} elsif ($dstPort && $srcPort) {
		$portNoClient++;
		next;
	} elsif ($dstPort == 0) {
		my $tmp = $dstIp;
		$dstIp = $srcIp;
		$srcIp = $tmp;
		$dstPort = $srcPort;
		$inBytes = $psize;
		$outBytes = 0;
	} elsif ($srcPort == 0) {
		$inBytes = 0;
		$outBytes = $psize;
	} else {
		die("Error selecting action.\n");
	}

	# округлим значение времени до 30 минут
	my ($d, $t) = $date =~ /^(.+)\s(.+)/;
	my ($hour, $min, $sec) = $t =~ /^(\d+):(\d+):(\d+)/;
	$date = "$d $hour:30:00";

	# добавим трафик к уже имеющемуся в базе
	my $rv = $outDbh->do(qq{update traffic set inBytes = inBytes + $inBytes, outBytes = outBytes + $outBytes
		where date = '$date' && srcIp = '$srcIp' && dstIp = '$dstIp' && dstPort = '$dstPort' && pId = '$pId'}) or
			die("Failed execute 'do' query: " . $outDbh->errstr);

	# если в базе еще нет записи о данном трафике, то добавим ее
	if ($rv eq "0E0") {
		$outSth->execute($date, $srcIp, $dstIp, $dstPort, $pId, $inBytes, $outBytes) or
			die("Failed execute query '$outQuery': " . $outDbh->errstr);
	} elsif ($rv > 1) {
		die("When add data to the database updated more than one record ($rv).");
	}

	$countAdd++;
}

$inSth->finish();
$inDbh->disconnect();
$outDbh->disconnect();

printf("Обработанно записей: %d\n", $count);
printf("Перенесенно записей: %d\n", $countAdd);
printf("Ошибок не обслуживаемых протоколов: %d\n", $proto);
printf("Ошибок одинаковых портов: %d\n", $portEqual);
printf("Ошибок не найденых слиентов: %d\n", $portNoClient);
