App-Milter-Limit-Plugin-SQLite
view release on metacpan or search on metacpan
lib/App/Milter/Limit/Plugin/SQLite.pm view on Meta::CPAN
sub init {
my $self = shift;
$self->_init_defaults;
App::Milter::Limit::Util::make_path($self->config_get('driver', 'home'));
$self->table( $self->config_get('driver', 'table') );
# setup the database
$self->_init_database;
}
sub _init_defaults {
my $self = shift;
$self->config_defaults('driver',
home => $self->config_get('global', 'state_dir'),
file => 'stats.db',
table => 'milter');
}
sub db_file {
my $self = shift;
my $home = $self->config_get('driver', 'home');
my $file = $self->config_get('driver', 'file');
return File::Spec->catfile($home, $file);
}
sub _new_dbh {
my $self = shift;
# setup connection to the database.
my $db_file = $self->db_file;
my $dbh = DBI->connect("dbi:SQLite:dbname=$db_file", '', '', {
PrintError => 0,
AutoCommit => 1 })
or die "failed to initialize SQLite: $!";
return $dbh;
}
# initialize the database
sub _init_database {
my $self = shift;
# setup connection to the database.
$self->_dbh($self->_new_dbh);
unless ($self->_table_exists($self->table)) {
$self->_create_table($self->table);
}
# make sure the db file has the right owner.
my $uid = $self->config_get('global', 'user');
my $gid = $self->config_get('global', 'group');
if (defined $uid and defined $gid) {
my $db_file = $self->db_file;
chown $uid, $gid, $db_file or die "chown($db_file): $!";
}
}
sub child_init {
my $self = shift;
debug("reopen db handle");
if (my $dbh = $self->_dbh) {
$dbh->disconnect;
$dbh = $self->_new_dbh;
$self->_dbh($dbh);
}
}
sub child_exit {
my $self = shift;
debug("close db handle");
if (my $dbh = $self->_dbh) {
$dbh->disconnect;
}
}
sub query {
my ($self, $from) = @_;
$from = lc $from;
my $rec = $self->_retrieve($from);
unless (defined $rec) {
# initialize new record for sender
$rec = $self->_create($from)
or return 0; # I give up
}
my $start = $$rec{first_seen} || time;
my $count = $$rec{messages} || 0;
my $expire = $self->config_get('global', 'expire');
# reset counter if it is expired
if ($start < time - $expire) {
$self->_reset($from);
return 1;
}
# update database for this sender.
$self->_update($from);
return $count + 1;
}
# return true if the given table exists in the db.
sub _table_exists {
my ($self, $table) = @_;
$self->_dbh->do("select 1 from $table limit 0")
or return 0;
( run in 0.471 second using v1.01-cache-2.11-cpan-5735350b133 )