Home  |  Linux  | Mysql  | PHP  | XML
From:byterock@cvs.perl.org Date:Fri Sep  5 10:43:46 2008
Subject:[svn:dbd-oracle] r11745 - dbd-oracle/branches/utf8_ea
Author: byterock
Date: Fri Sep  5 09:43:43 2008
New Revision: 11745

Modified:
   dbd-oracle/branches/utf8_ea/dbdimp.c
   dbd-oracle/branches/utf8_ea/dbdimp.h

Log:
applied patch

Modified: dbd-oracle/branches/utf8_ea/dbdimp.c
==============================================================================
--- dbd-oracle/branches/utf8_ea/dbdimp.c	(original)
+++ dbd-oracle/branches/utf8_ea/dbdimp.c	Fri Sep  5 09:43:43 2008
@@ -43,8 +43,14 @@
 int is_extproc = 0;
 int dbd_verbose = 0; /* DBD only debugging*/
 
+/* bitflag constants for figuring out how to handle utf8 for array binds */
+#define ARRAY_BIND_NATIVE 0x01
+#define ARRAY_BIND_UTF8   0x02
+#define ARRAY_BIND_MIXED  (ARRAY_BIND_NATIVE|ARRAY_BIND_UTF8)
+
 ub2 charsetid = 0;
 ub2 ncharsetid = 0;
+ub2 us7ascii_csid = 1;
 ub2 utf8_csid = 871;
 ub2 al32utf8_csid = 873;
 ub2 al16utf16_csid = 2000;
@@ -3086,13 +3092,18 @@
 }
 
 static int
-do_bind_array_exec(sth, imp_sth, phs)
+do_bind_array_exec(sth, imp_sth, phs, utf8)
     SV *sth;
     imp_sth_t *imp_sth;
     phs_t *phs;
