|
|
| version 1.2, 2001/10/28 14:51:30 | version 1.4, 2001/11/10 16:11:24 |
|---|---|
| Line 38 inline int max(int a, int b) { return a> | Line 38 inline int max(int a, int b) { return a> |
| inline int min(int a, int b){ return a<b?a:b; } | inline int min(int a, int b){ return a<b?a:b; } |
| #endif | #endif |
| static int pa_setenv(const char *name, const char *value) { | |
| #ifdef HAVE_PUTENV | |
| // MEM_LEAK_HERE. refer to EOF man putenv | |
| char *buf=(char *)::malloc(strlen(name)+1+strlen(value)+1); | |
| strcpy(buf, name); | |
| strcat(buf, "="); | |
| strcat(buf, value); | |
| return putenv(buf); | |
| #else | |
| //#ifdef HAVE_SETENV | |
| if(value) | |
| return setenv(name, value, 1/*overwrite*/); | |
| else { | |
| unsetenv(name); | |
| return 0; | |
| } | |
| #endif | |
| } | |
| static char *lsplit(char *string, char delim) { | static char *lsplit(char *string, char delim) { |
| if(string) { | if(string) { |
| char *v=strchr(string, delim); | char *v=strchr(string, delim); |
| Line 49 static char *lsplit(char *string, char d | Line 69 static char *lsplit(char *string, char d |
| return 0; | return 0; |
| } | } |
| static char *lsplit(char **string_ref, char delim) { | |
| char *result=*string_ref; | |
| char *next=lsplit(*string_ref, delim); | |
| *string_ref=next; | |
| return result; | |
| } | |
| #ifndef DOXYGEN | #ifndef DOXYGEN |
| struct OracleSQL_connection_struct { | struct OracleSQL_connection_struct { |
| jmp_buf mark; char error[MAX_STRING]; | jmp_buf mark; char error[MAX_STRING]; |
| Line 126 public: | Line 153 public: |
| if(!error) { | if(!error) { |
| // error="OCIInitialize replacer";/* | // error="OCIInitialize replacer";/* |
| OCIInitialize((ub4)OCI_THREADED, (dvoid *)0, | OCIInitialize((ub4)OCI_THREADED/*| OCI_OBJECT*/, (dvoid *)0, |
| (dvoid * (*)(void *, unsigned int))0, | (dvoid * (*)(void *, unsigned int))0, |
| (dvoid * (*)(void*, void*, unsigned int))0, | (dvoid * (*)(void*, void*, unsigned int))0, |
| (void (*)(void*, void*))0 ); | (void (*)(void*, void*))0 ); |
| Line 139 public: | Line 166 public: |
| /** connect | /** connect |
| @param used_only_in_connect_url | @param used_only_in_connect_url |
| format: @b user:pass@service | format: @b user:pass@service? |
| ORACLE_HOME=/u01/app/oracle/product/8.1.5& | |
| NLS_LANG=RUSSIAN_AMERICA.CL8MSWIN1251& | |
| ORA_ENCRYPT_LOGIN=TRUE | |
| @todo environment manupulation doesnt look thread safe | |
| */ | */ |
| void connect( | void connect( |
| char *used_only_in_connect_url, | char *used_only_in_connect_url, |
| Line 153 public: | Line 185 public: |
| char *user=used_only_in_connect_url; | char *user=used_only_in_connect_url; |
| char *service=lsplit(user, '@'); | char *service=lsplit(user, '@'); |
| char *pwd=lsplit(user, ':'); | char *pwd=lsplit(user, ':'); |
| char *options=lsplit(service, '?'); | |
| if(!(user && pwd && service)) | if(!(user && pwd && service)) |
| services._throw("mailformed connect part, must be 'user:pass@service'"); | services._throw("mailformed connect part, must be 'user:pass@service'"); |
| while(options) { | |
| if(char *key=lsplit(&options, '&')) { | |
| if(*key) { | |
| if(char *value=lsplit(key, '=')) { | |
| if(strncmp(key, "ORACLE_", 7)==0 // ORACLE_HOME & co | |
| || strncmp(key, "ORA_", 4)==0 // ORA_ENCRYPT_LOGIN & co | |
| || strncmp(key, "NLS_", 4)==0 // NLS_LANG & co | |
| ) { | |
| if(pa_setenv(key, value)!=0) | |
| services._throw("problem changing process environment" /*key*/); | |
| } else | |
| services._throw("unknown connect option (option must start with ORACLE_, ORA_ or NLS_)" /*key*/); | |
| } else | |
| services._throw("connect option without =value" /*key*/); | |
| } | |
| } | |
| } | |
| if(setjmp(cs.mark)) | if(setjmp(cs.mark)) |
| services._throw(cs.error); | services._throw(cs.error); |
| Line 269 public: | Line 320 public: |
| bool ping(SQL_Driver_services&, void *connection) { | bool ping(SQL_Driver_services&, void *connection) { |
| // maybe OCIServerVersion? | // maybe OCIServerVersion? |
| // select 0 from dual | |
| return true; | return true; |
| } | } |
| Line 535 private: // private funcs | Line 587 private: // private funcs |
| while(++column_count<=MAX_COLS) { | while(++column_count<=MAX_COLS) { |
| /* get next descriptor, if there is one */ | /* get next descriptor, if there is one */ |
| if(OCIParamGet(stmthp, OCI_HTYPE_STMT, cs.errhp, (void **)&mypard, | if(OCIParamGet(stmthp, OCI_HTYPE_STMT, cs.errhp, (void **)&mypard, |
| (ub4) column_count)!=OCI_SUCCESS) | (ub4) column_count)!=OCI_SUCCESS) { |
| --column_count; | |
| break; | break; |
| } | |
| /* Retrieve the data type attribute */ | /* Retrieve the data type attribute */ |
| check(services, cs, "get type", OCIAttrGet( | check(services, cs, "get type", OCIAttrGet( |
| Line 594 private: // private funcs | Line 648 private: // private funcs |
| for(unsigned long row=0; !limit||row<limit+offset; row++) { | for(unsigned long row=0; !limit||row<limit+offset; row++) { |
| sword status=OCIStmtFetch(stmthp, cs.errhp, (ub4)1, (ub4)OCI_FETCH_NEXT, | sword status=OCIStmtFetch(stmthp, cs.errhp, (ub4)1, (ub4)OCI_FETCH_NEXT, |
| (ub4)OCI_DEFAULT); | (ub4)OCI_DEFAULT); |
| if(status!=OCI_SUCCESS) { | if(status==OCI_NO_DATA) |
| if(status!=OCI_NO_DATA) | |
| check(services, cs, "fetch", status); | |
| break; | break; |
| } | check(services, cs, "fetch", status); |
| if(row>=offset) { | if(row>=offset) { |
| handlers.add_row(); | handlers.add_row(); |
| for(int i=0; i<column_count; i++) { | for(int i=0; i<column_count; i++) { |