Skip to content

Instantly share code, notes, and snippets.

@kazeburo
Created December 14, 2010 16:23
Show Gist options
  • Save kazeburo/740652 to your computer and use it in GitHub Desktop.
Save kazeburo/740652 to your computer and use it in GitHub Desktop.
Index: t/00base.t
===================================================================
--- t/00base.t (revision 38723)
+++ t/00base.t (working copy)
@@ -1,7 +1,7 @@
use strict;
use warnings;
-use Test::More tests => 20;
+use Test::More tests => 24;
BEGIN { use_ok('DBIx::Printf'); }
@@ -30,6 +30,13 @@
is($dbh->printf('select 1 like %like()'), "select 1 like ''", 'empty %like');
is($dbh->printf('select 1 like %like(%s%%)', 'a'), "select 1 like 'a%'", '%like');
is($dbh->printf('select 1 like %like(%s%%)', "%a_b'"), "select 1 like '\\%a\\_b''%'", '%like escape check');
+is($dbh->printf(q!select 1 like %like(%s%%) escape '\'!, "%a_b'"), qq!select 1 like '\\%a\\_b''%' escape '\\'!, '%like escape check backslash');
+is($dbh->printf(q!select 1 like %like(%s%%) ESCAPE '$'!, "%a_b'"), qq!select 1 like '\$%a\$_b''%' ESCAPE '\$'!, '%like escape check doller');
+is($dbh->printf(q!select 1 like %like(%s%%) Escape ''!, "%a_b'"), qq!select 1 like '%a_b''%' Escape ''!, '%like escape check backslash');
+is($dbh->printf(<<'EOF',"%a_b'"), qq!select 1 like '\*%a\*_b''%'\nESCAPE '\*'\n!, '%like escape check *');
+select 1 like %like(%s%%)
+ESCAPE '*'
+EOF
undef $@;
eval {
Index: lib/DBIx/Printf.pm
===================================================================
--- lib/DBIx/Printf.pm (revision 38723)
+++ lib/DBIx/Printf.pm (working copy)
@@ -9,14 +9,16 @@
our $VERSION = '0.07';
sub _printf {
- my ($dbh, $fmt, $params, $in_like) = @_;
+ my ($dbh, $fmt, $params, $in_like, $like_escape) = @_;
- $fmt =~ s/\%(?:([dfst\%])|like\((.*?)\))/
+ $fmt =~ s/\%(?:([dfst\%])|like\((.*?)\)((?i)\s+ESCAPE\s+(['"])(.*?)\4(?:\s+|$))?)/
_printf_quote({
dbh => $dbh,
params => $params,
type => $1 || 'like',
like_fmt => $2,
+ like_escape => $3,
+ like_escape_char => defined $like_escape ? $like_escape : $5,
in_like => $in_like,
})
/eg;
@@ -31,18 +33,18 @@
return '%';
} elsif ($in->{type} eq 'like') {
return "'"
- . _printf($in->{dbh}, $in->{like_fmt}, $in->{params}, 1)
- . "'";
+ . _printf($in->{dbh}, $in->{like_fmt}, $in->{params}, 1, $in->{like_escape_char})
+ . "'" . ($in->{like_escape} || '')
}
return _printf_quote_simple(
- $in->{dbh}, $in->{type}, $in->{params}, $in->{in_like}
+ $in->{dbh}, $in->{type}, $in->{params}, $in->{in_like}, $in->{like_escape_char}
);
}
sub _printf_quote_simple {
no warnings;
- my ($dbh, $type, $params, $in_like) = @_;
+ my ($dbh, $type, $params, $in_like, $like_escape_char) = @_;
Carp::Clan::croak "too few parameters\n" unless @$params;
my $param = shift @$params;
@@ -58,7 +60,8 @@
or Carp::Clan::croak "unexpected quote char used: $param\n";
} elsif ($type eq 's') {
if ($in_like) {
- $param =~ s/[%_]/\\$&/g;
+ my $escape_char = defined $like_escape_char ? $like_escape_char : '\\';
+ $param =~ s/[${escape_char}%_]/$escape_char$&/g;
}
$param = $dbh->quote($param);
if ($in_like) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment