Re: DBD-Oracle - obtaining OCI handles from $dbh

Charles Jardine <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.dbi.general
Message-ID <[email protected]>
On 28/10/11 16:09, Lyle Brooks wrote:
> Tim,
> 
> I have looked at the Oracle::OCI module.  I really like the
> concept, and it would undeniably be an extremely useful and
> powerful tool.  However, I couldn't get it to work (by that
> I mean...I couldn't get it to build).

I still use Oracle::OCI. There is a patch below which may
allow you to build it under Oracle 11.2.

As you will see, I have kept it going by botching things.
Whenever a new feature of OCI causes trouble, I add it to the
list of features to omit. I would like to do a better job, but
I simply don't have the time. All I can do is to offer this
patch on an as-seen basis, in the hope that it might inspire
some else to do a proper job of rescuing Oracle::OCI.


diff -ur Oracle-OCI-0.06.clean/01base.t Oracle-OCI-0.06.patched/01base.t
--- Oracle-OCI-0.06.clean/01base.t      2001-08-31 23:02:45.000000000 +0100
+++ Oracle-OCI-0.06.patched/01base.t    2011-10-17 10:52:24.204427839 +0100
@@ -96,7 +96,7 @@
 ok OCIAttrSet($$authp, OCI_HTYPE_SESSION, @user_buf_len, OCI_ATTR_USERNAME, $errhp), 0;
 ok OCIAttrSet($$authp, OCI_HTYPE_SESSION, @pass_buf_len, OCI_ATTR_PASSWORD, $errhp), 0;
 
-ok $status=OCISessionBegin($svchp, $errhp, $authp, OCI_CRED_RDBMS, OCI_DEFAULT), 0;
+ok $status=OCISessionBegin($svchp, $errhp, $authp, $user ? OCI_CRED_RDBMS : OCI_CRED_EXT, OCI_DEFAULT), 0;
 warn get_oci_error($errhp, $status) unless $status == OCI_SUCCESS;
 
 ok OCIAttrSet($$svchp, OCI_HTYPE_SVCCTX, $$authp, 0, OCI_ATTR_SESSION, $errhp), 0;
diff -ur Oracle-OCI-0.06.clean/boot Oracle-OCI-0.06.patched/boot
--- Oracle-OCI-0.06.clean/boot  2001-08-30 16:49:24.000000000 +0100
+++ Oracle-OCI-0.06.patched/boot        2011-10-17 11:31:37.856430344 +0100
@@ -1,9 +1,8 @@
-#!/opt/perl5/bin/perl -w
-
 require 5.6.0;
 use strict;
 
 use Carp;
+use Config;
 use File::Path;
 use File::Copy;
 use File::Basename;
@@ -17,6 +16,15 @@
 
 $| = 1;
 
+# The following is based on conventions entirely local to Jackdaw.
+# Perl install trees are at /usr/local/perl/<version>-<letter>.
+# Libraries for DBD::Oracle are at $ORACLE_HOME/PERL/<version>-<letter>/lib/DBD/Oracle.
+
+my $perlpath = $Config{perlpath};
+my $perlvl = (split /\//, $perlpath)[-3];
+my $ora_arch_dir = "$ENV{ORACLE_HOME}/PERL/$perlvl/lib/auto/DBD/Oracle";
+
+print "Oracle arch dir is $ora_arch_dir\n";
 
 ########################################################################
 # configuration section.  
@@ -99,6 +107,21 @@
        TypeArrayByRef  => "?",
        EnvCallback     => "?",
        SharedLibInit   => "uses 'dvoid *argv[]' type that we've not supported yet",
+        XmlDbInitXmlCtx => "",
+        XmlDbFreeXmlCtx => "",
+        XmlDbGetFullyQualifiedSchemaUrl => "",
+        XmlDbMemCallback => "",
+        XmlDbOrastreamFromLob => "",
+        XmlDbRewriteXMLDiff => "",
+        XmlDbStreamClose => "",
+        XmlDbStreamFromXMLType => "",
+        XmlDbStreamRead => "",
+        XmlFreeDRCtx => "",
+        XmlInitDRCtx => "",
+        LobGetDeduplicateRegions => "",
+        XStreamInLCRCallbackSend => "",
+        XStreamOutLCRCallbackReceive => "",
+       NumberToRealArray => "",
        '_ORACLE'       => "empty define - used to prevent multiple #includes",
        '_FLAGS'        => "empty define - used to prevent multiple #includes",
     } } ],
