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