use
5.10.0;
our
$VERSION
= 1.02;
my
@default_dbh_methods
=
qw/do
prepare
selectrow_array
selectrow_arrayref
selectrow_hashref
selectall_arrayref
selectall_array
selectall_hashref
selectcol_arrayref/
;
my
@default_sth_methods
=
qw/bind_param
bind_param_array
execute
execute_array/
;
sub
new {
my
(
$class
,
%options
) =
@_
;
my
$error
= __PACKAGE__ .
"->new()"
;
for
(
$options
{debug}) {!
$_
or
ref
$_
eq
'CODE'
or
die
"$error: 'debug' should be a coderef"
}
for
(
$options
{dbh_methods}) {!
$_
or
ref
$_
eq
'ARRAY'
or
die
"$error: 'dbh_methods' should be an arrayref"
}
for
(
$options
{sth_methods}) {!
$_
or
ref
$_
eq
'ARRAY'
or
die
"$error: 'sth_methods' should be an arrayref"
}
my
$self
= {
debug
=>
delete
$options
{debug},
dbh_methods
=>
delete
$options
{dbh_methods} // \
@default_dbh_methods
,
sth_methods
=>
delete
$options
{sth_methods} // \
@default_sth_methods
,
};
my
@invalid_options
=
keys
%options
;
die
"$error: invalid options : "
.
join
" / "
,
@invalid_options
if
@invalid_options
;
bless
$self
,
$class
;
}
sub
inject_callbacks {
my
(
$self
,
$dbh
,
@invalid_args
) =
@_
;
$dbh
->isa(
'DBI::db'
) or
die
'->inject_callbacks() : arg is not a database handle'
;
!
@invalid_args
or
die
'->inject_callbacks() : too many args'
;
my
$debug
=
$self
->{debug};
my
$upgrade_string_args
=
sub
{
$debug
->(
"$_ callback"
)
if
$debug
;
ARG:
foreach
my
$i
(1 ..
$#_
) { # start only at 1 because
$_
[0] is the DBI handle
next
ARG
if
!
$_
[
$i
];
if
(!
ref
$_
[
$i
]) {
next
ARG
if
looks_like_number(
$_
[
$i
]) or utf8::is_utf8(
$_
[
$i
]);
$debug
->(
"upgrading arg [$i] ($_[$i])"
)
if
$debug
;
utf8::upgrade(
$_
[
$i
]);
}
elsif
(
ref
$_
[
$i
] eq
'ARRAY'
) {
for
my
$val
(
grep
{
$_
&& !
ref
$_
&& !looks_like_number(
$_
) && !utf8::is_utf8(
$_
)} @{
$_
[
$i
]}) {
$debug
->(
"upgrading string in array arg [$i] ($val)"
)
if
$debug
;
utf8::upgrade(
$val
);
}
}
}
return
;
};
my
$parent_callbacks
=
$dbh
->{Callbacks} //= {};
my
$child_callbacks
=
$parent_callbacks
->{ChildCallbacks} //= {};
inject_callback(
$parent_callbacks
,
$_
=>
$upgrade_string_args
)
for
@{
$self
->{dbh_methods}};
inject_callback(
$child_callbacks
,
$_
=>
$upgrade_string_args
)
for
@{
$self
->{sth_methods}};
}
sub
inject_callback {
my
(
$hash
,
$key
,
$coderef
) =
@_
;
my
$previous_cb
=
$hash
->{
$key
};
my
$new_cb
=
$previous_cb
?
sub
{
&$coderef
;
&$previous_cb
} :
$coderef
;
$hash
->{
$key
} =
$new_cb
;
}
1;