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);

Reply via email to