Author: byterock
Date: Wed May 14 11:16:37 2008
New Revision: 11275

Modified:
   dbd-oracle/trunk/Oracle.pm
   dbd-oracle/trunk/dbdimp.c
   dbd-oracle/trunk/dbdimp.h
   dbd-oracle/trunk/oci8.c

Log:
improved version of persistent blobs.  It now uses a callback function to get 
the data during a fetch

Modified: dbd-oracle/trunk/Oracle.pm
==============================================================================
--- dbd-oracle/trunk/Oracle.pm  (original)
+++ dbd-oracle/trunk/Oracle.pm  Wed May 14 11:16:37 2008
@@ -1,6 +1,7 @@
 #   Oracle.pm
 #
 #   Copyright (c) 1994-2005 Tim Bunce, Ireland
+#   Copyright (c) 2006-2008 John Scoles (The Pythian Group), Canada
 #
 #   See COPYRIGHT section in the documentation below
 
@@ -3757,6 +3758,7 @@
 =head1 COPYRIGHT
 
 The DBD::Oracle module is Copyright (c) 1994-2006 Tim Bunce. Ireland.
+The DBD::Oracle module is Copyright (c) 2006-2008 John Scoles (The Pythian 
Group). Canada.
 
 The DBD::Oracle module is free open source software; you can
 redistribute it and/or modify it under the same terms as Perl 5.

Modified: dbd-oracle/trunk/dbdimp.c
==============================================================================
--- dbd-oracle/trunk/dbdimp.c   (original)
+++ dbd-oracle/trunk/dbdimp.c   Wed May 14 11:16:37 2008
@@ -272,8 +272,10 @@
 /* --- allocate and free oracle oci 'array' buffers --- */
 
 fb_ary_t *
-fb_ary_alloc(int bufl, int size)
+fb_ary_alloc(ub4 bufl, int size)
 {
+ dTHR;
+    dTHX;
     fb_ary_t *fb_ary;
     /* these should be reworked to only to one Newz()  */
     /* and setup the pointers in the head fb_ary struct        */
@@ -2933,6 +2935,7 @@
                                        (ub4)(is_select ? 0 : 1),
                                        0, 0, 0,(ub4)imp_sth->exe_mode,status);
 
