quotebot/lib/DB.pm
2016-08-31 17:51:18 -04:00

449 lines
13 KiB
Perl

package DB;
use strict;
use warnings;
use Data::Dumper;
use DBI;
use POE qw(Session);
use POE::Component::IRC::Common qw(:ALL);
my $dbh = DBI->connect("dbi:Pg:dbname=quotebot;host=andromeda128", "conanquotes", "conanquotes", {RaiseError => 0});
die "Failed to connect to DB" unless $dbh;
my $ses = POE::Session->create(
package_states =>
[
DB => [ qw(_start addquote addtrigger addsource appendtotrigger getquote removefromtrigger listsources listtriggers whatistrigger deletequote getbyqid getstrip getlastquote ping updatebotlist updatecrc updategroup updatesize isignored getignoredmsg updatemu getcid isbannedsource) ],
],
heap => { dbh => $dbh},);
my %sth;
$sth{addquote} = $dbh->prepare("INSERT INTO quotes (sid, quote, who, counter) VALUES (?, ?, ?, ?)");
$sth{addtrigger} = $dbh->prepare("INSERT INTO triggers (trigger) VALUES (UPPER(?))");
$sth{addsource} = $dbh->prepare("INSERT INTO sources (name,\"desc\") VALUES (UPPER(?), ?)");
$sth{appendtotrigger} = $dbh->prepare("INSERT INTO tidsources (tid, sid) VALUES (?, ?)");
$sth{removefromtrigger} = $dbh->prepare("DELETE FROM tidsources WHERE tid = ? AND sid = ?");
$sth{deletequote} = $dbh->prepare("UPDATE quotes SET deleted = true WHERE qid = ? AND NOT deleted");
$sth{getquote} = $dbh->prepare("SELECT quote, who, qid, \"desc\", sid FROM (SELECT * FROM list WHERE trigger = UPPER(?) ORDER BY counter, RANDOM() ASC LIMIT 15) as foo ORDER BY RANDOM() LIMIT 1;");
#"SELECT quote, who, qid, \"desc\" FROM list WHERE trigger = UPPER(?) ORDER BY RANDOM() LIMIT 1");
$sth{incquotecount} = $dbh->prepare("UPDATE quotes SET counter = counter+1 WHERE qid = ?");
$sth{inctrigcount} = $dbh->prepare("UPDATE triggers SET counter = counter+1 WHERE trigger = UPPER(?)");
$sth{getsid} = $dbh->prepare("SELECT sid FROM sources WHERE name = UPPER(?) LIMIT 1");
$sth{gettid} = $dbh->prepare("SELECT tid FROM triggers WHERE trigger = UPPER(?) LIMIT 1");
$sth{listtriggers} = $dbh->prepare("SELECT UPPER(trigger) FROM triggers WHERE tid > 0");
$sth{listsources} = $dbh->prepare("SELECT UPPER(name) FROM sources WHERE sid > 0");
$sth{whatistrigger} = $dbh->prepare("SELECT UPPER(name) FROM triggers, sources, tidsources WHERE triggers.tid = tidsources.tid AND tidsources.sid = sources.sid AND triggers.trigger = UPPER(?)");
$sth{getcid} = $dbh->prepare("SELECT cid FROM channelsetup WHERE channelsetup.channel = ? LIMIT 1");
$sth{getbyqid} = $dbh->prepare("SELECT quote, who, qid, \"desc\", sid FROM list WHERE list.qid=? LIMIT 1");
$sth{getstrip} = $dbh->prepare("SELECT stripcolors FROM channelsetup WHERE channel=? LIMIT 1");
$sth{getcounternew} = $dbh->prepare("SELECT ROUND(AVG(counter),0) FROM quotes WHERE sid=? GROUP BY sid LIMIT 1");
$sth{getlastquote} = $dbh->prepare("SELECT quotes.quote as quote, quotes.who as who, quotes.qid as qid, sources.\"desc\" as \"desc\" FROM quotes, sources WHERE quotes.sid = sources.sid AND quote != '' AND quotes.deleted != TRUE ORDER BY qid DESC LIMIT 1;");
$sth{updatebotlist} = $dbh->prepare("UPDATE episodeinfo SET botlisting = ? WHERE eid = ?");
$sth{updatecrc} = $dbh->prepare("UPDATE episodeinfo SET fcrc = ? WHERE eid = ?");
$sth{updategroup} = $dbh->prepare("UPDATE episodeinfo SET \"group\" = ? WHERE eid = ?");
$sth{updatesize} = $dbh->prepare("UPDATE episodeinfo SET \"fsize\" = ? WHERE eid = ?");
$sth{updatemu} = $dbh->prepare("UPDATE episodeinfo SET filelink = ? WHERE eid = ? AND now() - filelink_date >= interval '1 week'");
$sth{isignored} = $dbh->prepare("SELECT 1 FROM ignores WHERE nick = ?");
$sth{getignoredmsg} = $dbh->prepare("SELECT message FROM ignores WHERE nick = ?");
$sth{isbannedsource} = $dbh->prepare("SELECT 1 FROM channelsetup, bansource WHERE channelsetup.channel = ? AND bansource.sid = ? AND bansource.cid = channelsetup.cid LIMIT 1;");
sub _start
{
my ($kernel, $heap) = @_[KERNEL, HEAP];
$kernel->alias_set("DB");
$kernel->delay_add("ping", 1);
}
sub ping
{
my $kernel = $_[KERNEL];
$dbh->ping();
$kernel->delay_add("ping", 10);
# print "DB PING\n";
}
sub addquote
{
my ($kernel, $heap, $where, $who, $source, $quote) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2, ARG3];
$sth{getsid}->execute($source);
my ($sid) = $sth{getsid}->fetchrow_array();
if ($sid)
{
$sth{getcounternew}->execute($sid);
my ($counter) = $sth{getcounternew}->fetchrow_array();
$counter ||= 0;
$sth{addquote}->execute($sid, $quote, $who, $counter); #add the quote!
}
else
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "No such source: $source");
}
}
sub getstrip
{
my ($kernel, $heap, $channel) = @_[KERNEL, HEAP, ARG0];
my $r = $sth{getstrip}->execute(lc($channel)); #add the quote!
print "STRIP: $r | $channel \n";
return 0 if ($r == 0);
my @ar = $sth{getstrip}->fetchrow_array();
print Dumper(\@ar);
return $ar[0];
}
sub getbyqid
{
my ($kernel, $heap, $where, $who, $qid) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2];
my $r = $sth{getbyqid}->execute($qid);
my @quotes = $sth{getbyqid}->fetchrow_array(); #add the quote!
if ($r == 0) #no rows affected!
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to find quote with $qid, are you sure it exists?");
return ("","", 0, "");
}
else
{
my $banned = $kernel->call(DB => isbannedsource => $where->[0], $quotes[4]);
print "QID-B:".Dumper($banned);
if ($banned)
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to find quote with $qid, are you sure it exists?");
return ("","", 0, "");
}
else
{
print Dumper(\@quotes);
return @quotes;
}
}
}
sub getcid
{
my ($kernel, $heap, $where) = @_[KERNEL, HEAP, ARG0];
my $r = $sth{getcid}->execute(lc $where); #get the cid
print "CID: $r $where\n";
if ($r == 0) #no rows affected!
{
return undef;
}
else
{
my @quotes = $sth{getcid}->fetchrow_array(); #add the quote!
print "CID: @quotes\n";
return @quotes;
}
}
sub isbannedsource
{
my ($kernel, $heap, $where, $sid) = @_[KERNEL, HEAP, ARG0, ARG1];
print "BANNED SOURCE\n",Dumper($where, $sid);
my $r = $sth{isbannedsource}->execute(lc $where, $sid); #get the cid
my ($q) = $sth{isbannedsource}->fetchrow_array();
return $q;
}
sub deletequote
{
my ($kernel, $heap, $where, $who, $qid) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2];
my $r = $sth{deletequote}->execute($qid); #add the quote!
if ($r == 0) #no rows affected!
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to find quote with $qid, are you sure it exists?");
}
}
sub addsource
{
my ($kernel, $heap, $where, $who, $source, $desc) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2, ARG3];
$desc = undef unless $desc; #make sure its undef!
my $r = $sth{addsource}->execute($source, $desc); #add the quote!
if ($r == 0) #no rows affected!
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to add source, $source, does it already exist?");
}
}
sub addtrigger
{
my ($kernel, $heap, $where, $who, $trig) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2];
my $r = $sth{addtrigger}->execute($trig); #add the quote!
if ($r == 0) #no rows affected!
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to add trigger, $trig, does it already exist?");
}
}
sub getquote
{
my ($kernel, $heap, $what, $where) = @_[KERNEL, HEAP, ARG0, ARG1];
#print "GETQUOTE: $what\n";
#i should really do something to memoize this, but that'll come much later when i actually NEED some performance
my $sss = $sth{getquote}->execute($what);
return "" unless $sss; #got 0 results, just give back empty string
my @quotes = $sth{getquote}->fetchrow_array(); #add the quote!
$sth{inctrigcount}->execute($what);
return ("","", 0, "") unless $quotes[0];
$sth{incquotecount}->execute($quotes[2]); # don't ban this or someone can lock out a trigger!
print Dumper(\@quotes);
my $banned = $kernel->call(DB=>isbannedsource=>$where->[0], $quotes[4]);
print "$banned\n";
if ($banned)
{
print "GETQUOTE: failed check\n";
return ("", "", 0, "");
}
else
{
return @quotes;
}
}
sub getlastquote
{
my ($kernel, $heap) = @_[KERNEL, HEAP];
my $sss = $sth{getlastquote}->execute();
return "" unless $sss; #got 0 results, just give back empty string
my @quotes = $sth{getlastquote}->fetchrow_array(); #add the quote!
print Dumper(\@quotes);
return ("","", 0, "") unless $quotes[0];
return @quotes;
}
sub listtriggers
{
my ($kernel, $heap, $what) = @_[KERNEL, HEAP, ARG0];
my $sss = $sth{listtriggers}->execute();
return "" unless $sss;
my @trigs = @{$sth{listtriggers}->fetchall_arrayref()};
return "" unless $trigs[0];
my $string = join ', ', map {@{$_} unless ref($_) ne "ARRAY"} @trigs;
return $string;
}
sub listsources
{
my ($kernel, $heap, $what) = @_[KERNEL, HEAP, ARG0];
my $sss = $sth{listsources}->execute();
return "" unless $sss;
my @trigs = @{$sth{listsources}->fetchall_arrayref()};
return "" unless $trigs[0];
my $string = join ', ', map {@{$_} unless ref($_) ne "ARRAY"} @trigs;
return $string;
}
sub whatistrigger
{
my ($kernel, $heap, $where, $who, $what) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2];
my $sss = $sth{whatistrigger}->execute($what);
if ($sss == 0) #no rows found
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to find trigger, $what");
}
my @trigs = @{$sth{whatistrigger}->fetchall_arrayref()};
return "" unless $trigs[0];
my $string = join ', ', map {@{$_} unless ref($_) ne "ARRAY"} @trigs;
return $string;
}
sub appendtotrigger
{
my ($kernel, $heap, $where, $who, $source, $trigger) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2, ARG3];
$sth{getsid}->execute($source);
$sth{gettid}->execute($trigger);
my ($sid) = $sth{getsid}->fetchrow_array();
my ($tid) = $sth{gettid}->fetchrow_array();
print Dumper($sid, $tid);
unless (defined $sid) #no rows found
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to find source, $source");
return ""
}
unless ($tid > 0) #no rows found
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to find source, $trigger");
return ""
}
eval{$sth{appendtotrigger}->execute($tid, $sid)}; #add the quote!
}
sub removefromtrigger
{
my ($kernel, $heap, $where, $who, $source, $trigger) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2, ARG3];
$sth{getsid}->execute($source);
$sth{gettid}->execute($trigger);
my ($sid) = $sth{getsid}->fetchrow_array();
my ($tid) = $sth{gettid}->fetchrow_array();
print Dumper($sid, $tid);
unless ($sid > 0) #no rows found
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to find source, $source");
return ""
}
unless ($tid > 0) #no rows found
{
$kernel->post("IRCHANDLER", msgfromdb=>$who, $where, "Unable to find source, $trigger");
return ""
}
$sth{removefromtrigger}->execute($tid, $sid); #add the quote!
}
sub updatebotlist
{
my ($kernel, $heap, $eid, $botlist) = @_[KERNEL, HEAP, ARG0, ARG1];
$sth{updatebotlist}->execute($botlist, $eid);
}
sub updatecrc
{
my ($kernel, $heap, $eid, $crc) = @_[KERNEL, HEAP, ARG0, ARG1];
$sth{updatecrc}->execute($crc, $eid);
}
sub updategroup
{
my ($kernel, $heap, $eid, $group) = @_[KERNEL, HEAP, ARG0, ARG1];
$sth{updategroup}->execute($group, $eid);
}
sub updatesize
{
my ($kernel, $heap, $eid, $size) = @_[KERNEL, HEAP, ARG0, ARG1];
$sth{updatesize}->execute($size, $eid);
}
sub updatemu
{
my ($kernel, $heap, $eid, $mu) = @_[KERNEL, HEAP, ARG0, ARG1];
$sth{updatemu}->execute($mu, $eid);
}
sub getignoredmsg
{
my ($kernel, $heap, $nick) = @_[KERNEL, HEAP, ARG0];
my $r = $sth{getignoredmsg}->execute(lc($nick)); #add the quote!
return $sth{getignoredmsg}->fetchrow_array();
}
sub isignored
{
my ($kernel, $heap, $nick) = @_[KERNEL, HEAP, ARG0];
my $r = $sth{isignored}->execute(lc($nick)); #add the quote!
return $r > 0 ? 1 : 0;
}
=begin comment
TRIGGERS
-------------- 1
TID | TRIGGER
TIDSOURCES
---------- many -> many
TID | SID
SOURCES
---------- 1
SID | NAME
QUOTES
----------------- many -> 1
QID | SID | QUOTE
=end comment
=cut
##getquote
####Assume we have a TID already
#
#SELECT quotes.quote, sources.name FROM triggers, tidsources, sources, quotes WHERE triggers.trigger = ? AND tidsources.tid = triggers.tid AND tidsources.sid = sources.sid AND tidsources.sid = quotes.sid ORDER BY quotes.qid;
#SELECT quote FROM list WHERE trigger = ?; #VIEWS ARE AWSOME
##addsourcetotrigger
#AB: INSERT INTO tidsources (tid, sid) VALUES (TID, SID)
#
##addtrigger
##AB: INSERT INTO triggers (trigger) VALUES (TEXT)
# INSERT INTO triggers (trigger) VALUES (?)
##addsource
#AB: INSERT INTO sources (name) VALUES (NAME)
#INSERT INTO sources (name) VALUES (?)
##addquote
#AB: INSERT INTO quotes (source, text) VALUES (SID, TEXT)
#INSERT INTO quotes (source, text) VALUES (?, ?)
#
1;