|
|
| version 1.54, 2004/03/26 13:26:41 | version 1.60, 2004/06/18 15:55:52 |
|---|---|
| Line 83 static int pa_setenv(const char *name, c | Line 83 static int pa_setenv(const char *name, c |
| strcat(buf, value); | strcat(buf, value); |
| value=buf; | value=buf; |
| } | } |
| return setenv(name, value, 1/*overwrite*/); | return setenv(name, value, 1/*overwrite*/); |
| } else { | } else { |
| unsetenv(name); | unsetenv(name); |
| Line 130 struct Connection { | Line 129 struct Connection { |
| } options; | } options; |
| }; | }; |
| struct OracleSQL_query_lobs { | struct Query_lobs { |
| struct return_rows { | struct return_rows { |
| struct return_row { | struct return_row { |
| OCILobLocator *locator; ub4 len; | OCILobLocator *locator; ub4 len; |
| Line 139 struct OracleSQL_query_lobs { | Line 138 struct OracleSQL_query_lobs { |
| } *row; | } *row; |
| int count; | int count; |
| }; | }; |
| struct cbf_context_struct { | |
| Connection *connection; | |
| return_rows *rows; | |
| }; | |
| struct Item { | struct Item { |
| const char *name_ptr; size_t name_size; | const char *name_ptr; size_t name_size; |
| char *data_ptr; size_t data_size; | char *data_ptr; size_t data_size; |
| OCILobLocator *locator; | OCILobLocator *locator; |
| OCIBind *bind; | OCIBind *bind; |
| return_rows rows; | return_rows rows; |
| Connection *connection; | |
| } items[MAX_IN_LOBS]; | } items[MAX_IN_LOBS]; |
| int count; | int count; |
| }; | }; |
| #endif | #endif |
| // forwards | // forwards |
| void check(Connection& connection, const char *step, sword status); | static void faile(Connection& connection, const char *msg); |
| void check(Connection& connection, bool error); | static void check(Connection& connection, const char *step, sword status); |
| static void check(Connection& connection, bool error); | |
| static sb4 cbf_no_data( | static sb4 cbf_no_data( |
| dvoid *ctxp, | dvoid *ctxp, |
| OCIBind *bindp, | OCIBind *bindp, |
| Line 173 static sb4 cbf_get_data(dvoid *ctxp, | Line 171 static sb4 cbf_get_data(dvoid *ctxp, |
| ub1 *piecep, | ub1 *piecep, |
| dvoid **indpp, | dvoid **indpp, |
| ub2 **rcodepp); | ub2 **rcodepp); |
| static void tolower(char *out, const char *in, size_t size); | static void tolower_str(char *out, const char *in, size_t size); |
| static void toupper(char *out, const char *in, size_t size); | static void toupper_str(char *out, const char *in, size_t size); |
| static const char *options2env(char *s, Connection::Options* options) { | static const char *options2env(char *s, Connection::Options* options) { |
| while(s) { | while(s) { |
| Line 183 static const char *options2env(char *s, | Line 181 static const char *options2env(char *s, |
| if(char *value=lsplit(key, '=')) { | if(char *value=lsplit(key, '=')) { |
| if( strcmp( key, "ClientCharset" ) == 0 ) { | if( strcmp( key, "ClientCharset" ) == 0 ) { |
| if(options) { | if(options) { |
| toupper(value, value, strlen(value)); | toupper_str(value, value, strlen(value)); |
| options->cstrClientCharset = value; | options->cstrClientCharset = value; |
| } | } |
| continue; | continue; |
| Line 249 public: | Line 247 public: |
| } | } |
| /** connect | /** connect |
| @param used_only_in_connect_url | @param url |
| format: @b user:pass@service? | format: @b user:pass@service? |
| ORACLE_HOME=/u01/app/oracle/product/8.1.5& | ORACLE_HOME=/u01/app/oracle/product/8.1.5& |
| ORA_NLS33=/u01/app/oracle/product/8.1.5/ocommon/nls/admin/data& | ORA_NLS33=/u01/app/oracle/product/8.1.5/ocommon/nls/admin/data& |
| Line 257 public: | Line 255 public: |
| ORA_ENCRYPT_LOGIN=TRUE | ORA_ENCRYPT_LOGIN=TRUE |
| @todo environment manupulation doesnt look thread safe | @todo environment manupulation doesnt look thread safe |
| @todo allocate 'aused_only_in_connect_url' on gc heap, so it can be manipulated directly | |
| */ | */ |
| void connect( | void connect( |
| char *used_only_in_connect_url, | char *url, |
| SQL_Driver_services& services, | SQL_Driver_services& services, |
| void **connection_ref ///< output: Connection * | void **connection_ref ///< output: Connection * |
| ) { | ) |
| { | |
| // connections are cross-request, do not use services._alloc [linked with request] | |
| Connection& connection=*(Connection *)services.malloc(sizeof(Connection)); | Connection& connection=*(Connection *)services.malloc(sizeof(Connection)); |
| connection.services=&services; | connection.services=&services; |
| connection.options.bLowerCaseColumnNames = true; | connection.options.bLowerCaseColumnNames = true; |
| *connection_ref=&connection; | *connection_ref=&connection; |
| char *user=used_only_in_connect_url; | char *user=url; |
| char *service=lsplit(user, '@'); | char *service=lsplit(user, '@'); |
| char *pwd=lsplit(user, ':'); | char *pwd=lsplit(user, ':'); |
| char *options=lsplit(service, '?'); | char *options=lsplit(service, '?'); |
| Line 345 public: | Line 346 public: |
| void disconnect(void *aconnection) { | void disconnect(void *aconnection) { |
| Connection& connection=*static_cast<Connection *>(aconnection); | Connection& connection=*static_cast<Connection *>(aconnection); |
| // free fetch buffers | // free fetch buffers. leave that to GC [no such services func. yet?] |
| /* | |
| for(int i=0; i<MAX_COLS; i++) { | for(int i=0; i<MAX_COLS; i++) { |
| if(void* fetch_buffer=connection.fetch_buffers[i]) | if(void* fetch_buffer=connection.fetch_buffers[i]) |
| ::free(fetch_buffer); | connection.services->free(fetch_buffer); |
| else | else |
| break; | break; |
| } | } |
| */ | |
| // Terminate a user session | // Terminate a user session |
| OCISessionEnd( | OCISessionEnd( |
| Line 372 public: | Line 375 public: |
| OCIHandleFree( | OCIHandleFree( |
| (dvoid *)connection.envhp, (ub4)OCI_HTYPE_ENV); | (dvoid *)connection.envhp, (ub4)OCI_HTYPE_ENV); |
| // connections are cross-request, do not use services._alloc [linked with request] | // free connection. leave that to GC [no such services func. yet?] |
| ::free(&connection); | // connection.services->free(&connection); |
| } | } |
| void commit(void *aconnection) { | void commit(void *aconnection) { |
| Connection& connection=*static_cast<Connection *>(aconnection); | Connection& connection=*static_cast<Connection *>(aconnection); |
| Line 415 public: | Line 418 public: |
| *to=0; | *to=0; |
| return result; | return result; |
| } | } |
| void query(void *aconnection, | void query(void* aconnection, |
| const char *astatement, unsigned long offset, unsigned long limit, | const char* astatement, |
| size_t placeholders_count, Placeholder* placeholders, | |
| unsigned long offset, unsigned long limit, | |
| SQL_Driver_query_event_handlers& handlers) | SQL_Driver_query_event_handlers& handlers) |
| { | { |
| Connection& connection=*static_cast<Connection *>(aconnection); | Connection& connection=*static_cast<Connection *>(aconnection); |
| const char* cstrClientCharset=connection.options.cstrClientCharset; | const char* cstrClientCharset=connection.options.cstrClientCharset; |
| OracleSQL_query_lobs lobs={{0}, 0}; | Query_lobs lobs={{0}, 0}; |
| OCIStmt *stmthp=0; | OCIStmt *stmthp=0; |
| SQL_Driver_services& services=*connection.services; | SQL_Driver_services& services=*connection.services; |
| // transcode from $request:charset to connect-string?client_charset | // transcode from $request:charset to connect-string?client_charset |
| if(cstrClientCharset) { | if(cstrClientCharset) { |
| size_t transcoded_statement_size; | size_t transcoded_xxx_size; |
| services.transcode(astatement, strlen(astatement), | services.transcode(astatement, strlen(astatement), |
| astatement, transcoded_statement_size, | astatement, transcoded_xxx_size, |
| services.request_charset(), | services.request_charset(), |
| cstrClientCharset); | cstrClientCharset); |
| } | } |
| Line 448 public: | Line 453 public: |
| OCIStmtPrepare(stmthp, connection.errhp, (unsigned char *)statement, | OCIStmtPrepare(stmthp, connection.errhp, (unsigned char *)statement, |
| (ub4)strlen((char *)statement), | (ub4)strlen((char *)statement), |
| (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT)); | (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT)); |
| struct Bind_info { | |
| OCIBind *bind; | |
| sb2 indicator; | |
| }; | |
| int binds_size=sizeof(Bind_info) * placeholders_count; | |
| Bind_info* binds=static_cast<Bind_info*>(services.malloc_atomic(binds_size)); | |
| { | { |
| for(size_t i=0; i<placeholders_count; i++) { | |
| Placeholder& ph=placeholders[i]; | |
| Bind_info& bi=binds[i]; | |
| bi.bind=0; | |
| bi.indicator=ph.is_null? -1: 0/*9999*/; | |
| size_t value_length; | |
| if(cstrClientCharset) { | |
| size_t name_length; | |
| services.transcode(ph.name, strlen(ph.name), | |
| ph.name, name_length, | |
| services.request_charset(), | |
| cstrClientCharset); | |
| if(ph.value) | |
| services.transcode(ph.value, strlen(ph.value), | |
| ph.value, value_length, | |
| services.request_charset(), | |
| cstrClientCharset); | |
| } else { | |
| value_length=ph.value? strlen(ph.value): 0; | |
| } | |
| char placeholder_buf[MAX_STRING]; | |
| sb4 placeh_len=snprintf(placeholder_buf, sizeof(placeholder_buf), ":%s", ph.name); | |
| check(connection, "bind name", OCIBindByName(stmthp, | |
| &bi.bind, connection.errhp, | |
| (text*)placeholder_buf, placeh_len, | |
| (dvoid *)ph.value, (sword)value_length, SQLT_CHR/*SQLT_STR*/, (dvoid *)&bi.indicator, | |
| (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT)); | |
| } | |
| for(int i=0; i<lobs.count; i++) { | for(int i=0; i<lobs.count; i++) { |
| Query_lobs::Item &item=lobs.items[i]; | |
| check(connection, "alloc output var desc", OCIDescriptorAlloc( | check(connection, "alloc output var desc", OCIDescriptorAlloc( |
| (dvoid *)connection.envhp, (dvoid **)&lobs.items[i].locator, (ub4)OCI_DTYPE_LOB, 0, 0)); | (dvoid *)connection.envhp, (dvoid **)&item.locator, (ub4)OCI_DTYPE_LOB, 0, 0)); |
| check(connection, "bind output", OCIBindByPos(stmthp, | char placeholder_buf[MAX_STRING]; |
| &lobs.items[i].bind, connection.errhp, | sb4 placeh_len=snprintf(placeholder_buf, sizeof(placeholder_buf), |
| (ub4)1+i, | ":%.*s", item.name_size, item.name_ptr); |
| (dvoid *)&lobs.items[i].locator, | check(connection, "bind lob", OCIBindByName(stmthp, |
| (sword)sizeof (lobs.items[i].locator), SQLT_CLOB, (dvoid *)0, | &item.bind, connection.errhp, |
| (text*)placeholder_buf, placeh_len, | |
| (dvoid *)&item.locator, | |
| (sword)sizeof (item.locator), SQLT_CLOB, (dvoid *)0, | |
| (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DATA_AT_EXEC)); | (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DATA_AT_EXEC)); |
| lobs.items[i].rows.count=0; | item.rows.count=0; |
| OracleSQL_query_lobs::cbf_context_struct cbf_context={&connection, &lobs.items[i].rows}; | item.connection=&connection; |
| check(connection, "bind dynamic", OCIBindDynamic( | check(connection, "bind dynamic", OCIBindDynamic( |
| lobs.items[i].bind, connection.errhp, | item.bind, connection.errhp, |
| (dvoid *) &cbf_context, cbf_no_data, | (dvoid *) &item, cbf_no_data, |
| (dvoid *) &cbf_context, cbf_get_data)); | (dvoid *) &item, cbf_get_data)); |
| } | } |
| } | } |
| execute_prepared(connection, | execute_prepared(connection, |
| statement, stmthp, lobs, | statement, stmthp, lobs, |
| offset, limit, handlers); | offset, limit, handlers); |
| { | |
| for(size_t i=0; i<placeholders_count; i++) { | |
| Placeholder& ph=placeholders[i]; | |
| Bind_info& bi=binds[i]; | |
| if(bi.indicator==9999 /*unchanged*/) | |
| continue; | |
| if(bi.indicator==-1) | |
| ph.is_null=true; | |
| else | |
| if(bi.indicator==0) | |
| ph.is_null=false; | |
| else | |
| fail(connection, bi.indicator<0? | |
| "column return buffer overflow, additionally size too big to be returned in 'indicator'" | |
| : "column return buffer overflow"); | |
| ph.were_updated=true; | |
| if(cstrClientCharset) { | |
| if(ph.value) { | |
| size_t value_length; | |
| services.transcode(ph.value, strlen(ph.value), | |
| ph.value, value_length, | |
| cstrClientCharset, | |
| services.request_charset()); | |
| } | |
| } | |
| } | |
| } | |
| } | } |
| cleanup: // no check call after this point! | cleanup: // no check call after this point! |
| { | { |
| Line 481 cleanup: // no check call after this poi | Line 563 cleanup: // no check call after this poi |
| OCIDescriptorFree((dvoid *)locator, (ub4)OCI_DTYPE_LOB); | OCIDescriptorFree((dvoid *)locator, (ub4)OCI_DTYPE_LOB); |
| /* free rows descriptors */ | /* free rows descriptors */ |
| OracleSQL_query_lobs::return_rows &rows=lobs.items[i].rows; | Query_lobs::return_rows &rows=lobs.items[i].rows; |
| for(int r=0; r<rows.count; r++) | for(int r=0; r<rows.count; r++) |
| OCIDescriptorFree((dvoid *)rows.row[r].locator, (ub4)OCI_DTYPE_LOB); | OCIDescriptorFree((dvoid *)rows.row[r].locator, (ub4)OCI_DTYPE_LOB); |
| } | } |
| Line 499 cleanup: // no check call after this poi | Line 581 cleanup: // no check call after this poi |
| private: // private funcs | private: // private funcs |
| const char *preprocess_statement(Connection& connection, | const char *preprocess_statement(Connection& connection, |
| const char *astatement, OracleSQL_query_lobs &lobs) { | const char *astatement, Query_lobs &lobs) { |
| size_t statement_size=strlen(astatement); | size_t statement_size=strlen(astatement); |
| SQL_Driver_services& services=*connection.services; | SQL_Driver_services& services=*connection.services; |
| Line 528 private: // private funcs | Line 610 private: // private funcs |
| saved_o=0; // found, marking that | saved_o=0; // found, marking that |
| const char *name_end=o; | const char *name_end=o; |
| o+=4; | o+=4; |
| OracleSQL_query_lobs::Item &item=lobs.items[lobs.count++]; | Query_lobs::Item &item=lobs.items[lobs.count++]; |
| item.name_ptr=name_begin; item.name_size=name_end-name_begin; | item.name_ptr=name_begin; item.name_size=name_end-name_begin; |
| item.data_ptr=(char *)services.malloc_atomic(statement_size/*max*/); item.data_size=0; | item.data_ptr=(char *)services.malloc_atomic(statement_size/*max*/); item.data_size=0; |
| Line 587 private: // private funcs | Line 669 private: // private funcs |
| void execute_prepared( | void execute_prepared( |
| Connection& connection, | Connection& connection, |
| const char *statement, OCIStmt *stmthp, OracleSQL_query_lobs &lobs, | const char *statement, OCIStmt *stmthp, Query_lobs &lobs, |
| unsigned long offset, unsigned long limit, | unsigned long offset, unsigned long limit, |
| SQL_Driver_query_event_handlers& handlers) { | SQL_Driver_query_event_handlers& handlers) { |
| Line 620 private: // private funcs | Line 702 private: // private funcs |
| { | { |
| for(int i=0; i<lobs.count; i++) | for(int i=0; i<lobs.count; i++) |
| if(ub4 bytes_to_write=lobs.items[i].data_size) { | if(ub4 bytes_to_write=lobs.items[i].data_size) { |
| OracleSQL_query_lobs::return_rows *rows=&lobs.items[i].rows; | Query_lobs::return_rows *rows=&lobs.items[i].rows; |
| for(int r=0; r<rows->count; r++) { | for(int r=0; r<rows->count; r++) { |
| OCILobLocator *locator=rows->row[r].locator; | OCILobLocator *locator=rows->row[r].locator; |
| check(connection, "lobwrite", OCILobWrite ( | check(connection, "lobwrite", OCILobWrite ( |
| Line 720 private: // private funcs | Line 802 private: // private funcs |
| size_t length=(size_t)col_name_len; | size_t length=(size_t)col_name_len; |
| char *ptr=(char *)services.malloc_atomic(length+1); | char *ptr=(char *)services.malloc_atomic(length+1); |
| if( connection.options.bLowerCaseColumnNames ) | if( connection.options.bLowerCaseColumnNames ) |
| tolower(ptr, col_name, length); | tolower_str(ptr, col_name, length); |
| else | else |
| memcpy(ptr, col_name, length); | memcpy(ptr, col_name, length); |
| ptr[length]=0; | ptr[length]=0; |
| Line 747 private: // private funcs | Line 829 private: // private funcs |
| char*& buf=connection.fetch_buffers[column_count-1]; | char*& buf=connection.fetch_buffers[column_count-1]; |
| ptr=buf; // get cached buffer | ptr=buf; // get cached buffer |
| if(!ptr) // allocate if needed, caching it | if(!ptr) // allocate if needed, caching it |
| ptr=buf=(char *)::/*see disconnect*/malloc(MAX_OUT_STRING_LENGTH+1/*terminator*/); | ptr=buf=(char *)services.malloc_atomic(MAX_OUT_STRING_LENGTH+1/*terminator*/); |
| col.str=(char*)ptr; | col.str=(char*)ptr; |
| size=MAX_OUT_STRING_LENGTH; | size=MAX_OUT_STRING_LENGTH; |
| break; | break; |
| Line 781 private: // private funcs | Line 863 private: // private funcs |
| for(int i=0; i<column_count; i++) { | for(int i=0; i<column_count; i++) { |
| size_t length=0; | size_t length=0; |
| char* strm=0; | char* strm=0; |
| if(!cols[i].indicator) // not NULL | |
| sb2 indicator=cols[i].indicator; | |
| if(indicator!=-1) { // not NULL | |
| if(indicator!=0) | |
| fail(connection, indicator<0? | |
| "column return buffer overflow, additionally size too big to be returned in 'indicator'" | |
| : "column return buffer overflow"); | |
| switch(cols[i].type) { | switch(cols[i].type) { |
| case SQLT_CLOB: | case SQLT_CLOB: |
| { | { |
| Line 822 private: // private funcs | Line 911 private: // private funcs |
| } | } |
| break; | break; |
| } | } |
| } | |
| const char* str=strm; | const char* str=strm; |
| if(str && length) | if(str && length) |
| Line 858 cleanup: // no check call after this poi | Line 948 cleanup: // no check call after this poi |
| private: // conn client library funcs | private: // conn client library funcs |
| friend void fail(Connection& connection, const char *msg); | |
| friend void check(Connection& connection, const char *step, sword status); | friend void check(Connection& connection, const char *step, sword status); |
| friend sb4 cbf_get_data(dvoid *ctxp, | friend sb4 cbf_get_data(dvoid *ctxp, |
| OCIBind *bindp, | OCIBind *bindp, |
| Line 892 private: // conn client library funcs | Line 983 private: // conn client library funcs |
| ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, | ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, |
| ub4 maxarr_len, ub4 *curelep, ub4 mode)); | ub4 maxarr_len, ub4 *curelep, ub4 mode)); |
| OCI_DECL(BindByName, (OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp, | |
| text* placeholder, sb4 placeh_len, dvoid *valuep, sb4 value_sz, | |
| ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, | |
| ub4 maxarr_len, ub4 *curelep, ub4 mode)); | |
| OCI_DECL(BindDynamic, (OCIBind *bindp, OCIError *errhp, dvoid *ictxp, | OCI_DECL(BindDynamic, (OCIBind *bindp, OCIError *errhp, dvoid *ictxp, |
| OCICallbackInBind icbfp, dvoid *octxp, | OCICallbackInBind icbfp, dvoid *octxp, |
| OCICallbackOutBind ocbfp)); | OCICallbackOutBind ocbfp)); |
| Line 983 private: // conn client library funcs li | Line 1079 private: // conn client library funcs li |
| OCI_LINK(Initialize); | OCI_LINK(Initialize); |
| OCI_LINK(EnvInit); | OCI_LINK(EnvInit); |
| OCI_LINK(AttrGet); OCI_LINK(AttrSet); | OCI_LINK(AttrGet); OCI_LINK(AttrSet); |
| OCI_LINK(BindByPos); OCI_LINK(BindDynamic); | OCI_LINK(BindByPos); OCI_LINK(BindByName); OCI_LINK(BindDynamic); |
| OCI_LINK(DefineByPos); | OCI_LINK(DefineByPos); |
| OCI_LINK(DescriptorAlloc); OCI_LINK(DescriptorFree); | OCI_LINK(DescriptorAlloc); OCI_LINK(DescriptorFree); |
| OCI_LINK(ErrorGet); | OCI_LINK(ErrorGet); |
| Line 1052 void check(Connection& connection, const | Line 1148 void check(Connection& connection, const |
| longjmp(connection.mark, 1); | longjmp(connection.mark, 1); |
| } | } |
| void fail(Connection& connection, const char* msg) { | |
| snprintf(connection.error, sizeof(connection.error), "%s", msg); | |
| longjmp(connection.mark, 1); | |
| } | |
| void check(Connection& connection, bool error) { | void check(Connection& connection, bool error) { |
| if(error) | if(error) |
| longjmp(connection.mark, 1); | longjmp(connection.mark, 1); |
| Line 1060 void check(Connection& connection, bool | Line 1161 void check(Connection& connection, bool |
| /* ----------------------------------------------------------------- */ | /* ----------------------------------------------------------------- */ |
| /* Intbind callback that does not do any data input. */ | /* Intbind callback that does not do any data input. */ |
| /* ----------------------------------------------------------------- */ | /* ----------------------------------------------------------------- */ |
| static sb4 cbf_no_data( | sb4 cbf_no_data( |
| dvoid* /*ctxp*/, | dvoid* /*ctxp*/, |
| OCIBind* /*bindp*/, | OCIBind* /*bindp*/, |
| ub4 /*iter*/, ub4 /*index*/, | ub4 /*iter*/, ub4 /*index*/, |
| Line 1088 static sb4 cbf_get_data(dvoid *ctxp, | Line 1189 static sb4 cbf_get_data(dvoid *ctxp, |
| ub1 *piecep, | ub1 *piecep, |
| dvoid **indpp, | dvoid **indpp, |
| ub2 **rcodepp) { | ub2 **rcodepp) { |
| OracleSQL_query_lobs::cbf_context_struct &context= | Query_lobs::Item& context=*static_cast<Query_lobs::Item*>(ctxp); |
| *(OracleSQL_query_lobs::cbf_context_struct *)ctxp; | |
| if(index==0) { | if(index==0) { |
| static ub4 rows; | static ub4 rows; |
| Line 1097 static sb4 cbf_get_data(dvoid *ctxp, | Line 1197 static sb4 cbf_get_data(dvoid *ctxp, |
| OracleSQL_driver->OCIAttrGet( | OracleSQL_driver->OCIAttrGet( |
| (CONST dvoid *) bindp, OCI_HTYPE_BIND, (dvoid *)&rows, | (CONST dvoid *) bindp, OCI_HTYPE_BIND, (dvoid *)&rows, |
| (ub4 *)sizeof(ub2), OCI_ATTR_ROWS_RETURNED, context.connection->errhp)) ; | (ub4 *)sizeof(ub2), OCI_ATTR_ROWS_RETURNED, context.connection->errhp)) ; |
| context.rows->count=(ub2)rows; | context.rows.count=(ub2)rows; |
| context.rows->row=(OracleSQL_query_lobs::return_rows::return_row *) | context.rows.row=(Query_lobs::return_rows::return_row *) |
| context.connection->services->malloc_atomic(sizeof(OracleSQL_query_lobs::return_rows::return_row)*rows); | context.connection->services->malloc_atomic(sizeof(Query_lobs::return_rows::return_row)*rows); |
| } | } |
| OracleSQL_query_lobs::return_rows::return_row &var=context.rows->row[index]; | Query_lobs::return_rows::return_row &var=context.rows.row[index]; |
| check(*context.connection, "alloc output var desc dynamic", OracleSQL_driver->OCIDescriptorAlloc( | check(*context.connection, "alloc output var desc dynamic", OracleSQL_driver->OCIDescriptorAlloc( |
| (dvoid *) context.connection->envhp, (dvoid **)&var.locator, | (dvoid *) context.connection->envhp, (dvoid **)&var.locator, |
| Line 1118 static sb4 cbf_get_data(dvoid *ctxp, | Line 1218 static sb4 cbf_get_data(dvoid *ctxp, |
| return OCI_CONTINUE; | return OCI_CONTINUE; |
| } | } |
| static void tolower(char *out, const char *in, size_t size) { | static void tolower_str(char *out, const char *in, size_t size) { |
| while(size--) | while(size--) |
| *out++=(char)tolower(*in++); | *out++=(char)tolower(*in++); |
| } | } |
| static void toupper(char *out, const char *in, size_t size) { | static void toupper_str(char *out, const char *in, size_t size) { |
| while(size--) | while(size--) |
| *out++=(char)toupper(*in++); | *out++=(char)toupper(*in++); |
| } | } |