## W3C W3C::Database::LogInterface - W3C PERL Library

#Copyright Massachusetts Institute of technology, 1998.
#Written by Eric Prud'hommeaux
#Last revision, $Date: 1999/12/14 13:14:39 $

#things that need to be done:
#1. decide whether to use RESOURCE, KEYS, GNAMES

package W3C::Database::LogInterface;
use W3C::Database::DBIInterface;
use vars qw(@ISA, @EXPORT, @EXPORT_OK);
use Exporter;
@ISA = ('W3C::Database::DBIInterface', 'Exporter');
@EXPORT_OK = qw($ACCESS_CHLOG, $ACCESS_RLOG);

require 5.000;

$W3C::Database::LogInterface::revision = '$Id: LogInterface.pm,v 1.8 1999/12/14 13:14:39 eric Exp $ ';
$W3C::Database::LogInterface::VERSION = 0.96;

use Carp;

#####
# constants


use strict;

#####
# per-class data

my $Debugging = 0;	# whether to show debugging stuff

#####
# per-object data
# RESOURCE	- *unused*
# KEYS		- *unused*
# GNAMES	- *unused*
# DEBUG		- per-object control of debugging info

#####
# new - prepare a W3C::Database::LogInterface with a new connection

sub new {
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $database = shift;
    $database = 'w3cla' if (!defined $database);
    my $self = $class->SUPER::new($database, 'manual', 'manual6', 0, shift, shift); # !!! must be 0 for real production
    $self->{DATABASE} = $database;
    $self->{AS_NOS} = {};
    $self->{NET_NOS} = {};
    $self->{SERVER_NOS} = {};
    $self->{USE_SERVER} = undef;
    bless ($self, $class);
    return $self;
}

sub getAsNo {
    my $self = shift;
    my $asName = shift;
    my $asNo = $self->{AS_NOS}{$asName};
    return $asNo if (defined $asNo);

    # didn't exist so add to asns table
    my $escASName = $self->escape($asName);
    eval {
	$asNo = $self->executeSingleQuery('select id from asns where asn='.$escASName);
    }; if ($@ ne '') {
	$self->executeUpdate('insert into asns (asn) values ('.$escASName.')');
	$asNo = $self->executeSingleQuery('select id from asns where asn='.$escASName);
    }
    $self->{AS_NOS}{$asName} = $asNo;
    return $asNo;
}

sub getNetNo {
    my $self = shift;
    my $netName = $self->canonicalNetName(shift);
    my $netNo = $self->{NET_NOS}{$netName};
    return $netNo if (defined $netNo);

    # didn't exist so add to nets table
    my $escNetName = $self->escape($netName);
    eval {
	$netNo = $self->executeSingleQuery('select id from nets where net='.$escNetName);
    }; if ($@ ne '') {
	$self->executeUpdate('insert into nets (net) values ('.$escNetName.')');
	$netNo = $self->executeSingleQuery('select id from nets where net='.$escNetName);
    }
    $self->{NET_NOS}{$netName} = $netNo;
    return $netNo;
}

sub getServerNo {
    my $self = shift;
    my $serverName = shift;
    my $serverNo = $self->{SERVER_NOS}{$serverName};
    return $serverNo if (defined $serverNo);

    # didn't exist so add to servers table
    my $escServerName = $self->escape($serverName);
    eval {
	$serverNo = $self->executeSingleQuery('select id from servers where server='.$escServerName);
    }; if ($@ ne '') {
	$self->executeUpdate('insert into servers (server) values ('.$escServerName.')');
	$serverNo = $self->executeSingleQuery('select id from servers where server='.$escServerName);
    }
    $self->{SERVER_NOS}{$serverName} = $serverNo;
    return $serverNo;
}

sub canonicalNetName {
    my $self = shift;
    my $netName = shift;
    $netName =~ s/(\.\*)//g;
    return $netName;
}

sub computeAS {
    my $self = shift;
    my @ip=split(/\./, shift);
    foreach my $net (("$ip[0].$ip[1].$ip[2]", "$ip[0].$ip[1]", "$ip[0]")) {
	my $as = $self->{AS_NAMES}{$net};
	return $as if (defined $as);
    }

    # consult nets table with single query
    my $list = "'$ip[0].$ip[1].$ip[2]','$ip[0].$ip[1]','$ip[0]'";
    my @netAsn;
    # produces: select nets.net,netAsn.asn from nets,netAsn 
    # where nets.net in ('128.243.241','128.243','128') and nets.id=netAsn.net order by nets.net limit 1
    $self->executeWideQuery(\@netAsn, 'select nets.net,netAsn.asn from nets,netAsn where nets.net in ('.$list.
			    ') and nets.id=netAsn.net order by nets.net limit 1');
    if (defined $netAsn[0]) {
	$self->{SERVER_NOS}{$netAsn[0]} = $netAsn[1];
	return $netAsn[1];
    }
    return $self->getAsNo('AS_UNKNOWN');
}

sub importRawAsns {
    my $self = shift;
    my (@nets, %asns);
    $self->executeQuery(\@nets, \%asns, 'select net,asn from raw');
    foreach my $net (@nets) {
	$self->executeUpdate('insert into netAsn (net,asn) values('.$self->getNetNo($net).','.$self->getAsNo($asns{$net}).')');
    }
}

sub checkSummaryTables {
    my $self = shift;
    # Checks that the table exists
    foreach my $table ('asns', 'summaries', 'servers') {
	die "Table $table doesn't exist in database ".$self->{DATABASE}.".\n" if (!$self->tableExists($table));
    }
}

sub prepareSummaryFor {
    my $self = shift;
    $self->{USE_SERVER} = $self->getServerNo(shift);
    $self->{USE_DATE} = shift;
    $self->executeUpdate('delete from summaries where server='.$self->{USE_SERVER}.
			 ' and date="'.$self->{USE_DATE}.'"'); # otherwise we keep appending to it.
}

sub addSummaryEntry {
    my $self = shift;
    my ($as, $nb_requete, $size_requete, $time_requete) = @_;
    $as = $self->getAsNo($as) if ($as !~ /\A\d+\Z/); # if it has letters, get the DB id for it.
    $self->executeUpdate('INSERT INTO summaries (server, asn, date, nbRequest, size, time) VALUES ('.
			 $self->{USE_SERVER}.", $as, \'".$self->{USE_DATE}.
			 "\', $nb_requete, $size_requete, $time_requete)");
}

1;

