← Index
NYTProf Performance Profile   « line view »
For /usr/local/bin/sa-learn
  Run on Tue Nov 7 05:38:10 2017
Reported on Tue Nov 7 06:16:01 2017

Filename/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Conf/SQL.pm
StatementsExecuted 14 statements in 1.92ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11145µs241µsMail::SpamAssassin::Conf::SQL::::BEGIN@44Mail::SpamAssassin::Conf::SQL::BEGIN@44
11126µs40µsMail::SpamAssassin::Conf::SQL::::BEGIN@46Mail::SpamAssassin::Conf::SQL::BEGIN@46
11124µs31µsMail::SpamAssassin::Conf::SQL::::BEGIN@48Mail::SpamAssassin::Conf::SQL::BEGIN@48
11123µs102µsMail::SpamAssassin::Conf::SQL::::BEGIN@49Mail::SpamAssassin::Conf::SQL::BEGIN@49
11121µs59µsMail::SpamAssassin::Conf::SQL::::BEGIN@47Mail::SpamAssassin::Conf::SQL::BEGIN@47
11120µs104µsMail::SpamAssassin::Conf::SQL::::BEGIN@51Mail::SpamAssassin::Conf::SQL::BEGIN@51
0000s0sMail::SpamAssassin::Conf::SQL::::__ANON__[:104]Mail::SpamAssassin::Conf::SQL::__ANON__[:104]
0000s0sMail::SpamAssassin::Conf::SQL::::loadMail::SpamAssassin::Conf::SQL::load
0000s0sMail::SpamAssassin::Conf::SQL::::load_modulesMail::SpamAssassin::Conf::SQL::load_modules
0000s0sMail::SpamAssassin::Conf::SQL::::load_with_dbiMail::SpamAssassin::Conf::SQL::load_with_dbi
0000s0sMail::SpamAssassin::Conf::SQL::::newMail::SpamAssassin::Conf::SQL::new
0000s0sMail::SpamAssassin::Conf::SQL::::sa_dieMail::SpamAssassin::Conf::SQL::sa_die
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# <@LICENSE>
2# Licensed to the Apache Software Foundation (ASF) under one or more
3# contributor license agreements. See the NOTICE file distributed with
4# this work for additional information regarding copyright ownership.
5# The ASF licenses this file to you under the Apache License, Version 2.0
6# (the "License"); you may not use this file except in compliance with
7# the License. You may obtain a copy of the License at:
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# </@LICENSE>
17
18=head1 NAME
19
20Mail::SpamAssassin::Conf::SQL - load SpamAssassin scores from SQL database
21
22=head1 SYNOPSIS
23
24 (see Mail::SpamAssassin)
25
26
27=head1 DESCRIPTION
28
29Mail::SpamAssassin is a module to identify spam using text analysis and
30several internet-based realtime blacklists.
31
32This class is used internally by SpamAssassin to load scores from an SQL
33database. Please refer to the C<Mail::SpamAssassin> documentation for public
34interfaces.
35
36=head1 METHODS
37
38=over 4
39
40=cut
41
42package Mail::SpamAssassin::Conf::SQL;
43
44283µs2437µs
# spent 241µs (45+196) within Mail::SpamAssassin::Conf::SQL::BEGIN@44 which was called: # once (45µs+196µs) by Mail::SpamAssassin::BEGIN@72 at line 44
use Mail::SpamAssassin::Logger;
# spent 241µs making 1 call to Mail::SpamAssassin::Conf::SQL::BEGIN@44 # spent 196µs making 1 call to Exporter::import
45
46268µs254µs
# spent 40µs (26+14) within Mail::SpamAssassin::Conf::SQL::BEGIN@46 which was called: # once (26µs+14µs) by Mail::SpamAssassin::BEGIN@72 at line 46
use strict;
# spent 40µs making 1 call to Mail::SpamAssassin::Conf::SQL::BEGIN@46 # spent 14µs making 1 call to strict::import
47269µs297µs
# spent 59µs (21+38) within Mail::SpamAssassin::Conf::SQL::BEGIN@47 which was called: # once (21µs+38µs) by Mail::SpamAssassin::BEGIN@72 at line 47
use warnings;
# spent 59µs making 1 call to Mail::SpamAssassin::Conf::SQL::BEGIN@47 # spent 38µs making 1 call to warnings::import
48274µs238µs
# spent 31µs (24+7) within Mail::SpamAssassin::Conf::SQL::BEGIN@48 which was called: # once (24µs+7µs) by Mail::SpamAssassin::BEGIN@72 at line 48
use bytes;
# spent 31µs making 1 call to Mail::SpamAssassin::Conf::SQL::BEGIN@48 # spent 7µs making 1 call to bytes::import
49267µs2180µs
# spent 102µs (23+79) within Mail::SpamAssassin::Conf::SQL::BEGIN@49 which was called: # once (23µs+79µs) by Mail::SpamAssassin::BEGIN@72 at line 49
use re 'taint';
# spent 102µs making 1 call to Mail::SpamAssassin::Conf::SQL::BEGIN@49 # spent 78µs making 1 call to re::import
50
5112µs
# spent 104µs (20+83) within Mail::SpamAssassin::Conf::SQL::BEGIN@51 which was called: # once (20µs+83µs) by Mail::SpamAssassin::BEGIN@72 at line 53
use vars qw{
52 @ISA
5311.54ms2187µs};
# spent 104µs making 1 call to Mail::SpamAssassin::Conf::SQL::BEGIN@51 # spent 83µs making 1 call to vars::import
54
5518µs@ISA = qw();
56
57###########################################################################
58
59sub new {
60 my $class = shift;
61 $class = ref($class) || $class;
62 my ($main) = @_;
63
64 my $self = {
65 'main' => $main
66 };
67
68 bless ($self, $class);
69 $self;
70}
71
72###########################################################################
73
74sub load_modules { # static
75 eval {
76 require DBI;
77 };
78
79 # do any other preloading that will speed up operation
80}
81
82###########################################################################
83
84=item $f->load ($username)
85
86Read configuration paramaters from SQL database and parse scores from it.
87
88=back
89
90=cut
91
92sub load {
93 my ($self, $username) = @_;
94
95 my $conf = $self->{main}->{conf};
96 my $dsn = $conf->{user_scores_dsn};
97 if (!defined($dsn) || $dsn eq '') {
98 dbg("config: no DSN defined; skipping sql");
99 return 1;
100 }
101
102 eval {
103 # make sure we can see croak messages from DBI
104 local $SIG{'__DIE__'} = sub { die "$_[0]"; };
105 require DBI;
106 load_with_dbi($self, $username, $dsn);
107 1;
108 } or do {
109 my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
110 if ($conf->{user_scores_fail_to_global}) {
111 info("config: failed to load user (%s) scores from SQL database, ".
112 "using a global default: %s", $username, $eval_stat);
113 return 1;
114 } else {
115 warn sprintf(
116 "config: failed to load user (%s) scores from SQL database: %s\n",
117 $username, $eval_stat);
118 return 0;
119 }
120 };
121 return 1;
122}
123
124sub load_with_dbi {
125 my ($self, $username, $dsn) = @_;
126
127 my $main = $self->{main};
128 my $conf = $main->{conf};
129 my $dbuser = $conf->{user_scores_sql_username};
130 my $dbpass = $conf->{user_scores_sql_password};
131 my $custom_query = $conf->{user_scores_sql_custom_query};
132
133 my $f_preference = 'preference';
134 my $f_value = 'value';
135 my $f_username = 'username';
136 my $f_table = 'userpref';
137
138 my $dbh = DBI->connect($dsn, $dbuser, $dbpass, {'PrintError' => 0});
139
140 if ($dbh) {
141 my $sql;
142 if (defined($custom_query)) {
143 $sql = $custom_query;
144 my $quoted_username = $dbh->quote($username);
145 my ($mailbox, $domain) = split('@', $username);
146 my $quoted_mailbox = $dbh->quote($mailbox);
147 my $quoted_domain = $dbh->quote($domain);
148
149 $sql =~ s/_USERNAME_/$quoted_username/g;
150 $sql =~ s/_TABLE_/$f_table/g;
151 $sql =~ s/_MAILBOX_/$quoted_mailbox/g;
152 $sql =~ s/_DOMAIN_/$quoted_domain/g;
153 }
154 else {
155 $sql = "select $f_preference, $f_value from $f_table where ".
156 "$f_username = ".$dbh->quote($username).
157 " or $f_username = '\@GLOBAL' order by $f_username asc";
158 }
159 dbg("config: Conf::SQL: executing SQL: $sql");
160 my $sth = $dbh->prepare($sql);
161 if ($sth) {
162 my $rv = $sth->execute();
163 if ($rv) {
164 dbg("config: retrieving prefs for $username from SQL server");
165 my @row;
166 my $config_text = '';
167 while (@row = $sth->fetchrow_array()) {
168 $config_text .= (defined($row[0]) ? $row[0] : '') . "\t" .
169 (defined($row[1]) ? $row[1] : '') . "\n";
170 }
171 if ($config_text ne '') {
172 $conf->{main} = $main;
173 $conf->parse_scores_only($config_text);
174 delete $conf->{main};
175 }
176 $sth->finish();
177 undef $sth;
178 }
179 else {
180 die "config: SQL error: $sql\n".$sth->errstr."\n";
181 }
182 }
183 else {
184 die "config: SQL error: " . $dbh->errstr . "\n";
185 }
186 $dbh->disconnect();
187 }
188 else {
189 die "config: SQL error: " . DBI->errstr . "\n";
190 }
191}
192
193###########################################################################
194
195sub sa_die { Mail::SpamAssassin::sa_die(@_); }
196
197###########################################################################
198
19918µs1;