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