2021-07-21 06:38:07 +02:00
|
|
|
# File: SQLite.pm
|
2014-05-06 07:15:27 +02:00
|
|
|
#
|
2021-07-21 06:38:07 +02:00
|
|
|
# Purpose: SQLite backend for storing and retreiving quotegrabs.
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2021-07-11 00:00:22 +02:00
|
|
|
# SPDX-FileCopyrightText: 2021 Pragmatic Software <pragma78@gmail.com>
|
|
|
|
# SPDX-License-Identifier: MIT
|
2017-03-05 22:33:31 +01:00
|
|
|
|
2021-07-21 06:38:07 +02:00
|
|
|
package PBot::Plugin::Quotegrabs::Storage::SQLite;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2021-07-14 04:45:56 +02:00
|
|
|
use PBot::Imports;
|
2019-07-11 03:40:53 +02:00
|
|
|
|
2014-05-06 07:15:27 +02:00
|
|
|
use DBI;
|
|
|
|
use Carp qw(shortmess);
|
|
|
|
|
|
|
|
sub new {
|
2020-02-15 23:38:32 +01:00
|
|
|
if (ref($_[1]) eq 'HASH') { Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference"); }
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($class, %conf) = @_;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
my $self = bless {}, $class;
|
|
|
|
$self->initialize(%conf);
|
|
|
|
return $self;
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub initialize {
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($self, %conf) = @_;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference in " . __FILE__);
|
|
|
|
$self->{filename} = delete $conf{filename};
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub begin {
|
2020-02-15 23:38:32 +01:00
|
|
|
my $self = shift;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{pbot}->{logger}->log("Opening quotegrabs SQLite database: $self->{filename}\n");
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{dbh} = DBI->connect("dbi:SQLite:dbname=$self->{filename}", "", "", {RaiseError => 1, PrintError => 0, sqlite_unicode => 1}) or die $DBI::errstr;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
eval {
|
|
|
|
$self->{dbh}->do(<< 'SQL');
|
2014-05-06 07:15:27 +02:00
|
|
|
CREATE TABLE IF NOT EXISTS Quotegrabs (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
nick TEXT,
|
|
|
|
channel TEXT,
|
|
|
|
grabbed_by TEXT,
|
|
|
|
text TEXT,
|
|
|
|
timestamp NUMERIC
|
|
|
|
)
|
2023-04-10 17:06:35 +02:00
|
|
|
SQL
|
|
|
|
|
|
|
|
$self->{dbh}->do(<< 'SQL');
|
|
|
|
CREATE TABLE IF NOT EXISTS Seen (
|
|
|
|
id INTEGER UNIQUE
|
|
|
|
)
|
2014-05-06 07:15:27 +02:00
|
|
|
SQL
|
2020-02-15 23:38:32 +01:00
|
|
|
};
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub end {
|
2020-02-15 23:38:32 +01:00
|
|
|
my $self = shift;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{pbot}->{logger}->log("Closing quotegrabs SQLite database\n");
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
if (exists $self->{dbh} and defined $self->{dbh}) {
|
|
|
|
$self->{dbh}->disconnect();
|
|
|
|
delete $self->{dbh};
|
|
|
|
}
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub add_quotegrab {
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($self, $quotegrab) = @_;
|
|
|
|
|
|
|
|
my $id = eval {
|
|
|
|
my $sth = $self->{dbh}->prepare('INSERT INTO Quotegrabs VALUES (?, ?, ?, ?, ?, ?)');
|
|
|
|
$sth->bind_param(1, undef);
|
|
|
|
$sth->bind_param(2, $quotegrab->{nick});
|
|
|
|
$sth->bind_param(3, $quotegrab->{channel});
|
|
|
|
$sth->bind_param(4, $quotegrab->{grabbed_by});
|
|
|
|
$sth->bind_param(5, $quotegrab->{text});
|
|
|
|
$sth->bind_param(6, $quotegrab->{timestamp});
|
|
|
|
$sth->execute();
|
|
|
|
|
|
|
|
return $self->{dbh}->sqlite_last_insert_rowid();
|
|
|
|
};
|
|
|
|
|
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
|
|
|
return $id;
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub get_quotegrab {
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($self, $id) = @_;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
my $quotegrab = eval {
|
|
|
|
my $sth = $self->{dbh}->prepare('SELECT * FROM Quotegrabs WHERE id == ?');
|
|
|
|
$sth->bind_param(1, $id);
|
|
|
|
$sth->execute();
|
|
|
|
return $sth->fetchrow_hashref();
|
|
|
|
};
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
|
|
|
return $quotegrab;
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub get_random_quotegrab {
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($self, $nick, $channel, $text) = @_;
|
|
|
|
|
|
|
|
$nick =~ s/\.?\*\??/%/g if defined $nick;
|
|
|
|
$channel =~ s/\.?\*\??/%/g if defined $channel;
|
|
|
|
$text =~ s/\.?\*\??/%/g if defined $text;
|
|
|
|
|
|
|
|
$nick =~ s/\./_/g if defined $nick;
|
|
|
|
$channel =~ s/\./_/g if defined $channel;
|
|
|
|
$text =~ s/\./_/g if defined $text;
|
|
|
|
|
|
|
|
my $quotegrab = eval {
|
|
|
|
my $sql = 'SELECT * FROM Quotegrabs ';
|
|
|
|
my @params;
|
|
|
|
my $where = 'WHERE ';
|
|
|
|
my $and = '';
|
|
|
|
|
2023-03-30 15:33:33 +02:00
|
|
|
# multi-grabs have the nick separated by +'s so we must test for
|
|
|
|
# nick, nick+*, *+nick, and *+nick+* to match each of these cases
|
2020-02-15 23:38:32 +01:00
|
|
|
if (defined $nick) {
|
2023-04-10 17:06:35 +02:00
|
|
|
$sql .= $where . '(nick LIKE ? OR nick LIKE ? OR nick LIKE ? OR nick LIKE ?) ';
|
2020-02-15 23:38:32 +01:00
|
|
|
push @params, "$nick";
|
2023-03-30 15:33:33 +02:00
|
|
|
push @params, "$nick+%";
|
|
|
|
push @params, "%+$nick";
|
|
|
|
push @params, "%+$nick+%";
|
2020-02-15 23:38:32 +01:00
|
|
|
$where = '';
|
|
|
|
$and = 'AND ';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined $channel) {
|
|
|
|
$sql .= $where . $and . 'channel LIKE ? ';
|
|
|
|
push @params, $channel;
|
|
|
|
$where = '';
|
|
|
|
$and = 'AND ';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined $text) {
|
|
|
|
$sql .= $where . $and . 'text LIKE ? ';
|
|
|
|
push @params, "%$text%";
|
|
|
|
}
|
|
|
|
|
2023-04-10 17:06:35 +02:00
|
|
|
my $sth = $self->{dbh}->prepare($sql . $where . $and . 'id NOT IN Seen ORDER BY RANDOM() LIMIT 1');
|
2020-02-15 23:38:32 +01:00
|
|
|
$sth->execute(@params);
|
2023-04-10 17:06:35 +02:00
|
|
|
my $quotegrab = $sth->fetchrow_hashref();
|
|
|
|
|
|
|
|
# no unseen quote found, remove queried quotes from Seen table and try again
|
|
|
|
if (not defined $quotegrab) {
|
|
|
|
my $count = $self->remove_seen($sql, \@params);
|
|
|
|
|
|
|
|
# no matching quotes in Seen table, ergo no quote found
|
|
|
|
if ($count == 0) {
|
|
|
|
return undef;
|
|
|
|
}
|
|
|
|
|
|
|
|
# try again
|
|
|
|
$sth->execute(@params);
|
|
|
|
$quotegrab = $sth->fetchrow_hashref();
|
|
|
|
}
|
|
|
|
|
|
|
|
# mark quote as seen
|
|
|
|
if (defined $quotegrab) {
|
|
|
|
$self->add_seen($quotegrab->{id});
|
|
|
|
}
|
|
|
|
|
|
|
|
return $quotegrab;
|
2020-02-15 23:38:32 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
|
|
|
return $quotegrab;
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
2023-04-10 17:06:35 +02:00
|
|
|
sub remove_seen {
|
|
|
|
my ($self, $sql, $params) = @_;
|
|
|
|
|
|
|
|
$sql =~ s/^SELECT \*/SELECT id/;
|
|
|
|
|
|
|
|
my $count = eval {
|
|
|
|
my $sth = $self->{dbh}->prepare("DELETE from Seen WHERE id IN ($sql)");
|
|
|
|
$sth->execute(@$params);
|
|
|
|
return $sth->rows;
|
|
|
|
};
|
|
|
|
|
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
|
|
|
return $count;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub add_seen {
|
|
|
|
my ($self, $id) = @_;
|
|
|
|
|
|
|
|
eval {
|
|
|
|
my $sth = $self->{dbh}->prepare('INSERT INTO Seen VALUES (?)');
|
|
|
|
$sth->execute($id);
|
|
|
|
};
|
|
|
|
|
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
|
|
|
}
|
|
|
|
|
2014-05-06 07:15:27 +02:00
|
|
|
sub get_all_quotegrabs {
|
2020-02-15 23:38:32 +01:00
|
|
|
my $self = shift;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
my $quotegrabs = eval {
|
|
|
|
my $sth = $self->{dbh}->prepare('SELECT * from Quotegrabs');
|
|
|
|
$sth->execute();
|
|
|
|
return $sth->fetchall_arrayref({});
|
|
|
|
};
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
|
|
|
return $quotegrabs;
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub delete_quotegrab {
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($self, $id) = @_;
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
eval {
|
|
|
|
my $sth = $self->{dbh}->prepare('DELETE FROM Quotegrabs WHERE id == ?');
|
2023-04-10 17:06:35 +02:00
|
|
|
$sth->execute($id);
|
|
|
|
|
|
|
|
$sth = $self->{dbh}->prepare('DELETE FROM Seen WHERE id == ?');
|
|
|
|
$sth->execute($id);
|
2020-02-15 23:38:32 +01:00
|
|
|
};
|
2014-05-06 07:15:27 +02:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
2014-05-06 07:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
1;
|