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