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 )