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