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