@@ -131,15 +154,14 @@
 -d $orahome  or croak "Error:  no such directory: $orahome";
 -r _ && -x _ or croak "Error:  bad mods on $orahome";
 
-my $demodir  = "$orahome/rdbms/demo";
--d $demodir  or croak "Error:  no directory '$demodir'";
--r _ && -x _ or croak "Error:  bad mods on '$demodir'";
-my $oci_hdr = "$demodir/oci.h";
+my $publicdir  = "$orahome/rdbms/public";
+-d $publicdir  or croak "Error:  no directory '$publicdir'";
+-r _ && -x _ or croak "Error:  bad mods on '$publicdir'";
+my $oci_hdr = "$publicdir/oci.h";
 -e $oci_hdr or croak "Error:  hit by a missing oci.h";
 -r _        or croak "Error:  unreadable $oci_hdr";
 
-my @ora_dirs = ($demodir,
-       "$orahome/rdbms/public",
+my @ora_dirs = ($publicdir,
        "$orahome/network/public",
        "$orahome/plsql/public",
 );
@@ -165,7 +187,8 @@
 my $skip_regex = '^OCI(?!' . join('|',@skip_list) . ')|^SQL';
 
 my @h2xsargz = (
-    qw( ./h2xs -d -O -n Oracle::OCI ),
+    $perlpath,
+    qw( h2xs -d -O -n Oracle::OCI ),
     "-F ".join(" ", map { "-I$_" } @ora_dirs),
     "-I".join(",", @ora_dirs),
     "-E get_oci_error,get_oci_handle,oci_buf_len,OCIAttrGet",
@@ -293,8 +316,7 @@
                use DBI::DBD;
                my $dbi_dir      = dbd_dbi_dir();
                my $dbi_arch_dir = dbd_dbi_arch_dir();
-               (my $ora_arch_dir = $dbi_arch_dir) =~ s!DBI$!DBD/Oracle!;
-       }."\n" if $. == 1;
+               my $ora_arch_dir = }."'$ora_arch_dir';\n\n" if $. == 1;
        s!^\);!      CONFIGURE => \\&wmf_config,\n);!;
        print $new_mk $_;
     }
@@ -323,7 +345,7 @@
 }
 
 print "Building...\n";
-system("perl Makefile.PL && make && make test");
+system("$perlpath Makefile.PL && make && make test") && exit 1;
 
 exit 0;
 
diff -ur Oracle-OCI-0.06.clean/extra.typemap Oracle-OCI-0.06.patched/extra.typemap
--- Oracle-OCI-0.06.clean/extra.typemap 2001-08-05 23:58:29.000000000 +0100
+++ Oracle-OCI-0.06.patched/extra.typemap       2011-10-17 10:52:24.212663069 +0100
@@ -1,7 +1,10 @@
 OCIRaw *               T_PTROBJ
 OCIRef *               T_PTROBJ
+OCIString *            T_PTROBJ
 OCITrans *             T_PTROBJ
 OCIType *              T_PTROBJ
+OCITypeElem *          T_PTROBJ
+OCITypeMethod *                T_PTROBJ
 int *                  T_PTROBJ
 void *                 T_PTROBJ
 sb1                    T_IV
