Mail-DMARC

 view release on metacpan or  search on metacpan

lib/Mail/DMARC/Report/Store/SQL.pm  view on Meta::CPAN

    }
    my $query = $self->grammar->insert_rr_spf( \@fields );
    $self->query( $query, [ $row_id, @values ] );
    return 1;
}

sub insert_rr( $self, $report_id, $rec ) {
    $report_id or croak "report ID required?!";
    my $query = $self->grammar->insert_rr;

    my $ip = $rec->row->source_ip;
    $ip = $self->any_inet_pton($ip) if $self->grammar->language ne 'postgresql';
    my @args = ( $report_id, $ip, $rec->{row}{count}, );
    foreach my $f (qw/ header_from envelope_to envelope_from /) {
        push @args,
            $rec->identifiers->$f
            ? $self->get_domain_id( $rec->identifiers->$f )
            : undef;
    }
    push @args, map { $rec->row->policy_evaluated->$_ } qw/ disposition dkim spf /;
    my $rr_id = $self->query( $query, \@args ) or croak;
    return $self->{report_row_id} = $rr_id;
}

sub insert_policy_published( $self, $id, $pub ) {
    my $query = $self->grammar->insert_policy_published;
    $self->query( $query, [ $id, @$pub{qw/ adkim aspf p sp pct rua /} ] );
    return 1;
}

sub db_connect($self) {

    my $dsn  = $self->config->{report_store}{dsn} or croak;
    my $user = $self->config->{report_store}{user};
    my $pass = $self->config->{report_store}{pass};

    # cacheing
    if ( $self->{grammar} && $self->{dbix} ) {
        my $cached_grammar_type = $self->{grammar}->dsn;
        if ( $dsn =~ /$cached_grammar_type/ ) {
            return $self->{dbix};    # caching
        }
    }

    my $needs_tables;

    $self->{grammar} = undef;
    my %opts;

    if ( $dsn =~ /sqlite/i ) {
        my ($db) = ( split /=/, $dsn )[-1];
        if ( !$db || $db eq ':memory:' || !-e $db ) {
            my $schema = 'mail_dmarc_schema.sqlite';
            $needs_tables = $self->get_db_schema($schema)
                or croak
                "can't locate DB $db AND can't find $schema! Create $db manually.\n";
        }
        $self->{grammar} = Mail::DMARC::Report::Store::SQL::Grammars::SQLite->new();
    }
    elsif ( $dsn =~ /mysql/i ) {
        $opts{'mysql_enable_utf8mb4'} = 1;
        $self->{grammar} = Mail::DMARC::Report::Store::SQL::Grammars::MySQL->new();
    }
    elsif ( $dsn =~ /pg/i ) {
        $self->{grammar}
            = Mail::DMARC::Report::Store::SQL::Grammars::PostgreSQL->new();
    }
    else {
        croak "can't determine database type, so unable to load grammar.\n";
    }

    $self->{dbix} = DBIx::Simple->connect( $dsn, $user, $pass, \%opts )
        or return $self->error( DBIx::Simple->error );

    if ($needs_tables) {
        $self->apply_db_schema($needs_tables);
    }

    return $self->{dbix};
}

sub db_check_err( $self, $err ) {
    ## no critic (PackageVars)
    return if !defined $DBI::errstr;
    return if !$DBI::errstr;
    return if $DBI::errstr eq 'DBI error: ';
    croak $err . $DBI::errstr;
}

sub dbix($self) {
    return $self->{dbix} if $self->{dbix};
    return $self->db_connect();
}

sub apply_db_schema( $self, $file ) {
    my $setup = $self->slurp($file);
    foreach ( split /;/, $setup ) {

        # warn "$_\n";
        $self->dbix->query($_);
    }
    return;
}

sub get_db_schema( $self, $file ) {
    return "share/$file" if -f "share/$file";                   # when testing
    return File::ShareDir::dist_file( 'Mail-DMARC', $file );    # when installed
}

sub query( $self, $query, $params = undef, @extra ) {

    my @c   = caller;
    my $err = sprintf( "query called by %s, %s\n", $c[0], $c[2] ) . "\t$query\n\t";

    my @params;
    if ( defined $params ) {
        @params = ref $params eq 'ARRAY' ? @$params : $params;
        no warnings;    ## no critic (NoWarnings)
        $err .= join( ', ', @params );
    }



( run in 1.652 second using v1.01-cache-2.11-cpan-d06a3f9ecfd )