From: Laurent Dami Date: Fri, 17 Oct 2008 07:07:17 +0000 (+0000) Subject: 1.5 release candidate : filling some holes in the doc X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e3f9dff45ca1ab7eb5e88ffe50da48f048dc813f;hp=96449e8ea5159e5448ebfc81dfa200dc674f366b;p=scpubgit%2FQ-Branch.git 1.5 release candidate : filling some holes in the doc --- diff --git a/Changes b/Changes index 1b3d790..f8906ae 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,17 @@ Revision history for SQL::Abstract +---------------------------- +revision 1.49_01 + - deep internal refactoring (see L> 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) diff --git a/lib/SQL/Abstract.pm b/lib/SQL/Abstract.pm index bcc06f5..3bb452c 100644 --- a/lib/SQL/Abstract.pm +++ b/lib/SQL/Abstract.pm @@ -1283,7 +1283,7 @@ specify C, you will get an array that looks like this: ); You can then iterate through this manually, using DBI's C. - + $sth->prepare($stmt); my $i = 1; for (@bind) { @@ -1395,7 +1395,7 @@ The argument can be either an arrayref (interpreted as a list 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 @@ -1637,6 +1637,17 @@ You would do: -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 @@ -1898,12 +1909,67 @@ or an array of either of the two previous forms. Examples: =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. For other operators, +like the MATCH .. AGAINST example above which is +specific to MySQL, you can write your own operator handlers : +supply a C argument to the C 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 @@ -1973,8 +2039,6 @@ to clarify the semantics. Hence, client code that was relying on some dark areas of C v1.* B in v1.50. -=head1 Public changes - =over =item *