--- sql/oracle/parser3oracle.C 2004/06/18 15:55:52 1.60 +++ sql/oracle/parser3oracle.C 2008/06/30 15:22:28 1.69 @@ -7,7 +7,8 @@ 2001.07.30 using Oracle 8.1.6 [@test tested with Oracle 7.x.x] */ -static const char *RCSId="$Id: parser3oracle.C,v 1.60 2004/06/18 15:55:52 paf Exp $"; + +static const char *RCSId="$Id: parser3oracle.C,v 1.69 2008/06/30 15:22:28 misha Exp $"; #include "config_includes.h" @@ -19,6 +20,7 @@ static const char *RCSId="$Id: parser3or #define MAX_IN_LOBS 5 #define MAX_LOB_NAME_LENGTH 100 #define MAX_OUT_STRING_LENGTH 4000 +#define MAX_BINDS 100 #define EMPTY_CLOB_FUNC_CALL "empty_clob()" @@ -44,6 +46,8 @@ inline int min(int a, int b){ return a(aconnection); @@ -378,6 +403,7 @@ public: // free connection. leave that to GC [no such services func. yet?] // connection.services->free(&connection); } + void commit(void *aconnection) { Connection& connection=*static_cast(aconnection); if(setjmp(connection.mark)) @@ -385,6 +411,7 @@ public: check(connection, "commit", OCITransCommit(connection.svchp, connection.errhp, 0)); } + void rollback(void *aconnection) { Connection& connection=*static_cast(aconnection); if(setjmp(connection.mark)) @@ -418,26 +445,29 @@ public: *to=0; return result; } + void query(void* aconnection, - const char* astatement, - size_t placeholders_count, Placeholder* placeholders, - unsigned long offset, unsigned long limit, - SQL_Driver_query_event_handlers& handlers) - { + const char* astatement, + size_t placeholders_count, Placeholder* placeholders, + unsigned long offset, unsigned long limit, + SQL_Driver_query_event_handlers& handlers + ){ + Connection& connection=*static_cast(aconnection); - const char* cstrClientCharset=connection.options.cstrClientCharset; Query_lobs lobs={{0}, 0}; OCIStmt *stmthp=0; SQL_Driver_services& services=*connection.services; - // transcode from $request:charset to connect-string?client_charset - if(cstrClientCharset) { + bool transcode_needed=_transcode_required(connection); + + if(transcode_needed){ + // transcode query from $request:charset to ?ClientCharset size_t transcoded_xxx_size; services.transcode(astatement, strlen(astatement), astatement, transcoded_xxx_size, services.request_charset(), - cstrClientCharset); + connection.options.client_charset); } bool failed=false; @@ -445,6 +475,9 @@ public: failed=true; goto cleanup; } else { + if(placeholders_count>MAX_BINDS) + fail(connection, "too many bind variables"); + const char *statement=preprocess_statement(connection, astatement, lobs); check(connection, "HandleAlloc STMT", OCIHandleAlloc( @@ -460,38 +493,55 @@ public: }; int binds_size=sizeof(Bind_info) * placeholders_count; + // we DO store OCIBind* into ATOMIC gc memory, + // but we do not allocate/free it, that's done automatically from oracle [using environment handles] + // so we don't have to bother with that Bind_info* binds=static_cast(services.malloc_atomic(binds_size)); { for(size_t i=0; irequest_charset())!=0); + } + private: // conn client library funcs friend void fail(Connection& connection, const char *msg); @@ -1114,15 +1188,13 @@ void check(Connection& connection, const (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=connection.options.cstrClientCharset) { - if(msg) { - if(size_t msg_length=strlen(msg)) { - connection.services->transcode(msg, msg_length, - msg, msg_length, - cstrClientCharset, - connection.services->request_charset()); - } + // transcode server error message from ?ClientCharset to $request:charset + if(msg && connection.options.client_charset && strcmp(connection.options.client_charset, connection.services->request_charset())!=0){ + if(size_t msg_length=strlen(msg)){ + connection.services->transcode(msg, msg_length, + msg, msg_length, + connection.options.client_charset, + connection.services->request_charset()); } } } else @@ -1218,16 +1290,6 @@ static sb4 cbf_get_data(dvoid *ctxp, return OCI_CONTINUE; } -static void tolower_str(char *out, const char *in, size_t size) { - while(size--) - *out++=(char)tolower(*in++); -} -static void toupper_str(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(); }