+
                if (status != OCI_SUCCESS) { /* may be OCI_ERROR or 
OCI_SUCCESS_WITH_INFO etc */
        /* we record the error even for OCI_SUCCESS_WITH_INFO */
                        oci_error(sth, imp_sth->errhp, status, 
ora_sql_error(imp_sth,"OCIStmtExecute"));

Modified: dbd-oracle/trunk/dbdimp.h
==============================================================================
--- dbd-oracle/trunk/dbdimp.h   (original)
+++ dbd-oracle/trunk/dbdimp.h   Wed May 14 11:16:37 2008
@@ -120,7 +120,7 @@
 
 typedef struct fb_ary_st fb_ary_t;    /* field buffer array    */
 struct fb_ary_st {     /* field buffer array EXPERIMENTAL      */
-    ub2  bufl;         /* length of data buffer                */
+    ub4  bufl;         /* length of data buffer                */
     sb2  *aindp;       /* null/trunc indicator variable        */
     ub1  *abuf;                /* data buffer (points to sv data)      */
     ub2  *arlen;       /* length of returned data              */
@@ -157,6 +157,7 @@
     OCIDefine  *defnp;
     void               *desc_h;        /* descriptor if needed (LOBs etc)      
*/
     ub4                desc_t; /* OCI type of descriptor               */
+    ub4                define_mode; /*the normal case for a define*/
     int                (*fetch_func) _((SV *sth, imp_fbh_t *fbh, SV *dest_sv));
     void               (*fetch_cleanup) _((SV *sth, imp_fbh_t *fbh));
     ub2                dbtype; /* actual type of field (see ftype)     */
@@ -172,7 +173,7 @@
     ub2                csid;           /* OCI_ATTR_CHARSET_ID                  
*/
     ub1                csform; /* OCI_ATTR_CHARSET_FORM                */
 
-    sb4                disize; /* max display/buffer size              */
+    ub4                disize; /* max display/buffer size              */
     char               *bless; /* for Oracle::OCI style handle data    */
     void               *special;       /* hook for special purposes (LOBs etc) 
*/
 
@@ -261,7 +262,7 @@
 void ora_free_fbh_contents _((imp_fbh_t *fbh));
 void ora_free_templob _((SV *sth, imp_sth_t *imp_sth, OCILobLocator *lobloc));
 int ora_dbtype_is_long _((int dbtype));
-fb_ary_t *fb_ary_alloc _((int bufl, int size));
+fb_ary_t *fb_ary_alloc _((ub4 bufl, int size));
 int ora_db_reauthenticate _((SV *dbh, imp_dbh_t *imp_dbh, char *uid, char 
*pwd));
 
 void dbd_phs_sv_complete _((phs_t *phs, SV *sv, I32 debug));

Modified: dbd-oracle/trunk/oci8.c
==============================================================================
--- dbd-oracle/trunk/oci8.c     (original)
+++ dbd-oracle/trunk/oci8.c     Wed May 14 11:16:37 2008
@@ -583,6 +583,85 @@
 }
 
 
+
+/* -------------------------------------------------------------- */
+/* Fetch callback to specify buffers. */
+/* -------------------------------------------------------------- */
+static sb4 presist_lob_fetch_cbk(dvoid *octxp, OCIDefine *dfnhp, ub4 iter, 
dvoid **bufpp, 
+                      ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcpp)
+{
+  dTHX;
+  imp_fbh_t *fbh =(imp_fbh_t*)octxp;
+  fb_ary_t  *fb_ary;           
+  fb_ary =  fbh->fb_ary;
+  *indpp = (dvoid *) 0;
+  *rcpp = (ub2 *) 0;
+  *bufpp = (dvoid *) fb_ary->abuf;
+  *alenpp = &fb_ary->bufl;
+  /*ind = 0;
+    
+    if (glGetInd)
+      *indpp  = (dvoid *) &ind;
+    else
+      *indpp = (dvoid *)0;
+  
+    rc = 0;
+    if (glGetRc)
+      *rcpp  = (ub2 *) &rc;
+    else
+      *rcpp = (ub2 *)0;
+      
+ /*  switch (piecep[0]) {
+   
+      case OCI_ONE_PIECE:
+        PerlIO_printf(DBILOGFP," OCI_ONE_PIECE\n");
+        break;
+      case OCI_FIRST_PIECE:
+      
+        
+     /*  (void)SvUPGRADE(sv, SVt_PV);*/
+    /*    SvGROW(sv,fb_ary->bufl);
+  
+      PerlIO_printf(DBILOGFP," first piece \n");
+    /*  sv=newSVpvn((char*)bufpp, fb_ary->bufl);
+      PerlIO_printf(DBILOGFP,"SvLEN(sv)=%d\n",SvLEN(sv));
+   /*     *bufpp =  SvGROW(sv, fb_ary->bufl));*/
+       /* bufpp[fb_ary->bufl] = '\0';*/
+     /*   PerlIO_printf(DBILOGFP,"strlen(p)=%s\n",strlen(p));*/
+    /*     sv_setpvn(sv,(char*)(*bufpp), fb_ary->bufl);*/
+     /*   PerlIO_printf(DBILOGFP,"SvLEN(sv)=%d\n",SvLEN(sv));
+       break;
+      
+      case OCI_NEXT_PIECE:
+
+        PerlIO_printf(DBILOGFP," OCI_NEXT_PIECE\n");
+       
+      /*  sv_catpv(sv,(char *) bufpp);  
+        PerlIO_printf(DBILOGFP,"SvLEN(sv)=%d\n",SvLEN(sv));
+     /*         row_data=&fb_ary->abuf[0]+(fb_ary->bufl);
+                 p = (char*)row_data;
+             PerlIO_printf(DBILOGFP," OCI_FIRST_PIECE\n");  */
+               
+                /* bufpp[fb_ary->bufl] = '\0';*/
+             /*   PerlIO_printf(DBILOGFP,"strlen(p)=%s\n",strlen(p));
+    
+       
+       break;
+      
+      case OCI_LAST_PIECE:
+       PerlIO_printf(DBILOGFP," OCI_LAST_PIECE\n");
+       break;
+      default:
+       PerlIO_printf(DBILOGFP,"ERROR: piece-wise fetching, \n");
+               break;  
+   }
+  
+  PerlIO_printf(DBILOGFP," done internal loop\n");*/
+
+  return OCI_CONTINUE;
+  
+}
+
 #ifdef UTF8_SUPPORT
 /* How many bytes are n utf8 chars in buffer */
 static ub4
@@ -991,13 +1070,13 @@
                          /* lab  0, 0, (ub2)0, (ub1)SQLCS_IMPLICIT, status); */
 
       if (dbis->debug >= 3)
-       PerlIO_printf(DBILOGFP, "       OCILobRead field %d %s: LOBlen %lu, 
LongReadLen %lu, BufLen %lu, Got %lu\n",
-               fbh->field_num+1, oci_status_name(status), ul_t(loblen),
-               ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp));
+               PerlIO_printf(DBILOGFP, "       OCILobRead field %d %s: LOBlen 
%lu, LongReadLen %lu, BufLen %lu, Got %lu\n",
+                       fbh->field_num+1, oci_status_name(status), ul_t(loblen),
+                       ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp));
       if (status != OCI_SUCCESS) {
-       oci_error(sth, imp_sth->errhp, status, "OCILobRead");
-       sv_set_undef(dest_sv);  /* signal error */
-       return 0;
+               oci_error(sth, imp_sth->errhp, status, "OCILobRead");
+               sv_set_undef(dest_sv);  /* signal error */
+               return 0;
       }
 
       amtp = ora_utf8_to_bytes(buffer, len, amtp);
