Revision history for SQL::Abstract
+----------------------------
+revision 1.49_01
+ - deep internal refactoring (see L</"CHANGES")
+ - support for literal SQL through the C<< \ [$sql, bind] >> syntax.
+ - added -nest1, -nest2 or -nest_1, -nest_2, ...
+ - optional support for array datatypes
+ - defensive programming : check arguments to functions/methods
+ - fixed bug with global logic of -and/-or (no side-effects any more)
+ - changed logic for distributing an op over arrayrefs
+ - fixed semantics of _bindtype on array args
+ - dropped the C<_anoncopy> of the %where tree. No longer necessary.
+ - dropped the C<_modlogic> function
- Make col => [] and col => {$op => [] } DTRT or die instead of generating
broken SQL. Added tests for this.
- Added { -desc => 'column' } order by support (Ash)
);
You can then iterate through this manually, using DBI's C<bind_param()>.
-
+
$sth->prepare($stmt);
my $i = 1;
for (@bind) {
of field names, will be joined by commas and quoted), or a
plain scalar (literal SQL, not quoted).
Please observe that this API is not as flexible as for
-the first argument <$table>, for backwards compatibility reasons.
+the first argument C<$table>, for backwards compatibility reasons.
=item $where
-nest => [ workhrs => {'>', 20}, geo => 'ASIA' ],
);
+If you need several nested subexpressions, you can number
+the C<-nest> branches :
+
+ my %where = (
+ user => 'nwiger',
+ -nest1 => ...,
+ -nest2 => ...,
+ ...
+ );
+
+
=head2 Special operators : IN, BETWEEN, etc.
You can also use the hashref format to compare a list of fields using the
=head1 SPECIAL OPERATORS
-[to be written]
+ my $sqlmaker = SQL::Abstract->new(special_ops => [
+ {regex => qr/.../,
+ handler => sub {
+ my ($self, $field, $op, $arg) = @_;
+ ...
+ },
+ },
+ ]);
+
+A "special operator" is a SQL syntactic clause that can be
+applied to a field, instead of a usual binary operator.
+For example :
+
+ WHERE field IN (?, ?, ?)
+ WHERE field BETWEEN ? AND ?
+ WHERE MATCH(field) AGAINST (?, ?)
+Special operators IN and BETWEEN are fairly standard and therefore
+are builtin within C<SQL::Abstract>. For other operators,
+like the MATCH .. AGAINST example above which is
+specific to MySQL, you can write your own operator handlers :
+supply a C<special_ops> argument to the C<new> method.
+That argument takes an arrayref of operator definitions;
+each operator definition is a hashref with two entries
-=head1 TABLES AND JOINS
+=over
+
+=item regex
+
+the regular expression to match the operator
-[to be written]
+=item handler
+
+coderef that will be called when meeting that operator
+in the input tree. The coderef will be called with
+arguments C<< ($self, $field, $op, $arg) >>, and
+should return a C<< ($sql, @bind) >> structure.
+
+=back
+
+For example, here is an implementation
+of the MATCH .. AGAINST syntax for MySQL
+
+ my $sqlmaker = SQL::Abstract->new(special_ops => [
+
+ # special op for MySql MATCH (field) AGAINST(word1, word2, ...)
+ {regex => qr/^match$/i,
+ handler => sub {
+ my ($self, $field, $op, $arg) = @_;
+ $arg = [$arg] if not ref $arg;
+ my $label = $self->_quote($field);
+ my ($placeholder) = $self->_convert('?');
+ my $placeholders = join ", ", (($placeholder) x @$arg);
+ my $sql = $self->_sqlcase('match') . " ($label) "
+ . $self->_sqlcase('against') . " ($placeholders) ";
+ my @bind = $self->_bindtype($field, @$arg);
+ return ($sql, @bind);
+ }
+ },
+
+ ]);
=head1 PERFORMANCE
on some dark areas of C<SQL::Abstract> v1.*
B<might behave differently> in v1.50.
-=head1 Public changes
-
=over
=item *