Subject: | transform_sql() test file; patch: more robust regex for __FOO__ replacements |
Test file and patch for Class::DBI::SQL::Transformer::transform_sql() to
handle malformed strings such as __TABLETest)__ . Currently, it will
treat __TABLETest__, __TABLE(Test__, __TABLETest)__ as all the same, and
process it the same as __TABLE(Test)__.
Also treats __TABLE()__ as __TABLE__ (ditto for JOIN and ESSENTIAL).
While i'm not entirely sure that the second item (e.g. __ESSENTIAL()__)
is something bad/malformed, the first definitely is and could be hit,
e.g. __TABLES__
Side effect was that _expand_table($1) now can be passed undef (if no $1
matches) instead of always getting '' when no match, hence the defined()
check there. Alternatively, there could be two checks, one for __TABLE__
and one for __TABLE(foo)__ as for ESSENTIAL.
patch is against Class-DBI-v3.0.17
3.0.17 test suite passes before & after (i386-linux v5.6.1)
69c69,70
< my ($class, $alias) = split /=/, shift, 2;
---
Show quoted text
> my $s = shift;
> my ($class, $alias) = split /=/, defined($s)?$s:'', 2;
114,115c115,116
< $sql =~ s/__TABLE\(?(.*?)\)?__/$me->_expand_table($1)/eg;
< $sql =~ s/__JOIN\((.*?)\)__/$me->_expand_join($1)/eg;
---
Show quoted text> $sql =~ s/__TABLE(?:\((.+?)\))?__/$me->_expand_table($1)/eg;
> $sql =~ s/__JOIN\((.+?)\)__/$me->_expand_join($1)/eg;
118c119
< s/__ESSENTIAL\((.*?)\)__/join ", ", map "$1.$_",
$caller->_essential/eg;
---
Show quoted text> s/__ESSENTIAL\((.+?)\)__/join ", ", map "$1.$_",
$caller->_essential/eg;
Subject: | transform_sql.patch |
*** ../Class-DBI-v3.0.17/lib/Class/DBI/SQL/Transformer.pm Tue Sep 20 05:56:36 2005
--- lib/Class/DBI/SQL/Transformer.pm Sun Jan 6 20:29:54 2008
***************
*** 66,72 ****
sub _expand_table {
my $self = shift;
! my ($class, $alias) = split /=/, shift, 2;
my $caller = $self->{_caller};
my $table = $class ? $class->table : $caller->table;
$self->{cmap}{ $alias || $table } = $class || ref $caller || $caller;
--- 66,73 ----
sub _expand_table {
my $self = shift;
! my $s = shift;
! my ($class, $alias) = split /=/, defined($s)?$s:'', 2;
my $caller = $self->{_caller};
my $table = $class ? $class->table : $caller->table;
$self->{cmap}{ $alias || $table } = $class || ref $caller || $caller;
***************
*** 111,121 ****
my @args = @{ $me->{_args} };
my $caller = $me->{_caller};
! $sql =~ s/__TABLE\(?(.*?)\)?__/$me->_expand_table($1)/eg;
! $sql =~ s/__JOIN\((.*?)\)__/$me->_expand_join($1)/eg;
$sql =~ s/__ESSENTIAL__/join ", ", $caller->_essential/eg;
$sql =~
! s/__ESSENTIAL\((.*?)\)__/join ", ", map "$1.$_", $caller->_essential/eg;
if ($sql =~ /__IDENTIFIER__/) {
my $key_sql = join " AND ", map "$_=?", $caller->primary_columns;
$sql =~ s/__IDENTIFIER__/$key_sql/g;
--- 112,122 ----
my @args = @{ $me->{_args} };
my $caller = $me->{_caller};
! $sql =~ s/__TABLE(?:\((.+?)\))?__/$me->_expand_table($1)/eg;
! $sql =~ s/__JOIN\((.+?)\)__/$me->_expand_join($1)/eg;
$sql =~ s/__ESSENTIAL__/join ", ", $caller->_essential/eg;
$sql =~
! s/__ESSENTIAL\((.+?)\)__/join ", ", map "$1.$_", $caller->_essential/eg;
if ($sql =~ /__IDENTIFIER__/) {
my $key_sql = join " AND ", map "$_=?", $caller->primary_columns;
$sql =~ s/__IDENTIFIER__/$key_sql/g;
Subject: | transform_sql.t |
#!perl
use strict;
use warnings;
use Test::More tests => 19;
$|=1;
package Test;
use base qw/Class::DBI/;
__PACKAGE__->connection('DBI:Mock:', '', '');
__PACKAGE__->table('table_name');
__PACKAGE__->columns( Primary => qw/some_id/ );
__PACKAGE__->columns( Essential => qw/col1 col2 col3/ );
package main;
foreach my $test (
[ '__TABLE__', 'table_name' ],
[ '__TABLE(Test)__', 'table_name' ],
[ '__IDENTIFIER__', 'some_id=?' ],
[ '__ESSENTIAL__', 'some_id, col1, col2, col3' ],
[ '__ESSENTIAL(tbl)__', 'tbl.some_id, tbl.col1, tbl.col2, tbl.col3' ],
# these should come through verbatim
map( [ $_, $_ ], qw/
blarg
__FOO__
blarg(rogue open paren
blarg)rogue close paren
__TABLE(Test__
__TABLETest)__
__TABLETest__
__TABLE()__
__JOIN()__
__ESSENTIAL()__
/)
){
my $s = eval { Test->transform_sql( $test->[0], () ) };
is( $s, $test->[1], "sql: ".$test->[0] );
}
exit;