Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/Data/ObjectDriver/Driver/DBI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ sub prepare_fetch {

my $stmt = $driver->prepare_statement($class, $terms, $args);

my $sql = $stmt->as_sql;
my $sql = $stmt->as_sql($driver->rw_handle);
$sql .= "\nFOR UPDATE" if $orig_args->{for_update};
return ($sql, $stmt->{bind}, $stmt)
}
Expand Down
9 changes: 7 additions & 2 deletions lib/Data/ObjectDriver/SQL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,19 @@ sub add_index_hint {
}

sub as_sql {
my $stmt = shift;
my ($stmt, $dbh) = @_;
my $sql = '';
if (@{ $stmt->select }) {
$sql .= 'SELECT ';
$sql .= 'DISTINCT ' if $stmt->distinct;
$sql .= join(', ', map {
my $alias = $stmt->select_map->{$_};
$alias && /(?:^|\.)\Q$alias\E$/ ? $_ : "$_ $alias";
if ($alias && !/(?:^|\.)\Q$alias\E$/) {
$alias = $dbh->quote_identifier($alias) if $dbh;
qq!$_ $alias!
} else {
$_;
}
} @{ $stmt->select }) . "\n";
}
$sql .= 'FROM ';
Expand Down
72 changes: 62 additions & 10 deletions t/11-sql.t
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@

use strict;

use lib 't/lib';
use Data::ObjectDriver::SQL;
use Test::More tests => 113;
use Test::More tests => 111;
use DodTestUtil;

BEGIN { DodTestUtil->check_driver }

setup_dbs({
global => [ qw( wines ) ],
});

my $stmt = ns();
ok($stmt, 'Created SQL object');
Expand Down Expand Up @@ -284,15 +292,34 @@ $stmt->add_select('bar');
$stmt->from([ qw( baz ) ]);
is($stmt->as_sql, "SELECT foo, bar\nFROM baz\n");

$stmt = ns();
$stmt->add_select('f.foo' => 'foo');
$stmt->add_select('COUNT(*)' => 'count');
$stmt->from([ qw( baz ) ]);
is($stmt->as_sql, "SELECT f.foo, COUNT(*) count\nFROM baz\n");
my $map = $stmt->select_map;
is(scalar(keys %$map), 2);
is($map->{'f.foo'}, 'foo');
is($map->{'COUNT(*)'}, 'count');
subtest 'SQL functions' => sub {
$stmt = ns();
$stmt->add_select('f.foo' => 'foo');
$stmt->add_select('COUNT(*)' => 'count');
$stmt->from([ qw( baz ) ]);
is($stmt->as_sql, "SELECT f.foo, COUNT(*) count\nFROM baz\n");
my $map = $stmt->select_map;
is(scalar(keys %$map), 2);
is_deeply($map, {'f.foo' => 'foo', 'COUNT(*)' => 'count'}, 'right map');

$stmt = ns();
$stmt->add_select('count(foo)');
$stmt->add_select('count(bar)');
$stmt->from([qw( baz )]);
is($stmt->as_sql, "SELECT count(foo), count(bar)\nFROM baz\n");
my $map = $stmt->select_map;
is(scalar(keys %$map), 2);
is_deeply($map, {'count(foo)' => 'count(foo)', 'count(bar)' => 'count(bar)'}, 'right map');

$stmt = ns();
$stmt->add_select('count(foo)', 'count1');
$stmt->add_select('count(bar)', 'count2');
$stmt->from([qw( baz )]);
is($stmt->as_sql, "SELECT count(foo) count1, count(bar) count2\nFROM baz\n");
my $map = $stmt->select_map;
is(scalar(keys %$map), 2);
is_deeply($map, {'count(foo)' => 'count1', 'count(bar)' => 'count2'}, 'right map');
};

# HAVING
$stmt = ns();
Expand Down Expand Up @@ -386,4 +413,29 @@ is(
: "WHERE ((foo = ?)) AND ((baz = ?) AND ((bar LIKE ?) OR (bar LIKE ?)))\n"
);

subtest 'quote can be used based on given dbh' => sub {
use Wine;
$stmt = ns();
$stmt->add_select(foo => 'bar');
@{$stmt->from} = ('baz');
my $quoted = Wine->driver->rw_handle->quote_identifier('bar');
is sql_normalize($stmt->as_sql(Wine->driver->rw_handle)), sql_normalize(<<"EOF"), 'right sql';
SELECT foo $quoted FROM baz
EOF
};

sub ns { Data::ObjectDriver::SQL->new }

sub sql_normalize {
my $sql = shift;
$sql =~ s{\s+}{ }g;
$sql =~ s{\( }{(}g;
$sql =~ s{ \)}{)}g;
$sql =~ s{([\(\)]) ([\(\)])}{$1$2}g;
$sql;
}

END {
disconnect_all(qw/Wine/);
teardown_dbs(qw( global ));
}
Loading