Author: byterock
Date: Sun Mar 16 16:11:30 2008
New Revision: 10928
Modified:
dbd-oracle/branches/xml/Changes
dbd-oracle/branches/xml/Oracle.h
dbd-oracle/branches/xml/Oracle.pm
dbd-oracle/branches/xml/dbdimp.c
dbd-oracle/branches/xml/oci.def
dbd-oracle/branches/xml/ocitrace.h
Log:
changes for the xml patch
Modified: dbd-oracle/branches/xml/Changes
==============================================================================
--- dbd-oracle/branches/xml/Changes (original)
+++ dbd-oracle/branches/xml/Changes Sun Mar 16 16:11:30 2008
@@ -1,5 +1,6 @@
=head1 Changes in DBD-Oracle 1.21(svn rev xxxx)
+ Added support for direct insert of large XML data with XMLType from Hendrik
Fuss
Fixed memory leak (not releasing Temp Lob with OCILobFreeTemporary) when
created for a bind John Scoles
Added suppot for bind_param_inout_array with use with execute_array from
John Scoles
Added enhancement for Embedded Objects handling from Paul G. Weiss
Modified: dbd-oracle/branches/xml/Oracle.h
==============================================================================
--- dbd-oracle/branches/xml/Oracle.h (original)
+++ dbd-oracle/branches/xml/Oracle.h Sun Mar 16 16:11:30 2008
@@ -98,5 +98,5 @@
#define ORA_VARCHAR2_TABLE 201
#define ORA_NUMBER_TABLE 202
-
+#define XMLType 108
/* end of Oracle.h */
Modified: dbd-oracle/branches/xml/Oracle.pm
==============================================================================
--- dbd-oracle/branches/xml/Oracle.pm (original)
+++ dbd-oracle/branches/xml/Oracle.pm Sun Mar 16 16:11:30 2008
@@ -3221,6 +3221,36 @@
Any NULL values found in the embedded object will be returned as 'undef'.
+=head1 Support for Insert of XMLType
+
+Inserting large XML data sets into tables with XMLType fields is now supported
by DBD::Oracle. The only special
+requirement is the use of bind_param() with an attribute hash parameter that
specifies ora_type as XMLType. For
+example with a table like this;
+
+ create table books (book_id number, book_xml XMLType);
+
+one can insert data using this code
+
+ $sql='insert into books values (1,:p_xml)';
+ $xml= '<Books>
+ <Book id=1>
+ <Title>Programming the Perl DBI</Title>
+ <Subtitle>The Cheetah Book</Subtitle>
+ <Authors>
+ <Author>T. Bunce</Author>
+ <Author>Alligator Descartes</Author>
+ </Authors>
+
+ </Book>
+ </Books>....
+ <Book id=10000> ...';
+ my $sth =$dbh-> prepare($sql);
+ $sth-> bind_param("p_xml", $xml, { ora_type => XMLType });
+ $sth-> execute();
+
+In the above case we will assume that $xml has 10000 Book nodes and is over
4mb is size and is well formed XML.
+This will also work for XML that is smaller than 4mb as well. Attempting to
insert malformed XML will cause an error.
+
=head1 Oracle Related Links
=head2 Oracle Instant Client
Modified: dbd-oracle/branches/xml/dbdimp.c
==============================================================================
--- dbd-oracle/branches/xml/dbdimp.c (original)
+++ dbd-oracle/branches/xml/dbdimp.c Sun Mar 16 16:11:30 2008
@@ -986,6 +986,127 @@
/* ================================================================== */
+#define MAX_OCISTRING_LEN 32766
+
+SV *
+createxmlfromstring(imp_sth_t *imp_sth, SV *source){
+
+ dTHX;
+ OCIXMLType *xml = NULL;
+ ub4 len;
+ sword status;
+ ub1 src_type;
+ dvoid* src_ptr = NULL;
+ D_imp_dbh_from_sth;
+ SV* sv_dest;
+ dvoid *bufp;
+ ub1 csform;
+ ub2 csid;
+ csid = 0;
+ csform = SQLCS_IMPLICIT;
+ PerlIO_printf(DBILOGFP, "in createxmlfromstring strlen(source)=
%d\n",SvLEN(source));
+
+
+ len = SvLEN(source);
+bufp = SvPV(source, len);
+ if(len > MAX_OCISTRING_LEN) {
+ src_type = OCI_XMLTYPE_CREATE_CLOB;
+
+ printf("OCIDescriptorAlloc\n");
+ OCIDescriptorAlloc_ok(imp_dbh->envhp, &src_ptr, OCI_DTYPE_LOB);
+
+ /* OCIDescriptorAlloc((dvoid*)imp_dbh->envhp,
+ (dvoid **),
+ (ub4),
+ (size_t)0,
+ (dvoid**)0);*/
+
+ printf("OCILobCreateTemporary src_ptr=%d\n",src_ptr);
+
+ OCILobCreateTemporary_log_stat(imp_dbh->svchp, imp_sth->errhp,
+ (OCILobLocator *) src_ptr, (ub2) OCI_DEFAULT,
+ (ub1) OCI_DEFAULT, OCI_TEMP_CLOB, FALSE,
OCI_DURATION_SESSION, status);
+
+ printf("OCILobCreateTemporary OCI_SUCCESS=%d\n",OCI_SUCCESS);
+
+
+
+ /* OCILobCreateTemporary(imp_dbh->svchp,
+ imp_dbh->errhp,
+ (OCILobLocator*) src_ptr,
+ (ub2)0,
+ SQLCS_IMPLICIT,
+ OCI_TEMP_CLOB,
+ OCI_ATTR_NOCACHE,
+ OCI_DURATION_SESSION);
+*/
+ printf("OCILobWrite\n");
+
+ csid = (SvUTF8(source) && !CS_IS_UTF8(csid)) ? utf8_csid :
CSFORM_IMPLIED_CSID(csform);
+
+ OCILobWriteAppend_log_stat(imp_dbh->svchp, imp_dbh->errhp, src_ptr,
+ &len, bufp, (ub4)len, OCI_ONE_PIECE,
+ NULL, NULL,
+ csid, csform, status);
+
+ /* OCILobWriteAppend_log_stat(imp_dbh->svchp, imp_dbh->errhp, src_ptr,
+ &len,(ub1*) source,len, OCI_ONE_PIECE,
+ NULL, NULL,
+ 0, 0, status);
+*/
+ printf("OCILobWriteAppend_log_stat OCI_SUCCESS=%d\n",status);
+
+/* OCILobWriteAppend(imp_dbh->svchp,
+ imp_dbh->errhp,
+ (OCILobLocator*) src_ptr,
+ &len,
+ (ub1*)source,
+ len,
+ OCI_ONE_PIECE,
+ (dvoid *)0,
+ (sb4 (*)(dvoid*,dvoid*,ub4*,ub1 *))0,
+ 0,
+ SQLCS_IMPLICIT);
+*/
+ } else {
+ src_type = OCI_XMLTYPE_CREATE_OCISTRING;
+
+ printf("OCIStringAssignText\n");
+ OCIStringAssignText(imp_dbh->envhp,
+ imp_dbh->errhp,
+ (CONST text*) source,
+ (ub2) SvLEN(source),
+ (OCIString **) &src_ptr);
+ }
+
+ printf("OCIXMLTypeCreateFromSrc\n");
+
+/*
OCIXMLTypeCreateFromSrc_log_stat(imp_dbh->svchp,imp_dbh->envhp,src_type,src_ptr,&xml,status);
+*/
+
+status= OCIXMLTypeCreateFromSrc(imp_dbh->svchp,
+ imp_dbh->errhp,
+ (OCIDuration)OCI_DURATION_CALLOUT,
+ (ub1)src_type,
+ (dvoid *)src_ptr,
+ (sb4)OCI_IND_NOTNULL,
+ &xml);
+
+ printf("OCIXMLTypeCreateFromSrc status=%d\n",status);
+ /* free temporary resources */
+ if( src_type == OCI_XMLTYPE_CREATE_CLOB ) {
+ OCILobFreeTemporary(imp_dbh->svchp, imp_dbh->errhp,
+ (OCILobLocator*) src_ptr);
+
+ OCIDescriptorFree((dvoid *) src_ptr, (ub4) OCI_DTYPE_LOB);
+ }
+
+
+ sv_dest = newSViv(0);
+ sv_setref_pv(sv_dest, "OCIXMLTypePtr", xml);
+ return sv_dest;
+
+}
void
@@ -2273,6 +2394,9 @@
sword status;
SV* ptr;
+PerlIO_printf(DBILOGFP, "in dbd_rebind_ph_nty phs = %d\n",phs);
+ phs->sv=createxmlfromstring(imp_sth, phs->sv );
+
if (phs->is_inout)
croak("OUT binding for NTY is currently unsupported");
@@ -2311,7 +2435,7 @@
oci_error(sth, imp_sth->errhp, status, "OCIBindByName SQLT_NTY");
return 0;
}
- if (DBIS->debug >= 3)
+ if (DBIS->debug <= 3)
PerlIO_printf(DBILOGFP, " pp_rebind_ph_nty: END\n");
@@ -2339,11 +2463,13 @@
ub1 csform;
ub2 csid;
- if (trace_level >= 5)
+ if (trace_level <= 5)
PerlIO_printf(DBILOGFP, "dbd_rebind_ph() (1): rebinding %s as
%s (%s, ftype %d, csid %d, csform %d, inout %d)\n",
phs->name, (SvPOK(phs->sv) ? neatsvpv(phs->sv,0) :
"NULL"),(SvUTF8(phs->sv) ? "is-utf8" : "not-utf8"),
phs->ftype, phs->csid, phs->csform, phs->is_inout);
+PerlIO_printf(DBILOGFP, "phs->ftype = %d\n",phs->ftype);
+
switch (phs->ftype) {
case ORA_VARCHAR2_TABLE:
done = dbd_rebind_ph_varchar2_table(sth, imp_sth, phs);
@@ -2358,8 +2484,8 @@
case SQLT_RSET:
done = dbd_rebind_ph_rset(sth, imp_sth, phs);
break;
- case 108:
- done =dbd_rebind_ph_nty(sth, imp_sth, phs);
+ case XMLType:
+ done = dbd_rebind_ph_nty(sth, imp_sth, phs);
break;
default:
done = dbd_rebind_ph_char(imp_sth, phs);
@@ -2367,7 +2493,7 @@
if (done == 2) { /* the dbd_rebind_* did the OCI bind call itself
successfully */
- if (trace_level >= 3)
+ if (trace_level <= 3)
PerlIO_printf(DBILOGFP, " bind %s done with ftype
%d\n",
phs->name, phs->ftype);
return 1;
Modified: dbd-oracle/branches/xml/oci.def
==============================================================================
--- dbd-oracle/branches/xml/oci.def (original)
+++ dbd-oracle/branches/xml/oci.def Sun Mar 16 16:11:30 2008
@@ -374,4 +374,4 @@
OCILobFreeTemporary
OCILobLocatorAssign
OCILobCreateTemporary
-
+OCIXMLTypeCreateFromSrc
Modified: dbd-oracle/branches/xml/ocitrace.h
==============================================================================
--- dbd-oracle/branches/xml/ocitrace.h (original)
+++ dbd-oracle/branches/xml/ocitrace.h Sun Mar 16 16:11:30 2008
@@ -37,7 +37,13 @@
*/
-
+#define
OCIXMLTypeCreateFromSrc_log_stat(svchp,envhp,src_type,src_ptr,xml,stat)\
+ stat =OCIXMLTypeCreateFromSrc
(svchp,envhp,(OCIDuration)OCI_DURATION_CALLOUT,(ub1)src_type,(dvoid
*)src_ptr,(sb4)OCI_IND_NOTNULL, xml);\
+ (DBD_OCI_TRACEON) \
+ ? PerlIO_printf(DBD_OCI_TRACEFP,\
+
"%sOCIXMLTypeCreateFromSrc_log_stat(%p,%p,%p,%p,%d)=%s\n",\
+ OciTp, (void*)svchp,(void*)envhp, src_type,
src_ptr,oci_status_name(stat)),stat \
+ : stat
#define OCILobLocatorIsInit_log_stat(envhp,errhp,loc,is_init,stat)\
stat =OCILobLocatorIsInit (envhp,errhp,loc,is_init );\