DBIx-QuickORM
view release on metacpan or search on metacpan
t/AI/literal_source.t view on Meta::CPAN
# An existing scalar reference is copied, not blessed in place.
my $sql = "SELECT 1 AS a";
my $ref = DBIx::QuickORM::LiteralSource->new(\$sql);
isa_ok($ref, ['DBIx::QuickORM::LiteralSource'], "constructed from a scalar reference");
is($ref->source_db_moniker, "SELECT 1 AS a",
"source_db_moniker returns the referenced SQL");
ok(!ref($sql), "new() does not bless the caller's scalar ref in place");
is($sql, "SELECT 1 AS a", "caller's variable is left untouched");
# Non-scalar references are rejected.
like(dies { DBIx::QuickORM::LiteralSource->new({}) },
qr/is not a scalar reference/, "a hashref is rejected");
like(dies { DBIx::QuickORM::LiteralSource->new([]) },
qr/is not a scalar reference/, "an arrayref is rejected");
# The subquery option wraps the SQL as a derived table.
my $named = DBIx::QuickORM::LiteralSource->new("SELECT 1", subquery => 'x');
is($named->source_db_moniker, "( SELECT 1 ) AS x",
"subquery => 'x' wraps as a derived table aliased x");
my $defaulted = DBIx::QuickORM::LiteralSource->new("SELECT 1", subquery => 1);
is($defaulted->source_db_moniker, "( SELECT 1 ) AS subquery",
"subquery => 1 uses the default alias");
};
subtest role_source_interface => sub {
my $ls = DBIx::QuickORM::LiteralSource->new("SELECT * FROM users");
ok($ls->DOES('DBIx::QuickORM::Role::Source'), "implements the Role::Source role");
is($ls->source_orm_name, 'LITERAL', "source_orm_name is 'LITERAL'");
is($ls->source_db_moniker, "SELECT * FROM users", "source_db_moniker is the raw SQL");
ok(!$ls->cachable, "a literal source is not cachable");
is($ls->fields_to_fetch, ['*'], "fields_to_fetch is ['*']");
is($ls->fields_list_all, ['*'], "fields_list_all is ['*']");
is($ls->field_affinity('anything'), 'string', "field_affinity is always 'string'");
# The remaining metadata accessors carry nothing for a literal source.
is($ls->primary_key, undef, "no primary key");
is($ls->row_class, undef, "no row class");
is($ls->field_type('x'), undef, "no field type");
is($ls->fields_to_omit, undef, "no fields to omit");
is($ls->has_field('x'), undef, "has_field reports nothing");
};
subtest query_through_connection => sub {
my $dir = tempdir(CLEANUP => 1);
my $dsn = "dbi:SQLite:dbname=$dir/literal.sqlite";
{
my $dbh = DBI->connect($dsn, '', '', {RaiseError => 1, PrintError => 0});
$dbh->do('CREATE TABLE people (id INTEGER PRIMARY KEY, surname TEXT)');
$dbh->do("INSERT INTO people (surname) VALUES ('smith'), ('jones')");
$dbh->disconnect;
}
my $con = DBIx::QuickORM->quick(credentials => {dsn => $dsn});
# $con->source(\$sql) builds a LiteralSource.
my $sql = "people";
my $src = $con->source(\$sql);
isa_ok($src, ['DBIx::QuickORM::LiteralSource'], "con->source(\\\$sql) builds a LiteralSource");
# The SQL builder splices the moniker in after FROM, so a literal source
# works as a FROM fragment (e.g. a table name). It is NOT a full
# standalone SELECT statement.
my @rows = $con->handle($src)->data_only->all;
is(scalar(@rows), 2, "queried the literal (FROM-fragment) source");
is(
[sort map { $_->{surname} } @rows],
['jones', 'smith'],
"rows came back from the literal source query",
);
# A full SELECT statement can be queried when wrapped as a subquery: the
# builder emits "SELECT * FROM ( <sql> ) AS <alias>".
my $sub = DBIx::QuickORM::LiteralSource->new(
"SELECT surname FROM people WHERE surname = 'smith'",
subquery => 'only_smith',
);
is(
$sub->source_db_moniker,
"( SELECT surname FROM people WHERE surname = 'smith' ) AS only_smith",
"subquery moniker is wrapped as a derived table",
);
my @sub_rows = $con->handle($sub)->data_only->all;
is(
[map { $_->{surname} } @sub_rows],
['smith'],
"queried a full statement via the subquery wrapping",
);
# Documented contract: handle() does NOT accept a scalar ref directly the
# way source() does; you must build the source first. (See the POD for
# Connection::handle and Handle's constructor args.)
like(
dies { $con->handle(\$sql) },
qr/Not sure what to do with 'SCALAR/,
"handle(\\\$sql) throws; build the source first via source(\\\$sql)",
);
};
done_testing;
( run in 0.889 second using v1.01-cache-2.11-cpan-5b529ec07f3 )