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

Reply via email to