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