288fd2ca59
Resolves: RHEL-43418
328 lines
8.9 KiB
Diff
328 lines
8.9 KiB
Diff
commit 3dd8ea4ff51d50a72212ac8cbb2f6f8d443c3489
|
|
Author: Henrik Krohns <hege@apache.org>
|
|
Date: Sun Apr 10 19:23:45 2022 +0000
|
|
|
|
Properly bind token as SQL_BINARY, allowing DBD::MariaDB driver to work also
|
|
|
|
|
|
git-svn-id: https://svn.apache.org/repos/asf/spamassassin/trunk@1899715 13f79535-47bb-0310-9956-ffa450edef68
|
|
|
|
diff --git a/lib/Mail/SpamAssassin/BayesStore/MySQL.pm b/lib/Mail/SpamAssassin/BayesStore/MySQL.pm
|
|
index c4bfb920c..dac7b6990 100644
|
|
--- a/lib/Mail/SpamAssassin/BayesStore/MySQL.pm
|
|
+++ b/lib/Mail/SpamAssassin/BayesStore/MySQL.pm
|
|
@@ -339,6 +339,147 @@ sub remove_running_expire_tok {
|
|
return 1;
|
|
}
|
|
|
|
+=head2 tok_get
|
|
+
|
|
+public instance (Integer, Integer, Integer) tok_get (String $token)
|
|
+
|
|
+Description:
|
|
+This method retrieves a specified token (C<$token>) from the database
|
|
+and returns it's spam_count, ham_count and last access time.
|
|
+
|
|
+=cut
|
|
+
|
|
+sub tok_get {
|
|
+ my ($self, $token) = @_;
|
|
+
|
|
+ return (0,0,0) unless (defined($self->{_dbh}));
|
|
+
|
|
+ my $sql = "SELECT spam_count, ham_count, atime
|
|
+ FROM bayes_token
|
|
+ WHERE id = ?
|
|
+ AND token = ?";
|
|
+
|
|
+ my $sth = $self->{_dbh}->prepare_cached($sql);
|
|
+
|
|
+ unless (defined($sth)) {
|
|
+ dbg("bayes: tok_get: SQL error: ".$self->{_dbh}->errstr());
|
|
+ $self->{_dbh}->rollback();
|
|
+ return (0,0,0);
|
|
+ }
|
|
+
|
|
+ $sth->bind_param(1, $self->{_userid});
|
|
+ $sth->bind_param(2, $token, DBI::SQL_BINARY);
|
|
+
|
|
+ my $rc = $sth->execute();
|
|
+
|
|
+ unless ($rc) {
|
|
+ dbg("bayes: tok_get: SQL error: ".$self->{_dbh}->errstr());
|
|
+ $self->{_dbh}->rollback();
|
|
+ return (0,0,0);
|
|
+ }
|
|
+
|
|
+ my ($spam_count, $ham_count, $atime) = $sth->fetchrow_array();
|
|
+
|
|
+ $sth->finish();
|
|
+
|
|
+ $spam_count = 0 if (!$spam_count || $spam_count < 0);
|
|
+ $ham_count = 0 if (!$ham_count || $ham_count < 0);
|
|
+ $atime = 0 if (!$atime);
|
|
+
|
|
+ return ($spam_count, $ham_count, $atime)
|
|
+}
|
|
+
|
|
+=head2 tok_get_all
|
|
+
|
|
+public instance (\@) tok_get (@ $tokens)
|
|
+
|
|
+Description:
|
|
+This method retrieves the specified tokens (C<$tokens>) from storage and returns
|
|
+an array ref of arrays spam count, ham count and last access time.
|
|
+
|
|
+=cut
|
|
+
|
|
+sub tok_get_all {
|
|
+ my ($self, @tokens) = @_;
|
|
+
|
|
+ return [] unless (defined($self->{_dbh}));
|
|
+
|
|
+ my $token_list_size = scalar(@tokens);
|
|
+ dbg("bayes: tok_get_all: token count: $token_list_size");
|
|
+ my @tok_results;
|
|
+
|
|
+ my $search_index = 0;
|
|
+ my $results_index = 0;
|
|
+ my $bunch_end;
|
|
+
|
|
+ my $token_select = $self->_token_select_string();
|
|
+
|
|
+ my $multi_sql = "SELECT $token_select, spam_count, ham_count, atime
|
|
+ FROM bayes_token
|
|
+ WHERE id = ?
|
|
+ AND token IN ";
|
|
+
|
|
+ # fetch tokens in bunches of 100 until there are <= 100 left, then just fetch the rest
|
|
+ while ($token_list_size > $search_index) {
|
|
+ my $bunch_size;
|
|
+ if ($token_list_size - $search_index > 100) {
|
|
+ $bunch_size = 100;
|
|
+ }
|
|
+ else {
|
|
+ $bunch_size = $token_list_size - $search_index;
|
|
+ }
|
|
+ while ($token_list_size - $search_index >= $bunch_size) {
|
|
+ my @tok;
|
|
+ my $in_str = '(';
|
|
+
|
|
+ $bunch_end = $search_index + $bunch_size;
|
|
+ for ( ; $search_index < $bunch_end; $search_index++) {
|
|
+ $in_str .= '?,';
|
|
+ push(@tok, $tokens[$search_index]);
|
|
+ }
|
|
+ chop $in_str;
|
|
+ $in_str .= ')';
|
|
+
|
|
+ my $dynamic_sql = $multi_sql . $in_str;
|
|
+
|
|
+ my $sth = $self->{_dbh}->prepare($dynamic_sql);
|
|
+
|
|
+ unless (defined($sth)) {
|
|
+ dbg("bayes: tok_get_all: SQL error: ".$self->{_dbh}->errstr());
|
|
+ $self->{_dbh}->rollback();
|
|
+ return [];
|
|
+ }
|
|
+
|
|
+ my $idx = 0;
|
|
+ $sth->bind_param(++$idx, $self->{_userid});
|
|
+ $sth->bind_param(++$idx, $_, DBI::SQL_BINARY) foreach (@tok);
|
|
+
|
|
+ my $rc = $sth->execute();
|
|
+
|
|
+ unless ($rc) {
|
|
+ dbg("bayes: tok_get_all: SQL error: ".$self->{_dbh}->errstr());
|
|
+ $self->{_dbh}->rollback();
|
|
+ return [];
|
|
+ }
|
|
+
|
|
+ my $results = $sth->fetchall_arrayref();
|
|
+
|
|
+ $sth->finish();
|
|
+
|
|
+ foreach my $result (@{$results}) {
|
|
+ # Make sure that spam_count and ham_count are not negative
|
|
+ $result->[1] = 0 if (!$result->[1] || $result->[1] < 0);
|
|
+ $result->[2] = 0 if (!$result->[2] || $result->[2] < 0);
|
|
+ # Make sure that atime has a value
|
|
+ $result->[3] = 0 if (!$result->[3]);
|
|
+ $tok_results[$results_index++] = $result;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return \@tok_results;
|
|
+}
|
|
+
|
|
=head2 nspam_nham_change
|
|
|
|
public instance (Boolean) nspam_nham_change (Integer $num_spam,
|
|
@@ -421,10 +562,22 @@ sub tok_touch {
|
|
AND token = ?
|
|
AND atime < ?";
|
|
|
|
- my $rows = $self->{_dbh}->do($sql, undef, $atime, $self->{_userid},
|
|
- $token, $atime);
|
|
+ my $sth = $self->{_dbh}->prepare_cached($sql);
|
|
+
|
|
+ unless (defined($sth)) {
|
|
+ dbg("bayes: tok_touch: SQL error: ".$self->{_dbh}->errstr());
|
|
+ $self->{_dbh}->rollback();
|
|
+ return 0;
|
|
+ }
|
|
|
|
- unless (defined($rows)) {
|
|
+ $sth->bind_param(1, $atime);
|
|
+ $sth->bind_param(2, $self->{_userid});
|
|
+ $sth->bind_param(3, $token, DBI::SQL_BINARY);
|
|
+ $sth->bind_param(4, $atime);
|
|
+
|
|
+ my $rows = $sth->execute();
|
|
+
|
|
+ unless ($rows) {
|
|
dbg("bayes: tok_touch: SQL error: ".$self->{_dbh}->errstr());
|
|
$self->{_dbh}->rollback();
|
|
return 0;
|
|
@@ -478,20 +631,29 @@ sub tok_touch_all {
|
|
return 1 unless (scalar(@{$tokens}));
|
|
|
|
my $sql = "UPDATE bayes_token SET atime = ? WHERE id = ? AND token IN (";
|
|
-
|
|
- my @bindings = ($atime, $self->{_userid});
|
|
- foreach my $token (@{$tokens}) {
|
|
+ foreach (@{$tokens}) {
|
|
$sql .= "?,";
|
|
- push(@bindings, $token);
|
|
}
|
|
chop($sql); # get rid of trailing ,
|
|
-
|
|
$sql .= ") AND atime < ?";
|
|
- push(@bindings, $atime);
|
|
|
|
- my $rows = $self->{_dbh}->do($sql, undef, @bindings);
|
|
+ my $sth = $self->{_dbh}->prepare($sql);
|
|
|
|
- unless (defined($rows)) {
|
|
+ unless (defined($sth)) {
|
|
+ dbg("bayes: tok_get_all: SQL error: ".$self->{_dbh}->errstr());
|
|
+ $self->{_dbh}->rollback();
|
|
+ return [];
|
|
+ }
|
|
+
|
|
+ my $idx = 0;
|
|
+ $sth->bind_param(++$idx, $atime);
|
|
+ $sth->bind_param(++$idx, $self->{_userid});
|
|
+ $sth->bind_param(++$idx, $_, DBI::SQL_BINARY) foreach (@{$tokens});
|
|
+ $sth->bind_param(++$idx, $atime);
|
|
+
|
|
+ my $rows = $sth->execute();
|
|
+
|
|
+ unless ($rows) {
|
|
dbg("bayes: tok_touch_all: SQL error: ".$self->{_dbh}->errstr());
|
|
$self->{_dbh}->rollback();
|
|
return 0;
|
|
@@ -735,7 +897,8 @@ sub _initialize_db {
|
|
return 0;
|
|
}
|
|
|
|
- $id = $self->{_dbh}->{'mysql_insertid'};
|
|
+ $id = $self->{_dsn} =~ /^DBI:MariaDB/i ?
|
|
+ $self->{_dbh}->{'mariadb_insertid'} : $self->{_dbh}->{'mysql_insertid'};
|
|
|
|
$self->{_dbh}->commit();
|
|
|
|
@@ -797,10 +960,12 @@ sub _put_token {
|
|
return 0;
|
|
}
|
|
|
|
- my $rc = $sth->execute($spam_count,
|
|
- $ham_count,
|
|
- $self->{_userid},
|
|
- $token);
|
|
+ $sth->bind_param(1, $spam_count);
|
|
+ $sth->bind_param(2, $ham_count);
|
|
+ $sth->bind_param(3, $self->{_userid});
|
|
+ $sth->bind_param(4, $token, DBI::SQL_BINARY);
|
|
+
|
|
+ my $rc = $sth->execute();
|
|
|
|
unless ($rc) {
|
|
dbg("bayes: _put_token: SQL error: ".$self->{_dbh}->errstr());
|
|
@@ -824,14 +989,16 @@ sub _put_token {
|
|
return 0;
|
|
}
|
|
|
|
- my $rc = $sth->execute($self->{_userid},
|
|
- $token,
|
|
- $spam_count,
|
|
- $ham_count,
|
|
- $atime,
|
|
- $spam_count,
|
|
- $ham_count,
|
|
- $atime);
|
|
+ $sth->bind_param(1, $self->{_userid});
|
|
+ $sth->bind_param(2, $token, DBI::SQL_BINARY);
|
|
+ $sth->bind_param(3, $spam_count);
|
|
+ $sth->bind_param(4, $ham_count);
|
|
+ $sth->bind_param(5, $atime);
|
|
+ $sth->bind_param(6, $spam_count);
|
|
+ $sth->bind_param(7, $ham_count);
|
|
+ $sth->bind_param(8, $atime);
|
|
+
|
|
+ my $rc = $sth->execute();
|
|
|
|
unless ($rc) {
|
|
dbg("bayes: _put_token: SQL error: ".$self->{_dbh}->errstr());
|
|
@@ -948,12 +1115,15 @@ sub _put_tokens {
|
|
return 0;
|
|
}
|
|
|
|
+ $sth->bind_param(1, $spam_count);
|
|
+ $sth->bind_param(2, $ham_count);
|
|
+ $sth->bind_param(3, $self->{_userid});
|
|
+ # 4, update token in foreach loop
|
|
+
|
|
my $error_p = 0;
|
|
foreach my $token (keys %{$tokens}) {
|
|
- my $rc = $sth->execute($spam_count,
|
|
- $ham_count,
|
|
- $self->{_userid},
|
|
- $token);
|
|
+ $sth->bind_param(4, $token, DBI::SQL_BINARY);
|
|
+ my $rc = $sth->execute();
|
|
|
|
unless ($rc) {
|
|
dbg("bayes: _put_tokens: SQL error: ".$self->{_dbh}->errstr());
|
|
@@ -984,18 +1154,21 @@ sub _put_tokens {
|
|
return 0;
|
|
}
|
|
|
|
+ $sth->bind_param(1, $self->{_userid});
|
|
+ # 2, update token in foreach loop
|
|
+ $sth->bind_param(3, $spam_count);
|
|
+ $sth->bind_param(4, $ham_count);
|
|
+ $sth->bind_param(5, $atime);
|
|
+ $sth->bind_param(6, $spam_count);
|
|
+ $sth->bind_param(7, $ham_count);
|
|
+ $sth->bind_param(8, $atime);
|
|
+
|
|
my $error_p = 0;
|
|
my $new_tokens = 0;
|
|
my $need_atime_update_p = 0;
|
|
foreach my $token (keys %{$tokens}) {
|
|
- my $rc = $sth->execute($self->{_userid},
|
|
- $token,
|
|
- $spam_count,
|
|
- $ham_count,
|
|
- $atime,
|
|
- $spam_count,
|
|
- $ham_count,
|
|
- $atime);
|
|
+ $sth->bind_param(2, $token, DBI::SQL_BINARY);
|
|
+ my $rc = $sth->execute();
|
|
|
|
if (!$rc) {
|
|
dbg("bayes: _put_tokens: SQL error: ".$self->{_dbh}->errstr());
|