test is case insensitive, result should be lower cased
[scpubgit/Q-Branch.git] / lib / SQL / Abstract.pm
CommitLineData
96449e8e 1package SQL::Abstract; # see doc at end of file
2
96449e8e 3use strict;
4use warnings;
b84764fb 5use Module::Runtime ();
9d9d5bd6 6use Carp ();
312d830b 7use List::Util ();
8use Scalar::Util ();
96449e8e 9
0da0fe34 10use Exporter 'import';
11our @EXPORT_OK = qw(is_plain_value is_literal_value);
12
13BEGIN {
14 if ($] < 5.009_005) {
15 require MRO::Compat;
16 }
17 else {
18 require mro;
19 }
843a94b5 20
21 *SQL::Abstract::_ENV_::DETECT_AUTOGENERATED_STRINGIFICATION = $ENV{SQLA_ISVALUE_IGNORE_AUTOGENERATED_STRINGIFICATION}
22 ? sub () { 0 }
23 : sub () { 1 }
24 ;
0da0fe34 25}
26
96449e8e 27#======================================================================
28# GLOBALS
29#======================================================================
30
dc6afcf8 31our $VERSION = '1.86';
7479e27e 32
22f1a437 33# This would confuse some packagers
c520207b 34$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
96449e8e 35
36our $AUTOLOAD;
37
38# special operators (-in, -between). May be extended/overridden by user.
39# See section WHERE: BUILTIN SPECIAL OPERATORS below for implementation
40my @BUILTIN_SPECIAL_OPS = (
f663e672 41 {regex => qr/^ (?: not \s )? between $/ix, handler => sub { die "NOPE" }},
87c8e45b 42 {regex => qr/^ is (?: \s+ not )? $/ix, handler => sub { die "NOPE" }},
909ec5ec 43 {regex => qr/^ (?: not \s )? in $/ix, handler => sub { die "NOPE" }},
b798961f 44 {regex => qr/^ ident $/ix, handler => sub { die "NOPE" }},
45 {regex => qr/^ value $/ix, handler => sub { die "NOPE" }},
96449e8e 46);
47
48#======================================================================
49# DEBUGGING AND ERROR REPORTING
50#======================================================================
51
52sub _debug {
53 return unless $_[0]->{debug}; shift; # a little faster
54 my $func = (caller(1))[3];
55 warn "[$func] ", @_, "\n";
56}
57
58sub belch (@) {
59 my($func) = (caller(1))[3];
9d9d5bd6 60 Carp::carp "[$func] Warning: ", @_;
96449e8e 61}
62
63sub puke (@) {
64 my($func) = (caller(1))[3];
9d9d5bd6 65 Carp::croak "[$func] Fatal: ", @_;
96449e8e 66}
67
0da0fe34 68sub is_literal_value ($) {
69 ref $_[0] eq 'SCALAR' ? [ ${$_[0]} ]
70 : ( ref $_[0] eq 'REF' and ref ${$_[0]} eq 'ARRAY' ) ? [ @${ $_[0] } ]
0da0fe34 71 : undef;
72}
73
6d7a39b3 74sub is_undef_value ($) {
75 !defined($_[0])
76 or (
77 ref($_[0]) eq 'HASH'
78 and exists $_[0]->{-value}
79 and not defined $_[0]->{-value}
80 );
81}
82
0da0fe34 83# FIXME XSify - this can be done so much more efficiently
84sub is_plain_value ($) {
85 no strict 'refs';
966200cc 86 ! length ref $_[0] ? \($_[0])
0da0fe34 87 : (
88 ref $_[0] eq 'HASH' and keys %{$_[0]} == 1
89 and
90 exists $_[0]->{-value}
966200cc 91 ) ? \($_[0]->{-value})
0da0fe34 92 : (
a1c9e0ff 93 # reuse @_ for even moar speedz
94 defined ( $_[1] = Scalar::Util::blessed $_[0] )
0da0fe34 95 and
96 # deliberately not using Devel::OverloadInfo - the checks we are
97 # intersted in are much more limited than the fullblown thing, and
98 # this is a very hot piece of code
99 (
e8d729d4 100 # simply using ->can('(""') can leave behind stub methods that
101 # break actually using the overload later (see L<perldiag/Stub
102 # found while resolving method "%s" overloading "%s" in package
103 # "%s"> and the source of overload::mycan())
44e54b41 104 #
0da0fe34 105 # either has stringification which DBI SHOULD prefer out of the box
a1c9e0ff 106 grep { *{ (qq[${_}::(""]) }{CODE} } @{ $_[2] = mro::get_linear_isa( $_[1] ) }
0da0fe34 107 or
20e178a8 108 # has nummification or boolification, AND fallback is *not* disabled
0da0fe34 109 (
843a94b5 110 SQL::Abstract::_ENV_::DETECT_AUTOGENERATED_STRINGIFICATION
111 and
20e178a8 112 (
113 grep { *{"${_}::(0+"}{CODE} } @{$_[2]}
114 or
115 grep { *{"${_}::(bool"}{CODE} } @{$_[2]}
116 )
0da0fe34 117 and
118 (
119 # no fallback specified at all
a1c9e0ff 120 ! ( ($_[3]) = grep { *{"${_}::()"}{CODE} } @{$_[2]} )
0da0fe34 121 or
122 # fallback explicitly undef
a1c9e0ff 123 ! defined ${"$_[3]::()"}
0da0fe34 124 or
125 # explicitly true
a1c9e0ff 126 !! ${"$_[3]::()"}
0da0fe34 127 )
128 )
129 )
966200cc 130 ) ? \($_[0])
0da0fe34 131 : undef;
132}
133
134
96449e8e 135
136#======================================================================
137# NEW
138#======================================================================
139
140sub new {
141 my $self = shift;
142 my $class = ref($self) || $self;
143 my %opt = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
144
145 # choose our case by keeping an option around
146 delete $opt{case} if $opt{case} && $opt{case} ne 'lower';
147
148 # default logic for interpreting arrayrefs
ef559da3 149 $opt{logic} = $opt{logic} ? uc $opt{logic} : 'OR';
96449e8e 150
151 # how to return bind vars
96449e8e 152 $opt{bindtype} ||= 'normal';
153
154 # default comparison is "=", but can be overridden
155 $opt{cmp} ||= '=';
156
3af02ccb 157 # try to recognize which are the 'equality' and 'inequality' ops
3cdadcbe 158 # (temporary quickfix (in 2007), should go through a more seasoned API)
159 $opt{equality_op} = qr/^( \Q$opt{cmp}\E | \= )$/ix;
160 $opt{inequality_op} = qr/^( != | <> )$/ix;
161
2809a2ff 162 $opt{like_op} = qr/^ (is_)?r?like $/xi;
163 $opt{not_like_op} = qr/^ (is_)?not_r?like $/xi;
96449e8e 164
165 # SQL booleans
166 $opt{sqltrue} ||= '1=1';
167 $opt{sqlfalse} ||= '0=1';
168
9d48860e 169 # special operators
30af97c5 170 $opt{special_ops} ||= [];
171
cf06e9dc 172 if ($class->isa('DBIx::Class::SQLMaker')) {
97c9af32 173 $opt{warn_once_on_nest} = 1;
b798961f 174 $opt{disable_old_special_ops} = 1;
dd1d0dbf 175 }
176
9d48860e 177 # unary operators
59f23b3d 178 $opt{unary_ops} ||= [];
59f23b3d 179
3af02ccb 180 # rudimentary sanity-check for user supplied bits treated as functions/operators
b6251592 181 # If a purported function matches this regular expression, an exception is thrown.
182 # Literal SQL is *NOT* subject to this check, only functions (and column names
183 # when quoting is not in effect)
96449e8e 184
b6251592 185 # FIXME
186 # need to guard against ()'s in column names too, but this will break tons of
187 # hacks... ideas anyone?
188 $opt{injection_guard} ||= qr/
189 \;
190 |
191 ^ \s* go \s
192 /xmi;
96449e8e 193
ec19b759 194 $opt{expand_unary} = {};
195
767b62e4 196 $opt{expand} = {
def45151 197 not => '_expand_not',
198 bool => '_expand_bool',
199 and => '_expand_op_andor',
200 or => '_expand_op_andor',
201 nest => '_expand_nest',
202 bind => '_expand_bind',
203 in => '_expand_in',
204 not_in => '_expand_in',
205 row => '_expand_row',
206 between => '_expand_between',
207 not_between => '_expand_between',
208 op => '_expand_op',
209 (map +($_ => '_expand_op_is'), ('is', 'is_not')),
210 ident => '_expand_ident',
211 value => '_expand_value',
a5536efa 212 func => '_expand_func',
767b62e4 213 };
214
143f50df 215 $opt{expand_op} = {
216 'between' => '_expand_between',
2809a2ff 217 'not_between' => '_expand_between',
416026a9 218 'in' => '_expand_in',
2809a2ff 219 'not_in' => '_expand_in',
5c633220 220 'nest' => '_expand_nest',
f49b02a0 221 (map +($_ => '_expand_op_andor'), ('and', 'or')),
2809a2ff 222 (map +($_ => '_expand_op_is'), ('is', 'is_not')),
bef0b297 223 'ident' => '_expand_ident',
7e461775 224 'value' => '_expand_value',
143f50df 225 };
ca158918 226
227 $opt{render} = {
01222ad2 228 (map +($_, "_render_$_"), qw(op func bind ident literal row)),
ca158918 229 %{$opt{render}||{}}
230 };
231
9159df95 232 $opt{render_op} = {
2809a2ff 233 (map +($_ => '_render_op_between'), 'between', 'not_between'),
234 (map +($_ => '_render_op_in'), 'in', 'not_in'),
9159df95 235 (map +($_ => '_render_unop_postfix'),
2809a2ff 236 'is_null', 'is_not_null', 'asc', 'desc',
9159df95 237 ),
82048a14 238 (not => '_render_unop_paren'),
9159df95 239 (map +($_ => '_render_op_andor'), qw(and or)),
df7bba54 240 ',' => '_render_op_multop',
9159df95 241 };
143f50df 242
b84764fb 243 if ($opt{lazy_join_sql_parts}) {
244 my $mod = Module::Runtime::use_module('SQL::Abstract::Parts');
245 $opt{join_sql_parts} ||= sub { $mod->new(@_) };
246 }
247
248 $opt{join_sql_parts} ||= sub { join $_[0], @_[1..$#_] };
249
b6251592 250 return bless \%opt, $class;
251}
96449e8e 252
e175845b 253sub sqltrue { +{ -literal => [ $_[0]->{sqltrue} ] } }
254sub sqlfalse { +{ -literal => [ $_[0]->{sqlfalse} ] } }
170e6c33 255
256sub _assert_pass_injection_guard {
257 if ($_[1] =~ $_[0]->{injection_guard}) {
258 my $class = ref $_[0];
259 puke "Possible SQL injection attempt '$_[1]'. If this is indeed a part of the "
260 . "desired SQL use literal SQL ( \'...' or \[ '...' ] ) or supply your own "
261 . "{injection_guard} attribute to ${class}->new()"
262 }
263}
264
265
96449e8e 266#======================================================================
267# INSERT methods
268#======================================================================
269
270sub insert {
02288357 271 my $self = shift;
272 my $table = $self->_table(shift);
273 my $data = shift || return;
274 my $options = shift;
96449e8e 275
35ecefe7 276 my $fields;
277
70b505ab 278 my ($f_aqt, $v_aqt) = $self->_expand_insert_values($data);
ede0de38 279
35ecefe7 280 my @parts = ([ $self->_sqlcase('insert into').' '.$table ]);
a7a125f7 281 push @parts, $self->render_aqt($f_aqt) if $f_aqt;
282 push @parts, [ $self->_sqlcase('values') ], $self->render_aqt($v_aqt);
02288357 283
e82e648a 284 if ($options->{returning}) {
35ecefe7 285 push @parts, [ $self->_insert_returning($options) ];
02288357 286 }
287
7e23f618 288 my ($sql, @bind) = @{ $self->join_query_parts(' ', @parts) };
289 return wantarray ? ($sql, @bind) : $sql;
96449e8e 290}
291
70b505ab 292sub _expand_insert_values {
293 my ($self, $data) = @_;
294 if (is_literal_value($data)) {
295 (undef, $self->expand_expr($data));
296 } else {
297 my ($fields, $values) = (
298 ref($data) eq 'HASH' ?
299 ([ sort keys %$data ], [ @{$data}{sort keys %$data} ])
300 : ([], $data)
301 );
302
303 # no names (arrayref) means can't generate bindtype
304 !($fields) && $self->{bindtype} eq 'columns'
305 && belch "can't do 'columns' bindtype when called with arrayref";
306
307 +(
308 (@$fields
309 ? $self->expand_expr({ -row => $fields }, -ident)
310 : undef
311 ),
312 +{ -row => [
313 map {
314 local our $Cur_Col_Meta = $fields->[$_];
315 $self->_expand_insert_value($values->[$_])
316 } 0..$#$values
317 ] },
318 );
319 }
320}
321
60f3fd3f 322# So that subclasses can override INSERT ... RETURNING separately from
323# UPDATE and DELETE (e.g. DBIx::Class::SQLMaker::Oracle does this)
b17a3ece 324sub _insert_returning { shift->_returning(@_) }
325
95904db5 326sub _returning {
e82e648a 327 my ($self, $options) = @_;
6b1fe79d 328
e82e648a 329 my $f = $options->{returning};
330
a7a125f7 331 my ($sql, @bind) = @{ $self->render_aqt(
dbc10abd 332 $self->_expand_maybe_list_expr($f, -ident)
a7a125f7 333 ) };
f9e868e7 334 return ($self->_sqlcase(' returning ').$sql, @bind);
6b1fe79d 335}
336
720ca4f7 337sub _expand_insert_value {
ede0de38 338 my ($self, $v) = @_;
339
340 my $k = our $Cur_Col_Meta;
96449e8e 341
720ca4f7 342 if (ref($v) eq 'ARRAY') {
343 if ($self->{array_datatypes}) {
ede0de38 344 return +{ -bind => [ $k, $v ] };
720ca4f7 345 }
346 my ($sql, @bind) = @$v;
347 $self->_assert_bindval_matches_bindtype(@bind);
348 return +{ -literal => $v };
349 }
350 if (ref($v) eq 'HASH') {
351 if (grep !/^-/, keys %$v) {
352 belch "HASH ref as bind value in insert is not supported";
ede0de38 353 return +{ -bind => [ $k, $v ] };
720ca4f7 354 }
355 }
356 if (!defined($v)) {
ede0de38 357 return +{ -bind => [ $k, undef ] };
720ca4f7 358 }
79d310f2 359 return $self->expand_expr($v);
96449e8e 360}
361
362
96449e8e 363
364#======================================================================
365# UPDATE methods
366#======================================================================
367
368
369sub update {
95904db5 370 my $self = shift;
371 my $table = $self->_table(shift);
372 my $data = shift || return;
373 my $where = shift;
374 my $options = shift;
96449e8e 375
376 # first build the 'SET' part of the sql statement
96449e8e 377 puke "Unsupported data type specified to \$sql->update"
378 unless ref $data eq 'HASH';
379
9ade906e 380 my ($sql, @all_bind) = $self->_update_set_values($data);
a9e94508 381 $sql = $self->_sqlcase('update ') . $table . $self->_sqlcase(' set ')
9ade906e 382 . $sql;
383
384 if ($where) {
385 my($where_sql, @where_bind) = $self->where($where);
386 $sql .= $where_sql;
387 push @all_bind, @where_bind;
388 }
389
390 if ($options->{returning}) {
391 my ($returning_sql, @returning_bind) = $self->_update_returning($options);
392 $sql .= $returning_sql;
393 push @all_bind, @returning_bind;
394 }
395
396 return wantarray ? ($sql, @all_bind) : $sql;
397}
398
399sub _update_set_values {
400 my ($self, $data) = @_;
401
a7a125f7 402 return @{ $self->render_aqt(
fe8b493f 403 $self->_expand_update_set_values(undef, $data),
a7a125f7 404 ) };
89690da2 405}
96449e8e 406
89690da2 407sub _expand_update_set_values {
fe8b493f 408 my ($self, undef, $data) = @_;
89690da2 409 $self->_expand_maybe_list_expr( [
410 map {
411 my ($k, $set) = @$_;
c4ed66f4 412 $set = { -bind => $_ } unless defined $set;
67e082b8 413 +{ -op => [ '=', { -ident => $k }, $set ] };
89690da2 414 }
415 map {
416 my $k = $_;
417 my $v = $data->{$k};
418 (ref($v) eq 'ARRAY'
419 ? ($self->{array_datatypes}
420 ? [ $k, +{ -bind => [ $k, $v ] } ]
421 : [ $k, +{ -literal => $v } ])
422 : do {
423 local our $Cur_Col_Meta = $k;
424 [ $k, $self->_expand_expr($v) ]
425 }
426 );
427 } sort keys %$data
428 ] );
96449e8e 429}
430
60f3fd3f 431# So that subclasses can override UPDATE ... RETURNING separately from
432# INSERT and DELETE
20bb2ad5 433sub _update_returning { shift->_returning(@_) }
96449e8e 434
435
436
437#======================================================================
438# SELECT
439#======================================================================
440
441
442sub select {
443 my $self = shift;
444 my $table = $self->_table(shift);
445 my $fields = shift || '*';
446 my $where = shift;
447 my $order = shift;
448
daa4ccdd 449 my ($fields_sql, @bind) = $self->_select_fields($fields);
96449e8e 450
daa4ccdd 451 my ($where_sql, @where_bind) = $self->where($where, $order);
452 push @bind, @where_bind;
453
454 my $sql = join(' ', $self->_sqlcase('select'), $fields_sql,
96449e8e 455 $self->_sqlcase('from'), $table)
456 . $where_sql;
457
9d48860e 458 return wantarray ? ($sql, @bind) : $sql;
96449e8e 459}
460
daa4ccdd 461sub _select_fields {
462 my ($self, $fields) = @_;
de63ce57 463 return $fields unless ref($fields);
a7a125f7 464 return @{ $self->render_aqt(
dbc10abd 465 $self->_expand_maybe_list_expr($fields, '-ident')
a7a125f7 466 ) };
daa4ccdd 467}
468
96449e8e 469#======================================================================
470# DELETE
471#======================================================================
472
473
474sub delete {
85327cd5 475 my $self = shift;
476 my $table = $self->_table(shift);
477 my $where = shift;
478 my $options = shift;
96449e8e 479
480 my($where_sql, @bind) = $self->where($where);
a9e94508 481 my $sql = $self->_sqlcase('delete from ') . $table . $where_sql;
96449e8e 482
85327cd5 483 if ($options->{returning}) {
ca4f826a 484 my ($returning_sql, @returning_bind) = $self->_delete_returning($options);
85327cd5 485 $sql .= $returning_sql;
486 push @bind, @returning_bind;
487 }
488
9d48860e 489 return wantarray ? ($sql, @bind) : $sql;
96449e8e 490}
491
60f3fd3f 492# So that subclasses can override DELETE ... RETURNING separately from
493# INSERT and UPDATE
85327cd5 494sub _delete_returning { shift->_returning(@_) }
495
496
96449e8e 497
498#======================================================================
499# WHERE: entry point
500#======================================================================
501
502
503
504# Finally, a separate routine just to handle WHERE clauses
505sub where {
506 my ($self, $where, $order) = @_;
507
7ad12721 508 local $self->{convert_where} = $self->{convert};
509
96449e8e 510 # where ?
e175845b 511 my ($sql, @bind) = defined($where)
512 ? $self->_recurse_where($where)
513 : (undef);
417dd15e 514 $sql = (defined $sql and length $sql) ? $self->_sqlcase(' where ') . "( $sql )" : '';
96449e8e 515
516 # order by?
517 if ($order) {
26fe4d30 518 my ($order_sql, @order_bind) = $self->_order_by($order);
519 $sql .= $order_sql;
520 push @bind, @order_bind;
96449e8e 521 }
522
9d48860e 523 return wantarray ? ($sql, @bind) : $sql;
96449e8e 524}
525
c349b750 526{ our $Default_Scalar_To = -value }
527
79d310f2 528sub expand_expr {
54d3140f 529 my ($self, $expr, $default_scalar_to) = @_;
530 local our $Default_Scalar_To = $default_scalar_to if $default_scalar_to;
7d93797d 531 $self->_expand_expr($expr);
79d310f2 532}
533
534sub render_aqt {
535 my ($self, $aqt) = @_;
536 my ($k, $v, @rest) = %$aqt;
537 die "No" if @rest;
5be20cbb 538 die "Not a node type: $k" unless $k =~ s/^-//;
21225d32 539 if (my $meth = $self->{render}{$k}) {
7e23f618 540 return $self->$meth($k, $v);
79d310f2 541 }
542 die "notreached: $k";
543}
544
6082a464 545sub render_expr {
ede0de38 546 my ($self, $expr, $default_scalar_to) = @_;
a7a125f7 547 return @{ $self->render_aqt(
7958f5c6 548 $self->expand_expr($expr, $default_scalar_to)
a7a125f7 549 ) };
6082a464 550}
551
24cd9525 552sub _normalize_op {
553 my ($self, $raw) = @_;
550eaa6f 554 my $op = lc $raw;
555 return $op if grep $_->{$op}, @{$self}{qw(is_op expand_op render_op)};
556 s/^-(?=.)//, s/\s+/_/g for $op;
24cd9525 557 $op;
558}
559
a2cd381d 560sub _expand_expr {
3a10d914 561 my ($self, $expr) = @_;
3ae10d16 562 our $Expand_Depth ||= 0; local $Expand_Depth = $Expand_Depth + 1;
252518da 563 return undef unless defined($expr);
59588695 564 if (ref($expr) eq 'HASH') {
767b62e4 565 return undef unless my $kc = keys %$expr;
566 if ($kc > 1) {
5be20cbb 567 return $self->_expand_op_andor(and => $expr);
59588695 568 }
767b62e4 569 my ($key, $value) = %$expr;
70f98e4b 570 if ($key =~ /^-/ and $key =~ s/ [_\s]? \d+ $//x ) {
571 belch 'Use of [and|or|nest]_N modifiers is deprecated and will be removed in SQLA v2.0. '
572 . "You probably wanted ...-and => [ $key => COND1, $key => COND2 ... ]";
573 }
e9d74ce7 574 return $self->_expand_hashpair($key, $value);
a2cd381d 575 }
08264f40 576 if (ref($expr) eq 'ARRAY') {
5be20cbb 577 return $self->_expand_op_andor(lc($self->{logic}), $expr);
08264f40 578 }
ca3da680 579 if (my $literal = is_literal_value($expr)) {
580 return +{ -literal => $literal };
581 }
99a65fa8 582 if (!ref($expr) or Scalar::Util::blessed($expr)) {
e9d74ce7 583 return $self->_expand_scalar($expr);
252518da 584 }
252518da 585 die "notreached";
a2cd381d 586}
96449e8e 587
e9d74ce7 588sub _expand_hashpair {
124b41ca 589 my ($self, $k, $v) = @_;
d13725da 590 unless (defined($k) and length($k)) {
2d64004f 591 if (defined($k) and my $literal = is_literal_value($v)) {
d13725da 592 belch 'Hash-pairs consisting of an empty string with a literal are deprecated, and will be removed in 2.0: use -and => [ $literal ] instead';
2d64004f 593 return { -literal => $literal };
d13725da 594 }
595 puke "Supplying an empty left hand side argument is not supported";
596 }
a93e8a87 597 if ($k =~ /^-./) {
e9d74ce7 598 return $self->_expand_hashpair_op($k, $v);
33ac0d7b 599 } elsif ($k =~ /^[^\w]/i) {
7741b7ad 600 my ($lhs, @rhs) = @$v;
601 return $self->_expand_op(
602 -op, [ $k, $self->expand_expr($lhs, -ident), @rhs ]
603 );
99a65fa8 604 }
e9d74ce7 605 return $self->_expand_hashpair_ident($k, $v);
1cc1e937 606}
607
e9d74ce7 608sub _expand_hashpair_ident {
1cc1e937 609 my ($self, $k, $v) = @_;
710cdeed 610
cd90d4f0 611 local our $Cur_Col_Meta = $k;
612
2e670469 613 # hash with multiple or no elements is andor
614
615 if (ref($v) eq 'HASH' and keys %$v != 1) {
5be20cbb 616 return $self->_expand_op_andor(and => $v, $k);
2e670469 617 }
618
710cdeed 619 # undef needs to be re-sent with cmp to achieve IS/IS NOT NULL
620
6d7a39b3 621 if (is_undef_value($v)) {
e9d74ce7 622 return $self->_expand_hashpair_cmp($k => undef);
99a65fa8 623 }
710cdeed 624
710cdeed 625 # scalars and objects get expanded as whatever requested or values
626
99a65fa8 627 if (!ref($v) or Scalar::Util::blessed($v)) {
e9d74ce7 628 return $self->_expand_hashpair_scalar($k, $v);
99a65fa8 629 }
0cdafc4b 630
631 # single key hashref is a hashtriple
632
99a65fa8 633 if (ref($v) eq 'HASH') {
e9d74ce7 634 return $self->_expand_hashtriple($k, %$v);
99a65fa8 635 }
0cdafc4b 636
637 # arrayref needs re-engineering over the elements
638
99a65fa8 639 if (ref($v) eq 'ARRAY') {
e175845b 640 return $self->sqlfalse unless @$v;
99a65fa8 641 $self->_debug("ARRAY($k) means distribute over elements");
124b41ca 642 my $logic = lc(
70f98e4b 643 $v->[0] =~ /^-(and|or)$/i
5be20cbb 644 ? (shift(@{$v = [ @$v ]}), $1)
645 : lc($self->{logic} || 'OR')
99a65fa8 646 );
d6ac0cfb 647 return $self->_expand_op_andor(
6393fa8e 648 $logic => $v, $k
66e362e4 649 );
99a65fa8 650 }
0cdafc4b 651
99a65fa8 652 if (my $literal = is_literal_value($v)) {
653 unless (length $k) {
654 belch 'Hash-pairs consisting of an empty string with a literal are deprecated, and will be removed in 2.0: use -and => [ $literal ] instead';
655 return \$literal;
656 }
657 my ($sql, @bind) = @$literal;
658 if ($self->{bindtype} eq 'columns') {
659 for (@bind) {
6fb2bd90 660 $self->_assert_bindval_matches_bindtype($_);
aa8d7bdb 661 }
331e2209 662 }
99a65fa8 663 return +{ -literal => [ $self->_quote($k).' '.$sql, @bind ] };
331e2209 664 }
99a65fa8 665 die "notreached";
59588695 666}
667
e9d74ce7 668sub _expand_scalar {
cd90d4f0 669 my ($self, $expr) = @_;
670
c349b750 671 return $self->_expand_expr({ (our $Default_Scalar_To) => $expr });
cd90d4f0 672}
673
e9d74ce7 674sub _expand_hashpair_scalar {
cd90d4f0 675 my ($self, $k, $v) = @_;
676
e9d74ce7 677 return $self->_expand_hashpair_cmp(
678 $k, $self->_expand_scalar($v),
cd90d4f0 679 );
680}
681
e9d74ce7 682sub _expand_hashpair_op {
d0ae57ad 683 my ($self, $k, $v) = @_;
710cdeed 684
2809a2ff 685 $self->_assert_pass_injection_guard($k =~ /\A-(.*)\Z/s);
24cd9525 686
2809a2ff 687 my $op = $self->_normalize_op($k);
710cdeed 688
def45151 689 if (my $exp = $self->{expand}{$op}) {
5be20cbb 690 return $self->$exp($op, $v);
def45151 691 }
692
710cdeed 693 # Ops prefixed with -not_ get converted
694
e57d8650 695 if (my ($rest) = $op =~/^not_(.*)$/) {
d0ae57ad 696 return +{ -op => [
697 'not',
698 $self->_expand_expr({ "-${rest}", $v })
2809a2ff 699 ] };
d0ae57ad 700 }
710cdeed 701
8e73de4b 702 { # Old SQLA compat
703
e57d8650 704 my $op = join(' ', split '_', $op);
705
8e73de4b 706 # the old special op system requires illegality for top-level use
707
708 if (
709 (our $Expand_Depth) == 1
fbb885c0 710 and (
711 List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}}
712 or (
713 $self->{disable_old_special_ops}
714 and List::Util::first { $op =~ $_->{regex} } @BUILTIN_SPECIAL_OPS
715 )
716 )
8e73de4b 717 ) {
718 puke "Illegal use of top-level '-$op'"
719 }
710cdeed 720
8e73de4b 721 # the old unary op system means we should touch nothing and let it work
710cdeed 722
8e73de4b 723 if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{unary_ops}}) {
724 return { -op => [ $op, $v ] };
725 }
d0ae57ad 726 }
710cdeed 727
728 # an explicit node type is currently assumed to be expanded (this is almost
729 # certainly wrong and there should be expansion anyway)
730
7256c844 731 if ($self->{render}{$op}) {
d0ae57ad 732 return { $k => $v };
733 }
710cdeed 734
7250aa13 735 my $type = $self->{unknown_unop_always_func} ? -func : -op;
710cdeed 736
7250aa13 737 { # Old SQLA compat
710cdeed 738
7250aa13 739 if (
740 ref($v) eq 'HASH'
741 and keys %$v == 1
742 and (keys %$v)[0] =~ /^-/
743 ) {
744 $type = (
745 (List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}})
746 ? -op
747 : -func
748 )
749 }
d0ae57ad 750 }
710cdeed 751
7250aa13 752 return +{ $type => [
753 $op,
754 ($type eq -func and ref($v) eq 'ARRAY')
755 ? map $self->_expand_expr($_), @$v
756 : $self->_expand_expr($v)
757 ] };
d0ae57ad 758}
759
e9d74ce7 760sub _expand_hashpair_cmp {
efcd97c3 761 my ($self, $k, $v) = @_;
e9d74ce7 762 $self->_expand_hashtriple($k, $self->{cmp}, $v);
efcd97c3 763}
764
e9d74ce7 765sub _expand_hashtriple {
0b2789b3 766 my ($self, $k, $vk, $vv) = @_;
767
67e082b8 768 my $ik = $self->_expand_expr({ -ident => $k });
0b2789b3 769
24cd9525 770 my $op = $self->_normalize_op($vk);
0b2789b3 771 $self->_assert_pass_injection_guard($op);
24cd9525 772
773 if ($op =~ s/ _? \d+ $//x ) {
0b2789b3 774 return $self->_expand_expr($k, { $vk, $vv });
775 }
776 if (my $x = $self->{expand_op}{$op}) {
777 local our $Cur_Col_Meta = $k;
778 return $self->$x($op, $vv, $k);
779 }
8e73de4b 780 { # Old SQLA compat
24cd9525 781
782 my $op = join(' ', split '_', $op);
783
8e73de4b 784 if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}}) {
785 return { -op => [ $op, $ik, $vv ] };
786 }
787 if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{unary_ops}}) {
788 return { -op => [
789 $self->{cmp},
790 $ik,
791 { -op => [ $op, $vv ] }
792 ] };
793 }
0b2789b3 794 }
795 if (ref($vv) eq 'ARRAY') {
796 my @raw = @$vv;
797 my $logic = (defined($raw[0]) and $raw[0] =~ /^-(and|or)$/i)
a0fdc34f 798 ? (shift(@raw), lc $1) : 'or';
0b2789b3 799 my @values = map +{ $vk => $_ }, @raw;
800 if (
801 $op =~ $self->{inequality_op}
802 or $op =~ $self->{not_like_op}
803 ) {
5be20cbb 804 if (lc($logic) eq 'or' and @values > 1) {
2809a2ff 805 belch "A multi-element arrayref as an argument to the inequality op '${\uc(join ' ', split '_', $op)}' "
0b2789b3 806 . 'is technically equivalent to an always-true 1=1 (you probably wanted '
807 . "to say ...{ \$inequality_op => [ -and => \@values ] }... instead)"
808 ;
809 }
810 }
811 unless (@values) {
812 # try to DWIM on equality operators
a4009a84 813 return ($self->_dwim_op_to_is($op,
814 "Supplying an empty arrayref to '%s' is deprecated",
815 "operator '%s' applied on an empty array (field '$k')"
816 ) ? $self->sqlfalse : $self->sqltrue);
0b2789b3 817 }
818 return $self->_expand_op_andor($logic => \@values, $k);
819 }
6d7a39b3 820 if (is_undef_value($vv)) {
a4009a84 821 my $is = ($self->_dwim_op_to_is($op,
5f2c2f1e 822 "Supplying an undefined argument to '%s' is deprecated",
823 "unexpected operator '%s' with undef operand",
a4009a84 824 ) ? 'is' : 'is not');
0b2789b3 825
e9d74ce7 826 return $self->_expand_hashpair($k => { $is, undef });
0b2789b3 827 }
828 local our $Cur_Col_Meta = $k;
829 return +{ -op => [
830 $op,
831 $ik,
832 $self->_expand_expr($vv)
833 ] };
834}
835
5f2c2f1e 836sub _dwim_op_to_is {
24cd9525 837 my ($self, $raw, $empty, $fail) = @_;
838
839 my $op = $self->_normalize_op($raw);
840
5f2c2f1e 841 if ($op =~ /^not$/i) {
a4009a84 842 return 0;
5f2c2f1e 843 }
844 if ($op =~ $self->{equality_op}) {
a4009a84 845 return 1;
5f2c2f1e 846 }
847 if ($op =~ $self->{like_op}) {
2809a2ff 848 belch(sprintf $empty, uc(join ' ', split '_', $op));
a4009a84 849 return 1;
5f2c2f1e 850 }
851 if ($op =~ $self->{inequality_op}) {
a4009a84 852 return 0;
5f2c2f1e 853 }
854 if ($op =~ $self->{not_like_op}) {
2809a2ff 855 belch(sprintf $empty, uc(join ' ', split '_', $op));
a4009a84 856 return 0;
5f2c2f1e 857 }
858 puke(sprintf $fail, $op);
859}
860
a5536efa 861sub _expand_func {
862 my ($self, undef, $args) = @_;
863 my ($func, @args) = @$args;
67e082b8 864 return +{ -func => [ $func, map $self->expand_expr($_), @args ] };
a5536efa 865}
866
9103bd14 867sub _expand_ident {
5be20cbb 868 my ($self, undef, $body, $k) = @_;
e9d74ce7 869 return $self->_expand_hashpair_cmp(
bef0b297 870 $k, { -ident => $body }
871 ) if defined($k);
83de255f 872 unless (defined($body) or (ref($body) and ref($body) eq 'ARRAY')) {
5be20cbb 873 puke "-ident requires a single plain scalar argument (a quotable identifier) or an arrayref of identifier parts";
83de255f 874 }
9103bd14 875 my @parts = map split(/\Q${\($self->{name_sep}||'.')}\E/, $_),
876 ref($body) ? @$body : $body;
944f2c7b 877 return { -ident => $parts[-1] } if $self->{_dequalify_idents};
878 unless ($self->{quote_char}) {
879 $self->_assert_pass_injection_guard($_) for @parts;
880 }
9103bd14 881 return +{ -ident => \@parts };
882}
883
71f1364b 884sub _expand_value {
e9d74ce7 885 return $_[0]->_expand_hashpair_cmp(
bef0b297 886 $_[3], { -value => $_[2] },
887 ) if defined($_[3]);
71f1364b 888 +{ -bind => [ our $Cur_Col_Meta, $_[2] ] };
889}
890
2a238661 891sub _expand_not {
892 +{ -op => [ 'not', $_[0]->_expand_expr($_[2]) ] };
893}
894
ec595dd8 895sub _expand_row {
057fab7b 896 my ($self, undef, $args) = @_;
897 +{ -row => [ map $self->expand_expr($_), @$args ] };
ec595dd8 898}
899
900sub _expand_op {
057fab7b 901 my ($self, undef, $args) = @_;
ec595dd8 902 my ($op, @opargs) = @$args;
4d865061 903 if (my $exp = $self->{expand_op}{$op}) {
904 return $self->$exp($op, \@opargs);
905 }
057fab7b 906 +{ -op => [ $op, map $self->expand_expr($_), @opargs ] };
ec595dd8 907}
908
05d37f9c 909sub _expand_bool {
910 my ($self, undef, $v) = @_;
911 if (ref($v)) {
912 return $self->_expand_expr($v);
913 }
914 puke "-bool => undef not supported" unless defined($v);
67e082b8 915 return $self->_expand_expr({ -ident => $v });
05d37f9c 916}
917
d6ac0cfb 918sub _expand_op_andor {
5be20cbb 919 my ($self, $logop, $v, $k) = @_;
9194eb8f 920 if (defined $k) {
5ce9d71b 921 $v = [ map +{ $k, $_ },
922 (ref($v) eq 'HASH')
923 ? (map +{ $_ => $v->{$_} }, sort keys %$v)
924 : @$v,
925 ];
9194eb8f 926 }
70f98e4b 927 if (ref($v) eq 'HASH') {
2e670469 928 return undef unless keys %$v;
70f98e4b 929 return +{ -op => [
124b41ca 930 $logop,
0a8de350 931 map $self->_expand_expr({ $_ => $v->{$_} }),
70f98e4b 932 sort keys %$v
933 ] };
934 }
935 if (ref($v) eq 'ARRAY') {
124b41ca 936 $logop eq 'and' or $logop eq 'or' or puke "unknown logic: $logop";
70f98e4b 937
938 my @expr = grep {
939 (ref($_) eq 'ARRAY' and @$_)
940 or (ref($_) eq 'HASH' and %$_)
941 or 1
942 } @$v;
943
944 my @res;
945
946 while (my ($el) = splice @expr, 0, 1) {
947 puke "Supplying an empty left hand side argument is not supported in array-pairs"
948 unless defined($el) and length($el);
949 my $elref = ref($el);
950 if (!$elref) {
951 local our $Expand_Depth = 0;
952 push(@res, grep defined, $self->_expand_expr({ $el, shift(@expr) }));
953 } elsif ($elref eq 'ARRAY') {
954 push(@res, grep defined, $self->_expand_expr($el)) if @$el;
955 } elsif (my $l = is_literal_value($el)) {
956 push @res, { -literal => $l };
957 } elsif ($elref eq 'HASH') {
958 local our $Expand_Depth = 0;
959 push @res, grep defined, $self->_expand_expr($el) if %$el;
960 } else {
961 die "notreached";
962 }
963 }
964 # ???
965 # return $res[0] if @res == 1;
124b41ca 966 return { -op => [ $logop, @res ] };
70f98e4b 967 }
968 die "notreached";
969}
970
f49b02a0 971sub _expand_op_is {
972 my ($self, $op, $vv, $k) = @_;
1279622f 973 ($k, $vv) = @$vv unless defined $k;
f49b02a0 974 puke "$op can only take undef as argument"
975 if defined($vv)
976 and not (
977 ref($vv) eq 'HASH'
978 and exists($vv->{-value})
979 and !defined($vv->{-value})
980 );
1279622f 981 return +{ -op => [ $op.'_null', $self->expand_expr($k, -ident) ] };
f49b02a0 982}
983
143f50df 984sub _expand_between {
985 my ($self, $op, $vv, $k) = @_;
b798961f 986 $k = shift @{$vv = [ @$vv ]} unless defined $k;
143f50df 987 my @rhs = map $self->_expand_expr($_),
988 ref($vv) eq 'ARRAY' ? @$vv : $vv;
989 unless (
990 (@rhs == 1 and ref($rhs[0]) eq 'HASH' and $rhs[0]->{-literal})
991 or
992 (@rhs == 2 and defined($rhs[0]) and defined($rhs[1]))
993 ) {
994 puke "Operator '${\uc($op)}' requires either an arrayref with two defined values or expressions, or a single literal scalarref/arrayref-ref";
995 }
996 return +{ -op => [
997 $op,
8d8f6cc8 998 $self->expand_expr(ref($k) ? $k : { -ident => $k }),
143f50df 999 @rhs
1000 ] }
1001}
1002
416026a9 1003sub _expand_in {
1da718c4 1004 my ($self, $op, $vv, $k) = @_;
3445a1e7 1005 $k = shift @{$vv = [ @$vv ]} unless defined $k;
416026a9 1006 if (my $literal = is_literal_value($vv)) {
1007 my ($sql, @bind) = @$literal;
1008 my $opened_sql = $self->_open_outer_paren($sql);
1009 return +{ -op => [
2c99e31e 1010 $op, $self->expand_expr($k, -ident),
4d865061 1011 { -literal => [ $opened_sql, @bind ] }
416026a9 1012 ] };
1013 }
1014 my $undef_err =
1015 'SQL::Abstract before v1.75 used to generate incorrect SQL when the '
1016 . "-${\uc($op)} operator was given an undef-containing list: !!!AUDIT YOUR CODE "
1017 . 'AND DATA!!! (the upcoming Data::Query-based version of SQL::Abstract '
1018 . 'will emit the logically correct SQL instead of raising this exception)'
1019 ;
1020 puke("Argument passed to the '${\uc($op)}' operator can not be undefined")
1021 if !defined($vv);
2282f2b7 1022 my @rhs = map $self->expand_expr($_, -value),
416026a9 1023 map { defined($_) ? $_: puke($undef_err) }
1024 (ref($vv) eq 'ARRAY' ? @$vv : $vv);
1025 return $self->${\($op =~ /^not/ ? 'sqltrue' : 'sqlfalse')} unless @rhs;
1026
1027 return +{ -op => [
1028 $op,
2c99e31e 1029 $self->expand_expr($k, -ident),
4d865061 1030 @rhs
416026a9 1031 ] };
1032}
1033
5c633220 1034sub _expand_nest {
057fab7b 1035 my ($self, undef, $v) = @_;
5c633220 1036 # DBIx::Class requires a nest warning to be emitted once but the private
1037 # method it overrode to do so no longer exists
97c9af32 1038 if ($self->{warn_once_on_nest}) {
5c633220 1039 unless (our $Nest_Warned) {
1040 belch(
1041 "-nest in search conditions is deprecated, you most probably wanted:\n"
1042 .q|{..., -and => [ \%cond0, \@cond1, \'cond2', \[ 'cond3', [ col => bind ] ], etc. ], ... }|
1043 );
1044 $Nest_Warned = 1;
1045 }
1046 }
1047 return $self->_expand_expr($v);
1048}
1049
59756d50 1050sub _expand_bind {
057fab7b 1051 my ($self, undef, $bind) = @_;
1052 return { -bind => $bind };
59756d50 1053}
1054
96449e8e 1055sub _recurse_where {
1056 my ($self, $where, $logic) = @_;
1057
5492d4c2 1058 # Special case: top level simple string treated as literal
1059
1060 my $where_exp = (ref($where)
ae56a156 1061 ? $self->_expand_expr($where, $logic)
5492d4c2 1062 : { -literal => [ $where ] });
e175845b 1063
e3e27543 1064 # dispatch expanded expression
311b2151 1065
7e23f618 1066 my ($sql, @bind) = defined($where_exp) ? @{ $self->render_aqt($where_exp) || [] } : ();
abe1a491 1067 # DBIx::Class used to call _recurse_where in scalar context
1068 # something else might too...
1069 if (wantarray) {
1070 return ($sql, @bind);
1071 }
1072 else {
1073 belch "Calling _recurse_where in scalar context is deprecated and will go away before 2.0";
1074 return $sql;
1075 }
96449e8e 1076}
1077
181dcebf 1078sub _render_ident {
a01911a2 1079 my ($self, undef, $ident) = @_;
cc422895 1080
7e23f618 1081 return [ $self->_convert($self->_quote($ident)) ];
cc422895 1082}
1083
c2065120 1084sub _render_row {
a01911a2 1085 my ($self, undef, $values) = @_;
7e23f618 1086 return $self->join_query_parts('',
1087 '(',
1088 $self->_render_op(undef, [ ',', @$values ]),
1089 ')'
1090 );
ca158918 1091}
1092
1093sub _render_func {
a01911a2 1094 my ($self, undef, $rest) = @_;
ca158918 1095 my ($func, @args) = @$rest;
778ee98b 1096 return $self->join_query_parts('',
7e23f618 1097 $self->_sqlcase($func),
b3b54441 1098 $self->join_query_parts('',
1099 '(',
1100 $self->join_query_parts(', ', @args),
1101 ')'
1102 ),
778ee98b 1103 );
ca158918 1104}
d13725da 1105
ca158918 1106sub _render_bind {
a01911a2 1107 my ($self, undef, $bind) = @_;
7e23f618 1108 return [ $self->_convert('?'), $self->_bindtype(@$bind) ];
ca158918 1109}
1110
1111sub _render_literal {
a01911a2 1112 my ($self, undef, $literal) = @_;
ca158918 1113 $self->_assert_bindval_matches_bindtype(@{$literal}[1..$#$literal]);
7e23f618 1114 return $literal;
ca158918 1115}
1116
5305e436 1117sub _render_op {
a01911a2 1118 my ($self, undef, $v) = @_;
5305e436 1119 my ($op, @args) = @$v;
1120 if (my $r = $self->{render_op}{$op}) {
1121 return $self->$r($op, \@args);
1122 }
1123
1124 { # Old SQLA compat
1125
24cd9525 1126 my $op = join(' ', split '_', $op);
1127
82048a14 1128 my $ss = List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}};
1129 if ($ss and @args > 1) {
5305e436 1130 puke "Special op '${op}' requires first value to be identifier"
1131 unless my ($ident) = map $_->{-ident}, grep ref($_) eq 'HASH', $args[0];
1132 my $k = join(($self->{name_sep}||'.'), @$ident);
1133 local our $Expand_Depth = 1;
7e23f618 1134 return [ $self->${\($ss->{handler})}($k, $op, $args[1]) ];
5305e436 1135 }
1136 if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{unary_ops}}) {
7e23f618 1137 return [ $self->${\($us->{handler})}($op, $args[0]) ];
5305e436 1138 }
82048a14 1139 if ($ss) {
1140 return $self->_render_unop_paren($op, \@args);
1141 }
5305e436 1142 }
1143 if (@args == 1) {
1144 return $self->_render_unop_prefix($op, \@args);
1145 } else {
1146 return $self->_render_op_multop($op, \@args);
1147 }
1148 die "notreached";
1149}
1150
1151
e748969f 1152sub _render_op_between {
1153 my ($self, $op, $args) = @_;
1154 my ($left, $low, $high) = @$args;
904e4989 1155 my @rh = do {
e748969f 1156 if (@$args == 2) {
1157 puke "Single arg to between must be a literal"
1158 unless $low->{-literal};
904e4989 1159 $low;
e748969f 1160 } else {
943e8554 1161 +($low, $self->format_keyword('and'), $high);
e748969f 1162 }
1163 };
904e4989 1164 return $self->join_query_parts(' ',
943e8554 1165 '(', $left, $self->format_keyword($op), @rh, ')',
e748969f 1166 );
1167}
1168
7dda9b27 1169sub _render_op_in {
1170 my ($self, $op, $args) = @_;
4d865061 1171 my ($lhs, @rhs) = @$args;
943e8554 1172
1173 return $self->join_query_parts(' ',
1174 $lhs,
1175 $self->format_keyword($op),
b3b54441 1176 $self->join_query_parts(' ',
1177 '(',
1178 $self->join_query_parts(', ', @rhs),
1179 ')'
1180 ),
7dda9b27 1181 );
1182}
1183
5edafff8 1184sub _render_op_andor {
1185 my ($self, $op, $args) = @_;
7e23f618 1186 return undef unless @$args;
31cab4ad 1187 return $self->join_query_parts('', $args->[0]) if @$args == 1;
0536821b 1188 my $inner = $self->_render_op_multop($op, $args);
1189 return undef unless defined($inner->[0]) and length($inner->[0]);
b3b54441 1190 return $self->join_query_parts(' ',
0536821b 1191 '(', $inner, ')'
31cab4ad 1192 );
3f51d831 1193}
1194
1195sub _render_op_multop {
df7bba54 1196 my ($self, $op, $args) = @_;
77d384f7 1197 my @parts = @$args;
7e23f618 1198 return undef unless @parts;
1199 return $self->render_aqt($parts[0]) if @parts == 1;
fd6f6be6 1200 my $join = ($op eq ','
1201 ? ', '
7a33f5fd 1202 : ' '.$self->format_keyword($op).' '
fd6f6be6 1203 );
0236f122 1204 return $self->join_query_parts($join, @parts);
fd6f6be6 1205}
1206
0236f122 1207sub join_query_parts {
fd6f6be6 1208 my ($self, $join, @parts) = @_;
8a61ebbc 1209 my @final = map +(
1210 ref($_) eq 'HASH'
a7a125f7 1211 ? $self->render_aqt($_)
7e23f618 1212 : ((ref($_) eq 'ARRAY') ? $_ : [ $_ ])
1213 ), @parts;
1214 return [
0536821b 1215 $self->{join_sql_parts}->($join, grep defined, map $_->[0], @final),
f9e868e7 1216 (map @{$_}[1..$#$_], @final),
7e23f618 1217 ];
5edafff8 1218}
fd6f6be6 1219
82048a14 1220sub _render_unop_paren {
2ddaa002 1221 my ($self, $op, $v) = @_;
7a33f5fd 1222 return $self->join_query_parts('',
7e23f618 1223 '(', $self->_render_unop_prefix($op, $v), ')'
7a33f5fd 1224 );
2ddaa002 1225}
1226
1227sub _render_unop_prefix {
1228 my ($self, $op, $v) = @_;
7a33f5fd 1229 return $self->join_query_parts(' ',
1230 $self->_sqlcase($op), $v->[0]
1231 );
2ddaa002 1232}
1233
b23fd5ff 1234sub _render_unop_postfix {
1235 my ($self, $op, $v) = @_;
7a33f5fd 1236 return $self->join_query_parts(' ',
1237 $v->[0], $self->format_keyword($op),
1238 );
b23fd5ff 1239}
1240
4a1f01a3 1241# Some databases (SQLite) treat col IN (1, 2) different from
1242# col IN ( (1, 2) ). Use this to strip all outer parens while
1243# adding them back in the corresponding method
1244sub _open_outer_paren {
1245 my ($self, $sql) = @_;
a5f91feb 1246
ca4f826a 1247 while (my ($inner) = $sql =~ /^ \s* \( (.*) \) \s* $/xs) {
a5f91feb 1248
1249 # there are closing parens inside, need the heavy duty machinery
1250 # to reevaluate the extraction starting from $sql (full reevaluation)
ca4f826a 1251 if ($inner =~ /\)/) {
a5f91feb 1252 require Text::Balanced;
1253
1254 my (undef, $remainder) = do {
1255 # idiotic design - writes to $@ but *DOES NOT* throw exceptions
1256 local $@;
ca4f826a 1257 Text::Balanced::extract_bracketed($sql, '()', qr/\s*/);
a5f91feb 1258 };
1259
1260 # the entire expression needs to be a balanced bracketed thing
1261 # (after an extract no remainder sans trailing space)
1262 last if defined $remainder and $remainder =~ /\S/;
1263 }
1264
1265 $sql = $inner;
1266 }
1267
1268 $sql;
4a1f01a3 1269}
1270
96449e8e 1271
96449e8e 1272#======================================================================
1273# ORDER BY
1274#======================================================================
1275
33177570 1276sub _expand_order_by {
96449e8e 1277 my ($self, $arg) = @_;
1278
33177570 1279 return unless defined($arg) and not (ref($arg) eq 'ARRAY' and !@$arg);
2b6158af 1280
bd00b85c 1281 return $self->_expand_maybe_list_expr($arg)
1282 if ref($arg) eq 'HASH' and ($arg->{-op}||[''])->[0] eq ',';
e5feec9f 1283
4325df6a 1284 my $expander = sub {
1285 my ($self, $dir, $expr) = @_;
52ca537e 1286 my @to_expand = ref($expr) eq 'ARRAY' ? @$expr : $expr;
1287 foreach my $arg (@to_expand) {
1288 if (
1289 ref($arg) eq 'HASH'
1290 and keys %$arg > 1
1291 and grep /^-(asc|desc)$/, keys %$arg
1292 ) {
1293 puke "ordering direction hash passed to order by must have exactly one key (-asc or -desc)";
1294 }
1295 }
7384c311 1296 my @exp = map +(
1297 defined($dir) ? { -op => [ $dir =~ /^-?(.*)$/ ,=> $_ ] } : $_
1298 ),
79d310f2 1299 map $self->expand_expr($_, -ident),
74156ee9 1300 map ref($_) eq 'ARRAY' ? @$_ : $_, @to_expand;
4e78f98d 1301 return undef unless @exp;
1302 return undef if @exp == 1 and not defined($exp[0]);
1303 return +{ -op => [ ',', @exp ] };
4325df6a 1304 };
18c743c8 1305
def45151 1306 local @{$self->{expand}}{qw(asc desc)} = (($expander) x 2);
f267b646 1307
33177570 1308 return $self->$expander(undef, $arg);
1309}
1310
1311sub _order_by {
1312 my ($self, $arg) = @_;
1313
1314 return '' unless defined(my $expanded = $self->_expand_order_by($arg));
4325df6a 1315
a7a125f7 1316 my ($sql, @bind) = @{ $self->render_aqt($expanded) };
4325df6a 1317
13cd9220 1318 return '' unless length($sql);
1319
4325df6a 1320 my $final_sql = $self->_sqlcase(' order by ').$sql;
1321
f9e868e7 1322 return ($final_sql, @bind);
f267b646 1323}
1324
2e3cc357 1325# _order_by no longer needs to call this so doesn't but DBIC uses it.
1326
33177570 1327sub _order_by_chunks {
1328 my ($self, $arg) = @_;
1329
1330 return () unless defined(my $expanded = $self->_expand_order_by($arg));
1331
b84764fb 1332 my @res = $self->_chunkify_order_by($expanded);
1333 (ref() ? $_->[0] : $_) .= '' for @res;
1334 return @res;
2e3cc357 1335}
1336
1337sub _chunkify_order_by {
1338 my ($self, $expanded) = @_;
1b630cfe 1339
a7a125f7 1340 return grep length, @{ $self->render_aqt($expanded) }
1b630cfe 1341 if $expanded->{-ident} or @{$expanded->{-literal}||[]} == 1;
1342
33177570 1343 for ($expanded) {
4a27fded 1344 if (ref() eq 'HASH' and $_->{-op} and $_->{-op}[0] eq ',') {
1345 my ($comma, @list) = @{$_->{-op}};
1346 return map $self->_chunkify_order_by($_), @list;
33177570 1347 }
a7a125f7 1348 return $self->render_aqt($_);
33177570 1349 }
1350}
1351
96449e8e 1352#======================================================================
1353# DATASOURCE (FOR NOW, JUST PLAIN TABLE OR LIST OF TABLES)
1354#======================================================================
1355
1356sub _table {
1357 my $self = shift;
1358 my $from = shift;
7e23f618 1359 $self->render_aqt(
dbc10abd 1360 $self->_expand_maybe_list_expr($from, -ident)
7e23f618 1361 )->[0];
96449e8e 1362}
1363
1364
1365#======================================================================
1366# UTILITY FUNCTIONS
1367#======================================================================
1368
8476c6a3 1369sub _expand_maybe_list_expr {
dbc10abd 1370 my ($self, $expr, $default) = @_;
bd00b85c 1371 return { -op => [
1372 ',', map $self->expand_expr($_, $default),
1373 @{$expr->{-op}}[1..$#{$expr->{-op}}]
1374 ] } if ref($expr) eq 'HASH' and ($expr->{-op}||[''])->[0] eq ',';
2c99e31e 1375 return +{ -op => [ ',',
1376 map $self->expand_expr($_, $default),
1377 ref($expr) eq 'ARRAY' ? @$expr : $expr
1378 ] };
8476c6a3 1379}
1380
955e77ca 1381# highly optimized, as it's called way too often
96449e8e 1382sub _quote {
955e77ca 1383 # my ($self, $label) = @_;
96449e8e 1384
955e77ca 1385 return '' unless defined $_[1];
955e77ca 1386 return ${$_[1]} if ref($_[1]) eq 'SCALAR';
d3162b5c 1387 puke 'Identifier cannot be hashref' if ref($_[1]) eq 'HASH';
96449e8e 1388
d3162b5c 1389 unless ($_[0]->{quote_char}) {
1390 if (ref($_[1]) eq 'ARRAY') {
1391 return join($_[0]->{name_sep}||'.', @{$_[1]});
1392 } else {
1393 $_[0]->_assert_pass_injection_guard($_[1]);
1394 return $_[1];
1395 }
1396 }
96449e8e 1397
07d7c35c 1398 my $qref = ref $_[0]->{quote_char};
439834d3 1399 my ($l, $r) =
1400 !$qref ? ($_[0]->{quote_char}, $_[0]->{quote_char})
1401 : ($qref eq 'ARRAY') ? @{$_[0]->{quote_char}}
1402 : puke "Unsupported quote_char format: $_[0]->{quote_char}";
1403
46be4313 1404 my $esc = $_[0]->{escape_char} || $r;
96449e8e 1405
07d7c35c 1406 # parts containing * are naturally unquoted
d3162b5c 1407 return join(
1408 $_[0]->{name_sep}||'',
1409 map +(
1410 $_ eq '*'
1411 ? $_
1412 : do { (my $n = $_) =~ s/(\Q$esc\E|\Q$r\E)/$esc$1/g; $l . $n . $r }
1413 ),
1414 (ref($_[1]) eq 'ARRAY'
1415 ? @{$_[1]}
1416 : (
1417 $_[0]->{name_sep}
1418 ? split (/\Q$_[0]->{name_sep}\E/, $_[1] )
1419 : $_[1]
1420 )
1421 )
955e77ca 1422 );
96449e8e 1423}
1424
1425
1426# Conversion, if applicable
d7c862e0 1427sub _convert {
07d7c35c 1428 #my ($self, $arg) = @_;
7e23f618 1429 if (my $conv = $_[0]->{convert_where}) {
1430 return @{ $_[0]->join_query_parts('',
1431 $_[0]->format_keyword($conv),
1432 '(' , $_[1] , ')'
1433 ) };
96449e8e 1434 }
07d7c35c 1435 return $_[1];
96449e8e 1436}
1437
1438# And bindtype
d7c862e0 1439sub _bindtype {
07d7c35c 1440 #my ($self, $col, @vals) = @_;
07d7c35c 1441 # called often - tighten code
1442 return $_[0]->{bindtype} eq 'columns'
1443 ? map {[$_[1], $_]} @_[2 .. $#_]
1444 : @_[2 .. $#_]
1445 ;
96449e8e 1446}
1447
fe3ae272 1448# Dies if any element of @bind is not in [colname => value] format
1449# if bindtype is 'columns'.
1450sub _assert_bindval_matches_bindtype {
c94a6c93 1451# my ($self, @bind) = @_;
1452 my $self = shift;
fe3ae272 1453 if ($self->{bindtype} eq 'columns') {
c94a6c93 1454 for (@_) {
1455 if (!defined $_ || ref($_) ne 'ARRAY' || @$_ != 2) {
3a06278c 1456 puke "bindtype 'columns' selected, you need to pass: [column_name => bind_value]"
fe3ae272 1457 }
1458 }
1459 }
1460}
1461
96449e8e 1462sub _join_sql_clauses {
1463 my ($self, $logic, $clauses_aref, $bind_aref) = @_;
1464
1465 if (@$clauses_aref > 1) {
1466 my $join = " " . $self->_sqlcase($logic) . " ";
1467 my $sql = '( ' . join($join, @$clauses_aref) . ' )';
1468 return ($sql, @$bind_aref);
1469 }
1470 elsif (@$clauses_aref) {
1471 return ($clauses_aref->[0], @$bind_aref); # no parentheses
1472 }
1473 else {
1474 return (); # if no SQL, ignore @$bind_aref
1475 }
1476}
1477
1478
1479# Fix SQL case, if so requested
1480sub _sqlcase {
96449e8e 1481 # LDNOTE: if $self->{case} is true, then it contains 'lower', so we
1482 # don't touch the argument ... crooked logic, but let's not change it!
07d7c35c 1483 return $_[0]->{case} ? $_[1] : uc($_[1]);
96449e8e 1484}
1485
eaba09fc 1486sub format_keyword { $_[0]->_sqlcase(join ' ', split '_', $_[1]) }
96449e8e 1487
1488#======================================================================
1489# DISPATCHING FROM REFKIND
1490#======================================================================
1491
1492sub _refkind {
1493 my ($self, $data) = @_;
96449e8e 1494
955e77ca 1495 return 'UNDEF' unless defined $data;
1496
1497 # blessed objects are treated like scalars
1498 my $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
1499
1500 return 'SCALAR' unless $ref;
1501
1502 my $n_steps = 1;
1503 while ($ref eq 'REF') {
96449e8e 1504 $data = $$data;
955e77ca 1505 $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
1506 $n_steps++ if $ref;
96449e8e 1507 }
1508
848556bc 1509 return ($ref||'SCALAR') . ('REF' x $n_steps);
96449e8e 1510}
1511
1512sub _try_refkind {
1513 my ($self, $data) = @_;
1514 my @try = ($self->_refkind($data));
1515 push @try, 'SCALAR_or_UNDEF' if $try[0] eq 'SCALAR' || $try[0] eq 'UNDEF';
1516 push @try, 'FALLBACK';
955e77ca 1517 return \@try;
96449e8e 1518}
1519
1520sub _METHOD_FOR_refkind {
1521 my ($self, $meth_prefix, $data) = @_;
f39eaa60 1522
1523 my $method;
955e77ca 1524 for (@{$self->_try_refkind($data)}) {
f39eaa60 1525 $method = $self->can($meth_prefix."_".$_)
1526 and last;
1527 }
1528
1529 return $method || puke "cannot dispatch on '$meth_prefix' for ".$self->_refkind($data);
96449e8e 1530}
1531
1532
1533sub _SWITCH_refkind {
1534 my ($self, $data, $dispatch_table) = @_;
1535
f39eaa60 1536 my $coderef;
955e77ca 1537 for (@{$self->_try_refkind($data)}) {
f39eaa60 1538 $coderef = $dispatch_table->{$_}
1539 and last;
1540 }
1541
1542 puke "no dispatch entry for ".$self->_refkind($data)
1543 unless $coderef;
1544
96449e8e 1545 $coderef->();
1546}
1547
1548
1549
1550
1551#======================================================================
1552# VALUES, GENERATE, AUTOLOAD
1553#======================================================================
1554
1555# LDNOTE: original code from nwiger, didn't touch code in that section
1556# I feel the AUTOLOAD stuff should not be the default, it should
1557# only be activated on explicit demand by user.
1558
1559sub values {
1560 my $self = shift;
1561 my $data = shift || return;
1562 puke "Argument to ", __PACKAGE__, "->values must be a \\%hash"
1563 unless ref $data eq 'HASH';
bab725ce 1564
1565 my @all_bind;
ca4f826a 1566 foreach my $k (sort keys %$data) {
bab725ce 1567 my $v = $data->{$k};
1568 $self->_SWITCH_refkind($v, {
9d48860e 1569 ARRAYREF => sub {
bab725ce 1570 if ($self->{array_datatypes}) { # array datatype
1571 push @all_bind, $self->_bindtype($k, $v);
1572 }
1573 else { # literal SQL with bind
1574 my ($sql, @bind) = @$v;
1575 $self->_assert_bindval_matches_bindtype(@bind);
1576 push @all_bind, @bind;
1577 }
1578 },
1579 ARRAYREFREF => sub { # literal SQL with bind
1580 my ($sql, @bind) = @${$v};
1581 $self->_assert_bindval_matches_bindtype(@bind);
1582 push @all_bind, @bind;
1583 },
1584 SCALARREF => sub { # literal SQL without bind
1585 },
1586 SCALAR_or_UNDEF => sub {
1587 push @all_bind, $self->_bindtype($k, $v);
1588 },
1589 });
1590 }
1591
1592 return @all_bind;
96449e8e 1593}
1594
1595sub generate {
1596 my $self = shift;
1597
1598 my(@sql, @sqlq, @sqlv);
1599
1600 for (@_) {
1601 my $ref = ref $_;
1602 if ($ref eq 'HASH') {
1603 for my $k (sort keys %$_) {
1604 my $v = $_->{$k};
1605 my $r = ref $v;
1606 my $label = $self->_quote($k);
1607 if ($r eq 'ARRAY') {
fe3ae272 1608 # literal SQL with bind
1609 my ($sql, @bind) = @$v;
1610 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 1611 push @sqlq, "$label = $sql";
fe3ae272 1612 push @sqlv, @bind;
96449e8e 1613 } elsif ($r eq 'SCALAR') {
fe3ae272 1614 # literal SQL without bind
96449e8e 1615 push @sqlq, "$label = $$v";
9d48860e 1616 } else {
96449e8e 1617 push @sqlq, "$label = ?";
1618 push @sqlv, $self->_bindtype($k, $v);
1619 }
1620 }
1621 push @sql, $self->_sqlcase('set'), join ', ', @sqlq;
1622 } elsif ($ref eq 'ARRAY') {
1623 # unlike insert(), assume these are ONLY the column names, i.e. for SQL
1624 for my $v (@$_) {
1625 my $r = ref $v;
fe3ae272 1626 if ($r eq 'ARRAY') { # literal SQL with bind
1627 my ($sql, @bind) = @$v;
1628 $self->_assert_bindval_matches_bindtype(@bind);
1629 push @sqlq, $sql;
1630 push @sqlv, @bind;
1631 } elsif ($r eq 'SCALAR') { # literal SQL without bind
96449e8e 1632 # embedded literal SQL
1633 push @sqlq, $$v;
9d48860e 1634 } else {
96449e8e 1635 push @sqlq, '?';
1636 push @sqlv, $v;
1637 }
1638 }
1639 push @sql, '(' . join(', ', @sqlq) . ')';
1640 } elsif ($ref eq 'SCALAR') {
1641 # literal SQL
1642 push @sql, $$_;
1643 } else {
1644 # strings get case twiddled
1645 push @sql, $self->_sqlcase($_);
1646 }
1647 }
1648
1649 my $sql = join ' ', @sql;
1650
1651 # this is pretty tricky
1652 # if ask for an array, return ($stmt, @bind)
1653 # otherwise, s/?/shift @sqlv/ to put it inline
1654 if (wantarray) {
1655 return ($sql, @sqlv);
1656 } else {
1657 1 while $sql =~ s/\?/my $d = shift(@sqlv);
1658 ref $d ? $d->[1] : $d/e;
1659 return $sql;
1660 }
1661}
1662
1663
1664sub DESTROY { 1 }
1665
1666sub AUTOLOAD {
1667 # This allows us to check for a local, then _form, attr
1668 my $self = shift;
1669 my($name) = $AUTOLOAD =~ /.*::(.+)/;
5b2308a1 1670 puke "AUTOLOAD invoked for method name ${name} and allow_autoload option not set" unless $self->{allow_autoload};
96449e8e 1671 return $self->generate($name, @_);
1672}
1673
16741;
1675
1676
1677
1678__END__
32eab2da 1679
1680=head1 NAME
1681
1682SQL::Abstract - Generate SQL from Perl data structures
1683
1684=head1 SYNOPSIS
1685
1686 use SQL::Abstract;
1687
1688 my $sql = SQL::Abstract->new;
1689
85783f3c 1690 my($stmt, @bind) = $sql->select($source, \@fields, \%where, $order);
32eab2da 1691
1692 my($stmt, @bind) = $sql->insert($table, \%fieldvals || \@values);
1693
1694 my($stmt, @bind) = $sql->update($table, \%fieldvals, \%where);
1695
1696 my($stmt, @bind) = $sql->delete($table, \%where);
1697
1698 # Then, use these in your DBI statements
1699 my $sth = $dbh->prepare($stmt);
1700 $sth->execute(@bind);
1701
1702 # Just generate the WHERE clause
85783f3c 1703 my($stmt, @bind) = $sql->where(\%where, $order);
32eab2da 1704
1705 # Return values in the same order, for hashed queries
1706 # See PERFORMANCE section for more details
1707 my @bind = $sql->values(\%fieldvals);
1708
1709=head1 DESCRIPTION
1710
1711This module was inspired by the excellent L<DBIx::Abstract>.
1712However, in using that module I found that what I really wanted
1713to do was generate SQL, but still retain complete control over my
1714statement handles and use the DBI interface. So, I set out to
1715create an abstract SQL generation module.
1716
1717While based on the concepts used by L<DBIx::Abstract>, there are
1718several important differences, especially when it comes to WHERE
1719clauses. I have modified the concepts used to make the SQL easier
1720to generate from Perl data structures and, IMO, more intuitive.
1721The underlying idea is for this module to do what you mean, based
1722on the data structures you provide it. The big advantage is that
1723you don't have to modify your code every time your data changes,
1724as this module figures it out.
1725
1726To begin with, an SQL INSERT is as easy as just specifying a hash
1727of C<key=value> pairs:
1728
1729 my %data = (
1730 name => 'Jimbo Bobson',
1731 phone => '123-456-7890',
1732 address => '42 Sister Lane',
1733 city => 'St. Louis',
1734 state => 'Louisiana',
1735 );
1736
1737The SQL can then be generated with this:
1738
1739 my($stmt, @bind) = $sql->insert('people', \%data);
1740
1741Which would give you something like this:
1742
1743 $stmt = "INSERT INTO people
1744 (address, city, name, phone, state)
1745 VALUES (?, ?, ?, ?, ?)";
1746 @bind = ('42 Sister Lane', 'St. Louis', 'Jimbo Bobson',
1747 '123-456-7890', 'Louisiana');
1748
1749These are then used directly in your DBI code:
1750
1751 my $sth = $dbh->prepare($stmt);
1752 $sth->execute(@bind);
1753
96449e8e 1754=head2 Inserting and Updating Arrays
1755
1756If your database has array types (like for example Postgres),
1757activate the special option C<< array_datatypes => 1 >>
9d48860e 1758when creating the C<SQL::Abstract> object.
96449e8e 1759Then you may use an arrayref to insert and update database array types:
1760
1761 my $sql = SQL::Abstract->new(array_datatypes => 1);
1762 my %data = (
1763 planets => [qw/Mercury Venus Earth Mars/]
1764 );
9d48860e 1765
96449e8e 1766 my($stmt, @bind) = $sql->insert('solar_system', \%data);
1767
1768This results in:
1769
1770 $stmt = "INSERT INTO solar_system (planets) VALUES (?)"
1771
1772 @bind = (['Mercury', 'Venus', 'Earth', 'Mars']);
1773
1774
1775=head2 Inserting and Updating SQL
1776
1777In order to apply SQL functions to elements of your C<%data> you may
1778specify a reference to an arrayref for the given hash value. For example,
1779if you need to execute the Oracle C<to_date> function on a value, you can
1780say something like this:
32eab2da 1781
1782 my %data = (
1783 name => 'Bill',
3ae1c5e2 1784 date_entered => \[ "to_date(?,'MM/DD/YYYY')", "03/02/2003" ],
9d48860e 1785 );
32eab2da 1786
1787The first value in the array is the actual SQL. Any other values are
1788optional and would be included in the bind values array. This gives
1789you:
1790
1791 my($stmt, @bind) = $sql->insert('people', \%data);
1792
9d48860e 1793 $stmt = "INSERT INTO people (name, date_entered)
32eab2da 1794 VALUES (?, to_date(?,'MM/DD/YYYY'))";
1795 @bind = ('Bill', '03/02/2003');
1796
1797An UPDATE is just as easy, all you change is the name of the function:
1798
1799 my($stmt, @bind) = $sql->update('people', \%data);
1800
1801Notice that your C<%data> isn't touched; the module will generate
1802the appropriately quirky SQL for you automatically. Usually you'll
1803want to specify a WHERE clause for your UPDATE, though, which is
1804where handling C<%where> hashes comes in handy...
1805
96449e8e 1806=head2 Complex where statements
1807
32eab2da 1808This module can generate pretty complicated WHERE statements
1809easily. For example, simple C<key=value> pairs are taken to mean
1810equality, and if you want to see if a field is within a set
1811of values, you can use an arrayref. Let's say we wanted to
1812SELECT some data based on this criteria:
1813
1814 my %where = (
1815 requestor => 'inna',
1816 worker => ['nwiger', 'rcwe', 'sfz'],
1817 status => { '!=', 'completed' }
1818 );
1819
1820 my($stmt, @bind) = $sql->select('tickets', '*', \%where);
1821
1822The above would give you something like this:
1823
1824 $stmt = "SELECT * FROM tickets WHERE
1825 ( requestor = ? ) AND ( status != ? )
1826 AND ( worker = ? OR worker = ? OR worker = ? )";
1827 @bind = ('inna', 'completed', 'nwiger', 'rcwe', 'sfz');
1828
1829Which you could then use in DBI code like so:
1830
1831 my $sth = $dbh->prepare($stmt);
1832 $sth->execute(@bind);
1833
1834Easy, eh?
1835
0da0fe34 1836=head1 METHODS
32eab2da 1837
13cc86af 1838The methods are simple. There's one for every major SQL operation,
32eab2da 1839and a constructor you use first. The arguments are specified in a
13cc86af 1840similar order for each method (table, then fields, then a where
32eab2da 1841clause) to try and simplify things.
1842
32eab2da 1843=head2 new(option => 'value')
1844
1845The C<new()> function takes a list of options and values, and returns
1846a new B<SQL::Abstract> object which can then be used to generate SQL
1847through the methods below. The options accepted are:
1848
1849=over
1850
1851=item case
1852
1853If set to 'lower', then SQL will be generated in all lowercase. By
1854default SQL is generated in "textbook" case meaning something like:
1855
1856 SELECT a_field FROM a_table WHERE some_field LIKE '%someval%'
1857
96449e8e 1858Any setting other than 'lower' is ignored.
1859
32eab2da 1860=item cmp
1861
1862This determines what the default comparison operator is. By default
1863it is C<=>, meaning that a hash like this:
1864
1865 %where = (name => 'nwiger', email => 'nate@wiger.org');
1866
1867Will generate SQL like this:
1868
1869 WHERE name = 'nwiger' AND email = 'nate@wiger.org'
1870
1871However, you may want loose comparisons by default, so if you set
1872C<cmp> to C<like> you would get SQL such as:
1873
1874 WHERE name like 'nwiger' AND email like 'nate@wiger.org'
1875
3af02ccb 1876You can also override the comparison on an individual basis - see
32eab2da 1877the huge section on L</"WHERE CLAUSES"> at the bottom.
1878
96449e8e 1879=item sqltrue, sqlfalse
1880
1881Expressions for inserting boolean values within SQL statements.
6e0c6552 1882By default these are C<1=1> and C<1=0>. They are used
1883by the special operators C<-in> and C<-not_in> for generating
1884correct SQL even when the argument is an empty array (see below).
96449e8e 1885
32eab2da 1886=item logic
1887
1888This determines the default logical operator for multiple WHERE
7cac25e6 1889statements in arrays or hashes. If absent, the default logic is "or"
1890for arrays, and "and" for hashes. This means that a WHERE
32eab2da 1891array of the form:
1892
1893 @where = (
9d48860e 1894 event_date => {'>=', '2/13/99'},
1895 event_date => {'<=', '4/24/03'},
32eab2da 1896 );
1897
7cac25e6 1898will generate SQL like this:
32eab2da 1899
1900 WHERE event_date >= '2/13/99' OR event_date <= '4/24/03'
1901
1902This is probably not what you want given this query, though (look
1903at the dates). To change the "OR" to an "AND", simply specify:
1904
1905 my $sql = SQL::Abstract->new(logic => 'and');
1906
1907Which will change the above C<WHERE> to:
1908
1909 WHERE event_date >= '2/13/99' AND event_date <= '4/24/03'
1910
96449e8e 1911The logic can also be changed locally by inserting
be21dde3 1912a modifier in front of an arrayref:
96449e8e 1913
9d48860e 1914 @where = (-and => [event_date => {'>=', '2/13/99'},
7cac25e6 1915 event_date => {'<=', '4/24/03'} ]);
96449e8e 1916
1917See the L</"WHERE CLAUSES"> section for explanations.
1918
32eab2da 1919=item convert
1920
1921This will automatically convert comparisons using the specified SQL
1922function for both column and value. This is mostly used with an argument
1923of C<upper> or C<lower>, so that the SQL will have the effect of
1924case-insensitive "searches". For example, this:
1925
1926 $sql = SQL::Abstract->new(convert => 'upper');
1927 %where = (keywords => 'MaKe iT CAse inSeNSItive');
1928
1929Will turn out the following SQL:
1930
1931 WHERE upper(keywords) like upper('MaKe iT CAse inSeNSItive')
1932
1933The conversion can be C<upper()>, C<lower()>, or any other SQL function
1934that can be applied symmetrically to fields (actually B<SQL::Abstract> does
1935not validate this option; it will just pass through what you specify verbatim).
1936
1937=item bindtype
1938
1939This is a kludge because many databases suck. For example, you can't
1940just bind values using DBI's C<execute()> for Oracle C<CLOB> or C<BLOB> fields.
1941Instead, you have to use C<bind_param()>:
1942
1943 $sth->bind_param(1, 'reg data');
1944 $sth->bind_param(2, $lots, {ora_type => ORA_CLOB});
1945
1946The problem is, B<SQL::Abstract> will normally just return a C<@bind> array,
1947which loses track of which field each slot refers to. Fear not.
1948
1949If you specify C<bindtype> in new, you can determine how C<@bind> is returned.
1950Currently, you can specify either C<normal> (default) or C<columns>. If you
1951specify C<columns>, you will get an array that looks like this:
1952
1953 my $sql = SQL::Abstract->new(bindtype => 'columns');
1954 my($stmt, @bind) = $sql->insert(...);
1955
1956 @bind = (
1957 [ 'column1', 'value1' ],
1958 [ 'column2', 'value2' ],
1959 [ 'column3', 'value3' ],
1960 );
1961
1962You can then iterate through this manually, using DBI's C<bind_param()>.
e3f9dff4 1963
32eab2da 1964 $sth->prepare($stmt);
1965 my $i = 1;
1966 for (@bind) {
1967 my($col, $data) = @$_;
1968 if ($col eq 'details' || $col eq 'comments') {
1969 $sth->bind_param($i, $data, {ora_type => ORA_CLOB});
1970 } elsif ($col eq 'image') {
1971 $sth->bind_param($i, $data, {ora_type => ORA_BLOB});
1972 } else {
1973 $sth->bind_param($i, $data);
1974 }
1975 $i++;
1976 }
1977 $sth->execute; # execute without @bind now
1978
1979Now, why would you still use B<SQL::Abstract> if you have to do this crap?
1980Basically, the advantage is still that you don't have to care which fields
1981are or are not included. You could wrap that above C<for> loop in a simple
1982sub called C<bind_fields()> or something and reuse it repeatedly. You still
1983get a layer of abstraction over manual SQL specification.
1984
3ae1c5e2 1985Note that if you set L</bindtype> to C<columns>, the C<\[ $sql, @bind ]>
deb148a2 1986construct (see L</Literal SQL with placeholders and bind values (subqueries)>)
1987will expect the bind values in this format.
1988
32eab2da 1989=item quote_char
1990
1991This is the character that a table or column name will be quoted
9d48860e 1992with. By default this is an empty string, but you could set it to
32eab2da 1993the character C<`>, to generate SQL like this:
1994
1995 SELECT `a_field` FROM `a_table` WHERE `some_field` LIKE '%someval%'
1996
96449e8e 1997Alternatively, you can supply an array ref of two items, the first being the left
1998hand quote character, and the second the right hand quote character. For
1999example, you could supply C<['[',']']> for SQL Server 2000 compliant quotes
2000that generates SQL like this:
2001
2002 SELECT [a_field] FROM [a_table] WHERE [some_field] LIKE '%someval%'
2003
9d48860e 2004Quoting is useful if you have tables or columns names that are reserved
96449e8e 2005words in your database's SQL dialect.
32eab2da 2006
46be4313 2007=item escape_char
2008
2009This is the character that will be used to escape L</quote_char>s appearing
2010in an identifier before it has been quoted.
2011
80790166 2012The parameter default in case of a single L</quote_char> character is the quote
46be4313 2013character itself.
2014
2015When opening-closing-style quoting is used (L</quote_char> is an arrayref)
9de2bd86 2016this parameter defaults to the B<closing (right)> L</quote_char>. Occurrences
46be4313 2017of the B<opening (left)> L</quote_char> within the identifier are currently left
2018untouched. The default for opening-closing-style quotes may change in future
2019versions, thus you are B<strongly encouraged> to specify the escape character
2020explicitly.
2021
32eab2da 2022=item name_sep
2023
2024This is the character that separates a table and column name. It is
2025necessary to specify this when the C<quote_char> option is selected,
2026so that tables and column names can be individually quoted like this:
2027
2028 SELECT `table`.`one_field` FROM `table` WHERE `table`.`other_field` = 1
2029
b6251592 2030=item injection_guard
2031
2032A regular expression C<qr/.../> that is applied to any C<-function> and unquoted
2033column name specified in a query structure. This is a safety mechanism to avoid
2034injection attacks when mishandling user input e.g.:
2035
2036 my %condition_as_column_value_pairs = get_values_from_user();
2037 $sqla->select( ... , \%condition_as_column_value_pairs );
2038
2039If the expression matches an exception is thrown. Note that literal SQL
2040supplied via C<\'...'> or C<\['...']> is B<not> checked in any way.
2041
2042Defaults to checking for C<;> and the C<GO> keyword (TransactSQL)
2043
96449e8e 2044=item array_datatypes
32eab2da 2045
9d48860e 2046When this option is true, arrayrefs in INSERT or UPDATE are
2047interpreted as array datatypes and are passed directly
96449e8e 2048to the DBI layer.
2049When this option is false, arrayrefs are interpreted
2050as literal SQL, just like refs to arrayrefs
2051(but this behavior is for backwards compatibility; when writing
2052new queries, use the "reference to arrayref" syntax
2053for literal SQL).
32eab2da 2054
32eab2da 2055
96449e8e 2056=item special_ops
32eab2da 2057
9d48860e 2058Takes a reference to a list of "special operators"
96449e8e 2059to extend the syntax understood by L<SQL::Abstract>.
2060See section L</"SPECIAL OPERATORS"> for details.
32eab2da 2061
59f23b3d 2062=item unary_ops
2063
9d48860e 2064Takes a reference to a list of "unary operators"
59f23b3d 2065to extend the syntax understood by L<SQL::Abstract>.
2066See section L</"UNARY OPERATORS"> for details.
2067
32eab2da 2068
32eab2da 2069
96449e8e 2070=back
32eab2da 2071
02288357 2072=head2 insert($table, \@values || \%fieldvals, \%options)
32eab2da 2073
2074This is the simplest function. You simply give it a table name
2075and either an arrayref of values or hashref of field/value pairs.
2076It returns an SQL INSERT statement and a list of bind values.
96449e8e 2077See the sections on L</"Inserting and Updating Arrays"> and
2078L</"Inserting and Updating SQL"> for information on how to insert
2079with those data types.
32eab2da 2080
02288357 2081The optional C<\%options> hash reference may contain additional
2082options to generate the insert SQL. Currently supported options
2083are:
2084
2085=over 4
2086
2087=item returning
2088
2089Takes either a scalar of raw SQL fields, or an array reference of
2090field names, and adds on an SQL C<RETURNING> statement at the end.
2091This allows you to return data generated by the insert statement
2092(such as row IDs) without performing another C<SELECT> statement.
2093Note, however, this is not part of the SQL standard and may not
2094be supported by all database engines.
2095
2096=back
2097
95904db5 2098=head2 update($table, \%fieldvals, \%where, \%options)
32eab2da 2099
2100This takes a table, hashref of field/value pairs, and an optional
86298391 2101hashref L<WHERE clause|/WHERE CLAUSES>. It returns an SQL UPDATE function and a list
32eab2da 2102of bind values.
96449e8e 2103See the sections on L</"Inserting and Updating Arrays"> and
2104L</"Inserting and Updating SQL"> for information on how to insert
2105with those data types.
32eab2da 2106
95904db5 2107The optional C<\%options> hash reference may contain additional
2108options to generate the update SQL. Currently supported options
2109are:
2110
2111=over 4
2112
2113=item returning
2114
2115See the C<returning> option to
2116L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2117
2118=back
2119
96449e8e 2120=head2 select($source, $fields, $where, $order)
32eab2da 2121
9d48860e 2122This returns a SQL SELECT statement and associated list of bind values, as
be21dde3 2123specified by the arguments:
32eab2da 2124
96449e8e 2125=over
32eab2da 2126
96449e8e 2127=item $source
32eab2da 2128
9d48860e 2129Specification of the 'FROM' part of the statement.
96449e8e 2130The argument can be either a plain scalar (interpreted as a table
2131name, will be quoted), or an arrayref (interpreted as a list
2132of table names, joined by commas, quoted), or a scalarref
063097a3 2133(literal SQL, not quoted).
32eab2da 2134
96449e8e 2135=item $fields
32eab2da 2136
9d48860e 2137Specification of the list of fields to retrieve from
96449e8e 2138the source.
2139The argument can be either an arrayref (interpreted as a list
9d48860e 2140of field names, will be joined by commas and quoted), or a
96449e8e 2141plain scalar (literal SQL, not quoted).
521647e7 2142Please observe that this API is not as flexible as that of
2143the first argument C<$source>, for backwards compatibility reasons.
32eab2da 2144
96449e8e 2145=item $where
32eab2da 2146
96449e8e 2147Optional argument to specify the WHERE part of the query.
2148The argument is most often a hashref, but can also be
9d48860e 2149an arrayref or plain scalar --
96449e8e 2150see section L<WHERE clause|/"WHERE CLAUSES"> for details.
32eab2da 2151
96449e8e 2152=item $order
32eab2da 2153
96449e8e 2154Optional argument to specify the ORDER BY part of the query.
9d48860e 2155The argument can be a scalar, a hashref or an arrayref
96449e8e 2156-- see section L<ORDER BY clause|/"ORDER BY CLAUSES">
2157for details.
32eab2da 2158
96449e8e 2159=back
32eab2da 2160
32eab2da 2161
85327cd5 2162=head2 delete($table, \%where, \%options)
32eab2da 2163
86298391 2164This takes a table name and optional hashref L<WHERE clause|/WHERE CLAUSES>.
32eab2da 2165It returns an SQL DELETE statement and list of bind values.
2166
85327cd5 2167The optional C<\%options> hash reference may contain additional
2168options to generate the delete SQL. Currently supported options
2169are:
2170
2171=over 4
2172
2173=item returning
2174
2175See the C<returning> option to
2176L<insert|/insert($table, \@values || \%fieldvals, \%options)>.
2177
2178=back
2179
85783f3c 2180=head2 where(\%where, $order)
32eab2da 2181
2182This is used to generate just the WHERE clause. For example,
2183if you have an arbitrary data structure and know what the
2184rest of your SQL is going to look like, but want an easy way
2185to produce a WHERE clause, use this. It returns an SQL WHERE
2186clause and list of bind values.
2187
32eab2da 2188
2189=head2 values(\%data)
2190
2191This just returns the values from the hash C<%data>, in the same
2192order that would be returned from any of the other above queries.
2193Using this allows you to markedly speed up your queries if you
2194are affecting lots of rows. See below under the L</"PERFORMANCE"> section.
2195
32eab2da 2196=head2 generate($any, 'number', $of, \@data, $struct, \%types)
2197
2198Warning: This is an experimental method and subject to change.
2199
2200This returns arbitrarily generated SQL. It's a really basic shortcut.
2201It will return two different things, depending on return context:
2202
2203 my($stmt, @bind) = $sql->generate('create table', \$table, \@fields);
2204 my $stmt_and_val = $sql->generate('create table', \$table, \@fields);
2205
2206These would return the following:
2207
2208 # First calling form
2209 $stmt = "CREATE TABLE test (?, ?)";
2210 @bind = (field1, field2);
2211
2212 # Second calling form
2213 $stmt_and_val = "CREATE TABLE test (field1, field2)";
2214
2215Depending on what you're trying to do, it's up to you to choose the correct
2216format. In this example, the second form is what you would want.
2217
2218By the same token:
2219
2220 $sql->generate('alter session', { nls_date_format => 'MM/YY' });
2221
2222Might give you:
2223
2224 ALTER SESSION SET nls_date_format = 'MM/YY'
2225
2226You get the idea. Strings get their case twiddled, but everything
2227else remains verbatim.
2228
0da0fe34 2229=head1 EXPORTABLE FUNCTIONS
2230
2231=head2 is_plain_value
2232
2233Determines if the supplied argument is a plain value as understood by this
2234module:
2235
2236=over
2237
2238=item * The value is C<undef>
2239
2240=item * The value is a non-reference
2241
2242=item * The value is an object with stringification overloading
2243
2244=item * The value is of the form C<< { -value => $anything } >>
2245
2246=back
2247
9de2bd86 2248On failure returns C<undef>, on success returns a B<scalar> reference
966200cc 2249to the original supplied argument.
0da0fe34 2250
843a94b5 2251=over
2252
2253=item * Note
2254
2255The stringification overloading detection is rather advanced: it takes
2256into consideration not only the presence of a C<""> overload, but if that
2257fails also checks for enabled
2258L<autogenerated versions of C<"">|overload/Magic Autogeneration>, based
2259on either C<0+> or C<bool>.
2260
2261Unfortunately testing in the field indicates that this
2262detection B<< may tickle a latent bug in perl versions before 5.018 >>,
2263but only when very large numbers of stringifying objects are involved.
2264At the time of writing ( Sep 2014 ) there is no clear explanation of
2265the direct cause, nor is there a manageably small test case that reliably
2266reproduces the problem.
2267
2268If you encounter any of the following exceptions in B<random places within
2269your application stack> - this module may be to blame:
2270
2271 Operation "ne": no method found,
2272 left argument in overloaded package <something>,
2273 right argument in overloaded package <something>
2274
2275or perhaps even
2276
2277 Stub found while resolving method "???" overloading """" in package <something>
2278
2279If you fall victim to the above - please attempt to reduce the problem
2280to something that could be sent to the L<SQL::Abstract developers
1f490ae4 2281|DBIx::Class/GETTING HELP/SUPPORT>
843a94b5 2282(either publicly or privately). As a workaround in the meantime you can
2283set C<$ENV{SQLA_ISVALUE_IGNORE_AUTOGENERATED_STRINGIFICATION}> to a true
2284value, which will most likely eliminate your problem (at the expense of
2285not being able to properly detect exotic forms of stringification).
2286
2287This notice and environment variable will be removed in a future version,
2288as soon as the underlying problem is found and a reliable workaround is
2289devised.
2290
2291=back
2292
0da0fe34 2293=head2 is_literal_value
2294
2295Determines if the supplied argument is a literal value as understood by this
2296module:
2297
2298=over
2299
2300=item * C<\$sql_string>
2301
2302=item * C<\[ $sql_string, @bind_values ]>
2303
0da0fe34 2304=back
2305
9de2bd86 2306On failure returns C<undef>, on success returns an B<array> reference
966200cc 2307containing the unpacked version of the supplied literal SQL and bind values.
0da0fe34 2308
32eab2da 2309=head1 WHERE CLAUSES
2310
96449e8e 2311=head2 Introduction
2312
32eab2da 2313This module uses a variation on the idea from L<DBIx::Abstract>. It
2314is B<NOT>, repeat I<not> 100% compatible. B<The main logic of this
2315module is that things in arrays are OR'ed, and things in hashes
2316are AND'ed.>
2317
2318The easiest way to explain is to show lots of examples. After
2319each C<%where> hash shown, it is assumed you used:
2320
2321 my($stmt, @bind) = $sql->where(\%where);
2322
2323However, note that the C<%where> hash can be used directly in any
2324of the other functions as well, as described above.
2325
96449e8e 2326=head2 Key-value pairs
2327
32eab2da 2328So, let's get started. To begin, a simple hash:
2329
2330 my %where = (
2331 user => 'nwiger',
2332 status => 'completed'
2333 );
2334
2335Is converted to SQL C<key = val> statements:
2336
2337 $stmt = "WHERE user = ? AND status = ?";
2338 @bind = ('nwiger', 'completed');
2339
2340One common thing I end up doing is having a list of values that
2341a field can be in. To do this, simply specify a list inside of
2342an arrayref:
2343
2344 my %where = (
2345 user => 'nwiger',
2346 status => ['assigned', 'in-progress', 'pending'];
2347 );
2348
2349This simple code will create the following:
9d48860e 2350
32eab2da 2351 $stmt = "WHERE user = ? AND ( status = ? OR status = ? OR status = ? )";
2352 @bind = ('nwiger', 'assigned', 'in-progress', 'pending');
2353
9d48860e 2354A field associated to an empty arrayref will be considered a
7cac25e6 2355logical false and will generate 0=1.
8a68b5be 2356
b864ba9b 2357=head2 Tests for NULL values
2358
2359If the value part is C<undef> then this is converted to SQL <IS NULL>
2360
2361 my %where = (
2362 user => 'nwiger',
2363 status => undef,
2364 );
2365
2366becomes:
2367
2368 $stmt = "WHERE user = ? AND status IS NULL";
2369 @bind = ('nwiger');
2370
e9614080 2371To test if a column IS NOT NULL:
2372
2373 my %where = (
2374 user => 'nwiger',
2375 status => { '!=', undef },
2376 );
cc422895 2377
6e0c6552 2378=head2 Specific comparison operators
96449e8e 2379
32eab2da 2380If you want to specify a different type of operator for your comparison,
2381you can use a hashref for a given column:
2382
2383 my %where = (
2384 user => 'nwiger',
2385 status => { '!=', 'completed' }
2386 );
2387
2388Which would generate:
2389
2390 $stmt = "WHERE user = ? AND status != ?";
2391 @bind = ('nwiger', 'completed');
2392
2393To test against multiple values, just enclose the values in an arrayref:
2394
96449e8e 2395 status => { '=', ['assigned', 'in-progress', 'pending'] };
2396
f2d5020d 2397Which would give you:
96449e8e 2398
2399 "WHERE status = ? OR status = ? OR status = ?"
2400
2401
2402The hashref can also contain multiple pairs, in which case it is expanded
32eab2da 2403into an C<AND> of its elements:
2404
2405 my %where = (
2406 user => 'nwiger',
2407 status => { '!=', 'completed', -not_like => 'pending%' }
2408 );
2409
2410 # Or more dynamically, like from a form
2411 $where{user} = 'nwiger';
2412 $where{status}{'!='} = 'completed';
2413 $where{status}{'-not_like'} = 'pending%';
2414
2415 # Both generate this
2416 $stmt = "WHERE user = ? AND status != ? AND status NOT LIKE ?";
2417 @bind = ('nwiger', 'completed', 'pending%');
2418
96449e8e 2419
32eab2da 2420To get an OR instead, you can combine it with the arrayref idea:
2421
2422 my %where => (
2423 user => 'nwiger',
1a6f2a03 2424 priority => [ { '=', 2 }, { '>', 5 } ]
32eab2da 2425 );
2426
2427Which would generate:
2428
1a6f2a03 2429 $stmt = "WHERE ( priority = ? OR priority > ? ) AND user = ?";
2430 @bind = ('2', '5', 'nwiger');
32eab2da 2431
44b9e502 2432If you want to include literal SQL (with or without bind values), just use a
13cc86af 2433scalar reference or reference to an arrayref as the value:
44b9e502 2434
2435 my %where = (
2436 date_entered => { '>' => \["to_date(?, 'MM/DD/YYYY')", "11/26/2008"] },
2437 date_expires => { '<' => \"now()" }
2438 );
2439
2440Which would generate:
2441
13cc86af 2442 $stmt = "WHERE date_entered > to_date(?, 'MM/DD/YYYY') AND date_expires < now()";
44b9e502 2443 @bind = ('11/26/2008');
2444
96449e8e 2445
2446=head2 Logic and nesting operators
2447
2448In the example above,
2449there is a subtle trap if you want to say something like
32eab2da 2450this (notice the C<AND>):
2451
2452 WHERE priority != ? AND priority != ?
2453
2454Because, in Perl you I<can't> do this:
2455
13cc86af 2456 priority => { '!=' => 2, '!=' => 1 }
32eab2da 2457
2458As the second C<!=> key will obliterate the first. The solution
2459is to use the special C<-modifier> form inside an arrayref:
2460
9d48860e 2461 priority => [ -and => {'!=', 2},
96449e8e 2462 {'!=', 1} ]
2463
32eab2da 2464
2465Normally, these would be joined by C<OR>, but the modifier tells it
2466to use C<AND> instead. (Hint: You can use this in conjunction with the
2467C<logic> option to C<new()> in order to change the way your queries
2468work by default.) B<Important:> Note that the C<-modifier> goes
2469B<INSIDE> the arrayref, as an extra first element. This will
2470B<NOT> do what you think it might:
2471
2472 priority => -and => [{'!=', 2}, {'!=', 1}] # WRONG!
2473
2474Here is a quick list of equivalencies, since there is some overlap:
2475
2476 # Same
2477 status => {'!=', 'completed', 'not like', 'pending%' }
2478 status => [ -and => {'!=', 'completed'}, {'not like', 'pending%'}]
2479
2480 # Same
2481 status => {'=', ['assigned', 'in-progress']}
2482 status => [ -or => {'=', 'assigned'}, {'=', 'in-progress'}]
2483 status => [ {'=', 'assigned'}, {'=', 'in-progress'} ]
2484
e3f9dff4 2485
2486
be21dde3 2487=head2 Special operators: IN, BETWEEN, etc.
96449e8e 2488
32eab2da 2489You can also use the hashref format to compare a list of fields using the
2490C<IN> comparison operator, by specifying the list as an arrayref:
2491
2492 my %where = (
2493 status => 'completed',
2494 reportid => { -in => [567, 2335, 2] }
2495 );
2496
2497Which would generate:
2498
2499 $stmt = "WHERE status = ? AND reportid IN (?,?,?)";
2500 @bind = ('completed', '567', '2335', '2');
2501
9d48860e 2502The reverse operator C<-not_in> generates SQL C<NOT IN> and is used in
96449e8e 2503the same way.
2504
6e0c6552 2505If the argument to C<-in> is an empty array, 'sqlfalse' is generated
be21dde3 2506(by default: C<1=0>). Similarly, C<< -not_in => [] >> generates
2507'sqltrue' (by default: C<1=1>).
6e0c6552 2508
e41c3bdd 2509In addition to the array you can supply a chunk of literal sql or
2510literal sql with bind:
6e0c6552 2511
e41c3bdd 2512 my %where = {
2513 customer => { -in => \[
2514 'SELECT cust_id FROM cust WHERE balance > ?',
2515 2000,
2516 ],
2517 status => { -in => \'SELECT status_codes FROM states' },
2518 };
6e0c6552 2519
e41c3bdd 2520would generate:
2521
2522 $stmt = "WHERE (
2523 customer IN ( SELECT cust_id FROM cust WHERE balance > ? )
2524 AND status IN ( SELECT status_codes FROM states )
2525 )";
2526 @bind = ('2000');
2527
0dfd2442 2528Finally, if the argument to C<-in> is not a reference, it will be
2529treated as a single-element array.
e41c3bdd 2530
2531Another pair of operators is C<-between> and C<-not_between>,
96449e8e 2532used with an arrayref of two values:
32eab2da 2533
2534 my %where = (
2535 user => 'nwiger',
2536 completion_date => {
2537 -not_between => ['2002-10-01', '2003-02-06']
2538 }
2539 );
2540
2541Would give you:
2542
2543 WHERE user = ? AND completion_date NOT BETWEEN ( ? AND ? )
2544
e41c3bdd 2545Just like with C<-in> all plausible combinations of literal SQL
2546are possible:
2547
2548 my %where = {
2549 start0 => { -between => [ 1, 2 ] },
2550 start1 => { -between => \["? AND ?", 1, 2] },
2551 start2 => { -between => \"lower(x) AND upper(y)" },
9d48860e 2552 start3 => { -between => [
e41c3bdd 2553 \"lower(x)",
2554 \["upper(?)", 'stuff' ],
2555 ] },
2556 };
2557
2558Would give you:
2559
2560 $stmt = "WHERE (
2561 ( start0 BETWEEN ? AND ? )
2562 AND ( start1 BETWEEN ? AND ? )
2563 AND ( start2 BETWEEN lower(x) AND upper(y) )
2564 AND ( start3 BETWEEN lower(x) AND upper(?) )
2565 )";
2566 @bind = (1, 2, 1, 2, 'stuff');
2567
2568
9d48860e 2569These are the two builtin "special operators"; but the
be21dde3 2570list can be expanded: see section L</"SPECIAL OPERATORS"> below.
96449e8e 2571
59f23b3d 2572=head2 Unary operators: bool
97a920ef 2573
2574If you wish to test against boolean columns or functions within your
2575database you can use the C<-bool> and C<-not_bool> operators. For
2576example to test the column C<is_user> being true and the column
827bb0eb 2577C<is_enabled> being false you would use:-
97a920ef 2578
2579 my %where = (
2580 -bool => 'is_user',
2581 -not_bool => 'is_enabled',
2582 );
2583
2584Would give you:
2585
277b5d3f 2586 WHERE is_user AND NOT is_enabled
97a920ef 2587
0b604e9d 2588If a more complex combination is required, testing more conditions,
2589then you should use the and/or operators:-
2590
2591 my %where = (
2592 -and => [
2593 -bool => 'one',
23401b81 2594 -not_bool => { two=> { -rlike => 'bar' } },
2595 -not_bool => { three => [ { '=', 2 }, { '>', 5 } ] },
0b604e9d 2596 ],
2597 );
2598
2599Would give you:
2600
23401b81 2601 WHERE
2602 one
2603 AND
2604 (NOT two RLIKE ?)
2605 AND
2606 (NOT ( three = ? OR three > ? ))
97a920ef 2607
2608
107b72f1 2609=head2 Nested conditions, -and/-or prefixes
96449e8e 2610
32eab2da 2611So far, we've seen how multiple conditions are joined with a top-level
2612C<AND>. We can change this by putting the different conditions we want in
2613hashes and then putting those hashes in an array. For example:
2614
2615 my @where = (
2616 {
2617 user => 'nwiger',
2618 status => { -like => ['pending%', 'dispatched'] },
2619 },
2620 {
2621 user => 'robot',
2622 status => 'unassigned',
2623 }
2624 );
2625
2626This data structure would create the following:
2627
2628 $stmt = "WHERE ( user = ? AND ( status LIKE ? OR status LIKE ? ) )
2629 OR ( user = ? AND status = ? ) )";
2630 @bind = ('nwiger', 'pending', 'dispatched', 'robot', 'unassigned');
2631
107b72f1 2632
48d9f5f8 2633Clauses in hashrefs or arrayrefs can be prefixed with an C<-and> or C<-or>
be21dde3 2634to change the logic inside:
32eab2da 2635
2636 my @where = (
2637 -and => [
2638 user => 'nwiger',
48d9f5f8 2639 [
2640 -and => [ workhrs => {'>', 20}, geo => 'ASIA' ],
2641 -or => { workhrs => {'<', 50}, geo => 'EURO' },
32eab2da 2642 ],
2643 ],
2644 );
2645
2646That would yield:
2647
13cc86af 2648 $stmt = "WHERE ( user = ?
2649 AND ( ( workhrs > ? AND geo = ? )
2650 OR ( workhrs < ? OR geo = ? ) ) )";
2651 @bind = ('nwiger', '20', 'ASIA', '50', 'EURO');
107b72f1 2652
cc422895 2653=head3 Algebraic inconsistency, for historical reasons
107b72f1 2654
7cac25e6 2655C<Important note>: when connecting several conditions, the C<-and->|C<-or>
2656operator goes C<outside> of the nested structure; whereas when connecting
2657several constraints on one column, the C<-and> operator goes
be21dde3 2658C<inside> the arrayref. Here is an example combining both features:
7cac25e6 2659
2660 my @where = (
2661 -and => [a => 1, b => 2],
2662 -or => [c => 3, d => 4],
2663 e => [-and => {-like => 'foo%'}, {-like => '%bar'} ]
2664 )
2665
2666yielding
2667
9d48860e 2668 WHERE ( ( ( a = ? AND b = ? )
2669 OR ( c = ? OR d = ? )
7cac25e6 2670 OR ( e LIKE ? AND e LIKE ? ) ) )
2671
107b72f1 2672This difference in syntax is unfortunate but must be preserved for
be21dde3 2673historical reasons. So be careful: the two examples below would
107b72f1 2674seem algebraically equivalent, but they are not
2675
a948b1fe 2676 { col => [ -and =>
2677 { -like => 'foo%' },
2678 { -like => '%bar' },
2679 ] }
be21dde3 2680 # yields: WHERE ( ( col LIKE ? AND col LIKE ? ) )
107b72f1 2681
a948b1fe 2682 [ -and =>
2683 { col => { -like => 'foo%' } },
2684 { col => { -like => '%bar' } },
2685 ]
be21dde3 2686 # yields: WHERE ( ( col LIKE ? OR col LIKE ? ) )
107b72f1 2687
7cac25e6 2688
cc422895 2689=head2 Literal SQL and value type operators
96449e8e 2690
cc422895 2691The basic premise of SQL::Abstract is that in WHERE specifications the "left
2692side" is a column name and the "right side" is a value (normally rendered as
2693a placeholder). This holds true for both hashrefs and arrayref pairs as you
2694see in the L</WHERE CLAUSES> examples above. Sometimes it is necessary to
2695alter this behavior. There are several ways of doing so.
e9614080 2696
cc422895 2697=head3 -ident
2698
2699This is a virtual operator that signals the string to its right side is an
2700identifier (a column name) and not a value. For example to compare two
2701columns you would write:
32eab2da 2702
e9614080 2703 my %where = (
2704 priority => { '<', 2 },
cc422895 2705 requestor => { -ident => 'submitter' },
e9614080 2706 );
2707
2708which creates:
2709
2710 $stmt = "WHERE priority < ? AND requestor = submitter";
2711 @bind = ('2');
2712
cc422895 2713If you are maintaining legacy code you may see a different construct as
2714described in L</Deprecated usage of Literal SQL>, please use C<-ident> in new
2715code.
2716
2717=head3 -value
e9614080 2718
cc422895 2719This is a virtual operator that signals that the construct to its right side
2720is a value to be passed to DBI. This is for example necessary when you want
2721to write a where clause against an array (for RDBMS that support such
2722datatypes). For example:
e9614080 2723
32eab2da 2724 my %where = (
cc422895 2725 array => { -value => [1, 2, 3] }
32eab2da 2726 );
2727
cc422895 2728will result in:
32eab2da 2729
cc422895 2730 $stmt = 'WHERE array = ?';
2731 @bind = ([1, 2, 3]);
32eab2da 2732
cc422895 2733Note that if you were to simply say:
32eab2da 2734
2735 my %where = (
cc422895 2736 array => [1, 2, 3]
32eab2da 2737 );
2738
3af02ccb 2739the result would probably not be what you wanted:
cc422895 2740
2741 $stmt = 'WHERE array = ? OR array = ? OR array = ?';
2742 @bind = (1, 2, 3);
2743
2744=head3 Literal SQL
96449e8e 2745
cc422895 2746Finally, sometimes only literal SQL will do. To include a random snippet
2747of SQL verbatim, you specify it as a scalar reference. Consider this only
2748as a last resort. Usually there is a better way. For example:
96449e8e 2749
2750 my %where = (
cc422895 2751 priority => { '<', 2 },
2752 requestor => { -in => \'(SELECT name FROM hitmen)' },
96449e8e 2753 );
2754
cc422895 2755Would create:
96449e8e 2756
cc422895 2757 $stmt = "WHERE priority < ? AND requestor IN (SELECT name FROM hitmen)"
2758 @bind = (2);
2759
2760Note that in this example, you only get one bind parameter back, since
2761the verbatim SQL is passed as part of the statement.
2762
2763=head4 CAVEAT
2764
2765 Never use untrusted input as a literal SQL argument - this is a massive
2766 security risk (there is no way to check literal snippets for SQL
2767 injections and other nastyness). If you need to deal with untrusted input
2768 use literal SQL with placeholders as described next.
96449e8e 2769
cc422895 2770=head3 Literal SQL with placeholders and bind values (subqueries)
96449e8e 2771
2772If the literal SQL to be inserted has placeholders and bind values,
2773use a reference to an arrayref (yes this is a double reference --
2774not so common, but perfectly legal Perl). For example, to find a date
2775in Postgres you can use something like this:
2776
2777 my %where = (
3ae1c5e2 2778 date_column => \[ "= date '2008-09-30' - ?::integer", 10 ]
96449e8e 2779 )
2780
2781This would create:
2782
d2a8fe1a 2783 $stmt = "WHERE ( date_column = date '2008-09-30' - ?::integer )"
96449e8e 2784 @bind = ('10');
2785
deb148a2 2786Note that you must pass the bind values in the same format as they are returned
85783f3c 2787by L<where|/where(\%where, $order)>. This means that if you set L</bindtype>
1f490ae4 2788to C<columns>, you must provide the bind values in the
2789C<< [ column_meta => value ] >> format, where C<column_meta> is an opaque
2790scalar value; most commonly the column name, but you can use any scalar value
2791(including references and blessed references), L<SQL::Abstract> will simply
2792pass it through intact. So if C<bindtype> is set to C<columns> the above
2793example will look like:
deb148a2 2794
2795 my %where = (
3ae1c5e2 2796 date_column => \[ "= date '2008-09-30' - ?::integer", [ {} => 10 ] ]
deb148a2 2797 )
96449e8e 2798
2799Literal SQL is especially useful for nesting parenthesized clauses in the
be21dde3 2800main SQL query. Here is a first example:
96449e8e 2801
2802 my ($sub_stmt, @sub_bind) = ("SELECT c1 FROM t1 WHERE c2 < ? AND c3 LIKE ?",
2803 100, "foo%");
2804 my %where = (
2805 foo => 1234,
2806 bar => \["IN ($sub_stmt)" => @sub_bind],
2807 );
2808
be21dde3 2809This yields:
96449e8e 2810
9d48860e 2811 $stmt = "WHERE (foo = ? AND bar IN (SELECT c1 FROM t1
96449e8e 2812 WHERE c2 < ? AND c3 LIKE ?))";
2813 @bind = (1234, 100, "foo%");
2814
9d48860e 2815Other subquery operators, like for example C<"E<gt> ALL"> or C<"NOT IN">,
96449e8e 2816are expressed in the same way. Of course the C<$sub_stmt> and
9d48860e 2817its associated bind values can be generated through a former call
96449e8e 2818to C<select()> :
2819
2820 my ($sub_stmt, @sub_bind)
9d48860e 2821 = $sql->select("t1", "c1", {c2 => {"<" => 100},
96449e8e 2822 c3 => {-like => "foo%"}});
2823 my %where = (
2824 foo => 1234,
2825 bar => \["> ALL ($sub_stmt)" => @sub_bind],
2826 );
2827
2828In the examples above, the subquery was used as an operator on a column;
9d48860e 2829but the same principle also applies for a clause within the main C<%where>
be21dde3 2830hash, like an EXISTS subquery:
96449e8e 2831
9d48860e 2832 my ($sub_stmt, @sub_bind)
96449e8e 2833 = $sql->select("t1", "*", {c1 => 1, c2 => \"> t0.c0"});
48d9f5f8 2834 my %where = ( -and => [
96449e8e 2835 foo => 1234,
48d9f5f8 2836 \["EXISTS ($sub_stmt)" => @sub_bind],
2837 ]);
96449e8e 2838
2839which yields
2840
9d48860e 2841 $stmt = "WHERE (foo = ? AND EXISTS (SELECT * FROM t1
96449e8e 2842 WHERE c1 = ? AND c2 > t0.c0))";
2843 @bind = (1234, 1);
2844
2845
9d48860e 2846Observe that the condition on C<c2> in the subquery refers to
be21dde3 2847column C<t0.c0> of the main query: this is I<not> a bind
9d48860e 2848value, so we have to express it through a scalar ref.
96449e8e 2849Writing C<< c2 => {">" => "t0.c0"} >> would have generated
2850C<< c2 > ? >> with bind value C<"t0.c0"> ... not exactly
2851what we wanted here.
2852
96449e8e 2853Finally, here is an example where a subquery is used
2854for expressing unary negation:
2855
9d48860e 2856 my ($sub_stmt, @sub_bind)
96449e8e 2857 = $sql->where({age => [{"<" => 10}, {">" => 20}]});
2858 $sub_stmt =~ s/^ where //i; # don't want "WHERE" in the subclause
2859 my %where = (
2860 lname => {like => '%son%'},
48d9f5f8 2861 \["NOT ($sub_stmt)" => @sub_bind],
96449e8e 2862 );
2863
2864This yields
2865
2866 $stmt = "lname LIKE ? AND NOT ( age < ? OR age > ? )"
2867 @bind = ('%son%', 10, 20)
2868
cc422895 2869=head3 Deprecated usage of Literal SQL
2870
2871Below are some examples of archaic use of literal SQL. It is shown only as
2872reference for those who deal with legacy code. Each example has a much
2873better, cleaner and safer alternative that users should opt for in new code.
2874
2875=over
2876
2877=item *
2878
2879 my %where = ( requestor => \'IS NOT NULL' )
2880
2881 $stmt = "WHERE requestor IS NOT NULL"
2882
2883This used to be the way of generating NULL comparisons, before the handling
2884of C<undef> got formalized. For new code please use the superior syntax as
2885described in L</Tests for NULL values>.
96449e8e 2886
cc422895 2887=item *
2888
2889 my %where = ( requestor => \'= submitter' )
2890
2891 $stmt = "WHERE requestor = submitter"
2892
2893This used to be the only way to compare columns. Use the superior L</-ident>
2894method for all new code. For example an identifier declared in such a way
2895will be properly quoted if L</quote_char> is properly set, while the legacy
2896form will remain as supplied.
2897
2898=item *
2899
2900 my %where = ( is_ready => \"", completed => { '>', '2012-12-21' } )
2901
2902 $stmt = "WHERE completed > ? AND is_ready"
2903 @bind = ('2012-12-21')
2904
2905Using an empty string literal used to be the only way to express a boolean.
2906For all new code please use the much more readable
2907L<-bool|/Unary operators: bool> operator.
2908
2909=back
96449e8e 2910
2911=head2 Conclusion
2912
32eab2da 2913These pages could go on for a while, since the nesting of the data
2914structures this module can handle are pretty much unlimited (the
2915module implements the C<WHERE> expansion as a recursive function
2916internally). Your best bet is to "play around" with the module a
2917little to see how the data structures behave, and choose the best
2918format for your data based on that.
2919
2920And of course, all the values above will probably be replaced with
2921variables gotten from forms or the command line. After all, if you
2922knew everything ahead of time, you wouldn't have to worry about
2923dynamically-generating SQL and could just hardwire it into your
2924script.
2925
86298391 2926=head1 ORDER BY CLAUSES
2927
9d48860e 2928Some functions take an order by clause. This can either be a scalar (just a
18710f60 2929column name), a hashref of C<< { -desc => 'col' } >> or C<< { -asc => 'col' }
2930>>, a scalarref, an arrayref-ref, or an arrayref of any of the previous
2931forms. Examples:
1cfa1db3 2932
8c15b421 2933 Given | Will Generate
18710f60 2934 ---------------------------------------------------------------
8c15b421 2935 |
2936 'colA' | ORDER BY colA
2937 |
2938 [qw/colA colB/] | ORDER BY colA, colB
2939 |
2940 {-asc => 'colA'} | ORDER BY colA ASC
2941 |
2942 {-desc => 'colB'} | ORDER BY colB DESC
2943 |
2944 ['colA', {-asc => 'colB'}] | ORDER BY colA, colB ASC
2945 |
2946 { -asc => [qw/colA colB/] } | ORDER BY colA ASC, colB ASC
2947 |
2948 \'colA DESC' | ORDER BY colA DESC
2949 |
2950 \[ 'FUNC(colA, ?)', $x ] | ORDER BY FUNC(colA, ?)
2951 | /* ...with $x bound to ? */
2952 |
bd805d85 2953 [ | ORDER BY
2954 { -asc => 'colA' }, | colA ASC,
2955 { -desc => [qw/colB/] }, | colB DESC,
2956 { -asc => [qw/colC colD/] },| colC ASC, colD ASC,
2957 \'colE DESC', | colE DESC,
2958 \[ 'FUNC(colF, ?)', $x ], | FUNC(colF, ?)
2959 ] | /* ...with $x bound to ? */
18710f60 2960 ===============================================================
86298391 2961
96449e8e 2962
2963
2964=head1 SPECIAL OPERATORS
2965
e3f9dff4 2966 my $sqlmaker = SQL::Abstract->new(special_ops => [
3a2e1a5e 2967 {
2968 regex => qr/.../,
e3f9dff4 2969 handler => sub {
2970 my ($self, $field, $op, $arg) = @_;
2971 ...
3a2e1a5e 2972 },
2973 },
2974 {
2975 regex => qr/.../,
2976 handler => 'method_name',
e3f9dff4 2977 },
2978 ]);
2979
9d48860e 2980A "special operator" is a SQL syntactic clause that can be
e3f9dff4 2981applied to a field, instead of a usual binary operator.
be21dde3 2982For example:
e3f9dff4 2983
2984 WHERE field IN (?, ?, ?)
2985 WHERE field BETWEEN ? AND ?
2986 WHERE MATCH(field) AGAINST (?, ?)
96449e8e 2987
e3f9dff4 2988Special operators IN and BETWEEN are fairly standard and therefore
3a2e1a5e 2989are builtin within C<SQL::Abstract> (as the overridable methods
2990C<_where_field_IN> and C<_where_field_BETWEEN>). For other operators,
2991like the MATCH .. AGAINST example above which is specific to MySQL,
2992you can write your own operator handlers - supply a C<special_ops>
2993argument to the C<new> method. That argument takes an arrayref of
2994operator definitions; each operator definition is a hashref with two
2995entries:
96449e8e 2996
e3f9dff4 2997=over
2998
2999=item regex
3000
3001the regular expression to match the operator
96449e8e 3002
e3f9dff4 3003=item handler
3004
3a2e1a5e 3005Either a coderef or a plain scalar method name. In both cases
3006the expected return is C<< ($sql, @bind) >>.
3007
3008When supplied with a method name, it is simply called on the
13cc86af 3009L<SQL::Abstract> object as:
3a2e1a5e 3010
ca4f826a 3011 $self->$method_name($field, $op, $arg)
3a2e1a5e 3012
3013 Where:
3014
3a2e1a5e 3015 $field is the LHS of the operator
13cc86af 3016 $op is the part that matched the handler regex
3a2e1a5e 3017 $arg is the RHS
3018
3019When supplied with a coderef, it is called as:
3020
3021 $coderef->($self, $field, $op, $arg)
3022
e3f9dff4 3023
3024=back
3025
9d48860e 3026For example, here is an implementation
e3f9dff4 3027of the MATCH .. AGAINST syntax for MySQL
3028
3029 my $sqlmaker = SQL::Abstract->new(special_ops => [
9d48860e 3030
e3f9dff4 3031 # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
9d48860e 3032 {regex => qr/^match$/i,
e3f9dff4 3033 handler => sub {
3034 my ($self, $field, $op, $arg) = @_;
3035 $arg = [$arg] if not ref $arg;
3036 my $label = $self->_quote($field);
3037 my ($placeholder) = $self->_convert('?');
3038 my $placeholders = join ", ", (($placeholder) x @$arg);
3039 my $sql = $self->_sqlcase('match') . " ($label) "
3040 . $self->_sqlcase('against') . " ($placeholders) ";
3041 my @bind = $self->_bindtype($field, @$arg);
3042 return ($sql, @bind);
3043 }
3044 },
9d48860e 3045
e3f9dff4 3046 ]);
96449e8e 3047
3048
59f23b3d 3049=head1 UNARY OPERATORS
3050
112b5232 3051 my $sqlmaker = SQL::Abstract->new(unary_ops => [
59f23b3d 3052 {
3053 regex => qr/.../,
3054 handler => sub {
3055 my ($self, $op, $arg) = @_;
3056 ...
3057 },
3058 },
3059 {
3060 regex => qr/.../,
3061 handler => 'method_name',
3062 },
3063 ]);
3064
9d48860e 3065A "unary operator" is a SQL syntactic clause that can be
59f23b3d 3066applied to a field - the operator goes before the field
3067
3068You can write your own operator handlers - supply a C<unary_ops>
3069argument to the C<new> method. That argument takes an arrayref of
3070operator definitions; each operator definition is a hashref with two
3071entries:
3072
3073=over
3074
3075=item regex
3076
3077the regular expression to match the operator
3078
3079=item handler
3080
3081Either a coderef or a plain scalar method name. In both cases
3082the expected return is C<< $sql >>.
3083
3084When supplied with a method name, it is simply called on the
13cc86af 3085L<SQL::Abstract> object as:
59f23b3d 3086
ca4f826a 3087 $self->$method_name($op, $arg)
59f23b3d 3088
3089 Where:
3090
3091 $op is the part that matched the handler regex
3092 $arg is the RHS or argument of the operator
3093
3094When supplied with a coderef, it is called as:
3095
3096 $coderef->($self, $op, $arg)
3097
3098
3099=back
3100
3101
32eab2da 3102=head1 PERFORMANCE
3103
3104Thanks to some benchmarking by Mark Stosberg, it turns out that
3105this module is many orders of magnitude faster than using C<DBIx::Abstract>.
3106I must admit this wasn't an intentional design issue, but it's a
3107byproduct of the fact that you get to control your C<DBI> handles
3108yourself.
3109
3110To maximize performance, use a code snippet like the following:
3111
3112 # prepare a statement handle using the first row
3113 # and then reuse it for the rest of the rows
3114 my($sth, $stmt);
3115 for my $href (@array_of_hashrefs) {
3116 $stmt ||= $sql->insert('table', $href);
3117 $sth ||= $dbh->prepare($stmt);
3118 $sth->execute($sql->values($href));
3119 }
3120
3121The reason this works is because the keys in your C<$href> are sorted
3122internally by B<SQL::Abstract>. Thus, as long as your data retains
3123the same structure, you only have to generate the SQL the first time
3124around. On subsequent queries, simply use the C<values> function provided
3125by this module to return your values in the correct order.
3126
b864ba9b 3127However this depends on the values having the same type - if, for
3128example, the values of a where clause may either have values
3129(resulting in sql of the form C<column = ?> with a single bind
3130value), or alternatively the values might be C<undef> (resulting in
3131sql of the form C<column IS NULL> with no bind value) then the
3132caching technique suggested will not work.
96449e8e 3133
32eab2da 3134=head1 FORMBUILDER
3135
3136If you use my C<CGI::FormBuilder> module at all, you'll hopefully
3137really like this part (I do, at least). Building up a complex query
3138can be as simple as the following:
3139
3140 #!/usr/bin/perl
3141
46dc2f3e 3142 use warnings;
3143 use strict;
3144
32eab2da 3145 use CGI::FormBuilder;
3146 use SQL::Abstract;
3147
3148 my $form = CGI::FormBuilder->new(...);
3149 my $sql = SQL::Abstract->new;
3150
3151 if ($form->submitted) {
3152 my $field = $form->field;
3153 my $id = delete $field->{id};
3154 my($stmt, @bind) = $sql->update('table', $field, {id => $id});
3155 }
3156
3157Of course, you would still have to connect using C<DBI> to run the
3158query, but the point is that if you make your form look like your
3159table, the actual query script can be extremely simplistic.
3160
3161If you're B<REALLY> lazy (I am), check out C<HTML::QuickTable> for
9d48860e 3162a fast interface to returning and formatting data. I frequently
32eab2da 3163use these three modules together to write complex database query
3164apps in under 50 lines.
3165
af733667 3166=head1 HOW TO CONTRIBUTE
3167
3168Contributions are always welcome, in all usable forms (we especially
3169welcome documentation improvements). The delivery methods include git-
3170or unified-diff formatted patches, GitHub pull requests, or plain bug
3171reports either via RT or the Mailing list. Contributors are generally
3172granted full access to the official repository after their first several
3173patches pass successful review.
3174
3175This project is maintained in a git repository. The code and related tools are
3176accessible at the following locations:
d8cc1792 3177
3178=over
3179
af733667 3180=item * Official repo: L<git://git.shadowcat.co.uk/dbsrgits/SQL-Abstract.git>
3181
3182=item * Official gitweb: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/SQL-Abstract.git>
3183
3184=item * GitHub mirror: L<https://github.com/dbsrgits/sql-abstract>
d8cc1792 3185
af733667 3186=item * Authorized committers: L<ssh://dbsrgits@git.shadowcat.co.uk/SQL-Abstract.git>
d8cc1792 3187
3188=back
32eab2da 3189
96449e8e 3190=head1 CHANGES
3191
3192Version 1.50 was a major internal refactoring of C<SQL::Abstract>.
3193Great care has been taken to preserve the I<published> behavior
3194documented in previous versions in the 1.* family; however,
9d48860e 3195some features that were previously undocumented, or behaved
96449e8e 3196differently from the documentation, had to be changed in order
3197to clarify the semantics. Hence, client code that was relying
9d48860e 3198on some dark areas of C<SQL::Abstract> v1.*
96449e8e 3199B<might behave differently> in v1.50.
32eab2da 3200
be21dde3 3201The main changes are:
d2a8fe1a 3202
96449e8e 3203=over
32eab2da 3204
9d48860e 3205=item *
32eab2da 3206
3ae1c5e2 3207support for literal SQL through the C<< \ [ $sql, @bind ] >> syntax.
96449e8e 3208
3209=item *
3210
145fbfc8 3211support for the { operator => \"..." } construct (to embed literal SQL)
3212
3213=item *
3214
9c37b9c0 3215support for the { operator => \["...", @bind] } construct (to embed literal SQL with bind values)
3216
3217=item *
3218
96449e8e 3219optional support for L<array datatypes|/"Inserting and Updating Arrays">
3220
9d48860e 3221=item *
96449e8e 3222
be21dde3 3223defensive programming: check arguments
96449e8e 3224
3225=item *
3226
3227fixed bug with global logic, which was previously implemented
7cac25e6 3228through global variables yielding side-effects. Prior versions would
96449e8e 3229interpret C<< [ {cond1, cond2}, [cond3, cond4] ] >>
3230as C<< "(cond1 AND cond2) OR (cond3 AND cond4)" >>.
3231Now this is interpreted
3232as C<< "(cond1 AND cond2) OR (cond3 OR cond4)" >>.
3233
96449e8e 3234
3235=item *
3236
3237fixed semantics of _bindtype on array args
3238
9d48860e 3239=item *
96449e8e 3240
3241dropped the C<_anoncopy> of the %where tree. No longer necessary,
3242we just avoid shifting arrays within that tree.
3243
3244=item *
3245
3246dropped the C<_modlogic> function
3247
3248=back
32eab2da 3249
32eab2da 3250=head1 ACKNOWLEDGEMENTS
3251
3252There are a number of individuals that have really helped out with
3253this module. Unfortunately, most of them submitted bugs via CPAN
3254so I have no idea who they are! But the people I do know are:
3255
9d48860e 3256 Ash Berlin (order_by hash term support)
b643abe1 3257 Matt Trout (DBIx::Class support)
32eab2da 3258 Mark Stosberg (benchmarking)
3259 Chas Owens (initial "IN" operator support)
3260 Philip Collins (per-field SQL functions)
3261 Eric Kolve (hashref "AND" support)
3262 Mike Fragassi (enhancements to "BETWEEN" and "LIKE")
3263 Dan Kubb (support for "quote_char" and "name_sep")
f5aab26e 3264 Guillermo Roditi (patch to cleanup "IN" and "BETWEEN", fix and tests for _order_by)
48d9f5f8 3265 Laurent Dami (internal refactoring, extensible list of special operators, literal SQL)
dbdf7648 3266 Norbert Buchmuller (support for literal SQL in hashpair, misc. fixes & tests)
e96c510a 3267 Peter Rabbitson (rewrite of SQLA::Test, misc. fixes & tests)
02288357 3268 Oliver Charles (support for "RETURNING" after "INSERT")
32eab2da 3269
3270Thanks!
3271
32eab2da 3272=head1 SEE ALSO
3273
86298391 3274L<DBIx::Class>, L<DBIx::Abstract>, L<CGI::FormBuilder>, L<HTML::QuickTable>.
32eab2da 3275
32eab2da 3276=head1 AUTHOR
3277
b643abe1 3278Copyright (c) 2001-2007 Nathan Wiger <nwiger@cpan.org>. All Rights Reserved.
3279
3280This module is actively maintained by Matt Trout <mst@shadowcatsystems.co.uk>
32eab2da 3281
abe72f94 3282For support, your best bet is to try the C<DBIx::Class> users mailing list.
3283While not an official support venue, C<DBIx::Class> makes heavy use of
3284C<SQL::Abstract>, and as such list members there are very familiar with
3285how to create queries.
3286
0d067ded 3287=head1 LICENSE
3288
d988ab87 3289This module is free software; you may copy this under the same
3290terms as perl itself (either the GNU General Public License or
3291the Artistic License)
32eab2da 3292
3293=cut