Re: Problems with empty/NULL lobs

[email protected] (Charles Jardine)
Newsgroups perl.dbi.users
Message-ID <[email protected]>
On 24/02/10 10:18, Martin Evans wrote:
> Tim Bunce wrote:
>> The Oracle::OCI module might be useful. See lob examples in
>> http://cpansearch.perl.org/src/TIMB/Oracle-OCI-0.06/05dbi.t
>>
>> Tim.
> 
> I tried but I don't have a full Oracle distribution just an instant
> client and after an hour of hackery I got close:

[ snip ]

> In the end I can change my procedure to return a reference cursor
> (although that will be annoying) or just an empty clob. I wish I had
> more time to look at this but I'm really struggling.

Oracle::OCI has received no maintenance since August 2001.

I have attached a patch I have used to make a version which
can be built against a full Oracle 10.2 client. 

I am offering this patch *completely unsupported*. I simply
do not have the time to maintain Oracle::OCI.

-- 
Charles Jardine - Computing Service, University of Cambridge
[email protected]    Tel: +44 1223 334506, Fax: +44 1223 334679
OCIpatch.txt (text/plain, 12.7 KB)
diff -r -u Oracle-OCI-0.06/01base.t Oracle-OCI-0.06.patched/01base.t
--- Oracle-OCI-0.06/01base.t	2001-08-31 23:02:45.000000000 +0100
+++ Oracle-OCI-0.06.patched/01base.t	2009-11-02 10:22:57.724121690 +0000
@@ -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 -r -u Oracle-OCI-0.06/boot Oracle-OCI-0.06.patched/boot
--- Oracle-OCI-0.06/boot	2001-08-30 16:49:24.000000000 +0100
+++ Oracle-OCI-0.06.patched/boot	2009-11-02 10:22:57.740121753 +0000
@@ -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,9 @@
 	TypeArrayByRef	=> "?",
 	EnvCallback	=> "?",
 	SharedLibInit	=> "uses 'dvoid *argv[]' type that we've not supported yet",
+        XmlDbInitXmlCtx => "",
+        XmlDbFreeXmlCtx => "",
+	NumberToRealArray => "",
 	'_ORACLE'	=> "empty define - used to prevent multiple #includes",
 	'_FLAGS'	=> "empty define - used to prevent multiple #includes",
     } } ],
@@ -131,15 +142,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 +175,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 +304,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 +333,7 @@
 }
 
 print "Building...\n";
-system("perl Makefile.PL && make && make test");
+system("$perlpath Makefile.PL && make && make test") && exit 1;
 
 exit 0;
 
diff -r -u Oracle-OCI-0.06/extra.typemap Oracle-OCI-0.06.patched/extra.typemap
--- Oracle-OCI-0.06/extra.typemap	2001-08-05 23:58:29.000000000 +0100
+++ Oracle-OCI-0.06.patched/extra.typemap	2009-11-02 10:22:57.752121800 +0000
@@ -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 -r -u Oracle-OCI-0.06/extra.xsh Oracle-OCI-0.06.patched/extra.xsh
--- Oracle-OCI-0.06/extra.xsh	2001-09-01 00:57:00.000000000 +0100
+++ Oracle-OCI-0.06.patched/extra.xsh	2009-11-02 10:35:52.187172901 +0000
@@ -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 -r -u Oracle-OCI-0.06/getptrdef.h Oracle-OCI-0.06.patched/getptrdef.h
--- Oracle-OCI-0.06/getptrdef.h	2001-07-11 10:32:56.000000000 +0100
+++ Oracle-OCI-0.06.patched/getptrdef.h	2009-11-02 10:22:57.800121989 +0000
@@ -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 -r -u Oracle-OCI-0.06/h2xs Oracle-OCI-0.06.patched/h2xs
--- Oracle-OCI-0.06/h2xs	2001-08-07 10:54:42.000000000 +0100
+++ Oracle-OCI-0.06.patched/h2xs	2009-11-02 10:22:57.824122084 +0000
@@ -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 -r -u Oracle-OCI-0.06/utility.c Oracle-OCI-0.06.patched/utility.c
--- Oracle-OCI-0.06/utility.c	2001-09-01 01:03:05.000000000 +0100
+++ Oracle-OCI-0.06.patched/utility.c	2009-11-02 10:22:57.848122179 +0000
@@ -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 -r -u Oracle-OCI-0.06/utility.h Oracle-OCI-0.06.patched/utility.h
--- Oracle-OCI-0.06/utility.h	2001-07-07 21:29:46.000000000 +0100
+++ Oracle-OCI-0.06.patched/utility.h	2009-11-02 10:22:57.856122210 +0000
@@ -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"
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.