diff -ur Oracle-OCI-0.06.clean/extra.xsh Oracle-OCI-0.06.patched/extra.xsh
--- Oracle-OCI-0.06.clean/extra.xsh     2001-09-01 00:57:00.000000000 +0100
+++ Oracle-OCI-0.06.patched/extra.xsh   2011-10-17 10:52:24.220628981 +0100
@@ -82,8 +82,7 @@
         int ptr_len = (SvNIOK(result_type)) ? SvIV(result_type) : 0;
        if (ptr_len==0 && !looks_like_number(result_type) ) {
            /* result_type is the name of a class to bless pointer into */
-           /* so we set ptr_len 4 and arrange to return a blessed ref. */
-           ptr_len = 4;
+           /* so we arrange to return a blessed ref.                   */
            bless = SvPV(result_type,lna);
        }
        switch (ptr_len) {
@@ -92,14 +91,23 @@
            RETVAL = OCIAttrGet(trgthndlp, trghndltyp, (void*)&b4_val, 0, attrtype, errhp);
            if (RETVAL==OCI_SUCCESS || RETVAL==OCI_SUCCESS_WITH_INFO) {
                switch (ptr_len) {
-               case  1: sv_setiv(attributep_sv, (IV)*((ub1*)&b4_val)); break;
+               case  1: sv_setuv(attributep_sv, (UV)*((ub1*)&b4_val)); break;
                case -1: sv_setiv(attributep_sv, (IV)*((sb1*)&b4_val)); break;
-               case  2: sv_setiv(attributep_sv, (IV)*((ub2*)&b4_val)); break;
+               case  2: sv_setuv(attributep_sv, (UV)*((ub2*)&b4_val)); break;
                case -2: sv_setiv(attributep_sv, (IV)*((sb2*)&b4_val)); break;
                case  4: sv_setuv(attributep_sv, (UV)*((ub4*)&b4_val)); break;
                case -4: sv_setiv(attributep_sv, (IV)*((sb4*)&b4_val)); break;
                }
                if (bless) {
+               }
+           }
+           else SvOK_off(attributep_sv);
+           break;
+       case 0:
+           if (bless) {
+               RETVAL = OCIAttrGet(trgthndlp, trghndltyp, &ptr, 0, attrtype, errhp);
+               if (RETVAL==OCI_SUCCESS || RETVAL==OCI_SUCCESS_WITH_INFO) {
+                   sv_setuv(attributep_sv, (UV)ptr);
                    SV *rv = newRV(sv_mortalcopy(attributep_sv));
                    HV * bless_stash = gv_stashpv(bless, 0);
                    if (!bless_stash) {
@@ -111,20 +119,20 @@
                    sv_bless(rv, bless_stash);
                    sv_setsv(attributep_sv, rv);
                }
+               else SvOK_off(attributep_sv);
            }
-           else SvOK_off(attributep_sv);
-           break;
-       case 0:
-           RETVAL = OCIAttrGet(trgthndlp, trghndltyp, &ptr, &sizep, attrtype, errhp);
-           if (RETVAL==OCI_SUCCESS || RETVAL==OCI_SUCCESS_WITH_INFO) {
-               /* OCIAttrGet may set ptr to null, sv_setpvn() treats that as undef */
-               sv_setpvn(attributep_sv, ptr, sizep);
-               if (!SvREADONLY(sizep_sv)) {
-                   sv_setiv(sizep_sv, sizep);
-                   SvSETMAGIC(sizep_sv); /* redundant */
+           else {
+               RETVAL = OCIAttrGet(trgthndlp, trghndltyp, &ptr, &sizep, attrtype, errhp);
+               if (RETVAL==OCI_SUCCESS || RETVAL==OCI_SUCCESS_WITH_INFO) {
+                   /* OCIAttrGet may set ptr to null, sv_setpvn() treats that as undef */
+                   sv_setpvn(attributep_sv, ptr, sizep);
+                   if (!SvREADONLY(sizep_sv)) {
+                       sv_setiv(sizep_sv, sizep);
+                       SvSETMAGIC(sizep_sv); /* redundant */
+                   }
                }
+               else SvOK_off(attributep_sv);
            }
-           else SvOK_off(attributep_sv);
            break;
        default:
            croak("Invalid pointer width '%s' for OCIAttrGet", SvPV(result_type,lna));
diff -ur Oracle-OCI-0.06.clean/getptrdef.h Oracle-OCI-0.06.patched/getptrdef.h
--- Oracle-OCI-0.06.clean/getptrdef.h   2001-07-11 10:32:56.000000000 +0100
+++ Oracle-OCI-0.06.patched/getptrdef.h 2011-10-17 10:52:24.228616063 +0100
@@ -1,13 +1,25 @@
 #define ora_getptr_Lda_DefPtr ora_getptr_generic
+#define ora_getptr_OCIAdminPtr ora_getptr_generic
+#define ora_getptr_OCIAnyDataPtr ora_getptr_generic
+#define ora_getptr_OCIAnyDataSetPtr ora_getptr_generic
 #define ora_getptr_OCIAQDeqOptionsPtr ora_getptr_generic
 #define ora_getptr_OCIAQEnqOptionsPtr ora_getptr_generic
 #define ora_getptr_OCIAQMsgPropertiesPtr ora_getptr_generic
+#define ora_getptr_OCIAuthInfoPtr ora_getptr_generic
 #define ora_getptr_OCIBindPtr ora_getptr_generic
 #define ora_getptr_OCICallbackDefine ora_getptr_generic
 #define ora_getptr_OCICallbackInBind ora_getptr_generic
+#define ora_getptr_OCICallbackLobArrayRead ora_getptr_generic
+#define ora_getptr_OCICallbackLobArrayWrite ora_getptr_generic
+#define ora_getptr_OCICallbackLobRead ora_getptr_generic
+#define ora_getptr_OCICallbackLobRead2 ora_getptr_generic
+#define ora_getptr_OCICallbackLobWrite ora_getptr_generic
+#define ora_getptr_OCICallbackLobWrite2 ora_getptr_generic
 #define ora_getptr_OCICallbackOutBind ora_getptr_generic
 #define ora_getptr_OCICollPtr ora_getptr_generic
 #define ora_getptr_OCIComplexObjectPtr ora_getptr_generic
+#define ora_getptr_OCICPoolPtr ora_getptr_generic
+#define ora_getptr_OCIDOMDocumentPtr ora_getptr_generic
 #define ora_getptr_OCIDatePtr ora_getptr_generic
 #define ora_getptr_OCIDateTimePtr ora_getptr_generic
 #define ora_getptr_OCIDefinePtr ora_getptr_generic
@@ -18,6 +30,7 @@
 #define ora_getptr_OCIDurationPtr ora_getptr_generic
 #define ora_getptr_OCIEnvPtr ora_getptr_generic
 #define ora_getptr_OCIErrorPtr ora_getptr_generic
+#define ora_getptr_OCIEventPtr ora_getptr_generic
 #define ora_getptr_OCIFileObjectPtr ora_getptr_generic
 #define ora_getptr_OCIIndPtr ora_getptr_generic
 #define ora_getptr_OCIIntervalPtr ora_getptr_generic
@@ -27,6 +40,7 @@
 #define ora_getptr_OCIMsgPtr ora_getptr_generic
 #define ora_getptr_OCINumberPtr ora_getptr_generic
 #define ora_getptr_OCIObjectEvent ora_getptr_generic
+#define ora_getptr_OCIParamPtr ora_getptr_generic
 #define ora_getptr_OCIObjectProperty ora_getptr_generic
 #define ora_getptr_OCIPicklerFdoPtr ora_getptr_generic
 #define ora_getptr_OCIPicklerImagePtr ora_getptr_generic
@@ -38,10 +52,12 @@
 #define ora_getptr_OCIRefPtr ora_getptr_generic
 #define ora_getptr_OCIRefreshOpt ora_getptr_generic
 #define ora_getptr_OCIResultPtr ora_getptr_generic
+#define ora_getptr_OCIRowidPtr ora_getptr_generic
 #define ora_getptr_OCISecurityPtr ora_getptr_generic
 #define ora_getptr_OCIServerPtr ora_getptr_generic
 #define ora_getptr_OCISessionPtr ora_getptr_generic
 #define ora_getptr_OCISnapshotPtr ora_getptr_generic
+#define ora_getptr_OCISPoolPtr ora_getptr_generic
 #define ora_getptr_OCIStmtPtr ora_getptr_generic
 #define ora_getptr_OCIStringPtr ora_getptr_generic
 #define ora_getptr_OCISubscriptionPtr ora_getptr_generic
@@ -63,6 +79,10 @@
 #define ora_getptr_OCIUserCallback ora_getptr_generic
 #define ora_getptr_OCIUserCallbackPtr ora_getptr_generic
 #define ora_getptr_OCIWcharPtr ora_getptr_generic
+#define ora_getptr_OCIXADFieldPtr ora_getptr_generic
+#define ora_getptr_OCIXADTablePtr ora_getptr_generic
+#define ora_getptr_OCIXMLTypePtr ora_getptr_generic
+#define ora_getptr_OraTextPtr ora_getptr_generic
 #define ora_getptr_nzttBufferBlockPtr ora_getptr_generic
 #define ora_getptr_nzttCipherType ora_getptr_generic
 #define ora_getptr_nzttIdentType ora_getptr_generic
diff -ur Oracle-OCI-0.06.clean/h2xs Oracle-OCI-0.06.patched/h2xs
--- Oracle-OCI-0.06.clean/h2xs  2001-08-07 10:54:42.000000000 +0100
+++ Oracle-OCI-0.06.patched/h2xs        2011-10-17 10:52:24.236604422 +0100
@@ -1,7 +1,3 @@
-#!/opt/perl5/bin/perl
-    eval 'exec /opt/perl5/bin/perl -S $0 ${1+"$@"}'
-       if $running_under_some_shell;
-
 =head1 NAME
 
 h2xs - convert .h C header files to Perl extensions
@@ -557,6 +553,7 @@
     my @td;
     my @good_td;
     my $addflags = $opt_F || '';
+    $addflags = "-D__extension__= -D__inline= -P $addflags";
 
     # pass -I dirs on into C::Scan
     my @dirs_h = split /,/, $opt_I||'';
@@ -571,8 +568,10 @@
        $filter = $';
       }
       warn "Scanning $filename for functions...\n";
+      my @styles = $Config{gccversion} ? qw(C++ C9X GNU) : qw(C++ C9X);
+      warn "c_styles: " , join(' ', @styles), "\n";
       $c = new C::Scan 'filename' => $filename, 'filename_filter' => $filter,
-       'add_cppflags' => $addflags, 'c_styles' => [qw(C++ C9X)];
+       'add_cppflags' => $addflags, 'c_styles' => \@styles;
       $c->set('includeDirs' => [@dirs_h,"$Config::Config{archlib}/CORE"]);
 
       # force addition of __restrict into keywords (asap)
diff -ur Oracle-OCI-0.06.clean/utility.c Oracle-OCI-0.06.patched/utility.c
--- Oracle-OCI-0.06.clean/utility.c     2001-09-01 01:03:05.000000000 +0100
+++ Oracle-OCI-0.06.patched/utility.c   2011-10-17 10:52:24.240427617 +0100
@@ -39,7 +39,7 @@
 
 
 I32
-oci_buf_getmaxlen(IV svptr_iv, SV* len_sv)
+oci_buf_getmaxlen(pTHX_ IV svptr_iv, SV* len_sv)
 {
     STRLEN lna;
     SV *buf_sv = (SV*)svptr_iv;
@@ -50,7 +50,7 @@
 }
 
 I32
-oci_buf_setcurlen(IV svptr_iv, SV* len_sv)
+oci_buf_setcurlen(pTHX_ IV svptr_iv, SV* len_sv)
 {
     SV *buf_sv = (SV*)svptr_iv;
     IV len = SvIV(len_sv);
diff -ur Oracle-OCI-0.06.clean/utility.h Oracle-OCI-0.06.patched/utility.h
--- Oracle-OCI-0.06.clean/utility.h     2001-07-07 21:29:46.000000000 +0100
+++ Oracle-OCI-0.06.patched/utility.h   2011-10-17 10:52:24.244495169 +0100
@@ -9,8 +9,8 @@
 
 void *ora_getptr_generic(SV *arg, char *var, char *type, char *func);
 
-I32 oci_buf_getmaxlen(IV svptr_iv, SV* len_sv);
-I32 oci_buf_setcurlen(IV svptr_iv, SV* len_sv);
+I32 oci_buf_getmaxlen(pTHX_ IV svptr_iv, SV* len_sv);
+I32 oci_buf_setcurlen(pTHX_ IV svptr_iv, SV* len_sv);
 
 
 #include "getptrdef.h"


-- 
Charles Jardine - Computing Service, University of Cambridge
[email protected]    Tel: +44 1223 334506, Fax: +44 1223 334679
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.