From 88825696cb89b33dbb7e5b869a256d940601113a Mon Sep 17 00:00:00 2001 From: Alexandre Morignot <erdnaxeli@cervoi.se> Date: Mon, 9 Feb 2015 13:20:04 +0100 Subject: [PATCH] New object commands::get::query --- lib/commands/get.pm | 44 +++++++-------- lib/commands/get/query.pm | 109 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 22 deletions(-) create mode 100644 lib/commands/get/query.pm diff --git a/lib/commands/get.pm b/lib/commands/get.pm index b5fefec..07f0fdd 100644 --- a/lib/commands/get.pm +++ b/lib/commands/get.pm @@ -2,12 +2,13 @@ package commands::get; use strict; use warnings; -use Scalar::Util qw(looks_like_number); use lib "$FindBin::Bin/lib/"; use utils::print; use utils::db; +use commands::get::query; + our $irc; our $log; @@ -18,18 +19,16 @@ my $sth; sub exec { my ($kernel, $nick, $chan, $msg) = @_; - # if we are in a query or arg -all, we search in all the channels - my $all = 0; - $all = 1 if ($chan->[0] !~ /^#/ || $msg =~ s/-a(ll)?//); + my $query = commands::get::query->new( + chan => $chan->[0], + query => ($msg) ? $msg : '' + ); - my @tags = ($msg =~ /#([a-zA-Z0-9_-]+)/g); my $content; my $req; my $rows; - my @words = ($msg =~ /(?:^| )([^#\s]+)/g); - - if (not defined $last_req or $msg ne $last_req) { + if (not defined $last_req or not ($query ~~ $last_req)) { # we close a previous session if needed if ($dbh) { $sth->finish if $sth->{'Active'}; @@ -40,32 +39,32 @@ sub exec { $dbh = utils::db::get_new_session; my @words_param; - foreach (@words) { + foreach (@{$query->words}) { unshift @words_param, '%'.$_.'%'; } my $words_sql; - foreach (@words) { + foreach (@{$query->words}) { $words_sql .= ' and ' if ($words_sql); $words_sql .= "concat(sender, ' ', title) like ?"; } - if (@words && looks_like_number($words[0])) { + if ($query->id >= 0) { $sth = $dbh->prepare('select id, sender, title, url, duration from playbot where id = ?'); - $sth->execute($words[0]); + $sth->execute($query->id); } - elsif (@tags) { + elsif (@{$query->tags}) { my @where; - foreach my $tag (@tags) { + foreach my $tag (@{$query->tags}) { unshift @where, 'p.id in (select pt.id from playbot_tags pt where pt.tag = ?)'; } my $where = join ' and ' => @where; - if ($all) { + if ($query->is_global) { $req = 'select id, sender, title, url, duration from playbot where '.$where; @@ -74,7 +73,7 @@ sub exec { order by rand()'; $sth = $dbh->prepare($req); - $sth->execute(@tags, @words_param); + $sth->execute(@{$query->tags}, @words_param); } else { $req = 'select p.id, p.sender, p.title, p.url, duration @@ -87,11 +86,11 @@ sub exec { order by rand()'; $sth = $dbh->prepare($req); - $sth->execute(@tags, @words_param, $chan->[0]); + $sth->execute(@{$query->tags}, @words_param, $query->chan); } } else { - if ($all) { + if ($query->is_global) { $req = 'select id, sender, title, url, duration from playbot'; $req .= ' where '.$words_sql if ($words_sql); $req .= ' group by id'; @@ -110,7 +109,7 @@ sub exec { $req .= ' order by rand()'; $sth = $dbh->prepare($req); - $sth->execute($chan->[0], @words_param); + $sth->execute($query->chan, @words_param); } } } @@ -118,11 +117,11 @@ sub exec { $content = $sth->fetch; if (!$content) { - if ($last_req eq $msg) { + if ($last_req ~~ $query) { # the request was already executed, there is nothing more $irc->yield(privmsg => $chan => "Tu tournes en rond, Jack !"); } - elsif (@words or @tags) { + elsif (@{$query->words} or @{$query->tags}) { $irc->yield(privmsg => $chan => "Je n'ai rien dans ce registre."); } else { @@ -173,9 +172,10 @@ sub exec { or $log->error("Couldn't finish transaction: " . $dbh->errstr); # we save the request - $last_req = $msg; + $last_req = $query; return $content->[0]; } + 1; diff --git a/lib/commands/get/query.pm b/lib/commands/get/query.pm new file mode 100644 index 0000000..cac4ec5 --- /dev/null +++ b/lib/commands/get/query.pm @@ -0,0 +1,109 @@ +package commands::get::query; + +use Moose; +use overload '~~' => \&_equals; +use Scalar::Util qw(looks_like_number); + +has 'query' => ( + is => 'ro', + isa => 'Str', + required => 1 +); + +has 'chan' => ( + is => 'ro', + isa => 'Str', + required => 1 +); + +has 'is_global' => ( + is => 'ro', + isa => 'Bool', + lazy => 1, + builder => '_build_is_global', + init_arg => undef +); + +has 'tags' => ( + is => 'ro', + isa => 'ArrayRef[Str]', + lazy => 1, + builder => '_build_tags', + init_arg => undef +); + +has 'words' => ( + is => 'ro', + isa => 'ArrayRef[Str]', + lazy => 1, + builder => '_build_words', + init_arg => undef +); + +has 'id' => ( + is => 'ro', + isa => 'Int', + lazy => 1, + builder => '_build_id', + init_arg => undef +); + + +sub _build_is_global { + my $self = shift; + + if ($self->chan !~ /^#/ || $self->query =~ /(^|\s)-a(ll)?($|\s)/) { + return 1; + } else { + return 0; + } +} + +sub _build_tags { + my $self = shift; + + my $query = $self->query; + $query =~ s/(^|\s)-a(ll)?($|\s)//; + + return [$query =~ /#([a-zA-Z0-9_-]+)/g]; +} + +sub _build_words { + my $self = shift; + + my $query = $self->query; + $query =~ s/(^|\s)-a(ll)?($|\s)//; + + return [$query =~ /(?:^| )([^#\s]+)/g]; +} + +sub _build_id { + my $self = shift; + + if (looks_like_number($self->words->[0])) { + return $self->words->[0]; + } else { + return -1; + } +} + +sub _equals { + my ($self, $query) = @_; + + return 0 unless (ref($self) eq ref($query)); + + my @tags1 = sort @{$self->tags}; + my @tags2 = sort @{$query->tags}; + my @words1 = sort @{$self->words}; + my @words2 = sort @{$query->words}; + + return ($self->is_global eq $query->is_global + and @tags1 ~~ @tags2 + and @words1 ~~ @words2 + and $self->id eq $query->id + ); +} + +__PACKAGE__->meta->make_immutable; + +1; -- GitLab