--- sql/oracle/parser3oracle.C 2003/12/15 08:57:22 1.41 +++ sql/oracle/parser3oracle.C 2003/12/24 12:03:32 1.46 @@ -7,7 +7,7 @@ 2001.07.30 using Oracle 8.1.6 [@test tested with Oracle 7.x.x] */ -static const char *RCSId="$Id: parser3oracle.C,v 1.41 2003/12/15 08:57:22 paf Exp $"; +static const char *RCSId="$Id: parser3oracle.C,v 1.46 2003/12/24 12:03:32 paf Exp $"; #include "config_includes.h" @@ -38,6 +38,12 @@ inline int max(int a, int b) { return a> inline int min(int a, int b){ return a_throw(cs.error); check(cs, "commit", OCITransCommit(cs.svchp, cs.errhp, 0)); } - void rollback(SQL_Driver_services& services, void *connection) { + void rollback(void *connection) { OracleSQL_connection_struct &cs=*(OracleSQL_connection_struct *)connection; if(setjmp(cs.mark)) - services._throw(cs.error); + cs.services->_throw(cs.error); - check(cs, "rollback", OCITransRollback(cs.svchp, cs.errhp, 0)); + // sometimes rollback is done in context when this yields error which masks previous error + // consider consequent errors not very important to report, reporting first one + /*check(cs, "rollback", */OCITransRollback(cs.svchp, cs.errhp, 0)/*)*/; } - bool ping(SQL_Driver_services&, void *connection) { + bool ping(void* /*connection*/) { // maybe OCIServerVersion? // select 0 from dual return true; } - const char* quote( - SQL_Driver_services& services, void *connection, - const char *from, unsigned int length) { - char *result=(char*)services.malloc_atomic(length*2+1); + const char* quote(void *connection, + const char *from, unsigned int length) + { + OracleSQL_connection_struct &cs=*(OracleSQL_connection_struct *)connection; + char *result=(char*)cs.services->malloc_atomic(length*2+1); char *to=result; while(length--) { switch(*from) { @@ -385,22 +410,30 @@ public: *to=0; return result; } - void query( - SQL_Driver_services& services, void *connection, + void query(void *connection, const char *astatement, unsigned long offset, unsigned long limit, - SQL_Driver_query_event_handlers& handlers) { - + SQL_Driver_query_event_handlers& handlers) + { OracleSQL_connection_struct &cs=*(OracleSQL_connection_struct *)connection; OracleSQL_query_lobs lobs={{0}, 0}; OCIStmt *stmthp=0; + SQL_Driver_services& services=*cs.services; + + // transcode from $request:charset to connect-string?client_charset + size_t transcoded_statement_size; + if(const char* cstrClientCharset=cs.options.cstrClientCharset) + services.transcode(astatement, strlen(astatement), + astatement, transcoded_statement_size, + services.request_charset(), + cstrClientCharset); + bool failed=false; if(setjmp(cs.mark)) { failed=true; goto cleanup; } else { - const char *statement=preprocess_statement(services, cs, - astatement, lobs); + const char *statement=preprocess_statement(cs, astatement, lobs); check(cs, "HandleAlloc STMT", OCIHandleAlloc( (dvoid *)cs.envhp, (dvoid **) &stmthp, (ub4)OCI_HTYPE_STMT, 0, 0)); @@ -421,8 +454,7 @@ public: (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DATA_AT_EXEC)); lobs.items[i].rows.count=0; - OracleSQL_query_lobs::cbf_context_struct cbf_context={ - &services, &cs, &lobs.items[i].rows}; + OracleSQL_query_lobs::cbf_context_struct cbf_context={&cs, &lobs.items[i].rows}; check(cs, "bind dynamic", OCIBindDynamic( lobs.items[i].bind, cs.errhp, (dvoid *) &cbf_context, cbf_no_data, @@ -430,7 +462,7 @@ public: } } - execute_prepared(services, cs, + execute_prepared(cs, statement, stmthp, lobs, offset, limit, handlers); } @@ -459,9 +491,10 @@ cleanup: // no check call after this poi private: // private funcs - const char *preprocess_statement(SQL_Driver_services& services, OracleSQL_connection_struct &cs, + const char *preprocess_statement(OracleSQL_connection_struct &cs, const char *astatement, OracleSQL_query_lobs &lobs) { size_t statement_size=strlen(astatement); + SQL_Driver_services& services=*cs.services; char *result=(char *)services.malloc_atomic(statement_size +MAX_STRING // in case of short 'strings' @@ -546,7 +579,7 @@ private: // private funcs } void execute_prepared( - SQL_Driver_services& services, OracleSQL_connection_struct &cs, + OracleSQL_connection_struct &cs, const char *statement, OCIStmt *stmthp, OracleSQL_query_lobs &lobs, unsigned long offset, unsigned long limit, SQL_Driver_query_event_handlers& handlers) { @@ -595,7 +628,7 @@ private: // private funcs switch(stmt_type) { case OCI_STMT_SELECT: - fetch_table(services, cs, + fetch_table(cs, stmthp, offset, limit, handlers); break; @@ -608,9 +641,11 @@ private: // private funcs } } - void fetch_table(SQL_Driver_services& services, OracleSQL_connection_struct &cs, + void fetch_table(OracleSQL_connection_struct &cs, OCIStmt *stmthp, unsigned long offset, unsigned long limit, - SQL_Driver_query_event_handlers& handlers) { + SQL_Driver_query_event_handlers& handlers) + { + SQL_Driver_services& services=*cs.services; ub4 prefetch_rows=100; check(cs, "AttrSet prefetch-rows", OCIAttrSet( @@ -669,7 +704,7 @@ private: // private funcs { size_t length=(size_t)col_name_len; char *ptr=(char *)services.malloc_atomic(length+1); - if( cs.bLowerCaseColumnNames ) + if( cs.options.bLowerCaseColumnNames ) tolower(ptr, (char *)col_name, length); else memcpy(ptr, col_name, length); @@ -694,7 +729,11 @@ private: // private funcs } default: coerce_type=SQLT_STR; - ptr=col.str=(char *)services.malloc_atomic(MAX_OUT_STRING_LENGTH+1); + char*& buf=cs.fetch_buffers[column_count-1]; + ptr=buf; // get cached buffer + if(!ptr) // allocate if needed, caching it + ptr=buf=(char *)services.malloc_atomic(MAX_OUT_STRING_LENGTH+1/*terminator*/); + col.str=(char*)ptr; size=MAX_OUT_STRING_LENGTH; break; } @@ -721,39 +760,65 @@ private: // private funcs check(cs, handlers.add_row(cs.sql_error)); for(int i=0; iOCIErrorGet((dvoid *)cs.errhp, (ub4)1, (text *)NULL, &errcode, - (text *)reason, (ub4)sizeof(reason), OCI_HTYPE_ERROR)==OCI_SUCCESS) - msg=reason; - else - msg="[can not get error description]"; - break; + sb4 errcode; + if(OracleSQL_driver->OCIErrorGet((dvoid *)cs.errhp, (ub4)1, (text *)NULL, &errcode, + (text *)reason, (ub4)sizeof(reason), OCI_HTYPE_ERROR)==OCI_SUCCESS) { + msg=reason; + + // transcode to $request:charset from connect-string?client_charset + if(const char* cstrClientCharset=cs.options.cstrClientCharset) { + if(msg) { + if(size_t msg_length=strlen(msg)) { + cs.services->transcode(msg, msg_length, + msg, msg_length, + cstrClientCharset, + cs.services->request_charset()); + } + } + } + } else + msg="[can not get error description]"; + break; } case OCI_NEED_DATA: msg="NEED_DATA"; break; @@ -970,9 +1046,9 @@ void check(OracleSQL_connection_struct & /* Intbind callback that does not do any data input. */ /* ----------------------------------------------------------------- */ static sb4 cbf_no_data( - dvoid *ctxp, - OCIBind *bindp, - ub4 iter, ub4 index, + dvoid* /*ctxp*/, + OCIBind* /*bindp*/, + ub4 /*iter*/, ub4 /*index*/, dvoid **bufpp, ub4 *alenpp, ub1 *piecep, @@ -991,7 +1067,7 @@ static sb4 cbf_no_data( /* ----------------------------------------------------------------- */ static sb4 cbf_get_data(dvoid *ctxp, OCIBind *bindp, - ub4 iter, ub4 index, + ub4 /*iter*/, ub4 index, dvoid **bufpp, ub4 **alenp, ub1 *piecep, @@ -1008,7 +1084,7 @@ static sb4 cbf_get_data(dvoid *ctxp, (ub4 *)sizeof(ub2), OCI_ATTR_ROWS_RETURNED, context.cs->errhp)) ; context.rows->count=(ub2)rows; context.rows->row=(OracleSQL_query_lobs::return_rows::return_row *) - context.services->malloc_atomic(sizeof(OracleSQL_query_lobs::return_rows::return_row)*rows); + context.cs->services->malloc_atomic(sizeof(OracleSQL_query_lobs::return_rows::return_row)*rows); } OracleSQL_query_lobs::return_rows::return_row &var=context.rows->row[index]; @@ -1029,8 +1105,13 @@ static sb4 cbf_get_data(dvoid *ctxp, void tolower(char *out, const char *in, size_t size) { while(size--) - *out++=tolower(*in++); + *out++=(char)tolower(*in++); } +void toupper(char *out, const char *in, size_t size) { + while(size--) + *out++=(char)toupper(*in++); +} + extern "C" SQL_Driver *SQL_DRIVER_CREATE() { return OracleSQL_driver=new OracleSQL_Driver();