|
|
| version 1.63, 2004/08/03 11:15:27 | version 1.66, 2004/10/11 14:30:24 |
|---|---|
| Line 7 | Line 7 |
| 2001.07.30 using Oracle 8.1.6 [@test tested with Oracle 7.x.x] | 2001.07.30 using Oracle 8.1.6 [@test tested with Oracle 7.x.x] |
| */ | */ |
| /* | |
| prob: | |
| kgepop: no error frame to pop to for error 21500 | |
| > I happy to tell you that I have solved the problem. | |
| Excellent news. | |
| > By allocating a separate | |
| > environment handle for every database handle I share | |
| */ | |
| static const char *RCSId="$Id$"; | static const char *RCSId="$Id$"; |
| Line 481 public: | Line 469 public: |
| }; | }; |
| int binds_size=sizeof(Bind_info) * placeholders_count; | 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<Bind_info*>(services.malloc_atomic(binds_size)); | Bind_info* binds=static_cast<Bind_info*>(services.malloc_atomic(binds_size)); |
| { | { |
| for(size_t i=0; i<placeholders_count; i++) { | for(size_t i=0; i<placeholders_count; i++) { |
| Line 508 public: | Line 499 public: |
| value_length=ph.value? strlen(ph.value): 0; | value_length=ph.value? strlen(ph.value): 0; |
| } | } |
| { | // clone value for possible output binds |
| // clone value for possible output binds | // note: even empty input can be replaced by huge output |
| // note: even empty input can be replaced by huge output | char*& value_buf=connection.bind_buffers[i]; // get cached buffer |
| char*& buf=connection.bind_buffers[i]; // get cached buffer | if(!value_buf) // allocate if needed, caching it |
| if(!buf) // allocate if needed, caching it | value_buf=(char *)services.malloc_atomic(MAX_OUT_STRING_LENGTH+1/*terminator*/); |
| buf=(char *)services.malloc_atomic(MAX_OUT_STRING_LENGTH+1/*terminator*/); | if(value_length) |
| if(value_length) | memcpy(value_buf, ph.value, value_length+1); |
| memcpy(buf, ph.value, value_length+1); | else |
| ph.value=buf; | value_buf[0]=0; |
| } | |
| char placeholder_buf[MAX_STRING]; | char name_buf[MAX_STRING]; |
| sb4 placeh_len=snprintf(placeholder_buf, sizeof(placeholder_buf), ":%s", ph.name); | sb4 placeh_len=snprintf(name_buf, sizeof(name_buf), ":%s", ph.name); |
| char check_step_buf[MAX_STRING]; | char check_step_buf[MAX_STRING]; |
| snprintf(check_step_buf, sizeof(check_step_buf), "bind by name :%s", ph.name); | snprintf(check_step_buf, sizeof(check_step_buf), "bind by name :%s", ph.name); |
| check(connection, check_step_buf, OCIBindByName(stmthp, | check(connection, check_step_buf, OCIBindByName(stmthp, |
| &bi.bind, connection.errhp, | &bi.bind, connection.errhp, |
| (text*)placeholder_buf, placeh_len, | (text*)name_buf, placeh_len, |
| (dvoid *)ph.value, (sword)(MAX_OUT_STRING_LENGTH+1), SQLT_STR, (dvoid *)&bi.indicator, | (dvoid *)value_buf, (sword)(MAX_OUT_STRING_LENGTH+1), SQLT_STR, (dvoid *)&bi.indicator, |
| (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT)); | (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT)); |
| } | } |
| Line 560 public: | Line 550 public: |
| { | { |
| for(size_t i=0; i<placeholders_count; i++) { | for(size_t i=0; i<placeholders_count; i++) { |
| Placeholder& ph=placeholders[i]; | |
| Bind_info& bi=binds[i]; | Bind_info& bi=binds[i]; |
| if(bi.indicator==MAGIC_INDICATOR_VALUE_MEANING_NOT_NULL_AND_UNCHANGED/*unchanged*/) | if(bi.indicator==MAGIC_INDICATOR_VALUE_MEANING_NOT_NULL_AND_UNCHANGED/*unchanged*/) |
| continue; | continue; |
| Placeholder& ph=placeholders[i]; | |
| if(bi.indicator==-1) | if(bi.indicator==-1) |
| ph.is_null=true; | ph.is_null=true; |
| else | else |
| Line 577 public: | Line 566 public: |
| : "output bind buffer overflow"); | : "output bind buffer overflow"); |
| ph.were_updated=true; | ph.were_updated=true; |
| const char* bind_buffer=connection.bind_buffers[i]; | |
| if(cstrClientCharset) { | if( size_t value_length=strlen(bind_buffer) ) { |
| if(ph.value) { | char* returned_value=(char*)services.malloc_atomic(value_length+1/*terminator*/); |
| size_t value_length; | memcpy(returned_value, bind_buffer, value_length+1 ); |
| services.transcode(ph.value, strlen(ph.value), | ph.value=returned_value; |
| ph.value, value_length, | |
| if(cstrClientCharset) { | |
| services.transcode(ph.value, value_length, | |
| ph.value, value_length/*<this new value is not used afterwards, actually*/, | |
| cstrClientCharset, | cstrClientCharset, |
| services.request_charset()); | services.request_charset()); |
| } | } |
| } else { | |
| ph.value=0; | |
| } | } |
| } | } |
| } | } |