@@ -1698,6 +1777,47 @@
 
 }
 
+
+/*static int
+fetch_presis_binary(SV *sth, imp_fbh_t *fbh,SV *dest_sv){
+
+       dTHX;
+       ub4   alen  = fbh->disize;
+       ub1   buf2[1];
+       ub1   piece  = OCI_FIRST_PIECE;
+       void *hdlptr = (dvoid *) 0;
+       ub4 hdltype  = OCI_HTYPE_DEFINE, iter = 0, idx = 0;
+       ub1   in_out = 0;
+       sb2   indptr = 0;
+       ub2   rcode  = 0;
+       sword status = OCI_NEED_DATA;
+    fb_ary_t *fb_ary = fbh->fb_ary;
+    ub1* row_data=&fb_ary->abuf[0]+(fb_ary->bufl*fbh->imp_sth->rs_array_idx);
+               
+       if (DBIS->debug <= 4) {
+                       PerlIO_printf(DBILOGFP, " getting an Presistant Binaray 
lob with picewise fetch row_data =%d\n",row_data);
+       }
+       
+       PerlIO_printf(DBILOGFP, "status=%d\n",status);
+       
+       while (status == OCI_NEED_DATA){
+          OCIStmtGetPieceInfo(fbh->imp_sth->stmhp, 
+                                                  fbh->imp_sth->errhp, 
&hdlptr, &hdltype,
+                                                                           
&in_out, &iter, &idx, &piece);
+               OCIStmtSetPieceInfo((dvoid *)hdlptr, (ub4)hdltype,
+                                                                               
  fbh->imp_sth->errhp, (dvoid *) &row_data, &alen, piece,
+                                                                               
  (dvoid *)&indptr, &rcode);
+           sv_catpv(dest_sv,  row_data);                              
+           status = OCIStmtFetch(fbh->imp_sth->stmhp,fbh->imp_sth->errhp, 
(ub4) 1, 
+                                                                         (ub2) 
OCI_FETCH_NEXT, (ub4) OCI_DEFAULT);
+               
+                       PerlIO_printf(DBILOGFP, "status=%d\n",status);
+
+       }       
+return 1;
+}
+
+*/
 int
 empty_oci_object(fbh_obj_t *obj){
        dTHX;
@@ -2092,7 +2212,7 @@
     int nested_cursors = 0;
     ub4 i = 0;
     sword status;
-
+    
 
     if (imp_sth->done_desc)
        return 1;       /* success, already done it */
@@ -2156,11 +2276,13 @@
     for(i = 1; i <= num_fields; ++i) { /*start define of filed struct[i] fbh */
                char *p;
                ub4 atrlen;
-               int avg_width = 0;
-               imp_fbh_t *fbh = &imp_sth->fbh[i-1];
-               fbh->imp_sth   = imp_sth;
-               fbh->field_num = i;
-
+               int avg_width    = 0;
+               imp_fbh_t *fbh   = &imp_sth->fbh[i-1];
+               fbh->imp_sth     = imp_sth;
+               fbh->field_num   = i;
+               fbh->define_mode = OCI_DEFAULT;
+       
+       
                OCIParamGet_log_stat(imp_sth->stmhp, OCI_HTYPE_STMT, 
imp_sth->errhp,
                                (dvoid**)&fbh->parmdp, (ub4)i, status);
 
@@ -2200,7 +2322,6 @@
 
                fbh->ftype   = 5;       /* default: return as null terminated 
string */
 
-
                switch (fbh->dbtype) {
                /*      the simple types        */
                        case   1:                               /* VARCHAR2     
*/
@@ -2287,7 +2408,9 @@
                            if (fbh->dbtype == 112){
                                fbh->ftype  = SQLT_CHR;
                            } else {
-                                       fbh->ftype  = SQLT_BIN; /*other Binary*/
+                                       fbh->ftype       = SQLT_BIN; /*other 
Binary*/
+                                       fbh->define_mode = OCI_DYNAMIC_FETCH; 
/* piecwise fetch*/
+                       /*              fbh->fetch_func = fetch_presis_binary; 
/* need a new fetch function for it */
                                }
 
                                } else {
@@ -2380,7 +2503,10 @@
                fbh->fb_ary = fb_ary_alloc(define_len, 1);
                fbh->fb_ary = fb_ary_alloc(define_len, imp_sth->rs_array_size);
                fb_ary = fbh->fb_ary;
-
+               if (fbh->ftype == SQLT_BIN)  {
+                       define_len++;
+                       /*add one extra byte incase the size of the lob is 
equal to the define_len*/
+               }
 
                if (fbh->ftype == 116) { /* RSET */
                    OCIHandleAlloc_ok(imp_sth->envhp,
@@ -2393,13 +2519,22 @@
                    imp_sth->errhp,
                    (ub4) i,
                    (fbh->desc_h) ? (dvoid*)&fbh->desc_h : (dvoid*)fb_ary->abuf,
-                   (fbh->desc_h) ?                   0 :         define_len,
+                   (fbh->desc_h) ?                   0 :        define_len,
                    (ub2)fbh->ftype,
                    fb_ary->aindp,
                    (ftype==94||ftype==95) ? NULL : fb_ary->arlen,
                    fb_ary->arcode,
-                   OCI_DEFAULT,
+                   fbh->define_mode,
                            status);
+                          
+                        if (fbh->ftype == SQLT_BIN)  {
+                               /* uses a dynamic callback for persistent 
binary lobs*/                  
+                               OCIDefineDynamic(fbh->defnp, imp_sth->errhp, 
(dvoid *) fbh,
+                                          (OCICallbackDefine) 
presist_lob_fetch_cbk);
+                        }
+
+                          
+
 
                        if (fbh->ftype == 108)  { /* Embedded object bind it 
differently*/
 
@@ -2532,7 +2667,7 @@
                }
        }
 
-    if (status != OCI_SUCCESS) {
+    if (status != OCI_SUCCESS && status !=OCI_NEED_DATA) {
                ora_fetchtest = 0;
 
                if (status == OCI_NO_DATA) {
@@ -2562,12 +2697,14 @@
 
     err = 0;
 
+ 
        for(i=0; i < num_fields; ++i) {
                imp_fbh_t *fbh = &imp_sth->fbh[i];
                fb_ary_t *fb_ary = fbh->fb_ary;
                int rc = fb_ary->arcode[imp_sth->rs_array_idx];
                ub1* 
row_data=&fb_ary->abuf[0]+(fb_ary->bufl*imp_sth->rs_array_idx);
                SV *sv = AvARRAY(av)[i]; /* Note: we (re)use the SV in the AV   
*/;
+                       
                if (rc == 1406                          /* field was truncated  
*/
                    && ora_dbtype_is_long(fbh->dbtype)/* field is a LONG        
*/
                ){
@@ -2586,7 +2723,7 @@
                }
 
 
-
+      
                if (rc == 0 ||  /* the normal case*/
                        (imp_sth->pers_lob && rc == 1406 && 
DBIc_has(imp_sth,DBIcf_LongTruncOk))/*or a trunckated record when using 10.2 
Persistent Lob interface*/
                ) {
@@ -2597,13 +2734,11 @@
                                }
 
                } else {
-                if (fbh->ftype == SQLT_BIN){
-                                       char *p = (char*)row_data;
-                                       sb4 datalen = strlen(p);
-                                       if (datalen >= fbh->disize){
-                                               datalen = fbh->disize;
-                                       }
-                                       sv_setpvn(sv, p, datalen);
+                if (fbh->ftype == SQLT_BIN){ /*This uses a picewise fecth call 
to presist_lob_fetch_cbk*/
+                   *(fb_ary->abuf+(fb_ary->bufl))='\0'; /* add a null 
teminator*/
+                   sv_setpvn(sv, (char*)fb_ary->abuf, 
strlen((char*)fb_ary->abuf));
+                          fb_ary->bufl=fbh->disize; /*reset this back to the 
disize -1*/
+                                       
                                } else {
                                        int datalen = 
fb_ary->arlen[imp_sth->rs_array_idx];
                                    char *p = (char*)row_data;

Reply via email to