--- parser3/src/sql/oracle/Attic/parser3oracle.C 2001/08/23 10:37:46 1.3 +++ parser3/src/sql/oracle/Attic/parser3oracle.C 2001/09/06 06:11:13 1.18 @@ -5,9 +5,9 @@ Author: Alexander Petrosyan (http://design.ru/paf) - 2001.07.30 using Oracle 8.1.6, tested with Oracle 7.x.x + 2001.07.30 using Oracle 8.1.6 [@test tested with Oracle 7.x.x] */ -static const char *RCSId="$Id: parser3oracle.C,v 1.3 2001/08/23 10:37:46 parser Exp $"; +static const char *RCSId="$Id: parser3oracle.C,v 1.18 2001/09/06 06:11:13 parser Exp $"; #include "config_includes.h" @@ -49,6 +49,7 @@ static char *lsplit(char *string, char d return 0; } +#ifndef DOXYGEN struct OracleSQL_connection_struct { jmp_buf mark; char error[MAX_STRING]; OCIEnv *envhp; @@ -81,7 +82,7 @@ struct OracleSQL_query_lobs { } items[MAX_IN_LOBS]; int count; }; - +#endif // forwards void check( @@ -118,17 +119,21 @@ public: int api_version() { return SQL_DRIVER_API_VERSION; } /// initialize driver by loading sql dynamic link library const char *initialize(const char *dlopen_file_spec) { -/* const char *error=dlopen_file_spec? + + const char *error=dlopen_file_spec? dlink(dlopen_file_spec):"client library column is empty"; - if(!error) {*/ - OCIInitialize((ub4)OCI_THREADED | OCI_OBJECT, (dvoid *)0, - (dvoid * (*)(void *, unsigned int)) 0, - (dvoid * (*)(void*, void*, unsigned int)) 0, - (void (*)(void*, void*)) 0 ); - /*} + if(!error) { + +// error="OCIInitialize replacer";/* + OCIInitialize((ub4)OCI_THREADED, (dvoid *)0, + (dvoid * (*)(void *, unsigned int))0, + (dvoid * (*)(void*, void*, unsigned int))0, + (void (*)(void*, void*))0 ); + +// */ + } - return error;*/ - return 0; + return error; } /** connect @@ -140,13 +145,14 @@ public: SQL_Driver_services& services, void **connection ///< output: OracleSQL_connection_struct * ) { + // connections are cross-request, do not use services._alloc [linked with request] + OracleSQL_connection_struct &cs= + *(OracleSQL_connection_struct *)::calloc(sizeof(OracleSQL_connection_struct), 1); + char *user=used_only_in_connect_url; char *service=lsplit(user, '@'); char *pwd=lsplit(user, ':'); - OracleSQL_connection_struct &cs= - *(OracleSQL_connection_struct *)services.calloc(sizeof(OracleSQL_connection_struct)); - if(!(user && pwd && service)) services._throw("mailformed connect part, must be 'user:pass@service'"); @@ -169,46 +175,46 @@ public: think, this is some sort of backward compatibility wonder. leaving as it is, and without check() */ - OCIHandleAlloc((dvoid *) NULL, (dvoid **) &cs.envhp, (ub4)OCI_HTYPE_ENV, 0, 0); + OCIHandleAlloc((dvoid *)NULL, (dvoid **) &cs.envhp, (ub4)OCI_HTYPE_ENV, 0, 0); // Initialize an environment handle, attempt #2 - check(services, cs, "OCIEnvInit", OCIEnvInit( + check(services, cs, "EnvInit", OCIEnvInit( &cs.envhp, (ub4)OCI_DEFAULT, 0, 0)); // Allocate and initialize OCIError handle - check(services, cs, "OCIHandleAlloc errhp", OCIHandleAlloc( + check(services, cs, "HandleAlloc errhp", OCIHandleAlloc( (dvoid *)cs.envhp, (dvoid **) &cs.errhp, (ub4)OCI_HTYPE_ERROR, 0, 0)); // Allocate and initialize OCIServer handle - check(services, cs, "OCIHandleAlloc srvhp", OCIHandleAlloc( + check(services, cs, "HandleAlloc srvhp", OCIHandleAlloc( (dvoid *)cs.envhp, (dvoid **) &cs.srvhp, (ub4)OCI_HTYPE_SERVER, 0, 0)); // Attach to a 'service'; initialize server context handle - check(services, cs, "OCIServerAttach", OCIServerAttach( - cs.srvhp, cs.errhp, (text *) service, (sb4) strlen(service), (ub4)OCI_DEFAULT)); + check(services, cs, "ServerAttach", OCIServerAttach( + cs.srvhp, cs.errhp, (text *)service, (sb4)strlen(service), (ub4)OCI_DEFAULT)); // Allocate and initialize OCISvcCtx handle - check(services, cs, "OCIHandleAlloc svchp", OCIHandleAlloc( + check(services, cs, "HandleAlloc svchp", OCIHandleAlloc( (dvoid *)cs.envhp, (dvoid **) &cs.svchp, (ub4)OCI_HTYPE_SVCCTX, 0, 0)); // set attribute server context in the service context - check(services, cs, "OCIAttrSet server-service", OCIAttrSet( + check(services, cs, "AttrSet server-service", OCIAttrSet( (dvoid *)cs.svchp, (ub4)OCI_HTYPE_SVCCTX, - (dvoid *)cs.srvhp, (ub4) 0, + (dvoid *)cs.srvhp, (ub4)0, (ub4)OCI_ATTR_SERVER, (OCIError *)cs.errhp)); // allocate a user context handle - check(services, cs, "OCIHandleAlloc usrhp", OCIHandleAlloc( + check(services, cs, "HandleAlloc usrhp", OCIHandleAlloc( (dvoid *)cs.envhp, (dvoid **)&cs.usrhp, (ub4)OCI_HTYPE_SESSION, 0, 0)); // set 'user' name - check(services, cs, "OCIAttrSet user-session", OCIAttrSet( + check(services, cs, "AttrSet user-session", OCIAttrSet( (dvoid *)cs.usrhp, (ub4)OCI_HTYPE_SESSION, (dvoid *)user, (ub4)strlen(user), OCI_ATTR_USERNAME, cs.errhp)); // set 'pwd' password - check(services, cs, "OCIAttrSet pwd-session", OCIAttrSet( + check(services, cs, "AttrSet pwd-session", OCIAttrSet( (dvoid *)cs.usrhp, (ub4)OCI_HTYPE_SESSION, (dvoid *)pwd, (ub4)strlen(pwd), OCI_ATTR_PASSWORD, cs.errhp)); // Authenticate a user - check(services, cs, "OCISessionBegin", OCISessionBegin( + check(services, cs, "SessionBegin", OCISessionBegin( cs.svchp, cs.errhp, cs.usrhp, OCI_CRED_RDBMS, OCI_DEFAULT)); // remember connection in session - check(services, cs, "OCIAttrSet service-session", OCIAttrSet( + check(services, cs, "AttrSet service-session", OCIAttrSet( (dvoid *)cs.svchp, (ub4)OCI_HTYPE_SVCCTX, (dvoid *)cs.usrhp, (ub4)0, OCI_ATTR_SESSION, cs.errhp)); @@ -216,38 +222,52 @@ public: // return created connection *(OracleSQL_connection_struct **)connection=&cs; } - void disconnect(SQL_Driver_services& services, void *connection) { - OracleSQL_connection_struct &cs=*(OracleSQL_connection_struct *)connection; + void disconnect(void *connection) { + return; + + + OracleSQL_connection_struct &cs=*(OracleSQL_connection_struct *)connection; // Terminate a user session - check(services, cs, "OCISessionEnd", OCISessionEnd( - cs.svchp, cs.errhp, cs.usrhp, (ub4)OCI_DEFAULT)); + OCISessionEnd( + cs.svchp, cs.errhp, cs.usrhp, (ub4)OCI_DEFAULT); // Detach from a server; uninitialize server context handle - check(services, cs, "OCIServerDetach", OCIServerDetach( - cs.srvhp, cs.errhp, (ub4)OCI_DEFAULT)); - // Free a previously allocated handle - check(services, cs, "OCIHandleFree srvhp", OCIHandleFree( - (dvoid *)cs.srvhp, (ub4)OCI_HTYPE_SERVER)); - check(services, cs, "OCIHandleFree svchp", OCIHandleFree( - (dvoid *)cs.svchp, (ub4)OCI_HTYPE_SVCCTX)); - check(services, cs, "OCIHandleFree errhp", OCIHandleFree( - (dvoid *)cs.errhp, (ub4)OCI_HTYPE_ERROR)); cs.errhp=0; - check(services, cs, "OCIHandleFree envhp", OCIHandleFree( - (dvoid *)cs.envhp, (ub4)OCI_HTYPE_ENV)); + OCIServerDetach( + cs.srvhp, cs.errhp, (ub4)OCI_DEFAULT); + // Free a previously allocated handles + /* + oci will free them up as belonging to env + OCIHandleFree( + (dvoid *)cs.srvhp, (ub4)OCI_HTYPE_SERVER); + OCIHandleFree( + (dvoid *)cs.svchp, (ub4)OCI_HTYPE_SVCCTX); + OCIHandleFree( + (dvoid *)cs.errhp, (ub4)OCI_HTYPE_ERROR); + */ + OCIHandleFree( + (dvoid *)cs.envhp, (ub4)OCI_HTYPE_ENV); + + // connections are cross-request, do not use services._alloc [linked with request] + ::free(&cs); } void commit(SQL_Driver_services& services, void *connection) { OracleSQL_connection_struct &cs=*(OracleSQL_connection_struct *)connection; + if(setjmp(cs.mark)) + services._throw(cs.error); check(services, cs, "commit", OCITransCommit(cs.svchp, cs.errhp, 0)); } void rollback(SQL_Driver_services& services, void *connection) { OracleSQL_connection_struct &cs=*(OracleSQL_connection_struct *)connection; + if(setjmp(cs.mark)) + services._throw(cs.error); check(services, cs, "rollback", OCITransRollback(cs.svchp, cs.errhp, 0)); } bool ping(SQL_Driver_services&, void *connection) { - return false; + // maybe OCIServerVersion? + return true; } unsigned int quote( @@ -274,7 +294,7 @@ public: SQL_Driver_services& services, void *connection, const char *astatement, unsigned long offset, unsigned long limit, SQL_Driver_query_event_handlers& handlers) { -// _asm int 3; + OracleSQL_connection_struct &cs=*(OracleSQL_connection_struct *)connection; OracleSQL_query_lobs lobs={{0}, 0}; OCIStmt *stmthp=0; @@ -283,16 +303,15 @@ public: if(setjmp(cs.mark)) { failed=true; goto cleanup; - } - { + } else { const char *statement=preprocess_statement(services, cs, astatement, lobs); - check(services, cs, "OCIHandleAlloc STMT", OCIHandleAlloc( + check(services, cs, "HandleAlloc STMT", OCIHandleAlloc( (dvoid *)cs.envhp, (dvoid **) &stmthp, (ub4)OCI_HTYPE_STMT, 0, 0)); check(services, cs, "syntax", OCIStmtPrepare(stmthp, cs.errhp, (unsigned char *)statement, - (ub4) strlen((char *) statement), + (ub4)strlen((char *)statement), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT)); { for(int i=0; icount; r++) { - /* free var locator */ - (void)OCIDescriptorFree((dvoid *) rows->row[r].locator, (ub4)OCI_DTYPE_LOB); - } + /* free rows descriptors */ + OracleSQL_query_lobs::return_rows &rows=lobs.items[i].rows; + for(int r=0; r=offset) { - handlers.add_row(); - for(int i=0; i=offset) { + handlers.add_row(); + 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; + else + msg="[can not get error description]"; break; } case OCI_SUCCESS_WITH_INFO: - msg="OCI_SUCCESS_WITH_INFO"; break; + msg="SUCCESS_WITH_INFO"; break; case OCI_NEED_DATA: - msg="OCI_NEED_DATA"; break; + msg="NEED_DATA"; break; case OCI_NO_DATA: - msg="OCI_NODATA"; break; + msg="NODATA"; break; case OCI_INVALID_HANDLE: - msg="OCI_INVALID_HANDLE"; break; + msg="INVALID_HANDLE"; break; case OCI_STILL_EXECUTING: - msg="OCI_STILL_EXECUTE"; break; + msg="STILL_EXECUTE"; break; case OCI_CONTINUE: - msg="OCI_CONTINUE"; break; - */ - } - if(!msg) { - sb4 errcode=0; - if(OCIErrorGet((dvoid *)cs.errhp, (ub4) 1, (text *) NULL, &errcode, - (text *) reason, (ub4) sizeof(reason), OCI_HTYPE_ERROR)==OCI_SUCCESS) - msg=reason; - else - msg="unknown error"; + msg="CONTINUE"; break; + default: + msg="unknown"; break; } snprintf(cs.error, sizeof(cs.error), "%s (%s, %d)", @@ -711,7 +865,7 @@ static sb4 cbf_no_data( ub4 *alenpp, ub1 *piecep, dvoid **indpp) { - *bufpp=(dvoid *) 0; + *bufpp=(dvoid *)0; *alenpp=0; static sb2 null_ind=-1; *indpp=(dvoid *) &null_ind; @@ -735,9 +889,11 @@ static sb4 cbf_get_data(dvoid *ctxp, *(OracleSQL_query_lobs::cbf_context_struct *)ctxp; if(index==0) { - static ub4 rows=0; - (void)OCIAttrGet((CONST dvoid *) bindp, OCI_HTYPE_BIND, (dvoid *)&rows, - (ub4 *)sizeof(ub2), OCI_ATTR_ROWS_RETURNED, context.cs->errhp); + static ub4 rows; + check(*context.services, *context.cs, "AttrGet cbf_get_data ROWS_RETURNED", + OracleSQL_driver->OCIAttrGet( + (CONST dvoid *) bindp, OCI_HTYPE_BIND, (dvoid *)&rows, + (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(sizeof(OracleSQL_query_lobs::return_rows::return_row)*rows); @@ -745,10 +901,10 @@ static sb4 cbf_get_data(dvoid *ctxp, OracleSQL_query_lobs::return_rows::return_row &var=context.rows->row[index]; - check(*context.services, *context.cs, "alloc output var desc dynamic", OCIDescriptorAlloc( + check(*context.services, *context.cs, "alloc output var desc dynamic", OracleSQL_driver->OCIDescriptorAlloc( (dvoid *) context.cs->envhp, (dvoid **)&var.locator, (ub4)OCI_DTYPE_LOB, - 0, (dvoid **) 0)); + 0, (dvoid **)0)); *bufpp=var.locator; *alenp=&var.len; @@ -764,6 +920,7 @@ void tolower(char *out, const char *in, *out++=tolower(*in++); } -extern "C" SQL_Driver *create() { - return new OracleSQL_Driver(); +extern "C" SQL_Driver *SQL_DRIVER_CREATE() { + //_asm int 3; + return OracleSQL_driver=new OracleSQL_Driver(); }