Hello!
On Fri, 7 Sep 2007, Tim Bunce wrote:
$sth->bind_param_inout(":mytable1", [EMAIL PROTECTED], 100, { TYPE =>
DBD::Oracle::ORA_VARCHAR2 } );
But autogenerated code from DBD prohibits array reference binds.
void
bind_param_inout(sth, param, value_ref, maxlen, attribs=Nullsv)
SV * sth
SV * param
SV * value_ref
IV maxlen
SV * attribs
CODE:
{
IV sql_type = 0;
D_imp_sth(sth);
SV *value;
if (!SvROK(value_ref) || SvTYPE(SvRV(value_ref)) > SVt_PVMG)
croak("bind_param_inout needs a reference to a scalar value");
value = SvRV(value_ref);
if (SvREADONLY(value))
croak("Modification of a read-only value attempted");
But it would be great to bind arrays inout. What is the proper way
to allow array bind?
My first thought was to allow a reference to an array to be passed in,
as you're trying to do. After some more thought I've decided it's not
needed.
Consider this example of how a script might use bind_param and bind_param_inout:
$foo = 42;
$sth->bind_param(":foo", $foo);
$sth->bind_param_inout(":foo", \$foo);
note that bind_param_inout is passed a reference because it will
overwrite the referenced value with a new one. Hence the check that
it's not a read-only value.
Now consider this example:
$foo = [ 42 ];
$sth->bind_param(":foo", $foo);
$sth->bind_param_inout(":foo", \$foo);
The kind of value has changed but bind_param_inout() is still passed a
reference to that value for the same reason: it may modify it.
So, the user would have to use references, not standard
types. This lacks another compile-time type checks, even though there are not
too many of them at all.
May be It's reasonable to #ifdef array bind ? So more
compile-time checks can be done. (Patch attached.)
Bye. Alex.
Index: Driver.xst
===================================================================
--- Driver.xst (revision 9919)
+++ Driver.xst (working copy)
@@ -526,13 +526,32 @@
IV sql_type = 0;
D_imp_sth(sth);
SV *value;
- if (!SvROK(value_ref) || SvTYPE(SvRV(value_ref)) > SVt_PVMG)
+ if (!SvROK(value_ref) ||
+ (
+ (SvTYPE(SvRV(value_ref)) > SVt_PVMG)
+#ifdef BIND_PARAM_INOUT_ALLOW_ARRAY
+ && (SvTYPE(SvRV(value_ref)) != SVt_PVAV)
+#endif
+ )
+ ){
+#ifdef BIND_PARAM_INOUT_ALLOW_ARRAY
+ croak("bind_param_inout needs a reference to a scalar or array value");
+#else
croak("bind_param_inout needs a reference to a scalar value");
+#endif
+ }
value = SvRV(value_ref);
if (SvREADONLY(value))
croak("Modification of a read-only value attempted");
- if (SvGMAGICAL(value))
- mg_get(value);
+#ifdef BIND_PARAM_INOUT_ALLOW_ARRAY
+ if(SvTYPE(SvRV(value_ref))==SVt_PVAV){
+ value=value_ref;
+ }else
+#endif
+ {
+ if (SvGMAGICAL(value))
+ mg_get(value);
+ }
if (attribs) {
if (SvNIOK(attribs)) {
sql_type = SvIV(attribs);