set version to 1.64_01 for dev users
[scpubgit/Q-Branch.git] / lib / SQL / Abstract.pm
CommitLineData
96449e8e 1package SQL::Abstract; # see doc at end of file
2
3# LDNOTE : this code is heavy refactoring from original SQLA.
4# Several design decisions will need discussion during
5# the test / diffusion / acceptance phase; those are marked with flag
6# 'LDNOTE' (note by laurent.dami AT free.fr)
7
8use Carp;
9use strict;
10use warnings;
312d830b 11use List::Util ();
12use Scalar::Util ();
96449e8e 13
14#======================================================================
15# GLOBALS
16#======================================================================
17
9d0a087f 18our $VERSION = '1.64_01';
7479e27e 19
22f1a437 20# This would confuse some packagers
21#$VERSION = eval $VERSION; # numify for warning-free dev releases
96449e8e 22
23our $AUTOLOAD;
24
25# special operators (-in, -between). May be extended/overridden by user.
26# See section WHERE: BUILTIN SPECIAL OPERATORS below for implementation
27my @BUILTIN_SPECIAL_OPS = (
3a2e1a5e 28 {regex => qr/^(not )?between$/i, handler => '_where_field_BETWEEN'},
29 {regex => qr/^(not )?in$/i, handler => '_where_field_IN'},
96449e8e 30);
31
97a920ef 32# unaryish operators - key maps to handler
59f23b3d 33my @BUILTIN_UNARY_OPS = (
a47b433a 34 # the digits are backcompat stuff
35 { regex => qr/^and (?: \s? \d+ )? $/xi, handler => '_where_op_ANDOR' },
36 { regex => qr/^or (?: \s? \d+ )? $/xi, handler => '_where_op_ANDOR' },
37 { regex => qr/^nest (?: \s? \d+ )? $/xi, handler => '_where_op_NEST' },
38 { regex => qr/^ (?: not \s )? bool $/xi, handler => '_where_op_BOOL' },
59f23b3d 39);
97a920ef 40
96449e8e 41#======================================================================
42# DEBUGGING AND ERROR REPORTING
43#======================================================================
44
45sub _debug {
46 return unless $_[0]->{debug}; shift; # a little faster
47 my $func = (caller(1))[3];
48 warn "[$func] ", @_, "\n";
49}
50
51sub belch (@) {
52 my($func) = (caller(1))[3];
53 carp "[$func] Warning: ", @_;
54}
55
56sub puke (@) {
57 my($func) = (caller(1))[3];
58 croak "[$func] Fatal: ", @_;
59}
60
61
62#======================================================================
63# NEW
64#======================================================================
65
66sub new {
67 my $self = shift;
68 my $class = ref($self) || $self;
69 my %opt = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
70
71 # choose our case by keeping an option around
72 delete $opt{case} if $opt{case} && $opt{case} ne 'lower';
73
74 # default logic for interpreting arrayrefs
ef559da3 75 $opt{logic} = $opt{logic} ? uc $opt{logic} : 'OR';
96449e8e 76
77 # how to return bind vars
78 # LDNOTE: changed nwiger code : why this 'delete' ??
79 # $opt{bindtype} ||= delete($opt{bind_type}) || 'normal';
80 $opt{bindtype} ||= 'normal';
81
82 # default comparison is "=", but can be overridden
83 $opt{cmp} ||= '=';
84
85 # try to recognize which are the 'equality' and 'unequality' ops
86 # (temporary quickfix, should go through a more seasoned API)
2281c758 87 $opt{equality_op} = qr/^(\Q$opt{cmp}\E|is|(is\s+)?like)$/i;
88 $opt{inequality_op} = qr/^(!=|<>|(is\s+)?not(\s+like)?)$/i;
96449e8e 89
90 # SQL booleans
91 $opt{sqltrue} ||= '1=1';
92 $opt{sqlfalse} ||= '0=1';
93
9d48860e 94 # special operators
96449e8e 95 $opt{special_ops} ||= [];
96 push @{$opt{special_ops}}, @BUILTIN_SPECIAL_OPS;
97
9d48860e 98 # unary operators
59f23b3d 99 $opt{unary_ops} ||= [];
100 push @{$opt{unary_ops}}, @BUILTIN_UNARY_OPS;
101
96449e8e 102 return bless \%opt, $class;
103}
104
105
106
107#======================================================================
108# INSERT methods
109#======================================================================
110
111sub insert {
02288357 112 my $self = shift;
113 my $table = $self->_table(shift);
114 my $data = shift || return;
115 my $options = shift;
96449e8e 116
117 my $method = $self->_METHOD_FOR_refkind("_insert", $data);
02288357 118 my ($sql, @bind) = $self->$method($data);
96449e8e 119 $sql = join " ", $self->_sqlcase('insert into'), $table, $sql;
02288357 120
6b1fe79d 121 if (my $ret = $options->{returning}) {
122 $sql .= $self->_insert_returning ($ret);
02288357 123 }
124
96449e8e 125 return wantarray ? ($sql, @bind) : $sql;
126}
127
6b1fe79d 128sub _insert_returning {
129 my ($self, $fields) = @_;
130
131 my $f = $self->_SWITCH_refkind($fields, {
132 ARRAYREF => sub {join ', ', map { $self->_quote($_) } @$fields;},
133 SCALAR => sub {$self->_quote($fields)},
134 SCALARREF => sub {$$fields},
135 });
136 return join (' ', $self->_sqlcase(' returning'), $f);
137}
138
96449e8e 139sub _insert_HASHREF { # explicit list of fields and then values
140 my ($self, $data) = @_;
141
142 my @fields = sort keys %$data;
143
fe3ae272 144 my ($sql, @bind) = $self->_insert_values($data);
96449e8e 145
146 # assemble SQL
147 $_ = $self->_quote($_) foreach @fields;
148 $sql = "( ".join(", ", @fields).") ".$sql;
149
150 return ($sql, @bind);
151}
152
153sub _insert_ARRAYREF { # just generate values(?,?) part (no list of fields)
154 my ($self, $data) = @_;
155
156 # no names (arrayref) so can't generate bindtype
157 $self->{bindtype} ne 'columns'
158 or belch "can't do 'columns' bindtype when called with arrayref";
159
fe3ae272 160 # fold the list of values into a hash of column name - value pairs
161 # (where the column names are artificially generated, and their
162 # lexicographical ordering keep the ordering of the original list)
163 my $i = "a"; # incremented values will be in lexicographical order
164 my $data_in_hash = { map { ($i++ => $_) } @$data };
165
166 return $self->_insert_values($data_in_hash);
167}
168
169sub _insert_ARRAYREFREF { # literal SQL with bind
170 my ($self, $data) = @_;
171
172 my ($sql, @bind) = @${$data};
173 $self->_assert_bindval_matches_bindtype(@bind);
174
175 return ($sql, @bind);
176}
177
178
179sub _insert_SCALARREF { # literal SQL without bind
180 my ($self, $data) = @_;
181
182 return ($$data);
183}
184
185sub _insert_values {
186 my ($self, $data) = @_;
187
96449e8e 188 my (@values, @all_bind);
fe3ae272 189 foreach my $column (sort keys %$data) {
190 my $v = $data->{$column};
96449e8e 191
192 $self->_SWITCH_refkind($v, {
193
9d48860e 194 ARRAYREF => sub {
96449e8e 195 if ($self->{array_datatypes}) { # if array datatype are activated
196 push @values, '?';
fe3ae272 197 push @all_bind, $self->_bindtype($column, $v);
96449e8e 198 }
199 else { # else literal SQL with bind
200 my ($sql, @bind) = @$v;
fe3ae272 201 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 202 push @values, $sql;
203 push @all_bind, @bind;
204 }
205 },
206
207 ARRAYREFREF => sub { # literal SQL with bind
208 my ($sql, @bind) = @${$v};
fe3ae272 209 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 210 push @values, $sql;
211 push @all_bind, @bind;
212 },
213
9d48860e 214 # THINK : anything useful to do with a HASHREF ?
5db47f9f 215 HASHREF => sub { # (nothing, but old SQLA passed it through)
216 #TODO in SQLA >= 2.0 it will die instead
217 belch "HASH ref as bind value in insert is not supported";
218 push @values, '?';
fe3ae272 219 push @all_bind, $self->_bindtype($column, $v);
5db47f9f 220 },
96449e8e 221
222 SCALARREF => sub { # literal SQL without bind
223 push @values, $$v;
224 },
225
226 SCALAR_or_UNDEF => sub {
227 push @values, '?';
fe3ae272 228 push @all_bind, $self->_bindtype($column, $v);
96449e8e 229 },
230
231 });
232
233 }
234
235 my $sql = $self->_sqlcase('values')." ( ".join(", ", @values)." )";
236 return ($sql, @all_bind);
237}
238
239
96449e8e 240
241#======================================================================
242# UPDATE methods
243#======================================================================
244
245
246sub update {
247 my $self = shift;
248 my $table = $self->_table(shift);
249 my $data = shift || return;
250 my $where = shift;
251
252 # first build the 'SET' part of the sql statement
253 my (@set, @all_bind);
254 puke "Unsupported data type specified to \$sql->update"
255 unless ref $data eq 'HASH';
256
257 for my $k (sort keys %$data) {
258 my $v = $data->{$k};
259 my $r = ref $v;
260 my $label = $self->_quote($k);
261
262 $self->_SWITCH_refkind($v, {
9d48860e 263 ARRAYREF => sub {
96449e8e 264 if ($self->{array_datatypes}) { # array datatype
265 push @set, "$label = ?";
266 push @all_bind, $self->_bindtype($k, $v);
267 }
268 else { # literal SQL with bind
269 my ($sql, @bind) = @$v;
fe3ae272 270 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 271 push @set, "$label = $sql";
fe3ae272 272 push @all_bind, @bind;
96449e8e 273 }
274 },
275 ARRAYREFREF => sub { # literal SQL with bind
276 my ($sql, @bind) = @${$v};
fe3ae272 277 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 278 push @set, "$label = $sql";
fe3ae272 279 push @all_bind, @bind;
96449e8e 280 },
281 SCALARREF => sub { # literal SQL without bind
282 push @set, "$label = $$v";
283 },
284 SCALAR_or_UNDEF => sub {
285 push @set, "$label = ?";
286 push @all_bind, $self->_bindtype($k, $v);
287 },
288 });
289 }
290
291 # generate sql
292 my $sql = $self->_sqlcase('update') . " $table " . $self->_sqlcase('set ')
293 . join ', ', @set;
294
295 if ($where) {
296 my($where_sql, @where_bind) = $self->where($where);
297 $sql .= $where_sql;
298 push @all_bind, @where_bind;
299 }
300
301 return wantarray ? ($sql, @all_bind) : $sql;
302}
303
304
305
306
307#======================================================================
308# SELECT
309#======================================================================
310
311
312sub select {
313 my $self = shift;
314 my $table = $self->_table(shift);
315 my $fields = shift || '*';
316 my $where = shift;
317 my $order = shift;
318
319 my($where_sql, @bind) = $self->where($where, $order);
320
321 my $f = (ref $fields eq 'ARRAY') ? join ', ', map { $self->_quote($_) } @$fields
322 : $fields;
9d48860e 323 my $sql = join(' ', $self->_sqlcase('select'), $f,
96449e8e 324 $self->_sqlcase('from'), $table)
325 . $where_sql;
326
9d48860e 327 return wantarray ? ($sql, @bind) : $sql;
96449e8e 328}
329
330#======================================================================
331# DELETE
332#======================================================================
333
334
335sub delete {
336 my $self = shift;
337 my $table = $self->_table(shift);
338 my $where = shift;
339
340
341 my($where_sql, @bind) = $self->where($where);
342 my $sql = $self->_sqlcase('delete from') . " $table" . $where_sql;
343
9d48860e 344 return wantarray ? ($sql, @bind) : $sql;
96449e8e 345}
346
347
348#======================================================================
349# WHERE: entry point
350#======================================================================
351
352
353
354# Finally, a separate routine just to handle WHERE clauses
355sub where {
356 my ($self, $where, $order) = @_;
357
358 # where ?
359 my ($sql, @bind) = $self->_recurse_where($where);
360 $sql = $sql ? $self->_sqlcase(' where ') . "( $sql )" : '';
361
362 # order by?
363 if ($order) {
364 $sql .= $self->_order_by($order);
365 }
366
9d48860e 367 return wantarray ? ($sql, @bind) : $sql;
96449e8e 368}
369
370
371sub _recurse_where {
372 my ($self, $where, $logic) = @_;
373
374 # dispatch on appropriate method according to refkind of $where
375 my $method = $self->_METHOD_FOR_refkind("_where", $where);
311b2151 376
9d48860e 377 my ($sql, @bind) = $self->$method($where, $logic);
311b2151 378
9d48860e 379 # DBIx::Class directly calls _recurse_where in scalar context, so
311b2151 380 # we must implement it, even if not in the official API
9d48860e 381 return wantarray ? ($sql, @bind) : $sql;
96449e8e 382}
383
384
385
386#======================================================================
387# WHERE: top-level ARRAYREF
388#======================================================================
389
390
391sub _where_ARRAYREF {
5e1d09d5 392 my ($self, $where, $logic) = @_;
96449e8e 393
5e1d09d5 394 $logic = uc($logic || $self->{logic});
96449e8e 395 $logic eq 'AND' or $logic eq 'OR' or puke "unknown logic: $logic";
396
397 my @clauses = @$where;
398
96449e8e 399 my (@sql_clauses, @all_bind);
96449e8e 400 # need to use while() so can shift() for pairs
9d48860e 401 while (my $el = shift @clauses) {
96449e8e 402
403 # switch according to kind of $el and get corresponding ($sql, @bind)
404 my ($sql, @bind) = $self->_SWITCH_refkind($el, {
405
406 # skip empty elements, otherwise get invalid trailing AND stuff
407 ARRAYREF => sub {$self->_recurse_where($el) if @$el},
408
474e3335 409 ARRAYREFREF => sub { @{${$el}} if @{${$el}}},
410
96449e8e 411 HASHREF => sub {$self->_recurse_where($el, 'and') if %$el},
412 # LDNOTE : previous SQLA code for hashrefs was creating a dirty
413 # side-effect: the first hashref within an array would change
414 # the global logic to 'AND'. So [ {cond1, cond2}, [cond3, cond4] ]
9d48860e 415 # was interpreted as "(cond1 AND cond2) OR (cond3 AND cond4)",
96449e8e 416 # whereas it should be "(cond1 AND cond2) OR (cond3 OR cond4)".
417
418 SCALARREF => sub { ($$el); },
419
420 SCALAR => sub {# top-level arrayref with scalars, recurse in pairs
421 $self->_recurse_where({$el => shift(@clauses)})},
422
423 UNDEF => sub {puke "not supported : UNDEF in arrayref" },
424 });
425
4b7b6026 426 if ($sql) {
427 push @sql_clauses, $sql;
428 push @all_bind, @bind;
429 }
96449e8e 430 }
431
432 return $self->_join_sql_clauses($logic, \@sql_clauses, \@all_bind);
433}
434
474e3335 435#======================================================================
436# WHERE: top-level ARRAYREFREF
437#======================================================================
96449e8e 438
474e3335 439sub _where_ARRAYREFREF {
440 my ($self, $where) = @_;
441 my ($sql, @bind) = @{${$where}};
442
443 return ($sql, @bind);
444}
96449e8e 445
446#======================================================================
447# WHERE: top-level HASHREF
448#======================================================================
449
450sub _where_HASHREF {
451 my ($self, $where) = @_;
452 my (@sql_clauses, @all_bind);
453
2281c758 454 for my $k (sort keys %$where) {
96449e8e 455 my $v = $where->{$k};
456
2281c758 457 # ($k => $v) is either a special unary op or a regular hashpair
458 my ($sql, @bind) = do {
459 if ($k =~ /^-./) {
460 # put the operator in canonical form
461 my $op = $k;
462 $op =~ s/^-//; # remove initial dash
463 $op =~ s/[_\t ]+/ /g; # underscores and whitespace become single spaces
464 $op =~ s/^\s+|\s+$//g;# remove leading/trailing space
465
466 $self->_debug("Unary OP(-$op) within hashref, recursing...");
467
312d830b 468 my $op_entry = List::Util::first {$op =~ $_->{regex}} @{$self->{unary_ops}};
2281c758 469 if (my $handler = $op_entry->{handler}) {
470 if (not ref $handler) {
471 if ($op =~ s/\s?\d+$//) {
472 belch 'Use of [and|or|nest]_N modifiers is deprecated and will be removed in SQLA v2.0. '
473 . "You probably wanted ...-and => [ -$op => COND1, -$op => COND2 ... ]";
474 }
475 $self->$handler ($op, $v);
476 }
477 elsif (ref $handler eq 'CODE') {
478 $handler->($self, $op, $v);
479 }
480 else {
481 puke "Illegal handler for operator $k - expecting a method name or a coderef";
482 }
483 }
484 else {
485 $self->debug("Generic unary OP: $k - recursing as function");
953d164e 486 my ($sql, @bind) = $self->_where_func_generic ($op, $v);
487 $sql = "($sql)" unless $self->{_nested_func_lhs} eq $k; # top level vs nested
488 ($sql, @bind);
2281c758 489 }
490 }
491 else {
492 my $method = $self->_METHOD_FOR_refkind("_where_hashpair", $v);
493 $self->$method($k, $v);
494 }
495 };
96449e8e 496
497 push @sql_clauses, $sql;
498 push @all_bind, @bind;
499 }
500
501 return $self->_join_sql_clauses('and', \@sql_clauses, \@all_bind);
502}
503
2281c758 504sub _where_func_generic {
505 my ($self, $op, $rhs) = @_;
96449e8e 506
2281c758 507 my ($sql, @bind) = $self->_SWITCH_refkind ($rhs, {
508 SCALAR => sub {
a7661cfc 509 puke "Illegal use of top-level '$op'"
510 unless $self->{_nested_func_lhs};
511
512 return (
513 $self->_convert('?'),
514 $self->_bindtype($self->{_nested_func_lhs}, $rhs)
515 );
2281c758 516 },
517 FALLBACK => sub {
518 $self->_recurse_where ($rhs)
519 },
520 });
96449e8e 521
953d164e 522 $sql = sprintf ('%s %s',
2281c758 523 $self->_sqlcase($op),
953d164e 524 $sql,
2281c758 525 );
96449e8e 526
2281c758 527 return ($sql, @bind);
97a920ef 528}
529
530sub _where_op_ANDOR {
2281c758 531 my ($self, $op, $v) = @_;
97a920ef 532
533 $self->_SWITCH_refkind($v, {
534 ARRAYREF => sub {
535 return $self->_where_ARRAYREF($v, $op);
536 },
537
538 HASHREF => sub {
59f23b3d 539 return ( $op =~ /^or/i )
97a920ef 540 ? $self->_where_ARRAYREF( [ map { $_ => $v->{$_} } ( sort keys %$v ) ], $op )
541 : $self->_where_HASHREF($v);
542 },
543
9d48860e 544 SCALARREF => sub {
97a920ef 545 puke "-$op => \\\$scalar not supported, use -nest => ...";
546 },
547
548 ARRAYREFREF => sub {
549 puke "-$op => \\[..] not supported, use -nest => ...";
550 },
551
552 SCALAR => sub { # permissively interpreted as SQL
553 puke "-$op => 'scalar' not supported, use -nest => \\'scalar'";
554 },
555
556 UNDEF => sub {
557 puke "-$op => undef not supported";
558 },
559 });
560}
561
562sub _where_op_NEST {
9d48860e 563 my ($self, $op, $v) = @_;
97a920ef 564
96449e8e 565 $self->_SWITCH_refkind($v, {
566
96449e8e 567 SCALAR => sub { # permissively interpreted as SQL
01a01e57 568 belch "literal SQL should be -nest => \\'scalar' "
569 . "instead of -nest => 'scalar' ";
9d48860e 570 return ($v);
96449e8e 571 },
572
573 UNDEF => sub {
574 puke "-$op => undef not supported";
575 },
e9501094 576
577 FALLBACK => sub {
578 $self->_recurse_where ($v);
579 },
580
96449e8e 581 });
582}
583
584
97a920ef 585sub _where_op_BOOL {
9d48860e 586 my ($self, $op, $v) = @_;
97a920ef 587
9d48860e 588 my ( $prefix, $suffix ) = ( $op =~ /\bnot\b/i )
589 ? ( '(NOT ', ')' )
ef03f1bc 590 : ( '', '' );
ef03f1bc 591
2281c758 592 my ($sql, @bind) = do {
593 $self->_SWITCH_refkind($v, {
594 SCALAR => sub { # interpreted as SQL column
595 $self->_convert($self->_quote($v));
596 },
ef03f1bc 597
2281c758 598 UNDEF => sub {
599 puke "-$op => undef not supported";
600 },
97a920ef 601
2281c758 602 FALLBACK => sub {
603 $self->_recurse_where ($v);
604 },
605 });
606 };
ef03f1bc 607
2281c758 608 return (
609 join ('', $prefix, $sql, $suffix),
610 @bind,
611 );
97a920ef 612}
613
614
96449e8e 615sub _where_hashpair_ARRAYREF {
616 my ($self, $k, $v) = @_;
617
618 if( @$v ) {
619 my @v = @$v; # need copy because of shift below
620 $self->_debug("ARRAY($k) means distribute over elements");
621
622 # put apart first element if it is an operator (-and, -or)
e3cecb45 623 my $op = (
624 (defined $v[0] && $v[0] =~ /^ - (?: AND|OR ) $/ix)
625 ? shift @v
626 : ''
04d940de 627 );
96449e8e 628 my @distributed = map { {$k => $_} } @v;
04d940de 629
630 if ($op) {
631 $self->_debug("OP($op) reinjected into the distributed array");
632 unshift @distributed, $op;
633 }
634
f67591bf 635 my $logic = $op ? substr($op, 1) : '';
96449e8e 636
f67591bf 637 return $self->_recurse_where(\@distributed, $logic);
9d48860e 638 }
96449e8e 639 else {
640 # LDNOTE : not sure of this one. What does "distribute over nothing" mean?
641 $self->_debug("empty ARRAY($k) means 0=1");
642 return ($self->{sqlfalse});
643 }
644}
645
646sub _where_hashpair_HASHREF {
eb49170d 647 my ($self, $k, $v, $logic) = @_;
648 $logic ||= 'and';
96449e8e 649
a7661cfc 650 local $self->{_nested_func_lhs} = $self->{_nested_func_lhs};
a7661cfc 651
eb49170d 652 my ($all_sql, @all_bind);
96449e8e 653
a47b433a 654 for my $orig_op (sort keys %$v) {
655 my $val = $v->{$orig_op};
96449e8e 656
657 # put the operator in canonical form
a47b433a 658 my $op = $orig_op;
659 $op =~ s/^-//; # remove initial dash
660 $op =~ s/[_\t ]+/ /g; # underscores and whitespace become single spaces
661 $op =~ s/^\s+|\s+$//g;# remove leading/trailing space
96449e8e 662
663 my ($sql, @bind);
664
2281c758 665 # CASE: col-value logic modifiers
666 if ( $orig_op =~ /^ \- (and|or) $/xi ) {
667 ($sql, @bind) = $self->_where_hashpair_HASHREF($k, $val, $1);
668 }
96449e8e 669 # CASE: special operators like -in or -between
312d830b 670 elsif ( my $special_op = List::Util::first {$op =~ $_->{regex}} @{$self->{special_ops}} ) {
3a2e1a5e 671 my $handler = $special_op->{handler};
672 if (! $handler) {
a47b433a 673 puke "No handler supplied for special operator $orig_op";
3a2e1a5e 674 }
675 elsif (not ref $handler) {
676 ($sql, @bind) = $self->$handler ($k, $op, $val);
677 }
678 elsif (ref $handler eq 'CODE') {
679 ($sql, @bind) = $handler->($self, $k, $op, $val);
680 }
681 else {
a47b433a 682 puke "Illegal handler for special operator $orig_op - expecting a method name or a coderef";
3a2e1a5e 683 }
96449e8e 684 }
96449e8e 685 else {
cf838930 686 $self->_SWITCH_refkind($val, {
687
688 ARRAYREF => sub { # CASE: col => {op => \@vals}
689 ($sql, @bind) = $self->_where_field_op_ARRAYREF($k, $op, $val);
690 },
691
fe3ae272 692 ARRAYREFREF => sub { # CASE: col => {op => \[$sql, @bind]} (literal SQL with bind)
b3be7bd0 693 my ($sub_sql, @sub_bind) = @$$val;
fe3ae272 694 $self->_assert_bindval_matches_bindtype(@sub_bind);
b3be7bd0 695 $sql = join ' ', $self->_convert($self->_quote($k)),
696 $self->_sqlcase($op),
697 $sub_sql;
fe3ae272 698 @bind = @sub_bind;
b3be7bd0 699 },
700
cf838930 701 UNDEF => sub { # CASE: col => {op => undef} : sql "IS (NOT)? NULL"
702 my $is = ($op =~ $self->{equality_op}) ? 'is' :
703 ($op =~ $self->{inequality_op}) ? 'is not' :
a47b433a 704 puke "unexpected operator '$orig_op' with undef operand";
cf838930 705 $sql = $self->_quote($k) . $self->_sqlcase(" $is null");
706 },
a47b433a 707
2281c758 708 FALLBACK => sub { # CASE: col => {op/func => $stuff}
07936978 709
953d164e 710 # retain for proper column type bind
711 $self->{_nested_func_lhs} ||= $k;
07936978 712
2281c758 713 ($sql, @bind) = $self->_where_func_generic ($op, $val);
953d164e 714
715 $sql = join (' ',
716 $self->_convert($self->_quote($k)),
717 $self->{_nested_func_lhs} eq $k ? $sql : "($sql)", # top level vs nested
718 );
cf838930 719 },
720 });
96449e8e 721 }
722
eb49170d 723 ($all_sql) = (defined $all_sql and $all_sql) ? $self->_join_sql_clauses($logic, [$all_sql, $sql], []) : $sql;
96449e8e 724 push @all_bind, @bind;
725 }
eb49170d 726 return ($all_sql, @all_bind);
96449e8e 727}
728
729
730
731sub _where_field_op_ARRAYREF {
732 my ($self, $k, $op, $vals) = @_;
733
ce261791 734 my @vals = @$vals; #always work on a copy
735
736 if(@vals) {
bd6a65ca 737 $self->_debug(sprintf '%s means multiple elements: [ %s ]',
738 $vals,
739 join (', ', map { defined $_ ? "'$_'" : 'NULL' } @vals ),
740 );
96449e8e 741
4030915f 742 # see if the first element is an -and/-or op
743 my $logic;
bd6a65ca 744 if (defined $vals[0] && $vals[0] =~ /^ - ( AND|OR ) $/ix) {
4030915f 745 $logic = uc $1;
ce261791 746 shift @vals;
4030915f 747 }
748
ce261791 749 # distribute $op over each remaining member of @vals, append logic if exists
750 return $self->_recurse_where([map { {$k => {$op, $_}} } @vals], $logic);
4030915f 751
9d48860e 752 # LDNOTE : had planned to change the distribution logic when
753 # $op =~ $self->{inequality_op}, because of Morgan laws :
96449e8e 754 # with {field => {'!=' => [22, 33]}}, it would be ridiculous to generate
9d48860e 755 # WHERE field != 22 OR field != 33 : the user probably means
96449e8e 756 # WHERE field != 22 AND field != 33.
4030915f 757 # To do this, replace the above to roughly :
f2d5020d 758 # my $logic = ($op =~ $self->{inequality_op}) ? 'AND' : 'OR';
ce261791 759 # return $self->_recurse_where([map { {$k => {$op, $_}} } @vals], $logic);
96449e8e 760
9d48860e 761 }
96449e8e 762 else {
9d48860e 763 # try to DWIM on equality operators
96449e8e 764 # LDNOTE : not 100% sure this is the correct thing to do ...
765 return ($self->{sqlfalse}) if $op =~ $self->{equality_op};
766 return ($self->{sqltrue}) if $op =~ $self->{inequality_op};
767
768 # otherwise
769 puke "operator '$op' applied on an empty array (field '$k')";
770 }
771}
772
773
774sub _where_hashpair_SCALARREF {
775 my ($self, $k, $v) = @_;
776 $self->_debug("SCALAR($k) means literal SQL: $$v");
777 my $sql = $self->_quote($k) . " " . $$v;
778 return ($sql);
779}
780
fe3ae272 781# literal SQL with bind
96449e8e 782sub _where_hashpair_ARRAYREFREF {
783 my ($self, $k, $v) = @_;
784 $self->_debug("REF($k) means literal SQL: @${$v}");
785 my ($sql, @bind) = @${$v};
fe3ae272 786 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 787 $sql = $self->_quote($k) . " " . $sql;
96449e8e 788 return ($sql, @bind );
789}
790
fe3ae272 791# literal SQL without bind
96449e8e 792sub _where_hashpair_SCALAR {
793 my ($self, $k, $v) = @_;
794 $self->_debug("NOREF($k) means simple key=val: $k $self->{cmp} $v");
9d48860e 795 my $sql = join ' ', $self->_convert($self->_quote($k)),
796 $self->_sqlcase($self->{cmp}),
96449e8e 797 $self->_convert('?');
798 my @bind = $self->_bindtype($k, $v);
799 return ( $sql, @bind);
800}
801
802
803sub _where_hashpair_UNDEF {
804 my ($self, $k, $v) = @_;
805 $self->_debug("UNDEF($k) means IS NULL");
806 my $sql = $self->_quote($k) . $self->_sqlcase(' is null');
807 return ($sql);
808}
809
810#======================================================================
811# WHERE: TOP-LEVEL OTHERS (SCALARREF, SCALAR, UNDEF)
812#======================================================================
813
814
815sub _where_SCALARREF {
816 my ($self, $where) = @_;
817
818 # literal sql
819 $self->_debug("SCALAR(*top) means literal SQL: $$where");
820 return ($$where);
821}
822
823
824sub _where_SCALAR {
825 my ($self, $where) = @_;
826
827 # literal sql
828 $self->_debug("NOREF(*top) means literal SQL: $where");
829 return ($where);
830}
831
832
833sub _where_UNDEF {
834 my ($self) = @_;
835 return ();
836}
837
838
839#======================================================================
840# WHERE: BUILTIN SPECIAL OPERATORS (-in, -between)
841#======================================================================
842
843
844sub _where_field_BETWEEN {
845 my ($self, $k, $op, $vals) = @_;
846
4d8b3dc4 847 my ($label, $and, $placeholder);
cf02fc47 848 $label = $self->_convert($self->_quote($k));
849 $and = ' ' . $self->_sqlcase('and') . ' ';
850 $placeholder = $self->_convert('?');
96449e8e 851 $op = $self->_sqlcase($op);
852
4d8b3dc4 853 my ($clause, @bind) = $self->_SWITCH_refkind($vals, {
854 ARRAYREFREF => sub {
855 return @$$vals;
856 },
857 SCALARREF => sub {
858 return $$vals;
859 },
860 ARRAYREF => sub {
861 puke "special op 'between' accepts an arrayref with exactly two values"
862 if @$vals != 2;
863
864 my (@all_sql, @all_bind);
865 foreach my $val (@$vals) {
866 my ($sql, @bind) = $self->_SWITCH_refkind($val, {
867 SCALAR => sub {
868 return ($placeholder, ($val));
869 },
870 SCALARREF => sub {
871 return ($self->_convert($$val), ());
872 },
873 ARRAYREFREF => sub {
874 my ($sql, @bind) = @$$val;
875 return ($self->_convert($sql), @bind);
876 },
877 });
878 push @all_sql, $sql;
879 push @all_bind, @bind;
880 }
881
882 return (
883 (join $and, @all_sql),
884 $self->_bindtype($k, @all_bind),
885 );
886 },
887 FALLBACK => sub {
888 puke "special op 'between' accepts an arrayref with two values, or a single literal scalarref/arrayref-ref";
889 },
890 });
cf02fc47 891
cf02fc47 892 my $sql = "( $label $op $clause )";
96449e8e 893 return ($sql, @bind)
894}
895
896
897sub _where_field_IN {
898 my ($self, $k, $op, $vals) = @_;
899
900 # backwards compatibility : if scalar, force into an arrayref
901 $vals = [$vals] if defined $vals && ! ref $vals;
902
96449e8e 903 my ($label) = $self->_convert($self->_quote($k));
904 my ($placeholder) = $self->_convert('?');
96449e8e 905 $op = $self->_sqlcase($op);
906
8a0d798a 907 my ($sql, @bind) = $self->_SWITCH_refkind($vals, {
908 ARRAYREF => sub { # list of choices
909 if (@$vals) { # nonempty list
910 my $placeholders = join ", ", (($placeholder) x @$vals);
911 my $sql = "$label $op ( $placeholders )";
912 my @bind = $self->_bindtype($k, @$vals);
96449e8e 913
8a0d798a 914 return ($sql, @bind);
915 }
916 else { # empty list : some databases won't understand "IN ()", so DWIM
917 my $sql = ($op =~ /\bnot\b/i) ? $self->{sqltrue} : $self->{sqlfalse};
918 return ($sql);
919 }
920 },
921
4a1f01a3 922 SCALARREF => sub { # literal SQL
923 my $sql = $self->_open_outer_paren ($$vals);
924 return ("$label $op ( $sql )");
925 },
8a0d798a 926 ARRAYREFREF => sub { # literal SQL with bind
927 my ($sql, @bind) = @$$vals;
fe3ae272 928 $self->_assert_bindval_matches_bindtype(@bind);
4a1f01a3 929 $sql = $self->_open_outer_paren ($sql);
8a0d798a 930 return ("$label $op ( $sql )", @bind);
931 },
932
933 FALLBACK => sub {
4a1f01a3 934 puke "special op 'in' requires an arrayref (or scalarref/arrayref-ref)";
8a0d798a 935 },
936 });
937
938 return ($sql, @bind);
96449e8e 939}
940
4a1f01a3 941# Some databases (SQLite) treat col IN (1, 2) different from
942# col IN ( (1, 2) ). Use this to strip all outer parens while
943# adding them back in the corresponding method
944sub _open_outer_paren {
945 my ($self, $sql) = @_;
171a709f 946 $sql = $1 while $sql =~ /^ \s* \( (.*) \) \s* $/xs;
4a1f01a3 947 return $sql;
948}
949
96449e8e 950
96449e8e 951#======================================================================
952# ORDER BY
953#======================================================================
954
955sub _order_by {
956 my ($self, $arg) = @_;
957
f267b646 958 my (@sql, @bind);
959 for my $c ($self->_order_by_chunks ($arg) ) {
960 $self->_SWITCH_refkind ($c, {
961 SCALAR => sub { push @sql, $c },
962 ARRAYREF => sub { push @sql, shift @$c; push @bind, @$c },
963 });
964 }
965
966 my $sql = @sql
967 ? sprintf ('%s %s',
968 $self->_sqlcase(' order by'),
969 join (', ', @sql)
970 )
971 : ''
972 ;
973
974 return wantarray ? ($sql, @bind) : $sql;
975}
976
977sub _order_by_chunks {
978 my ($self, $arg) = @_;
979
980 return $self->_SWITCH_refkind($arg, {
96449e8e 981
982 ARRAYREF => sub {
f267b646 983 map { $self->_order_by_chunks ($_ ) } @$arg;
96449e8e 984 },
985
f267b646 986 ARRAYREFREF => sub { [ @$$arg ] },
987
96449e8e 988 SCALAR => sub {$self->_quote($arg)},
f267b646 989
990 UNDEF => sub {return () },
991
96449e8e 992 SCALARREF => sub {$$arg}, # literal SQL, no quoting
96449e8e 993
f267b646 994 HASHREF => sub {
995 # get first pair in hash
996 my ($key, $val) = each %$arg;
96449e8e 997
f267b646 998 return () unless $key;
96449e8e 999
f267b646 1000 if ( (keys %$arg) > 1 or not $key =~ /^-(desc|asc)/i ) {
1001 puke "hash passed to _order_by must have exactly one key (-desc or -asc)";
1002 }
96449e8e 1003
f267b646 1004 my $direction = $1;
96449e8e 1005
e9bd3547 1006 my @ret;
f267b646 1007 for my $c ($self->_order_by_chunks ($val)) {
e9bd3547 1008 my ($sql, @bind);
96449e8e 1009
f267b646 1010 $self->_SWITCH_refkind ($c, {
1011 SCALAR => sub {
e9bd3547 1012 $sql = $c;
f267b646 1013 },
1014 ARRAYREF => sub {
e9bd3547 1015 ($sql, @bind) = @$c;
f267b646 1016 },
1017 });
96449e8e 1018
e9bd3547 1019 $sql = $sql . ' ' . $self->_sqlcase($direction);
96449e8e 1020
e9bd3547 1021 push @ret, [ $sql, @bind];
1022 }
96449e8e 1023
e9bd3547 1024 return @ret;
f267b646 1025 },
1026 });
96449e8e 1027}
1028
1029
96449e8e 1030#======================================================================
1031# DATASOURCE (FOR NOW, JUST PLAIN TABLE OR LIST OF TABLES)
1032#======================================================================
1033
1034sub _table {
1035 my $self = shift;
1036 my $from = shift;
1037 $self->_SWITCH_refkind($from, {
1038 ARRAYREF => sub {join ', ', map { $self->_quote($_) } @$from;},
1039 SCALAR => sub {$self->_quote($from)},
1040 SCALARREF => sub {$$from},
1041 ARRAYREFREF => sub {join ', ', @$from;},
1042 });
1043}
1044
1045
1046#======================================================================
1047# UTILITY FUNCTIONS
1048#======================================================================
1049
1050sub _quote {
1051 my $self = shift;
1052 my $label = shift;
1053
1054 $label or puke "can't quote an empty label";
1055
1056 # left and right quote characters
1057 my ($ql, $qr, @other) = $self->_SWITCH_refkind($self->{quote_char}, {
1058 SCALAR => sub {($self->{quote_char}, $self->{quote_char})},
1059 ARRAYREF => sub {@{$self->{quote_char}}},
1060 UNDEF => sub {()},
1061 });
1062 not @other
1063 or puke "quote_char must be an arrayref of 2 values";
1064
1065 # no quoting if no quoting chars
1066 $ql or return $label;
1067
1068 # no quoting for literal SQL
1069 return $$label if ref($label) eq 'SCALAR';
1070
1071 # separate table / column (if applicable)
1072 my $sep = $self->{name_sep} || '';
1073 my @to_quote = $sep ? split /\Q$sep\E/, $label : ($label);
1074
1075 # do the quoting, except for "*" or for `table`.*
1076 my @quoted = map { $_ eq '*' ? $_: $ql.$_.$qr} @to_quote;
1077
9d48860e 1078 # reassemble and return.
96449e8e 1079 return join $sep, @quoted;
1080}
1081
1082
1083# Conversion, if applicable
1084sub _convert ($) {
1085 my ($self, $arg) = @_;
1086
1087# LDNOTE : modified the previous implementation below because
1088# it was not consistent : the first "return" is always an array,
1089# the second "return" is context-dependent. Anyway, _convert
9d48860e 1090# seems always used with just a single argument, so make it a
96449e8e 1091# scalar function.
1092# return @_ unless $self->{convert};
1093# my $conv = $self->_sqlcase($self->{convert});
1094# my @ret = map { $conv.'('.$_.')' } @_;
1095# return wantarray ? @ret : $ret[0];
1096 if ($self->{convert}) {
1097 my $conv = $self->_sqlcase($self->{convert});
1098 $arg = $conv.'('.$arg.')';
1099 }
1100 return $arg;
1101}
1102
1103# And bindtype
1104sub _bindtype (@) {
1105 my $self = shift;
1106 my($col, @vals) = @_;
1107
9d48860e 1108 #LDNOTE : changed original implementation below because it did not make
96449e8e 1109 # sense when bindtype eq 'columns' and @vals > 1.
1110# return $self->{bindtype} eq 'columns' ? [ $col, @vals ] : @vals;
1111
1112 return $self->{bindtype} eq 'columns' ? map {[$col, $_]} @vals : @vals;
1113}
1114
fe3ae272 1115# Dies if any element of @bind is not in [colname => value] format
1116# if bindtype is 'columns'.
1117sub _assert_bindval_matches_bindtype {
1118 my ($self, @bind) = @_;
1119
1120 if ($self->{bindtype} eq 'columns') {
1121 foreach my $val (@bind) {
1122 if (!defined $val || ref($val) ne 'ARRAY' || @$val != 2) {
1123 die "bindtype 'columns' selected, you need to pass: [column_name => bind_value]"
1124 }
1125 }
1126 }
1127}
1128
96449e8e 1129sub _join_sql_clauses {
1130 my ($self, $logic, $clauses_aref, $bind_aref) = @_;
1131
1132 if (@$clauses_aref > 1) {
1133 my $join = " " . $self->_sqlcase($logic) . " ";
1134 my $sql = '( ' . join($join, @$clauses_aref) . ' )';
1135 return ($sql, @$bind_aref);
1136 }
1137 elsif (@$clauses_aref) {
1138 return ($clauses_aref->[0], @$bind_aref); # no parentheses
1139 }
1140 else {
1141 return (); # if no SQL, ignore @$bind_aref
1142 }
1143}
1144
1145
1146# Fix SQL case, if so requested
1147sub _sqlcase {
1148 my $self = shift;
1149
1150 # LDNOTE: if $self->{case} is true, then it contains 'lower', so we
1151 # don't touch the argument ... crooked logic, but let's not change it!
1152 return $self->{case} ? $_[0] : uc($_[0]);
1153}
1154
1155
1156#======================================================================
1157# DISPATCHING FROM REFKIND
1158#======================================================================
1159
1160sub _refkind {
1161 my ($self, $data) = @_;
1162 my $suffix = '';
1163 my $ref;
90aab162 1164 my $n_steps = 0;
96449e8e 1165
96449e8e 1166 while (1) {
90aab162 1167 # blessed objects are treated like scalars
312d830b 1168 $ref = (Scalar::Util::blessed $data) ? '' : ref $data;
90aab162 1169 $n_steps += 1 if $ref;
1170 last if $ref ne 'REF';
96449e8e 1171 $data = $$data;
1172 }
1173
90aab162 1174 my $base = $ref || (defined $data ? 'SCALAR' : 'UNDEF');
1175
1176 return $base . ('REF' x $n_steps);
96449e8e 1177}
1178
90aab162 1179
1180
96449e8e 1181sub _try_refkind {
1182 my ($self, $data) = @_;
1183 my @try = ($self->_refkind($data));
1184 push @try, 'SCALAR_or_UNDEF' if $try[0] eq 'SCALAR' || $try[0] eq 'UNDEF';
1185 push @try, 'FALLBACK';
1186 return @try;
1187}
1188
1189sub _METHOD_FOR_refkind {
1190 my ($self, $meth_prefix, $data) = @_;
f39eaa60 1191
1192 my $method;
1193 for ($self->_try_refkind($data)) {
1194 $method = $self->can($meth_prefix."_".$_)
1195 and last;
1196 }
1197
1198 return $method || puke "cannot dispatch on '$meth_prefix' for ".$self->_refkind($data);
96449e8e 1199}
1200
1201
1202sub _SWITCH_refkind {
1203 my ($self, $data, $dispatch_table) = @_;
1204
f39eaa60 1205 my $coderef;
1206 for ($self->_try_refkind($data)) {
1207 $coderef = $dispatch_table->{$_}
1208 and last;
1209 }
1210
1211 puke "no dispatch entry for ".$self->_refkind($data)
1212 unless $coderef;
1213
96449e8e 1214 $coderef->();
1215}
1216
1217
1218
1219
1220#======================================================================
1221# VALUES, GENERATE, AUTOLOAD
1222#======================================================================
1223
1224# LDNOTE: original code from nwiger, didn't touch code in that section
1225# I feel the AUTOLOAD stuff should not be the default, it should
1226# only be activated on explicit demand by user.
1227
1228sub values {
1229 my $self = shift;
1230 my $data = shift || return;
1231 puke "Argument to ", __PACKAGE__, "->values must be a \\%hash"
1232 unless ref $data eq 'HASH';
bab725ce 1233
1234 my @all_bind;
1235 foreach my $k ( sort keys %$data ) {
1236 my $v = $data->{$k};
1237 $self->_SWITCH_refkind($v, {
9d48860e 1238 ARRAYREF => sub {
bab725ce 1239 if ($self->{array_datatypes}) { # array datatype
1240 push @all_bind, $self->_bindtype($k, $v);
1241 }
1242 else { # literal SQL with bind
1243 my ($sql, @bind) = @$v;
1244 $self->_assert_bindval_matches_bindtype(@bind);
1245 push @all_bind, @bind;
1246 }
1247 },
1248 ARRAYREFREF => sub { # literal SQL with bind
1249 my ($sql, @bind) = @${$v};
1250 $self->_assert_bindval_matches_bindtype(@bind);
1251 push @all_bind, @bind;
1252 },
1253 SCALARREF => sub { # literal SQL without bind
1254 },
1255 SCALAR_or_UNDEF => sub {
1256 push @all_bind, $self->_bindtype($k, $v);
1257 },
1258 });
1259 }
1260
1261 return @all_bind;
96449e8e 1262}
1263
1264sub generate {
1265 my $self = shift;
1266
1267 my(@sql, @sqlq, @sqlv);
1268
1269 for (@_) {
1270 my $ref = ref $_;
1271 if ($ref eq 'HASH') {
1272 for my $k (sort keys %$_) {
1273 my $v = $_->{$k};
1274 my $r = ref $v;
1275 my $label = $self->_quote($k);
1276 if ($r eq 'ARRAY') {
fe3ae272 1277 # literal SQL with bind
1278 my ($sql, @bind) = @$v;
1279 $self->_assert_bindval_matches_bindtype(@bind);
96449e8e 1280 push @sqlq, "$label = $sql";
fe3ae272 1281 push @sqlv, @bind;
96449e8e 1282 } elsif ($r eq 'SCALAR') {
fe3ae272 1283 # literal SQL without bind
96449e8e 1284 push @sqlq, "$label = $$v";
9d48860e 1285 } else {
96449e8e 1286 push @sqlq, "$label = ?";
1287 push @sqlv, $self->_bindtype($k, $v);
1288 }
1289 }
1290 push @sql, $self->_sqlcase('set'), join ', ', @sqlq;
1291 } elsif ($ref eq 'ARRAY') {
1292 # unlike insert(), assume these are ONLY the column names, i.e. for SQL
1293 for my $v (@$_) {
1294 my $r = ref $v;
fe3ae272 1295 if ($r eq 'ARRAY') { # literal SQL with bind
1296 my ($sql, @bind) = @$v;
1297 $self->_assert_bindval_matches_bindtype(@bind);
1298 push @sqlq, $sql;
1299 push @sqlv, @bind;
1300 } elsif ($r eq 'SCALAR') { # literal SQL without bind
96449e8e 1301 # embedded literal SQL
1302 push @sqlq, $$v;
9d48860e 1303 } else {
96449e8e 1304 push @sqlq, '?';
1305 push @sqlv, $v;
1306 }
1307 }
1308 push @sql, '(' . join(', ', @sqlq) . ')';
1309 } elsif ($ref eq 'SCALAR') {
1310 # literal SQL
1311 push @sql, $$_;
1312 } else {
1313 # strings get case twiddled
1314 push @sql, $self->_sqlcase($_);
1315 }
1316 }
1317
1318 my $sql = join ' ', @sql;
1319
1320 # this is pretty tricky
1321 # if ask for an array, return ($stmt, @bind)
1322 # otherwise, s/?/shift @sqlv/ to put it inline
1323 if (wantarray) {
1324 return ($sql, @sqlv);
1325 } else {
1326 1 while $sql =~ s/\?/my $d = shift(@sqlv);
1327 ref $d ? $d->[1] : $d/e;
1328 return $sql;
1329 }
1330}
1331
1332
1333sub DESTROY { 1 }
1334
1335sub AUTOLOAD {
1336 # This allows us to check for a local, then _form, attr
1337 my $self = shift;
1338 my($name) = $AUTOLOAD =~ /.*::(.+)/;
1339 return $self->generate($name, @_);
1340}
1341
13421;
1343
1344
1345
1346__END__
32eab2da 1347
1348=head1 NAME
1349
1350SQL::Abstract - Generate SQL from Perl data structures
1351
1352=head1 SYNOPSIS
1353
1354 use SQL::Abstract;
1355
1356 my $sql = SQL::Abstract->new;
1357
1358 my($stmt, @bind) = $sql->select($table, \@fields, \%where, \@order);
1359
1360 my($stmt, @bind) = $sql->insert($table, \%fieldvals || \@values);
1361
1362 my($stmt, @bind) = $sql->update($table, \%fieldvals, \%where);
1363
1364 my($stmt, @bind) = $sql->delete($table, \%where);
1365
1366 # Then, use these in your DBI statements
1367 my $sth = $dbh->prepare($stmt);
1368 $sth->execute(@bind);
1369
1370 # Just generate the WHERE clause
abe72f94 1371 my($stmt, @bind) = $sql->where(\%where, \@order);
32eab2da 1372
1373 # Return values in the same order, for hashed queries
1374 # See PERFORMANCE section for more details
1375 my @bind = $sql->values(\%fieldvals);
1376
1377=head1 DESCRIPTION
1378
1379This module was inspired by the excellent L<DBIx::Abstract>.
1380However, in using that module I found that what I really wanted
1381to do was generate SQL, but still retain complete control over my
1382statement handles and use the DBI interface. So, I set out to
1383create an abstract SQL generation module.
1384
1385While based on the concepts used by L<DBIx::Abstract>, there are
1386several important differences, especially when it comes to WHERE
1387clauses. I have modified the concepts used to make the SQL easier
1388to generate from Perl data structures and, IMO, more intuitive.
1389The underlying idea is for this module to do what you mean, based
1390on the data structures you provide it. The big advantage is that
1391you don't have to modify your code every time your data changes,
1392as this module figures it out.
1393
1394To begin with, an SQL INSERT is as easy as just specifying a hash
1395of C<key=value> pairs:
1396
1397 my %data = (
1398 name => 'Jimbo Bobson',
1399 phone => '123-456-7890',
1400 address => '42 Sister Lane',
1401 city => 'St. Louis',
1402 state => 'Louisiana',
1403 );
1404
1405The SQL can then be generated with this:
1406
1407 my($stmt, @bind) = $sql->insert('people', \%data);
1408
1409Which would give you something like this:
1410
1411 $stmt = "INSERT INTO people
1412 (address, city, name, phone, state)
1413 VALUES (?, ?, ?, ?, ?)";
1414 @bind = ('42 Sister Lane', 'St. Louis', 'Jimbo Bobson',
1415 '123-456-7890', 'Louisiana');
1416
1417These are then used directly in your DBI code:
1418
1419 my $sth = $dbh->prepare($stmt);
1420 $sth->execute(@bind);
1421
96449e8e 1422=head2 Inserting and Updating Arrays
1423
1424If your database has array types (like for example Postgres),
1425activate the special option C<< array_datatypes => 1 >>
9d48860e 1426when creating the C<SQL::Abstract> object.
96449e8e 1427Then you may use an arrayref to insert and update database array types:
1428
1429 my $sql = SQL::Abstract->new(array_datatypes => 1);
1430 my %data = (
1431 planets => [qw/Mercury Venus Earth Mars/]
1432 );
9d48860e 1433
96449e8e 1434 my($stmt, @bind) = $sql->insert('solar_system', \%data);
1435
1436This results in:
1437
1438 $stmt = "INSERT INTO solar_system (planets) VALUES (?)"
1439
1440 @bind = (['Mercury', 'Venus', 'Earth', 'Mars']);
1441
1442
1443=head2 Inserting and Updating SQL
1444
1445In order to apply SQL functions to elements of your C<%data> you may
1446specify a reference to an arrayref for the given hash value. For example,
1447if you need to execute the Oracle C<to_date> function on a value, you can
1448say something like this:
32eab2da 1449
1450 my %data = (
1451 name => 'Bill',
96449e8e 1452 date_entered => \["to_date(?,'MM/DD/YYYY')", "03/02/2003"],
9d48860e 1453 );
32eab2da 1454
1455The first value in the array is the actual SQL. Any other values are
1456optional and would be included in the bind values array. This gives
1457you:
1458
1459 my($stmt, @bind) = $sql->insert('people', \%data);
1460
9d48860e 1461 $stmt = "INSERT INTO people (name, date_entered)
32eab2da 1462 VALUES (?, to_date(?,'MM/DD/YYYY'))";
1463 @bind = ('Bill', '03/02/2003');
1464
1465An UPDATE is just as easy, all you change is the name of the function:
1466
1467 my($stmt, @bind) = $sql->update('people', \%data);
1468
1469Notice that your C<%data> isn't touched; the module will generate
1470the appropriately quirky SQL for you automatically. Usually you'll
1471want to specify a WHERE clause for your UPDATE, though, which is
1472where handling C<%where> hashes comes in handy...
1473
96449e8e 1474=head2 Complex where statements
1475
32eab2da 1476This module can generate pretty complicated WHERE statements
1477easily. For example, simple C<key=value> pairs are taken to mean
1478equality, and if you want to see if a field is within a set
1479of values, you can use an arrayref. Let's say we wanted to
1480SELECT some data based on this criteria:
1481
1482 my %where = (
1483 requestor => 'inna',
1484 worker => ['nwiger', 'rcwe', 'sfz'],
1485 status => { '!=', 'completed' }
1486 );
1487
1488 my($stmt, @bind) = $sql->select('tickets', '*', \%where);
1489
1490The above would give you something like this:
1491
1492 $stmt = "SELECT * FROM tickets WHERE
1493 ( requestor = ? ) AND ( status != ? )
1494 AND ( worker = ? OR worker = ? OR worker = ? )";
1495 @bind = ('inna', 'completed', 'nwiger', 'rcwe', 'sfz');
1496
1497Which you could then use in DBI code like so:
1498
1499 my $sth = $dbh->prepare($stmt);
1500 $sth->execute(@bind);
1501
1502Easy, eh?
1503
1504=head1 FUNCTIONS
1505
1506The functions are simple. There's one for each major SQL operation,
1507and a constructor you use first. The arguments are specified in a
9d48860e 1508similar order to each function (table, then fields, then a where
32eab2da 1509clause) to try and simplify things.
1510
83cab70b 1511
83cab70b 1512
32eab2da 1513
1514=head2 new(option => 'value')
1515
1516The C<new()> function takes a list of options and values, and returns
1517a new B<SQL::Abstract> object which can then be used to generate SQL
1518through the methods below. The options accepted are:
1519
1520=over
1521
1522=item case
1523
1524If set to 'lower', then SQL will be generated in all lowercase. By
1525default SQL is generated in "textbook" case meaning something like:
1526
1527 SELECT a_field FROM a_table WHERE some_field LIKE '%someval%'
1528
96449e8e 1529Any setting other than 'lower' is ignored.
1530
32eab2da 1531=item cmp
1532
1533This determines what the default comparison operator is. By default
1534it is C<=>, meaning that a hash like this:
1535
1536 %where = (name => 'nwiger', email => 'nate@wiger.org');
1537
1538Will generate SQL like this:
1539
1540 WHERE name = 'nwiger' AND email = 'nate@wiger.org'
1541
1542However, you may want loose comparisons by default, so if you set
1543C<cmp> to C<like> you would get SQL such as:
1544
1545 WHERE name like 'nwiger' AND email like 'nate@wiger.org'
1546
1547You can also override the comparsion on an individual basis - see
1548the huge section on L</"WHERE CLAUSES"> at the bottom.
1549
96449e8e 1550=item sqltrue, sqlfalse
1551
1552Expressions for inserting boolean values within SQL statements.
6e0c6552 1553By default these are C<1=1> and C<1=0>. They are used
1554by the special operators C<-in> and C<-not_in> for generating
1555correct SQL even when the argument is an empty array (see below).
96449e8e 1556
32eab2da 1557=item logic
1558
1559This determines the default logical operator for multiple WHERE
7cac25e6 1560statements in arrays or hashes. If absent, the default logic is "or"
1561for arrays, and "and" for hashes. This means that a WHERE
32eab2da 1562array of the form:
1563
1564 @where = (
9d48860e 1565 event_date => {'>=', '2/13/99'},
1566 event_date => {'<=', '4/24/03'},
32eab2da 1567 );
1568
7cac25e6 1569will generate SQL like this:
32eab2da 1570
1571 WHERE event_date >= '2/13/99' OR event_date <= '4/24/03'
1572
1573This is probably not what you want given this query, though (look
1574at the dates). To change the "OR" to an "AND", simply specify:
1575
1576 my $sql = SQL::Abstract->new(logic => 'and');
1577
1578Which will change the above C<WHERE> to:
1579
1580 WHERE event_date >= '2/13/99' AND event_date <= '4/24/03'
1581
96449e8e 1582The logic can also be changed locally by inserting
7cac25e6 1583a modifier in front of an arrayref :
96449e8e 1584
9d48860e 1585 @where = (-and => [event_date => {'>=', '2/13/99'},
7cac25e6 1586 event_date => {'<=', '4/24/03'} ]);
96449e8e 1587
1588See the L</"WHERE CLAUSES"> section for explanations.
1589
32eab2da 1590=item convert
1591
1592This will automatically convert comparisons using the specified SQL
1593function for both column and value. This is mostly used with an argument
1594of C<upper> or C<lower>, so that the SQL will have the effect of
1595case-insensitive "searches". For example, this:
1596
1597 $sql = SQL::Abstract->new(convert => 'upper');
1598 %where = (keywords => 'MaKe iT CAse inSeNSItive');
1599
1600Will turn out the following SQL:
1601
1602 WHERE upper(keywords) like upper('MaKe iT CAse inSeNSItive')
1603
1604The conversion can be C<upper()>, C<lower()>, or any other SQL function
1605that can be applied symmetrically to fields (actually B<SQL::Abstract> does
1606not validate this option; it will just pass through what you specify verbatim).
1607
1608=item bindtype
1609
1610This is a kludge because many databases suck. For example, you can't
1611just bind values using DBI's C<execute()> for Oracle C<CLOB> or C<BLOB> fields.
1612Instead, you have to use C<bind_param()>:
1613
1614 $sth->bind_param(1, 'reg data');
1615 $sth->bind_param(2, $lots, {ora_type => ORA_CLOB});
1616
1617The problem is, B<SQL::Abstract> will normally just return a C<@bind> array,
1618which loses track of which field each slot refers to. Fear not.
1619
1620If you specify C<bindtype> in new, you can determine how C<@bind> is returned.
1621Currently, you can specify either C<normal> (default) or C<columns>. If you
1622specify C<columns>, you will get an array that looks like this:
1623
1624 my $sql = SQL::Abstract->new(bindtype => 'columns');
1625 my($stmt, @bind) = $sql->insert(...);
1626
1627 @bind = (
1628 [ 'column1', 'value1' ],
1629 [ 'column2', 'value2' ],
1630 [ 'column3', 'value3' ],
1631 );
1632
1633You can then iterate through this manually, using DBI's C<bind_param()>.
e3f9dff4 1634
32eab2da 1635 $sth->prepare($stmt);
1636 my $i = 1;
1637 for (@bind) {
1638 my($col, $data) = @$_;
1639 if ($col eq 'details' || $col eq 'comments') {
1640 $sth->bind_param($i, $data, {ora_type => ORA_CLOB});
1641 } elsif ($col eq 'image') {
1642 $sth->bind_param($i, $data, {ora_type => ORA_BLOB});
1643 } else {
1644 $sth->bind_param($i, $data);
1645 }
1646 $i++;
1647 }
1648 $sth->execute; # execute without @bind now
1649
1650Now, why would you still use B<SQL::Abstract> if you have to do this crap?
1651Basically, the advantage is still that you don't have to care which fields
1652are or are not included. You could wrap that above C<for> loop in a simple
1653sub called C<bind_fields()> or something and reuse it repeatedly. You still
1654get a layer of abstraction over manual SQL specification.
1655
deb148a2 1656Note that if you set L</bindtype> to C<columns>, the C<\[$sql, @bind]>
1657construct (see L</Literal SQL with placeholders and bind values (subqueries)>)
1658will expect the bind values in this format.
1659
32eab2da 1660=item quote_char
1661
1662This is the character that a table or column name will be quoted
9d48860e 1663with. By default this is an empty string, but you could set it to
32eab2da 1664the character C<`>, to generate SQL like this:
1665
1666 SELECT `a_field` FROM `a_table` WHERE `some_field` LIKE '%someval%'
1667
96449e8e 1668Alternatively, you can supply an array ref of two items, the first being the left
1669hand quote character, and the second the right hand quote character. For
1670example, you could supply C<['[',']']> for SQL Server 2000 compliant quotes
1671that generates SQL like this:
1672
1673 SELECT [a_field] FROM [a_table] WHERE [some_field] LIKE '%someval%'
1674
9d48860e 1675Quoting is useful if you have tables or columns names that are reserved
96449e8e 1676words in your database's SQL dialect.
32eab2da 1677
1678=item name_sep
1679
1680This is the character that separates a table and column name. It is
1681necessary to specify this when the C<quote_char> option is selected,
1682so that tables and column names can be individually quoted like this:
1683
1684 SELECT `table`.`one_field` FROM `table` WHERE `table`.`other_field` = 1
1685
96449e8e 1686=item array_datatypes
32eab2da 1687
9d48860e 1688When this option is true, arrayrefs in INSERT or UPDATE are
1689interpreted as array datatypes and are passed directly
96449e8e 1690to the DBI layer.
1691When this option is false, arrayrefs are interpreted
1692as literal SQL, just like refs to arrayrefs
1693(but this behavior is for backwards compatibility; when writing
1694new queries, use the "reference to arrayref" syntax
1695for literal SQL).
32eab2da 1696
32eab2da 1697
96449e8e 1698=item special_ops
32eab2da 1699
9d48860e 1700Takes a reference to a list of "special operators"
96449e8e 1701to extend the syntax understood by L<SQL::Abstract>.
1702See section L</"SPECIAL OPERATORS"> for details.
32eab2da 1703
59f23b3d 1704=item unary_ops
1705
9d48860e 1706Takes a reference to a list of "unary operators"
59f23b3d 1707to extend the syntax understood by L<SQL::Abstract>.
1708See section L</"UNARY OPERATORS"> for details.
1709
32eab2da 1710
32eab2da 1711
96449e8e 1712=back
32eab2da 1713
02288357 1714=head2 insert($table, \@values || \%fieldvals, \%options)
32eab2da 1715
1716This is the simplest function. You simply give it a table name
1717and either an arrayref of values or hashref of field/value pairs.
1718It returns an SQL INSERT statement and a list of bind values.
96449e8e 1719See the sections on L</"Inserting and Updating Arrays"> and
1720L</"Inserting and Updating SQL"> for information on how to insert
1721with those data types.
32eab2da 1722
02288357 1723The optional C<\%options> hash reference may contain additional
1724options to generate the insert SQL. Currently supported options
1725are:
1726
1727=over 4
1728
1729=item returning
1730
1731Takes either a scalar of raw SQL fields, or an array reference of
1732field names, and adds on an SQL C<RETURNING> statement at the end.
1733This allows you to return data generated by the insert statement
1734(such as row IDs) without performing another C<SELECT> statement.
1735Note, however, this is not part of the SQL standard and may not
1736be supported by all database engines.
1737
1738=back
1739
32eab2da 1740=head2 update($table, \%fieldvals, \%where)
1741
1742This takes a table, hashref of field/value pairs, and an optional
86298391 1743hashref L<WHERE clause|/WHERE CLAUSES>. It returns an SQL UPDATE function and a list
32eab2da 1744of bind values.
96449e8e 1745See the sections on L</"Inserting and Updating Arrays"> and
1746L</"Inserting and Updating SQL"> for information on how to insert
1747with those data types.
32eab2da 1748
96449e8e 1749=head2 select($source, $fields, $where, $order)
32eab2da 1750
9d48860e 1751This returns a SQL SELECT statement and associated list of bind values, as
96449e8e 1752specified by the arguments :
32eab2da 1753
96449e8e 1754=over
32eab2da 1755
96449e8e 1756=item $source
32eab2da 1757
9d48860e 1758Specification of the 'FROM' part of the statement.
96449e8e 1759The argument can be either a plain scalar (interpreted as a table
1760name, will be quoted), or an arrayref (interpreted as a list
1761of table names, joined by commas, quoted), or a scalarref
1762(literal table name, not quoted), or a ref to an arrayref
1763(list of literal table names, joined by commas, not quoted).
32eab2da 1764
96449e8e 1765=item $fields
32eab2da 1766
9d48860e 1767Specification of the list of fields to retrieve from
96449e8e 1768the source.
1769The argument can be either an arrayref (interpreted as a list
9d48860e 1770of field names, will be joined by commas and quoted), or a
96449e8e 1771plain scalar (literal SQL, not quoted).
1772Please observe that this API is not as flexible as for
e3f9dff4 1773the first argument C<$table>, for backwards compatibility reasons.
32eab2da 1774
96449e8e 1775=item $where
32eab2da 1776
96449e8e 1777Optional argument to specify the WHERE part of the query.
1778The argument is most often a hashref, but can also be
9d48860e 1779an arrayref or plain scalar --
96449e8e 1780see section L<WHERE clause|/"WHERE CLAUSES"> for details.
32eab2da 1781
96449e8e 1782=item $order
32eab2da 1783
96449e8e 1784Optional argument to specify the ORDER BY part of the query.
9d48860e 1785The argument can be a scalar, a hashref or an arrayref
96449e8e 1786-- see section L<ORDER BY clause|/"ORDER BY CLAUSES">
1787for details.
32eab2da 1788
96449e8e 1789=back
32eab2da 1790
32eab2da 1791
1792=head2 delete($table, \%where)
1793
86298391 1794This takes a table name and optional hashref L<WHERE clause|/WHERE CLAUSES>.
32eab2da 1795It returns an SQL DELETE statement and list of bind values.
1796
32eab2da 1797=head2 where(\%where, \@order)
1798
1799This is used to generate just the WHERE clause. For example,
1800if you have an arbitrary data structure and know what the
1801rest of your SQL is going to look like, but want an easy way
1802to produce a WHERE clause, use this. It returns an SQL WHERE
1803clause and list of bind values.
1804
32eab2da 1805
1806=head2 values(\%data)
1807
1808This just returns the values from the hash C<%data>, in the same
1809order that would be returned from any of the other above queries.
1810Using this allows you to markedly speed up your queries if you
1811are affecting lots of rows. See below under the L</"PERFORMANCE"> section.
1812
32eab2da 1813=head2 generate($any, 'number', $of, \@data, $struct, \%types)
1814
1815Warning: This is an experimental method and subject to change.
1816
1817This returns arbitrarily generated SQL. It's a really basic shortcut.
1818It will return two different things, depending on return context:
1819
1820 my($stmt, @bind) = $sql->generate('create table', \$table, \@fields);
1821 my $stmt_and_val = $sql->generate('create table', \$table, \@fields);
1822
1823These would return the following:
1824
1825 # First calling form
1826 $stmt = "CREATE TABLE test (?, ?)";
1827 @bind = (field1, field2);
1828
1829 # Second calling form
1830 $stmt_and_val = "CREATE TABLE test (field1, field2)";
1831
1832Depending on what you're trying to do, it's up to you to choose the correct
1833format. In this example, the second form is what you would want.
1834
1835By the same token:
1836
1837 $sql->generate('alter session', { nls_date_format => 'MM/YY' });
1838
1839Might give you:
1840
1841 ALTER SESSION SET nls_date_format = 'MM/YY'
1842
1843You get the idea. Strings get their case twiddled, but everything
1844else remains verbatim.
1845
32eab2da 1846
32eab2da 1847
32eab2da 1848
1849=head1 WHERE CLAUSES
1850
96449e8e 1851=head2 Introduction
1852
32eab2da 1853This module uses a variation on the idea from L<DBIx::Abstract>. It
1854is B<NOT>, repeat I<not> 100% compatible. B<The main logic of this
1855module is that things in arrays are OR'ed, and things in hashes
1856are AND'ed.>
1857
1858The easiest way to explain is to show lots of examples. After
1859each C<%where> hash shown, it is assumed you used:
1860
1861 my($stmt, @bind) = $sql->where(\%where);
1862
1863However, note that the C<%where> hash can be used directly in any
1864of the other functions as well, as described above.
1865
96449e8e 1866=head2 Key-value pairs
1867
32eab2da 1868So, let's get started. To begin, a simple hash:
1869
1870 my %where = (
1871 user => 'nwiger',
1872 status => 'completed'
1873 );
1874
1875Is converted to SQL C<key = val> statements:
1876
1877 $stmt = "WHERE user = ? AND status = ?";
1878 @bind = ('nwiger', 'completed');
1879
1880One common thing I end up doing is having a list of values that
1881a field can be in. To do this, simply specify a list inside of
1882an arrayref:
1883
1884 my %where = (
1885 user => 'nwiger',
1886 status => ['assigned', 'in-progress', 'pending'];
1887 );
1888
1889This simple code will create the following:
9d48860e 1890
32eab2da 1891 $stmt = "WHERE user = ? AND ( status = ? OR status = ? OR status = ? )";
1892 @bind = ('nwiger', 'assigned', 'in-progress', 'pending');
1893
9d48860e 1894A field associated to an empty arrayref will be considered a
7cac25e6 1895logical false and will generate 0=1.
8a68b5be 1896
6e0c6552 1897=head2 Specific comparison operators
96449e8e 1898
32eab2da 1899If you want to specify a different type of operator for your comparison,
1900you can use a hashref for a given column:
1901
1902 my %where = (
1903 user => 'nwiger',
1904 status => { '!=', 'completed' }
1905 );
1906
1907Which would generate:
1908
1909 $stmt = "WHERE user = ? AND status != ?";
1910 @bind = ('nwiger', 'completed');
1911
1912To test against multiple values, just enclose the values in an arrayref:
1913
96449e8e 1914 status => { '=', ['assigned', 'in-progress', 'pending'] };
1915
f2d5020d 1916Which would give you:
96449e8e 1917
1918 "WHERE status = ? OR status = ? OR status = ?"
1919
1920
1921The hashref can also contain multiple pairs, in which case it is expanded
32eab2da 1922into an C<AND> of its elements:
1923
1924 my %where = (
1925 user => 'nwiger',
1926 status => { '!=', 'completed', -not_like => 'pending%' }
1927 );
1928
1929 # Or more dynamically, like from a form
1930 $where{user} = 'nwiger';
1931 $where{status}{'!='} = 'completed';
1932 $where{status}{'-not_like'} = 'pending%';
1933
1934 # Both generate this
1935 $stmt = "WHERE user = ? AND status != ? AND status NOT LIKE ?";
1936 @bind = ('nwiger', 'completed', 'pending%');
1937
96449e8e 1938
32eab2da 1939To get an OR instead, you can combine it with the arrayref idea:
1940
1941 my %where => (
1942 user => 'nwiger',
1943 priority => [ {'=', 2}, {'!=', 1} ]
1944 );
1945
1946Which would generate:
1947
1948 $stmt = "WHERE user = ? AND priority = ? OR priority != ?";
1949 @bind = ('nwiger', '2', '1');
1950
44b9e502 1951If you want to include literal SQL (with or without bind values), just use a
1952scalar reference or array reference as the value:
1953
1954 my %where = (
1955 date_entered => { '>' => \["to_date(?, 'MM/DD/YYYY')", "11/26/2008"] },
1956 date_expires => { '<' => \"now()" }
1957 );
1958
1959Which would generate:
1960
1961 $stmt = "WHERE date_entered > "to_date(?, 'MM/DD/YYYY') AND date_expires < now()";
1962 @bind = ('11/26/2008');
1963
96449e8e 1964
1965=head2 Logic and nesting operators
1966
1967In the example above,
1968there is a subtle trap if you want to say something like
32eab2da 1969this (notice the C<AND>):
1970
1971 WHERE priority != ? AND priority != ?
1972
1973Because, in Perl you I<can't> do this:
1974
1975 priority => { '!=', 2, '!=', 1 }
1976
1977As the second C<!=> key will obliterate the first. The solution
1978is to use the special C<-modifier> form inside an arrayref:
1979
9d48860e 1980 priority => [ -and => {'!=', 2},
96449e8e 1981 {'!=', 1} ]
1982
32eab2da 1983
1984Normally, these would be joined by C<OR>, but the modifier tells it
1985to use C<AND> instead. (Hint: You can use this in conjunction with the
1986C<logic> option to C<new()> in order to change the way your queries
1987work by default.) B<Important:> Note that the C<-modifier> goes
1988B<INSIDE> the arrayref, as an extra first element. This will
1989B<NOT> do what you think it might:
1990
1991 priority => -and => [{'!=', 2}, {'!=', 1}] # WRONG!
1992
1993Here is a quick list of equivalencies, since there is some overlap:
1994
1995 # Same
1996 status => {'!=', 'completed', 'not like', 'pending%' }
1997 status => [ -and => {'!=', 'completed'}, {'not like', 'pending%'}]
1998
1999 # Same
2000 status => {'=', ['assigned', 'in-progress']}
2001 status => [ -or => {'=', 'assigned'}, {'=', 'in-progress'}]
2002 status => [ {'=', 'assigned'}, {'=', 'in-progress'} ]
2003
e3f9dff4 2004
2005
96449e8e 2006=head2 Special operators : IN, BETWEEN, etc.
2007
32eab2da 2008You can also use the hashref format to compare a list of fields using the
2009C<IN> comparison operator, by specifying the list as an arrayref:
2010
2011 my %where = (
2012 status => 'completed',
2013 reportid => { -in => [567, 2335, 2] }
2014 );
2015
2016Which would generate:
2017
2018 $stmt = "WHERE status = ? AND reportid IN (?,?,?)";
2019 @bind = ('completed', '567', '2335', '2');
2020
9d48860e 2021The reverse operator C<-not_in> generates SQL C<NOT IN> and is used in
96449e8e 2022the same way.
2023
6e0c6552 2024If the argument to C<-in> is an empty array, 'sqlfalse' is generated
2025(by default : C<1=0>). Similarly, C<< -not_in => [] >> generates
2026'sqltrue' (by default : C<1=1>).
2027
e41c3bdd 2028In addition to the array you can supply a chunk of literal sql or
2029literal sql with bind:
6e0c6552 2030
e41c3bdd 2031 my %where = {
2032 customer => { -in => \[
2033 'SELECT cust_id FROM cust WHERE balance > ?',
2034 2000,
2035 ],
2036 status => { -in => \'SELECT status_codes FROM states' },
2037 };
6e0c6552 2038
e41c3bdd 2039would generate:
2040
2041 $stmt = "WHERE (
2042 customer IN ( SELECT cust_id FROM cust WHERE balance > ? )
2043 AND status IN ( SELECT status_codes FROM states )
2044 )";
2045 @bind = ('2000');
2046
2047
2048
2049Another pair of operators is C<-between> and C<-not_between>,
96449e8e 2050used with an arrayref of two values:
32eab2da 2051
2052 my %where = (
2053 user => 'nwiger',
2054 completion_date => {
2055 -not_between => ['2002-10-01', '2003-02-06']
2056 }
2057 );
2058
2059Would give you:
2060
2061 WHERE user = ? AND completion_date NOT BETWEEN ( ? AND ? )
2062
e41c3bdd 2063Just like with C<-in> all plausible combinations of literal SQL
2064are possible:
2065
2066 my %where = {
2067 start0 => { -between => [ 1, 2 ] },
2068 start1 => { -between => \["? AND ?", 1, 2] },
2069 start2 => { -between => \"lower(x) AND upper(y)" },
9d48860e 2070 start3 => { -between => [
e41c3bdd 2071 \"lower(x)",
2072 \["upper(?)", 'stuff' ],
2073 ] },
2074 };
2075
2076Would give you:
2077
2078 $stmt = "WHERE (
2079 ( start0 BETWEEN ? AND ? )
2080 AND ( start1 BETWEEN ? AND ? )
2081 AND ( start2 BETWEEN lower(x) AND upper(y) )
2082 AND ( start3 BETWEEN lower(x) AND upper(?) )
2083 )";
2084 @bind = (1, 2, 1, 2, 'stuff');
2085
2086
9d48860e 2087These are the two builtin "special operators"; but the
96449e8e 2088list can be expanded : see section L</"SPECIAL OPERATORS"> below.
2089
59f23b3d 2090=head2 Unary operators: bool
97a920ef 2091
2092If you wish to test against boolean columns or functions within your
2093database you can use the C<-bool> and C<-not_bool> operators. For
2094example to test the column C<is_user> being true and the column
2095<is_enabled> being false you would use:-
2096
2097 my %where = (
2098 -bool => 'is_user',
2099 -not_bool => 'is_enabled',
2100 );
2101
2102Would give you:
2103
277b5d3f 2104 WHERE is_user AND NOT is_enabled
97a920ef 2105
0b604e9d 2106If a more complex combination is required, testing more conditions,
2107then you should use the and/or operators:-
2108
2109 my %where = (
2110 -and => [
2111 -bool => 'one',
2112 -bool => 'two',
2113 -bool => 'three',
2114 -not_bool => 'four',
2115 ],
2116 );
2117
2118Would give you:
2119
2120 WHERE one AND two AND three AND NOT four
97a920ef 2121
2122
107b72f1 2123=head2 Nested conditions, -and/-or prefixes
96449e8e 2124
32eab2da 2125So far, we've seen how multiple conditions are joined with a top-level
2126C<AND>. We can change this by putting the different conditions we want in
2127hashes and then putting those hashes in an array. For example:
2128
2129 my @where = (
2130 {
2131 user => 'nwiger',
2132 status => { -like => ['pending%', 'dispatched'] },
2133 },
2134 {
2135 user => 'robot',
2136 status => 'unassigned',
2137 }
2138 );
2139
2140This data structure would create the following:
2141
2142 $stmt = "WHERE ( user = ? AND ( status LIKE ? OR status LIKE ? ) )
2143 OR ( user = ? AND status = ? ) )";
2144 @bind = ('nwiger', 'pending', 'dispatched', 'robot', 'unassigned');
2145
107b72f1 2146
01a01e57 2147There is also a special C<-nest>
107b72f1 2148operator which adds an additional set of parens, to create a subquery.
2149For example, to get something like this:
2150
2151 $stmt = "WHERE user = ? AND ( workhrs > ? OR geo = ? )";
2152 @bind = ('nwiger', '20', 'ASIA');
2153
2154You would do:
2155
2156 my %where = (
2157 user => 'nwiger',
01a01e57 2158 -nest => [ workhrs => {'>', 20}, geo => 'ASIA' ],
107b72f1 2159 );
2160
2161
2162Finally, clauses in hashrefs or arrayrefs can be
7cac25e6 2163prefixed with an C<-and> or C<-or> to change the logic
2164inside :
32eab2da 2165
2166 my @where = (
2167 -and => [
2168 user => 'nwiger',
01a01e57 2169 -nest => [
7cac25e6 2170 -and => [workhrs => {'>', 20}, geo => 'ASIA' ],
2171 -and => [workhrs => {'<', 50}, geo => 'EURO' ]
32eab2da 2172 ],
2173 ],
2174 );
2175
2176That would yield:
2177
9d48860e 2178 WHERE ( user = ? AND
32eab2da 2179 ( ( workhrs > ? AND geo = ? )
2180 OR ( workhrs < ? AND geo = ? ) ) )
2181
107b72f1 2182
2183=head2 Algebraic inconsistency, for historical reasons
2184
7cac25e6 2185C<Important note>: when connecting several conditions, the C<-and->|C<-or>
2186operator goes C<outside> of the nested structure; whereas when connecting
2187several constraints on one column, the C<-and> operator goes
2188C<inside> the arrayref. Here is an example combining both features :
2189
2190 my @where = (
2191 -and => [a => 1, b => 2],
2192 -or => [c => 3, d => 4],
2193 e => [-and => {-like => 'foo%'}, {-like => '%bar'} ]
2194 )
2195
2196yielding
2197
9d48860e 2198 WHERE ( ( ( a = ? AND b = ? )
2199 OR ( c = ? OR d = ? )
7cac25e6 2200 OR ( e LIKE ? AND e LIKE ? ) ) )
2201
107b72f1 2202This difference in syntax is unfortunate but must be preserved for
2203historical reasons. So be careful : the two examples below would
2204seem algebraically equivalent, but they are not
2205
9d48860e 2206 {col => [-and => {-like => 'foo%'}, {-like => '%bar'}]}
107b72f1 2207 # yields : WHERE ( ( col LIKE ? AND col LIKE ? ) )
2208
9d48860e 2209 [-and => {col => {-like => 'foo%'}, {col => {-like => '%bar'}}]]
107b72f1 2210 # yields : WHERE ( ( col LIKE ? OR col LIKE ? ) )
2211
7cac25e6 2212
96449e8e 2213=head2 Literal SQL
2214
32eab2da 2215Finally, sometimes only literal SQL will do. If you want to include
2216literal SQL verbatim, you can specify it as a scalar reference, namely:
2217
2218 my $inn = 'is Not Null';
2219 my %where = (
2220 priority => { '<', 2 },
2221 requestor => \$inn
2222 );
2223
2224This would create:
2225
2226 $stmt = "WHERE priority < ? AND requestor is Not Null";
2227 @bind = ('2');
2228
2229Note that in this example, you only get one bind parameter back, since
2230the verbatim SQL is passed as part of the statement.
2231
2232Of course, just to prove a point, the above can also be accomplished
2233with this:
2234
2235 my %where = (
2236 priority => { '<', 2 },
2237 requestor => { '!=', undef },
2238 );
2239
96449e8e 2240
e41c3bdd 2241TMTOWTDI
32eab2da 2242
0b604e9d 2243Conditions on boolean columns can be expressed in the same way, passing
2244a reference to an empty string, however using liternal SQL in this way
2245is deprecated - the preferred method is to use the boolean operators -
2246see L</"Unary operators: bool"> :
96449e8e 2247
2248 my %where = (
2249 priority => { '<', 2 },
2250 is_ready => \"";
2251 );
2252
2253which yields
2254
2255 $stmt = "WHERE priority < ? AND is_ready";
2256 @bind = ('2');
2257
2258
2259=head2 Literal SQL with placeholders and bind values (subqueries)
2260
2261If the literal SQL to be inserted has placeholders and bind values,
2262use a reference to an arrayref (yes this is a double reference --
2263not so common, but perfectly legal Perl). For example, to find a date
2264in Postgres you can use something like this:
2265
2266 my %where = (
2267 date_column => \[q/= date '2008-09-30' - ?::integer/, 10/]
2268 )
2269
2270This would create:
2271
d2a8fe1a 2272 $stmt = "WHERE ( date_column = date '2008-09-30' - ?::integer )"
96449e8e 2273 @bind = ('10');
2274
deb148a2 2275Note that you must pass the bind values in the same format as they are returned
62552e7d 2276by L</where>. That means that if you set L</bindtype> to C<columns>, you must
26f2dca5 2277provide the bind values in the C<< [ column_meta => value ] >> format, where
2278C<column_meta> is an opaque scalar value; most commonly the column name, but
62552e7d 2279you can use any scalar value (including references and blessed references),
2280L<SQL::Abstract> will simply pass it through intact. So if C<bindtype> is set
2281to C<columns> the above example will look like:
deb148a2 2282
2283 my %where = (
2284 date_column => \[q/= date '2008-09-30' - ?::integer/, [ dummy => 10 ]/]
2285 )
96449e8e 2286
2287Literal SQL is especially useful for nesting parenthesized clauses in the
2288main SQL query. Here is a first example :
2289
2290 my ($sub_stmt, @sub_bind) = ("SELECT c1 FROM t1 WHERE c2 < ? AND c3 LIKE ?",
2291 100, "foo%");
2292 my %where = (
2293 foo => 1234,
2294 bar => \["IN ($sub_stmt)" => @sub_bind],
2295 );
2296
2297This yields :
2298
9d48860e 2299 $stmt = "WHERE (foo = ? AND bar IN (SELECT c1 FROM t1
96449e8e 2300 WHERE c2 < ? AND c3 LIKE ?))";
2301 @bind = (1234, 100, "foo%");
2302
9d48860e 2303Other subquery operators, like for example C<"E<gt> ALL"> or C<"NOT IN">,
96449e8e 2304are expressed in the same way. Of course the C<$sub_stmt> and
9d48860e 2305its associated bind values can be generated through a former call
96449e8e 2306to C<select()> :
2307
2308 my ($sub_stmt, @sub_bind)
9d48860e 2309 = $sql->select("t1", "c1", {c2 => {"<" => 100},
96449e8e 2310 c3 => {-like => "foo%"}});
2311 my %where = (
2312 foo => 1234,
2313 bar => \["> ALL ($sub_stmt)" => @sub_bind],
2314 );
2315
2316In the examples above, the subquery was used as an operator on a column;
9d48860e 2317but the same principle also applies for a clause within the main C<%where>
96449e8e 2318hash, like an EXISTS subquery :
2319
9d48860e 2320 my ($sub_stmt, @sub_bind)
96449e8e 2321 = $sql->select("t1", "*", {c1 => 1, c2 => \"> t0.c0"});
2322 my %where = (
2323 foo => 1234,
01a01e57 2324 -nest => \["EXISTS ($sub_stmt)" => @sub_bind],
96449e8e 2325 );
2326
2327which yields
2328
9d48860e 2329 $stmt = "WHERE (foo = ? AND EXISTS (SELECT * FROM t1
96449e8e 2330 WHERE c1 = ? AND c2 > t0.c0))";
2331 @bind = (1234, 1);
2332
2333
9d48860e 2334Observe that the condition on C<c2> in the subquery refers to
2335column C<t0.c0> of the main query : this is I<not> a bind
2336value, so we have to express it through a scalar ref.
96449e8e 2337Writing C<< c2 => {">" => "t0.c0"} >> would have generated
2338C<< c2 > ? >> with bind value C<"t0.c0"> ... not exactly
2339what we wanted here.
2340
2341Another use of the subquery technique is when some SQL clauses need
2342parentheses, as it often occurs with some proprietary SQL extensions
9d48860e 2343like for example fulltext expressions, geospatial expressions,
96449e8e 2344NATIVE clauses, etc. Here is an example of a fulltext query in MySQL :
2345
2346 my %where = (
01a01e57 2347 -nest => \["MATCH (col1, col2) AGAINST (?)" => qw/apples/]
96449e8e 2348 );
2349
2350Finally, here is an example where a subquery is used
2351for expressing unary negation:
2352
9d48860e 2353 my ($sub_stmt, @sub_bind)
96449e8e 2354 = $sql->where({age => [{"<" => 10}, {">" => 20}]});
2355 $sub_stmt =~ s/^ where //i; # don't want "WHERE" in the subclause
2356 my %where = (
2357 lname => {like => '%son%'},
01a01e57 2358 -nest => \["NOT ($sub_stmt)" => @sub_bind],
96449e8e 2359 );
2360
2361This yields
2362
2363 $stmt = "lname LIKE ? AND NOT ( age < ? OR age > ? )"
2364 @bind = ('%son%', 10, 20)
2365
2366
2367
2368=head2 Conclusion
2369
32eab2da 2370These pages could go on for a while, since the nesting of the data
2371structures this module can handle are pretty much unlimited (the
2372module implements the C<WHERE> expansion as a recursive function
2373internally). Your best bet is to "play around" with the module a
2374little to see how the data structures behave, and choose the best
2375format for your data based on that.
2376
2377And of course, all the values above will probably be replaced with
2378variables gotten from forms or the command line. After all, if you
2379knew everything ahead of time, you wouldn't have to worry about
2380dynamically-generating SQL and could just hardwire it into your
2381script.
2382
96449e8e 2383
2384
2385
86298391 2386=head1 ORDER BY CLAUSES
2387
9d48860e 2388Some functions take an order by clause. This can either be a scalar (just a
86298391 2389column name,) a hash of C<< { -desc => 'col' } >> or C<< { -asc => 'col' } >>,
1cfa1db3 2390or an array of either of the two previous forms. Examples:
2391
952f9e2d 2392 Given | Will Generate
1cfa1db3 2393 ----------------------------------------------------------
952f9e2d 2394 |
2395 \'colA DESC' | ORDER BY colA DESC
2396 |
2397 'colA' | ORDER BY colA
2398 |
2399 [qw/colA colB/] | ORDER BY colA, colB
2400 |
2401 {-asc => 'colA'} | ORDER BY colA ASC
2402 |
2403 {-desc => 'colB'} | ORDER BY colB DESC
2404 |
2405 ['colA', {-asc => 'colB'}] | ORDER BY colA, colB ASC
2406 |
855e6047 2407 { -asc => [qw/colA colB/] } | ORDER BY colA ASC, colB ASC
952f9e2d 2408 |
2409 [ |
2410 { -asc => 'colA' }, | ORDER BY colA ASC, colB DESC,
2411 { -desc => [qw/colB/], | colC ASC, colD ASC
2412 { -asc => [qw/colC colD/],|
2413 ] |
2414 ===========================================================
86298391 2415
96449e8e 2416
2417
2418=head1 SPECIAL OPERATORS
2419
e3f9dff4 2420 my $sqlmaker = SQL::Abstract->new(special_ops => [
3a2e1a5e 2421 {
2422 regex => qr/.../,
e3f9dff4 2423 handler => sub {
2424 my ($self, $field, $op, $arg) = @_;
2425 ...
3a2e1a5e 2426 },
2427 },
2428 {
2429 regex => qr/.../,
2430 handler => 'method_name',
e3f9dff4 2431 },
2432 ]);
2433
9d48860e 2434A "special operator" is a SQL syntactic clause that can be
e3f9dff4 2435applied to a field, instead of a usual binary operator.
9d48860e 2436For example :
e3f9dff4 2437
2438 WHERE field IN (?, ?, ?)
2439 WHERE field BETWEEN ? AND ?
2440 WHERE MATCH(field) AGAINST (?, ?)
96449e8e 2441
e3f9dff4 2442Special operators IN and BETWEEN are fairly standard and therefore
3a2e1a5e 2443are builtin within C<SQL::Abstract> (as the overridable methods
2444C<_where_field_IN> and C<_where_field_BETWEEN>). For other operators,
2445like the MATCH .. AGAINST example above which is specific to MySQL,
2446you can write your own operator handlers - supply a C<special_ops>
2447argument to the C<new> method. That argument takes an arrayref of
2448operator definitions; each operator definition is a hashref with two
2449entries:
96449e8e 2450
e3f9dff4 2451=over
2452
2453=item regex
2454
2455the regular expression to match the operator
96449e8e 2456
e3f9dff4 2457=item handler
2458
3a2e1a5e 2459Either a coderef or a plain scalar method name. In both cases
2460the expected return is C<< ($sql, @bind) >>.
2461
2462When supplied with a method name, it is simply called on the
2463L<SQL::Abstract/> object as:
2464
2465 $self->$method_name ($field, $op, $arg)
2466
2467 Where:
2468
2469 $op is the part that matched the handler regex
2470 $field is the LHS of the operator
2471 $arg is the RHS
2472
2473When supplied with a coderef, it is called as:
2474
2475 $coderef->($self, $field, $op, $arg)
2476
e3f9dff4 2477
2478=back
2479
9d48860e 2480For example, here is an implementation
e3f9dff4 2481of the MATCH .. AGAINST syntax for MySQL
2482
2483 my $sqlmaker = SQL::Abstract->new(special_ops => [
9d48860e 2484
e3f9dff4 2485 # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
9d48860e 2486 {regex => qr/^match$/i,
e3f9dff4 2487 handler => sub {
2488 my ($self, $field, $op, $arg) = @_;
2489 $arg = [$arg] if not ref $arg;
2490 my $label = $self->_quote($field);
2491 my ($placeholder) = $self->_convert('?');
2492 my $placeholders = join ", ", (($placeholder) x @$arg);
2493 my $sql = $self->_sqlcase('match') . " ($label) "
2494 . $self->_sqlcase('against') . " ($placeholders) ";
2495 my @bind = $self->_bindtype($field, @$arg);
2496 return ($sql, @bind);
2497 }
2498 },
9d48860e 2499
e3f9dff4 2500 ]);
96449e8e 2501
2502
59f23b3d 2503=head1 UNARY OPERATORS
2504
112b5232 2505 my $sqlmaker = SQL::Abstract->new(unary_ops => [
59f23b3d 2506 {
2507 regex => qr/.../,
2508 handler => sub {
2509 my ($self, $op, $arg) = @_;
2510 ...
2511 },
2512 },
2513 {
2514 regex => qr/.../,
2515 handler => 'method_name',
2516 },
2517 ]);
2518
9d48860e 2519A "unary operator" is a SQL syntactic clause that can be
59f23b3d 2520applied to a field - the operator goes before the field
2521
2522You can write your own operator handlers - supply a C<unary_ops>
2523argument to the C<new> method. That argument takes an arrayref of
2524operator definitions; each operator definition is a hashref with two
2525entries:
2526
2527=over
2528
2529=item regex
2530
2531the regular expression to match the operator
2532
2533=item handler
2534
2535Either a coderef or a plain scalar method name. In both cases
2536the expected return is C<< $sql >>.
2537
2538When supplied with a method name, it is simply called on the
2539L<SQL::Abstract/> object as:
2540
2541 $self->$method_name ($op, $arg)
2542
2543 Where:
2544
2545 $op is the part that matched the handler regex
2546 $arg is the RHS or argument of the operator
2547
2548When supplied with a coderef, it is called as:
2549
2550 $coderef->($self, $op, $arg)
2551
2552
2553=back
2554
2555
32eab2da 2556=head1 PERFORMANCE
2557
2558Thanks to some benchmarking by Mark Stosberg, it turns out that
2559this module is many orders of magnitude faster than using C<DBIx::Abstract>.
2560I must admit this wasn't an intentional design issue, but it's a
2561byproduct of the fact that you get to control your C<DBI> handles
2562yourself.
2563
2564To maximize performance, use a code snippet like the following:
2565
2566 # prepare a statement handle using the first row
2567 # and then reuse it for the rest of the rows
2568 my($sth, $stmt);
2569 for my $href (@array_of_hashrefs) {
2570 $stmt ||= $sql->insert('table', $href);
2571 $sth ||= $dbh->prepare($stmt);
2572 $sth->execute($sql->values($href));
2573 }
2574
2575The reason this works is because the keys in your C<$href> are sorted
2576internally by B<SQL::Abstract>. Thus, as long as your data retains
2577the same structure, you only have to generate the SQL the first time
2578around. On subsequent queries, simply use the C<values> function provided
2579by this module to return your values in the correct order.
2580
96449e8e 2581
32eab2da 2582=head1 FORMBUILDER
2583
2584If you use my C<CGI::FormBuilder> module at all, you'll hopefully
2585really like this part (I do, at least). Building up a complex query
2586can be as simple as the following:
2587
2588 #!/usr/bin/perl
2589
2590 use CGI::FormBuilder;
2591 use SQL::Abstract;
2592
2593 my $form = CGI::FormBuilder->new(...);
2594 my $sql = SQL::Abstract->new;
2595
2596 if ($form->submitted) {
2597 my $field = $form->field;
2598 my $id = delete $field->{id};
2599 my($stmt, @bind) = $sql->update('table', $field, {id => $id});
2600 }
2601
2602Of course, you would still have to connect using C<DBI> to run the
2603query, but the point is that if you make your form look like your
2604table, the actual query script can be extremely simplistic.
2605
2606If you're B<REALLY> lazy (I am), check out C<HTML::QuickTable> for
9d48860e 2607a fast interface to returning and formatting data. I frequently
32eab2da 2608use these three modules together to write complex database query
2609apps in under 50 lines.
2610
32eab2da 2611
96449e8e 2612=head1 CHANGES
2613
2614Version 1.50 was a major internal refactoring of C<SQL::Abstract>.
2615Great care has been taken to preserve the I<published> behavior
2616documented in previous versions in the 1.* family; however,
9d48860e 2617some features that were previously undocumented, or behaved
96449e8e 2618differently from the documentation, had to be changed in order
2619to clarify the semantics. Hence, client code that was relying
9d48860e 2620on some dark areas of C<SQL::Abstract> v1.*
96449e8e 2621B<might behave differently> in v1.50.
32eab2da 2622
d2a8fe1a 2623The main changes are :
2624
96449e8e 2625=over
32eab2da 2626
9d48860e 2627=item *
32eab2da 2628
96449e8e 2629support for literal SQL through the C<< \ [$sql, bind] >> syntax.
2630
2631=item *
2632
145fbfc8 2633support for the { operator => \"..." } construct (to embed literal SQL)
2634
2635=item *
2636
9c37b9c0 2637support for the { operator => \["...", @bind] } construct (to embed literal SQL with bind values)
2638
2639=item *
2640
96449e8e 2641optional support for L<array datatypes|/"Inserting and Updating Arrays">
2642
9d48860e 2643=item *
96449e8e 2644
2645defensive programming : check arguments
2646
2647=item *
2648
2649fixed bug with global logic, which was previously implemented
7cac25e6 2650through global variables yielding side-effects. Prior versions would
96449e8e 2651interpret C<< [ {cond1, cond2}, [cond3, cond4] ] >>
2652as C<< "(cond1 AND cond2) OR (cond3 AND cond4)" >>.
2653Now this is interpreted
2654as C<< "(cond1 AND cond2) OR (cond3 OR cond4)" >>.
2655
96449e8e 2656
2657=item *
2658
2659fixed semantics of _bindtype on array args
2660
9d48860e 2661=item *
96449e8e 2662
2663dropped the C<_anoncopy> of the %where tree. No longer necessary,
2664we just avoid shifting arrays within that tree.
2665
2666=item *
2667
2668dropped the C<_modlogic> function
2669
2670=back
32eab2da 2671
32eab2da 2672
32eab2da 2673
2674=head1 ACKNOWLEDGEMENTS
2675
2676There are a number of individuals that have really helped out with
2677this module. Unfortunately, most of them submitted bugs via CPAN
2678so I have no idea who they are! But the people I do know are:
2679
9d48860e 2680 Ash Berlin (order_by hash term support)
b643abe1 2681 Matt Trout (DBIx::Class support)
32eab2da 2682 Mark Stosberg (benchmarking)
2683 Chas Owens (initial "IN" operator support)
2684 Philip Collins (per-field SQL functions)
2685 Eric Kolve (hashref "AND" support)
2686 Mike Fragassi (enhancements to "BETWEEN" and "LIKE")
2687 Dan Kubb (support for "quote_char" and "name_sep")
f5aab26e 2688 Guillermo Roditi (patch to cleanup "IN" and "BETWEEN", fix and tests for _order_by)
01a01e57 2689 Laurent Dami (internal refactoring, multiple -nest, extensible list of special operators, literal SQL)
dbdf7648 2690 Norbert Buchmuller (support for literal SQL in hashpair, misc. fixes & tests)
e96c510a 2691 Peter Rabbitson (rewrite of SQLA::Test, misc. fixes & tests)
02288357 2692 Oliver Charles (support for "RETURNING" after "INSERT")
32eab2da 2693
2694Thanks!
2695
32eab2da 2696=head1 SEE ALSO
2697
86298391 2698L<DBIx::Class>, L<DBIx::Abstract>, L<CGI::FormBuilder>, L<HTML::QuickTable>.
32eab2da 2699
32eab2da 2700=head1 AUTHOR
2701
b643abe1 2702Copyright (c) 2001-2007 Nathan Wiger <nwiger@cpan.org>. All Rights Reserved.
2703
2704This module is actively maintained by Matt Trout <mst@shadowcatsystems.co.uk>
32eab2da 2705
abe72f94 2706For support, your best bet is to try the C<DBIx::Class> users mailing list.
2707While not an official support venue, C<DBIx::Class> makes heavy use of
2708C<SQL::Abstract>, and as such list members there are very familiar with
2709how to create queries.
2710
0d067ded 2711=head1 LICENSE
2712
d988ab87 2713This module is free software; you may copy this under the same
2714terms as perl itself (either the GNU General Public License or
2715the Artistic License)
32eab2da 2716
2717=cut
2718