SQL: Doc and test adjustments
This commit is contained in:
parent
145d086bea
commit
8036b8f0bf
2 changed files with 34 additions and 10 deletions
26
FU/SQL.pm
26
FU/SQL.pm
|
|
@ -180,8 +180,7 @@ B<String literals> are interpreted as raw SQL fragments.
|
||||||
|
|
||||||
=item 2.
|
=item 2.
|
||||||
|
|
||||||
Objects returned by other functions listed below can be included as
|
Objects returned by other functions listed below are included as SQL fragments.
|
||||||
SQL fragments.
|
|
||||||
|
|
||||||
=item 3.
|
=item 3.
|
||||||
|
|
||||||
|
|
@ -200,8 +199,8 @@ These rules allow for flexible SQL construction:
|
||||||
There is some magic going on in order to differentiate between a I<string
|
There is some magic going on in order to differentiate between a I<string
|
||||||
literal> and other arguments. The rule is that anything that is
|
literal> and other arguments. The rule is that anything that is
|
||||||
C<builtin::created_as_string()> and read-only (as per
|
C<builtin::created_as_string()> and read-only (as per
|
||||||
C<Internals::SvREADONLY()>) is considered raw SQL. Variables are by definition
|
C<Internals::SvREADONLY()>) is considered raw SQL. Regular variables, array
|
||||||
writable:
|
elements and hash values are always writable:
|
||||||
|
|
||||||
my $x = 'SELECT 1';
|
my $x = 'SELECT 1';
|
||||||
SQL $x; # BAD: $x is used as bind parameter instead
|
SQL $x; # BAD: $x is used as bind parameter instead
|
||||||
|
|
@ -210,8 +209,16 @@ writable:
|
||||||
my $x = SQL 'SELECT 1';
|
my $x = SQL 'SELECT 1';
|
||||||
SQL $x;
|
SQL $x;
|
||||||
|
|
||||||
In most cases, though, this is the behavior you want. In the few cases where it
|
Constants created with C<use constant> are considered string literals, and
|
||||||
isn't, you can always use C<P()> or C<RAW()> to force an argument as bind
|
there are probably plenty of other creative ways to end up with variables that
|
||||||
|
may be considered a "string literal" by this module. L<Hash::Util>,
|
||||||
|
L<Scalar::Readonly>, other modules and tied hashes or arrays all have the
|
||||||
|
potential to create read-only strings, but I don't expect that these are
|
||||||
|
commonly applied on untrusted user input.
|
||||||
|
|
||||||
|
In most cases, this heuristic should work out well. In the few cases where it
|
||||||
|
doesn't, or when you're not entirely sure what kind of value you're dealing
|
||||||
|
with, you can always use C<P()> or C<RAW()> to force an argument as bind
|
||||||
parameter or SQL string.
|
parameter or SQL string.
|
||||||
|
|
||||||
=item P($val)
|
=item P($val)
|
||||||
|
|
@ -235,7 +242,7 @@ Force the given C<$sql> string to be included as SQL. For example:
|
||||||
SQL 'WHERE * FROM', RAW $tables[1];
|
SQL 'WHERE * FROM', RAW $tables[1];
|
||||||
# 'SELECT * FROM b'
|
# 'SELECT * FROM b'
|
||||||
|
|
||||||
Absolutely do not use this function with untrusted input.
|
Never use this function with untrusted input.
|
||||||
|
|
||||||
=item PARENS(@args)
|
=item PARENS(@args)
|
||||||
|
|
||||||
|
|
@ -271,7 +278,7 @@ C<'1=1'> (i.e. true) if C<@conditions> is an empty list.
|
||||||
|
|
||||||
=item AND($hashref)
|
=item AND($hashref)
|
||||||
|
|
||||||
A special form of C<AND()> that tests the given column for equality instead.
|
A special form of C<AND()> that tests the given columns for equality instead.
|
||||||
The keys of the hashref are interpreted as raw SQL and the values as bind
|
The keys of the hashref are interpreted as raw SQL and the values as bind
|
||||||
parameters.
|
parameters.
|
||||||
|
|
||||||
|
|
@ -335,8 +342,7 @@ convenient insert-or-update:
|
||||||
SQL 'INSERT INTO table', VALUES($data),
|
SQL 'INSERT INTO table', VALUES($data),
|
||||||
'ON CONFLICT (name) DO UPDATE', SET($data);
|
'ON CONFLICT (name) DO UPDATE', SET($data);
|
||||||
|
|
||||||
(The bind parameters are duplicated though, there's no duplicate detection yet.
|
(The bind parameters are duplicated though)
|
||||||
Not sure if that's even worth it)
|
|
||||||
|
|
||||||
=item IN($arrayref)
|
=item IN($arrayref)
|
||||||
|
|
||||||
|
|
|
||||||
18
t/sql.t
18
t/sql.t
|
|
@ -68,4 +68,22 @@ t IN([]), '= ANY($1)', [[]], in_style => 'pg', placeholder_style => 'pg';
|
||||||
|
|
||||||
t WHERE({ id => IN([1,2]) }), 'WHERE ( id IN(?,?) )', [1,2];
|
t WHERE({ id => IN([1,2]) }), 'WHERE ( id IN(?,?) )', [1,2];
|
||||||
|
|
||||||
|
sub somefunc { 'not actually const' }
|
||||||
|
t SQL(somefunc), '?', [somefunc];
|
||||||
|
|
||||||
|
use constant constval => 'this is a constant';
|
||||||
|
t SQL(constval), constval, [];
|
||||||
|
|
||||||
|
sub otherfunc { constval }
|
||||||
|
t SQL(otherfunc), '?', [otherfunc];
|
||||||
|
|
||||||
|
sub passthrough { $_[0] }
|
||||||
|
t SQL(passthrough 'hi'), '?', ['hi'];
|
||||||
|
|
||||||
|
use Hash::Util;
|
||||||
|
my %hash = (v => 'value');
|
||||||
|
Hash::Util::lock_keys(%hash);
|
||||||
|
Hash::Util::lock_value(%hash, 'v');
|
||||||
|
t SQL($hash{v}), 'value', [];
|
||||||
|
|
||||||
done_testing;
|
done_testing;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue