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