+    int utf8;
 {
 	dTHX;
     sword status;
+    ub1 csform;
+    ub2 csid;
+    int trace_level = DBIS->debug;
+  
     OCIBindByName_log_stat(imp_sth->stmhp, &phs->bndhp, imp_sth->errhp,
             (text*)phs->name, (sb4)strlen(phs->name),
             0,
@@ -3117,6 +3128,71 @@
         oci_error(sth, imp_sth->errhp, status, "OCIBindDynamic");
         return 0;
     }
+    
+    /* copied and adapted from dbd_rebind_ph */
+	csform = phs->csform;
+	if (!csform && (utf8 & ARRAY_BIND_UTF8)) {
+		/* try to default csform to avoid translation through non-unicode */
+		if (CSFORM_IMPLIES_UTF8(SQLCS_IMPLICIT))                /* prefer IMPLICIT */
+			csform = SQLCS_IMPLICIT;
+		else if (CSFORM_IMPLIES_UTF8(SQLCS_NCHAR))
+		     csform = SQLCS_NCHAR;   /* else leave csform == 0 */
+		
+		if (trace_level || dbd_verbose >= 1)
+			PerlIO_printf(DBILOGFP, "do_bind_array_exec() (2): rebinding %s with UTF8 value %s", phs->name,
+			(csform == SQLCS_IMPLICIT) ? "so setting csform=SQLCS_IMPLICIT" :
+			(csform == SQLCS_NCHAR)    ? "so setting csform=SQLCS_NCHAR" :
+			"but neither CHAR nor NCHAR are unicode\n");
+	}
+	
+	if (csform) {
+		/* set OCI_ATTR_CHARSET_FORM before we get the default OCI_ATTR_CHARSET_ID */
+		OCIAttrSet_log_stat(phs->bndhp, (ub4) OCI_HTYPE_BIND,&csform, (ub4) 0, (ub4) OCI_ATTR_CHARSET_FORM, imp_sth->errhp, status);
+		if ( status != OCI_SUCCESS ) {
+			oci_error(sth, imp_sth->errhp, status, ora_sql_error(imp_sth,"OCIAttrSet (OCI_ATTR_CHARSET_FORM)"));
+			return 0;
+		}
+	}
+	
+	if (!phs->csid_orig) {      /* get the default csid Oracle would use */
+		OCIAttrGet_log_stat(phs->bndhp, OCI_HTYPE_BIND, &phs->csid_orig, (ub4)0 ,
+                OCI_ATTR_CHARSET_ID, imp_sth->errhp, status);
+	}
+	
+	/* if app has specified a csid then use that, else use default */
+	csid = (phs->csid) ? phs->csid : phs->csid_orig;
+	
+	/* if data is utf8 but charset isn't then switch to utf8 csid if possible */
+	if ((utf8 & ARRAY_BIND_UTF8) && !CS_IS_UTF8(csid)) {
+		/* if the specified or default csid is not utf8 _compatible_ AND we have */
+		/* mixed utf8 and native (non-utf8) data, then it's a fatal problem */
+	    /* utf8 _compatible_ means, can be upgraded to utf8, ie. utf8 or ascii */
+	    if ((utf8 & ARRAY_BIND_NATIVE) && !CS_IS_UTF8_COMPATIBLE(csid)) {
+			croak("Can't mix utf8 and non-utf8 in array bind");
+	    }
+		csid = utf8_csid; /* not al32utf8_csid here on purpose */
+	}
+	
+	if (trace_level >= 3 || dbd_verbose >= 3 )
+		PerlIO_printf(DBILOGFP, "do_bind_array_exec(): bind %s <== [array of values] "
+			"(%s, %s, csid %d->%d->%d, ftype %d (%s), csform %d->%d, maxlen %lu, maxdata_size %lu)\n",
+			phs->name, 
+			(phs->is_inout) ? "inout" : "in",
+		    (utf8 ? "is-utf8" : "not-utf8"),
+	        phs->csid_orig, phs->csid, csid,
+	        phs->ftype,sql_typecode_name(phs->ftype), phs->csform, csform,
+	        (unsigned long)phs->maxlen, (unsigned long)phs->maxdata_size);
+	
+	
+	if (csid) {
+		OCIAttrSet_log_stat(phs->bndhp, (ub4) OCI_HTYPE_BIND,
+			&csid, (ub4) 0, (ub4) OCI_ATTR_CHARSET_ID, imp_sth->errhp, status);
+		if ( status != OCI_SUCCESS ) {
+			oci_error(sth, imp_sth->errhp, status, ora_sql_error(imp_sth,"OCIAttrSet (OCI_ATTR_CHARSET_ID)"));
+			return 0;
+		}
+	}
+
     return 1;
 }
 
@@ -3166,7 +3242,8 @@
     char namebuf[30];
     STRLEN len;
     int outparams = (imp_sth->out_params_av) ? AvFILL(imp_sth->out_params_av)+1 : 0;
