--- sql/oracle/parser3oracle.C 2003/07/24 10:09:40 1.32 +++ sql/oracle/parser3oracle.C 2003/12/22 12:38:50 1.43 @@ -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.32 2003/07/24 10:09:40 paf Exp $"; +static const char *RCSId="$Id: parser3oracle.C,v 1.43 2003/12/22 12:38:50 paf Exp $"; #include "config_includes.h" @@ -38,7 +38,7 @@ 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) { case '\'': // "'" -> "''" - *to++='\''; result++; + *to++='\''; break; } *to++=*from++; @@ -376,22 +399,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)); @@ -412,8 +443,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, @@ -450,9 +480,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' @@ -467,6 +498,7 @@ private: // private funcs o[0]=='/' && o[1]=='*' && o[2]=='*') { // name start + const char* saved_o=o; o+=3; const char *name_begin=o; while(*o) @@ -475,6 +507,7 @@ private: // private funcs o[1]=='*' && o[2]=='/' && o[3]=='\'') { // name end + saved_o=0; // found, marking that const char *name_end=o; o+=4; OracleSQL_query_lobs::Item &item=lobs.items[lobs.count++]; @@ -506,6 +539,10 @@ private: // private funcs break; } else o++; // /**skip**/'xxx' + if(saved_o) { + o=saved_o; + *n++=*o++; + } } else *n++=*o++; } @@ -518,17 +555,12 @@ private: // private funcs if(i) *n++=','; n+=sprintf(n, "%.*s", lobs.items[i].name_size, lobs.items[i].name_ptr); - /*memcpy(n, lobs.items[i].name_ptr, lobs.items[i].name_size); - n+=lobs.items[i].name_size;*/ } n+=sprintf(n, " into "); for(i=0; i=offset) { 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; + + // 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; @@ -993,7 +1069,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]; @@ -1018,6 +1094,5 @@ void tolower(char *out, const char *in, } extern "C" SQL_Driver *SQL_DRIVER_CREATE() { - //_asm int 3; return OracleSQL_driver=new OracleSQL_Driver(); }