From 28334a4a001770d8f1731d2ad60089efb8bc467b Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Sun, 14 Oct 2018 18:41:32 +0300 Subject: [PATCH] Core::Handle - make simple_query a little less simple The simplest of joins is to take two tables, and join on a single field from each table. If we're agreed that's simple, then it is worth supporting. So, rather than: $urow = database->quick_select('users', { login => $uname }); $crow = database->quick_select('countries', { id => $urow->{'country'} }); One can now do: $row = database->quick_select([ 'users', 'countries' ], { login => $uname }, { join_keys => ['country','id'] }); (defaulting to inner join), or: $row = database->quick_select([ 'users', 'countries'], { login => $uname }, { join_type => 'left', join_keys => ['country','id'] }); Signed-off-by: Phil Carmody --- .../lib/Dancer/Plugin/Database/Core/Handle.pm | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/Shared/lib/Dancer/Plugin/Database/Core/Handle.pm b/Shared/lib/Dancer/Plugin/Database/Core/Handle.pm index 1d00f411..12136490 100644 --- a/Shared/lib/Dancer/Plugin/Database/Core/Handle.pm +++ b/Shared/lib/Dancer/Plugin/Database/Core/Handle.pm @@ -252,9 +252,16 @@ sub _quick_query { carp "Unrecognised query type $type!"; return; } - if (!$table_name || ref $table_name) { - carp "Expected table name as a straight scalar"; - return; + if ($type =~ m{^ (SELECT|COUNT) $}x && ref $table_name eq 'ARRAY') { + if (scalar(@$table_name) != 2) { + carp "join over more than one table"; + return; + } + } else { + if (!$table_name || ref $table_name) { + carp "Expected table name as a straight scalar"; + return; + } } if (($type eq 'INSERT' || $type eq 'UPDATE') && (!$data || ref $data ne 'HASH')) @@ -323,16 +330,31 @@ sub _generate_sql { $which_cols = join(',', map { $self->_quote_identifier($_) } @cols); } - $table_name = $self->_quote_identifier($table_name); my @bind_params; - my $sql = { - SELECT => "SELECT $which_cols FROM $table_name", - INSERT => "INSERT INTO $table_name ", - UPDATE => "UPDATE $table_name SET ", - DELETE => "DELETE FROM $table_name ", - COUNT => "SELECT COUNT(*) FROM $table_name", - }->{$type}; + my $sql; + if (ref $table_name) { + my $payload = ($type eq 'COUNT') ? 'COUNT(*)' : $which_cols; + my @ts = map { $self->_quote_identifier($_); } @$table_name; + my $join = ($opts->{'join_type'}//'INNER') . " JOIN $ts[1]"; + if (!ref $opts->{'join_keys'}) { + $join .= ' USING ' . $self->_quote_identifier($opts->{'join_keys'}) + if ($opts->{'join_keys'}); + } else { + $join .= " ON $ts[0]." . $self->_quote_identifier($opts->{'join_keys'}[0]) + . " = $ts[1]." . $self->_quote_identifier($opts->{'join_keys'}[1]); + } + $sql = "SELECT $payload FROM $ts[0] $join"; + } else { + $table_name = $self->_quote_identifier($table_name); + $sql = { + SELECT => "SELECT $which_cols FROM $table_name", + INSERT => "INSERT INTO $table_name ", + UPDATE => "UPDATE $table_name SET ", + DELETE => "DELETE FROM $table_name ", + COUNT => "SELECT COUNT(*) FROM $table_name", + }->{$type}; + } if ($type eq 'INSERT') { my (@keys, @values); for my $key (sort keys %$data) {