[icinga-checkins] icinga.org: icinga-core/dev/ido: idoutils:enhance clob bind functions #2342 , #2303

git at icinga.org git at icinga.org
Wed Apr 4 13:48:08 CEST 2012


Module: icinga-core
Branch: dev/ido
Commit: 703426fd129f5947a6d2737c9baf69957e99053f
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=703426fd129f5947a6d2737c9baf69957e99053f

Author: Thomas Dressler <tdressler at tdressler.net>
Date:   Mon Apr  2 20:34:50 2012 +0200

idoutils:enhance clob bind functions #2342,#2303
refs #2303,#2342

---

 module/idoutils/include/db.h |    4 +++
 module/idoutils/src/db.c     |   43 +++++++++++++++++++++++++++++++++--------
 2 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/module/idoutils/include/db.h b/module/idoutils/include/db.h
index c9da99d..11e9253 100644
--- a/module/idoutils/include/db.h
+++ b/module/idoutils/include/db.h
@@ -167,6 +167,8 @@ int ido2db_db_trim_data_table(ido2db_idi *,char *,char *,unsigned long);
 #define OCI_STR_SIZE 256 /* default small string buffer size */
 #define OCI_BINDARRAY_MAX_SIZE 5000 /* default array buffer and commit size for bulk ops */
 #define OCI_OUTPUT_BUFFER_SIZE 32000 /* Buffer size for dbms_output calls */
+#define OCI_LOB_CHUNK_SIZE 16 /* Buffer size for LOB operations */
+
 void ido2db_ocilib_err_handler(OCI_Error *);
 unsigned long ido2db_oci_sequence_lastid(ido2db_idi *, char *);
 int ido2db_oci_prepared_statement_bind_null_param(OCI_Statement *, char *);
@@ -176,6 +178,8 @@ int ido2db_oci_execute_out(OCI_Statement *,char *);
 int ido2db_oci_set_session_info(OCI_Connection *, char *);
 void ido2db_oci_print_binds(OCI_Statement *,int,char **);
 void ido2db_oci_statement_free(OCI_Statement *,char *);
+/* Helper */
+int ido2db_oci_StringUTF8Length(const char *str);
 #endif /* Oracle ocilib specific */
 
 #endif
diff --git a/module/idoutils/src/db.c b/module/idoutils/src/db.c
index 92842cc..419388f 100644
--- a/module/idoutils/src/db.c
+++ b/module/idoutils/src/db.c
@@ -7826,10 +7826,11 @@ void ido2db_oci_statement_free(OCI_Statement *st, char * stname) {
 int ido2db_oci_bind_clob(OCI_Statement *st, char * bindname, char * text, OCI_Lob ** lobp) {
 	char * fname = "ido2db_oci_bind_clob";
 	unsigned long len = 0;
+	unsigned long slen = 0;
 	unsigned int cb = 0; //char byte
 	unsigned int bb = 0; //bin�r byte
 	unsigned long rc = 0; //recent position
-	const int chunk = 1024; //max chunk size
+	const int chunk = OCI_LOB_CHUNK_SIZE; //max chunk size
 	char * buffer =NULL; //temporary buffer
 	int code=0;
 
@@ -7853,6 +7854,7 @@ int ido2db_oci_bind_clob(OCI_Statement *st, char * bindname, char * text, OCI_Lo
 
 
 	len = text ? strlen(text) : 0;
+	slen= text ? ido2db_oci_StringUTF8Length(text):0;
 	if (len == 0) {
 		ido2db_log_debug_info(IDO2DB_DEBUGL_SQL, 2, "%s:Bind %s,Null or empty\n", fname, bindname);
 		OCI_BindSetNull(OCI_GetBind2(st, bindname));
@@ -7870,22 +7872,23 @@ int ido2db_oci_bind_clob(OCI_Statement *st, char * bindname, char * text, OCI_Lo
 	ido2db_log_debug_info(IDO2DB_DEBUGL_SQL, 2, "%s:Bind %s,%lu Bytes requested\n", fname, bindname, len);
 
 	while ((len - rc) > 0) {
+
 		if ((len - rc) > chunk) {
-			bb = chunk;
+			bb = chunk; //buffer full size
 		} else {
-			bb = len - rc;
+			bb = len - rc; //remaining bytes
 		}
 		if (bb < 1) break; //should not happens
 		ido2db_log_debug_info(IDO2DB_DEBUGL_SQL, 2, "%s:Bind %s,Next chunk %lu bytes from pos %lu (total %lu) \n", fname, bindname,bb,rc, len);
 
 		memset(buffer,0,chunk+1);
 		memcpy(buffer,text+rc,bb);
-
+		cb=0;//reset character pointer, we will work with bytes
 		if (OCI_LobWrite2(*lobp, buffer, &cb, &bb)) {
 			rc = rc + bb;
-			ido2db_log_debug_info(IDO2DB_DEBUGL_SQL, 2, "%s:Bind %s,%d Bytes(total %lu/%lu)   appended\n", fname, bindname, bb, rc, len);
+			ido2db_log_debug_info(IDO2DB_DEBUGL_SQL, 2, "%s:Bind %s,%d Bytes=%d Chars (total %lu/%lu)   appended\n", fname, bindname, bb, cb,rc, len);
 		} else {
-			ido2db_log_debug_info(IDO2DB_DEBUGL_SQL, 2, "%s:Bind %s,Last append failed: %d Bytes(total %lu/%lu):'%s'\n", fname, bindname, bb, rc, len,buffer);
+			ido2db_log_debug_info(IDO2DB_DEBUGL_SQL, 2, "%s:Bind %s,Last append failed: %d Bytes=%d Chars(total %lu/%lu):'%s'\n", fname, bindname, bb, cb, rc, len,buffer);
 			code=1; //this is an error
 			break;
 		}
@@ -7893,16 +7896,38 @@ int ido2db_oci_bind_clob(OCI_Statement *st, char * bindname, char * text, OCI_Lo
 	}
 	//final length check
 	cb = OCI_LobGetLength(*lobp);
-	if (cb == len) {
-		ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "%s:Bind %s,Lob successfully written:%lu bytes \n", fname, bindname, len);
+	if (cb == slen) {
+		ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "%s:Bind %s,Lob successfully written:%lu bytes=%lu chars \n", fname, bindname, len,slen);
 	} else {
 		//final size differs, but only an error if write failed
-		ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "%s:Bind %s,Lob write warning:len %lu, but lob size %lu (last chunk '%s')\n", fname, bindname, len, cb,buffer);
+		ido2db_log_debug_info(IDO2DB_DEBUGL_PROCESSINFO, 2, "%s:Bind %s,Lob write warning:len %lu, but lob size %lu bytes=%lu chars (last chunk '%s')\n", fname, bindname, len,slen, cb,buffer);
 	}
 	free(buffer);
 	if (code == 1) return IDO_ERROR;
 	return IDO_OK;
 }
+/* UTF8 ready string length function,
+ * taken from http://sourceforge.net/projects/orclib/forums/forum/470801/topic/5000325
+ */
+int ido2db_oci_StringUTF8Length
+(
+    const char *str
+)
+{
+    int size = 0;
+
+    while (*str)
+    {
+        if ((*str & 0xc0) != 0x80)
+        {
+            size++;
+        }
+
+        str++;
+    }
+
+    return size;
+}
 /*
 int ido2db_oci_bind_bigint(OCI_Statement *st, char * bindname, void ** data) {
 #ifdef OCI_BIG_UINT_ENABLED





More information about the icinga-checkins mailing list