-
+    int *utf8_flgs;
+    
     if (debug >= 2  || dbd_verbose >=2)
  		PerlIO_printf(DBILOGFP, "  ora_st_execute_array %s count=%d (%s %s %s)...\n",
                       oci_stmt_type_name(imp_sth->stmt_type), exe_count,
@@ -3229,18 +3306,23 @@
 
     param_count=DBIc_NUM_PARAMS(imp_sth);
 	phs = safemalloc(param_count*sizeof(*phs));
+	utf8_flgs = safemalloc(param_count*sizeof(int));
     memset(phs, 0, param_count*sizeof(*phs));
+    memset(utf8_flgs, 0, param_count*sizeof(int));
+    
 
    	for(j = 0; (unsigned int) j < exe_count; j++) {
 
     	sv_p = av_fetch(tuples_av, j, 0);
         if(sv_p == NULL) {
-            Safefree(phs);
-             croak("Cannot fetch tuple %d", j);
+        	Safefree(phs);
+        	Safefree(utf8_flgs);
+            croak("Cannot fetch tuple %d", j);
         }
         sv = *sv_p;
         if(!SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVAV) {
-            Safefree(phs);
+        	Safefree(phs);
+        	Safefree(utf8_flgs);
             croak("Not an array ref in element %d", j);
         }
         av = (AV*)SvRV(sv);
@@ -3252,11 +3334,13 @@
                                 namebuf, strlen(namebuf), 0);
                if (phs_svp == NULL) {
                     Safefree(phs);
+                    Safefree(utf8_flgs);
                     croak("Can't execute for non-existent placeholder :%d", i);
                }
                phs[i] = (phs_t*)(void*)SvPVX(*phs_svp); /* placeholder struct */
                if(phs[i]->idx < 0) {
                    Safefree(phs);
+                   Safefree(utf8_flgs);
                    croak("Placeholder %d not of ?/:1 type", i);
                 }
                 init_bind_for_array_exec(phs[i]);
@@ -3264,6 +3348,7 @@
             sv_p = av_fetch(av, phs[i]->idx, 0);
             if(sv_p == NULL) {
                 Safefree(phs);
+                Safefree(utf8_flgs);
                 croak("Cannot fetch value for param %d in entry %d", i, j);
         	}
 
@@ -3281,22 +3366,33 @@
         	/* Find the value length, and increase maxlen if needed. */
         	if(SvROK(sv)) {
         	    Safefree(phs);
+        	    Safefree(utf8_flgs);
         	    croak("Can't bind a reference (%s) for param %d, entry %d",
         	    neatsvpv(sv,0), i, j);
         	}
         	if(len > (unsigned int) phs[i]->maxlen)
         	    phs[i]->maxlen = len;
 
+			/* update the utf8_flgs for this value */
+			if (SvUTF8(sv)) {
+				utf8_flgs[i] |= ARRAY_BIND_UTF8;
+			} 
+			else {
+				utf8_flgs[i] |= ARRAY_BIND_NATIVE;
+			}
+         
         	/* Do OCI bind calls on last iteration. */
         	if( ((unsigned int) j ) == exe_count - 1 ) {
-        	    if(!do_bind_array_exec(sth, imp_sth, phs[i])) {
-        	        Safefree(phs);
+        	    if(!do_bind_array_exec(sth, imp_sth, phs[i], utf8_flgs[i])) {
+					Safefree(phs);
+	                Safefree(utf8_flgs);
         		}
 			}
     	}
   	}
 	Safefree(phs);
-
+	Safefree(utf8_flgs);
+	
     /* Store array of bind typles, for use in OCIBindDynamic() callback. */
     imp_sth->bind_tuples = tuples_av;
     imp_sth->rowwise = (columns_av == NULL);

Modified: dbd-oracle/branches/utf8_ea/dbdimp.h
==============================================================================
--- dbd-oracle/branches/utf8_ea/dbdimp.h	(original)
+++ dbd-oracle/branches/utf8_ea/dbdimp.h	Fri Sep  5 09:43:43 2008
@@ -254,6 +254,7 @@
 
 extern ub2 charsetid;
 extern ub2 ncharsetid;
+extern ub2 us7ascii_csid;
 extern ub2 utf8_csid;
 extern ub2 al32utf8_csid;
 extern ub2 al16utf16_csid;
@@ -261,6 +262,9 @@
 #define CS_IS_UTF8( cs ) \
    (  ( cs == utf8_csid ) || ( cs == al32utf8_csid ) )
 
+#define CS_IS_UTF8_COMPATIBLE( cs ) \
+  ( CS_IS_UTF8(cs) || ( (cs) == us7ascii_csid ) )
+
 #define CS_IS_UTF16( cs ) ( cs == al16utf16_csid )
 
 #define CSFORM_IMPLIED_CSID(csform) \
Navigate in group perl.dbd.oracle.changes at sever nntp.perl.org
Previous Next




  
© No Copyright
You are free to use Anything
Site Maintained by PHP Developer
Powered By PHP Consultants