package DB; use Moose; use DB::Schema; use BotConfig; use Carp qw/confess cluck/; my $dbconf = BotConfig->instance->db; my $schema = DB::Schema->connect("dbi:Pg:dbname=" . $dbconf->database . ";host=" . $dbconf->host, $dbconf->username, $dbconf->password, { RaiseError => 1 }); $schema->storage->sql_maker->quote_char('"'); has schema => ( is => 'ro', default => sub { return $schema; }, isa => 'DB::Schema', ); sub _quote_to_ret { my $row = shift; return map { $row->$_ } qw/quote who qid desc sid/; } sub source { return $_[0]->schema->resultset('Source'); } sub quote { return $_[0]->schema->resultset('Quote'); } sub trigger { return $_[0]->schema->resultset('Trigger'); } sub channelsetup { return $_[0]->schema->resultset('Channelsetup'); } sub bansource { return $_[0]->schema->resultset('Bansource'); } sub quotelist { return $_[0]->schema->resultset('List'); } sub ignore { return $_[0]->schema->resultset('Ignore'); } sub episodeinfo { return $_[0]->schema->resultset('Episodeinfo'); } sub tidsource { return $_[0]->schema->resultset('Tidsource'); } sub addquote { my ($self, $where, $who, $source, $quote) = @_; my $source_row = $self->source->search({ name => uc $source })->first; if ($source_row) { my $counter_row = $self->quote->search({ sid => $source_row->sid }, { 'select' => [ { 'AVG' => 'counter' } ], 'as' => ['newcount'], 'group_by' => ['me.sid'] })->first; my $counter = $counter_row ? int($counter_row->get_column('newcount')) || 0 : 0; my $quote_row = $self->quote->find_or_create({ quote => $quote, sid => $source_row->sid, counter => $counter, who => $who }); } else { return "No such source: $source"; } } sub getstrip { my ($self, $channel) = @_; my $row = $self->channelsetup->search({ channel => lc $channel })->first; return !$row ? 0 : $row->stripcolors(); } sub getbyqid { my ($self, $where, $who, $qid) = @_; my $row = $self->quotelist->search({ qid => $qid })->first; if (!$row) { return "Unable to find quote with $qid, are you sure it exists?"; } else { # TODO swap this to local call, rather than through POE my $banned = $self->isbannedsource($where->[0], $row->sid); if ($banned) { return "Unable to find quote with $qid, are you sure it exists?"; } else { # TODO this should be a nicer return value return _quote_to_ret($row); } } } sub getcid { my ($self, $where) = @_; my $row = $self->channelsetup->search({ channel => lc $where })->first; return $row ? $row->cid : undef; } sub isbannedsource { my ($self, $where, $sid) = @_; my $row = $self->bansource->search({ 'me.sid' => $sid, 'channelsetup.channel' => lc $where }, { join => 'channelsetup' })->first; return $row ? 1 : 0; } sub deletequote { my ($self, $where, $who, $qid) = @_; $self->quote->find({ qid => $qid })->update({ deleted => 1 }); } sub addsource { my ($self, $where, $who, $source, $desc) = @_; my $row = $self->source->find_or_create({ name => uc $source, desc => $desc }); } sub addtrigger { my ($self, $where, $who, $trig) = @_; my $row = $self->trigger->find_or_create({ trigger => uc $trig }); } sub getquote { my ($self, $what, $where) = @_; $self->trigger->search({ trigger => uc $what })->update({ counter => \'counter + 1' }); # grab the bottom 15 rows by counter+random(), do the final selection in perl my @rows = $self->quotelist->search({ trigger => uc $what }, { order_by => { '-asc' => [ 'me.counter', \'RANDOM()' ] }, rows => 15 })->all; my $final_row = $rows[ rand @rows ]; return "" unless $final_row; my $qid = $final_row->qid; my $quote_row = $self->quote->find({ qid => $qid }); $quote_row->update({ counter => \'counter + 1' }); my $banned = $self->isbannedsource($where->[0], $final_row->sid); if ($banned) { print "GETQUOTE: failed check\n"; return ("", "", 0, ""); } else { return _quote_to_ret($final_row); } } sub getlastquote { my ($self) = @_; my $row = $self->quotelist->search({}, { order_by => { '-desc' => 'me.qid' } })->first; return _quote_to_ret($row) if $row; return ("", "", 0, ""); } sub listtriggers { my ($self, $what) = @_; my @triggers = map { uc $_->trigger } $self->trigger->search({ tid => { '>' => 0 } })->all; my $string = join ', ', @triggers; return $string; } sub listsources { my ($self, $what) = @_; my @sources = map { uc $_->name } $self->source->search({ sid => { '>' => 0 } })->all; my $string = join ', ', @sources; return $string; } sub whatistrigger { my ($self, $where, $who, $what) = @_; my $trig = $self->trigger->search({ trigger => uc $what })->first; unless ($trig) { #no rows found return "Unable to find trigger, $what"; } my @sources = map { $_->source } $trig->tidsources->all; my $string = join ', ', map { $_->name } @sources; return $string; } sub appendtotrigger { my ($self, $where, $who, $source, $trigger) = @_; my $source_row = $self->source->find({ name => uc $source }); my $trigger_row = $self->trigger->find({ trigger => uc $trigger }); unless ($source_row && $source_row->sid > 0) { return "Unable to find source, $source"; } unless ($trigger_row && $trigger_row->tid > 0) { return "Unable to find trigger, $trigger"; } # add the source to the trigger $trigger_row->tidsources->find_or_create({ sid => $source_row->sid }); } sub removefromtrigger { my ($self, $where, $who, $source, $trigger) = @_; my $source_row = $self->source->find({ name => uc $source }); my $trigger_row = $self->trigger->find({ trigger => uc $trigger }); unless ($source_row && $source_row->sid > 0) { return "Unable to find source, $source"; } unless ($trigger_row && $trigger_row->tid > 0) { return "Unable to find trigger, $trigger"; } $trigger_row->tidsources->search({ sid => $source_row->sid })->delete(); } sub updatebotlist { my ($self, $eid, $botlist) = @_; $self->episodeinfo->search({ eid => $eid })->update({ botlisting => $botlist }); } sub updatecrc { my ($self, $eid, $crc) = @_; $self->episodeinfo->search({ eid => $eid })->update({ fcrc => $crc }); } sub updategroup { my ($self, $eid, $group) = @_; $self->episodeinfo->search({ eid => $eid })->update({ group => $group }); } sub updatesize { my ($self, $eid, $size) = @_; $self->episodeinfo->search({ eid => $eid })->update({ fsize => $size }); } sub updatemu { my ($self, $eid, $mu) = @_; $self->episodeinfo->search({ eid => $eid })->update({ filelink => $mu }); } sub getignoredmsg { my ($self, $nick) = @_; my $row = $self->ignore->search({ nick => lc $nick })->first; return $row ? $row->message : undef; } sub isignored { my ($self, $nick) = @_; my $row = $self->ignore->search({ nick => lc $nick })->first; return !!$row; } 1;