📄 oracle8connection.c
字号:
// Copyright (c) 1999-2001 David Muse// See the file COPYING for more information#include <oracle8connection.h>#include <rudiments/charstring.h>#include <rudiments/rawbuffer.h>#include <rudiments/character.h>#include <rudiments/environment.h>#include <config.h>#include <datatypes.h>#include <stdio.h>#include <stdlib.h>#define MAX_BYTES_PER_CHAR 4oracle8connection::oracle8connection() : sqlrconnection_svr() { statementmode=OCI_DEFAULT;#ifdef OCI_ATTR_PROXY_CREDENTIALS newsession=NULL;#endif}oracle8connection::~oracle8connection() {}uint16_t oracle8connection::getNumberOfConnectStringVars() { return NUM_CONNECT_STRING_VARS;}void oracle8connection::handleConnectString() { setUser(connectStringValue("user")); setPassword(connectStringValue("password")); sid=connectStringValue("oracle_sid"); home=connectStringValue("oracle_home"); nlslang=connectStringValue("nls_lang"); const char *autocom=connectStringValue("autocommit"); setAutoCommitBehavior((autocom && !charstring::compareIgnoringCase(autocom,"yes"))); fetchatonce=charstring::toUnsignedInteger( connectStringValue("fetchatonce")); if (!fetchatonce) { fetchatonce=FETCH_AT_ONCE; } maxselectlistsize=charstring::toUnsignedInteger( connectStringValue("maxselectlistsize")); if (!maxselectlistsize) { maxselectlistsize=MAX_SELECT_LIST_SIZE; } maxitembuffersize=charstring::toUnsignedInteger( connectStringValue("maxitembuffersize")); if (!maxitembuffersize) { maxitembuffersize=MAX_ITEM_BUFFER_SIZE; } if (maxitembuffersize<MAX_BYTES_PER_CHAR) { maxitembuffersize=MAX_BYTES_PER_CHAR; }}bool oracle8connection::logIn(bool printerrors) { // get user/password const char *user=getUser(); const char *password=getPassword(); // handle ORACLE_HOME if (home) { if (!environment::setValue("ORACLE_HOME",home)) { if (printerrors) { fprintf(stderr,"Failed to set ORACLE_HOME environment variable.\n"); } return false; } } else { if (!environment::getValue("ORACLE_HOME")) { if (printerrors) { fprintf(stderr,"No ORACLE_HOME environment variable set or specified in connect string.\n"); } return false; } } // handle ORACLE_SID if (sid) { if (!environment::setValue("ORACLE_SID",sid)) { if (printerrors) { fprintf(stderr,"Failed to set ORACLE_SID environment variable.\n"); } return false; } } else { if (!environment::getValue("ORACLE_SID")) { if (printerrors) { fprintf(stderr,"No ORACLE_SID environment variable set or specified in connect string.\n"); } return false; } } // handle TWO_TASK if (sid) { if (!environment::setValue("TWO_TASK",sid)) { if (printerrors) { fprintf(stderr,"Failed to set TWO_TASK environment variable.\n"); } return false; } } else { // allow empty TWO_TASK when using OS-authentication // allow it in all cases? if (!environment::getValue("TWO_TASK") && charstring::length(user) && charstring::length(password)) { if (printerrors) { fprintf(stderr,"No TWO_TASK environment variable set or specified in connect string.\n"); } return false; } } // handle NLS_LANG if (nlslang) { if (!environment::setValue("NLS_LANG",nlslang)) { if (printerrors) { fprintf(stderr,"Failed to set NLS_LANG environment variable.\n"); } return false; } } // init OCI#ifdef HAVE_ORACLE_8i if (OCIEnvCreate((OCIEnv **)&env,OCI_DEFAULT|OCI_OBJECT,(dvoid *)0, (dvoid *(*)(dvoid *, size_t))0, (dvoid *(*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0, (size_t)0,(dvoid **)0)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIEnvCreate() failed."); } return false; }#else if (OCIInitialize(OCI_DEFAULT,NULL,NULL,NULL,NULL)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIInitialize() failed.\n"); } return false; } if (OCIEnvInit((OCIEnv **)&env,OCI_DEFAULT, 0,(dvoid **)0)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIEnvInit() failed.\n"); } return false; }#endif // allocate an error handle if (OCIHandleAlloc((dvoid *)env,(dvoid **)&err, OCI_HTYPE_ERROR,0,NULL)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIHandleAlloc(OCI_HTYPE_ERROR) failed.\n"); } OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // allocate a server handle if (OCIHandleAlloc((dvoid *)env,(dvoid **)&srv, OCI_HTYPE_SERVER,0,NULL)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIHandleAlloc(OCI_HTYPE_SERVER) failed.\n"); } OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // allocate a service context handle if (OCIHandleAlloc((dvoid *)env,(dvoid **)&svc, OCI_HTYPE_SVCCTX,0,NULL)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIHandleAlloc(OCI_HTYPE_SVCCTX) failed.\n"); } OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // attach to the server if (OCIServerAttach(srv,err,(text *)sid, charstring::length(sid),0)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIServerAttach() failed.\n"); } OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // attach the server to the service if (OCIAttrSet((dvoid *)svc,OCI_HTYPE_SVCCTX, (dvoid *)srv,(ub4)0, OCI_ATTR_SERVER,(OCIError *)err)!=OCI_SUCCESS) { if (printerrors) { logInError("Attach server to service failed.\n"); } OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // allocate a session handle if (OCIHandleAlloc((dvoid *)env,(dvoid **)&session, (ub4)OCI_HTYPE_SESSION,0,NULL)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIHandleAlloc(OCI_HTYPE_SESSION) failed.\n"); } OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // set username and password if (charstring::length(user) && OCIAttrSet((dvoid *)session,(ub4)OCI_HTYPE_SESSION, (dvoid *)user, (ub4)charstring::length(user), (ub4)OCI_ATTR_USERNAME,err)!=OCI_SUCCESS) { if (printerrors) { logInError("Set username failed.\n"); } OCIHandleFree(err,OCI_HTYPE_SESSION); OCIServerDetach(srv,err,OCI_DEFAULT); OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } if (charstring::length(password) && OCIAttrSet((dvoid *)session,(ub4)OCI_HTYPE_SESSION, (dvoid *)password, (ub4)charstring::length(password), (ub4)OCI_ATTR_PASSWORD,err)!=OCI_SUCCESS) { if (printerrors) { logInError("Set password failed.\n"); } OCIHandleFree(err,OCI_HTYPE_SESSION); OCIServerDetach(srv,err,OCI_DEFAULT); OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // start a session sword cred=OCI_CRED_RDBMS; if (!charstring::length(user) && !charstring::length(password)) { cred=OCI_CRED_EXT; } if (OCISessionBegin(svc,err,session, cred,(ub4)OCI_DEFAULT)!=OCI_SUCCESS) { if (printerrors) { logInError("OCISessionBegin() failed.\n"); } OCIHandleFree(err,OCI_HTYPE_SESSION); OCIServerDetach(srv,err,OCI_DEFAULT); OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // attach the session to the service if (OCIAttrSet((dvoid *)svc,(ub4)OCI_HTYPE_SVCCTX, (dvoid *)session,(ub4)0, (ub4)OCI_ATTR_SESSION,err)!=OCI_SUCCESS) { if (printerrors) { logInError("Attach session to service failed.\n"); } OCISessionEnd(svc,err,session,OCI_DEFAULT); OCIHandleFree(err,OCI_HTYPE_SESSION); OCIServerDetach(srv,err,OCI_DEFAULT); OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // allocate a transaction handle if (OCIHandleAlloc((dvoid *)env,(dvoid **)&trans, OCI_HTYPE_TRANS,0,0)!=OCI_SUCCESS) { if (printerrors) { logInError("OCIHandleAlloc(OCI_HTYPE_TRANS) failed.\n"); } OCISessionEnd(svc,err,session,OCI_DEFAULT); OCIHandleFree(err,OCI_HTYPE_SESSION); OCIServerDetach(srv,err,OCI_DEFAULT); OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; } // attach the transaction to the service if (OCIAttrSet((dvoid *)svc,OCI_HTYPE_SVCCTX, (dvoid *)trans,(ub4)0, (ub4)OCI_ATTR_TRANS,err)!=OCI_SUCCESS) { OCIHandleFree(err,OCI_HTYPE_TRANS); OCISessionEnd(svc,err,session,OCI_DEFAULT); OCIHandleFree(err,OCI_HTYPE_SESSION); OCIServerDetach(srv,err,OCI_DEFAULT); OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV); return false; }#ifdef OCI_ATTR_PROXY_CREDENTIALS // figure out what version database we're connected to... supportsproxycredentials=false; if (OCIServerVersion((dvoid *)svc,err, (text *)versionbuf,sizeof(versionbuf), OCI_HTYPE_SVCCTX)==OCI_SUCCESS && (!charstring::compare(versionbuf,"Oracle8i ",9) || !charstring::compare(versionbuf,"Oracle9i ",9) || !charstring::compare(versionbuf,"Oracle10g ",10))) { supportsproxycredentials=true; }#endif return true;}void oracle8connection::logInError(const char *errmsg) { fprintf(stderr,"%s\n\n",errmsg); // get the error message from oracle text message[1024]; rawbuffer::zero((void *)message,sizeof(message)); sb4 errcode; OCIErrorGet((dvoid *)err,1,(text *)0,&errcode, message,sizeof(message),OCI_HTYPE_ERROR); message[1023]=(char)NULL; fprintf(stderr,"error: %s\n",message);}sqlrcursor_svr *oracle8connection::initCursor() { return (sqlrcursor_svr *)new oracle8cursor((sqlrconnection_svr *)this);}void oracle8connection::deleteCursor(sqlrcursor_svr *curs) { delete (oracle8cursor *)curs;}void oracle8connection::logOut() {#ifdef OCI_ATTR_PROXY_CREDENTIALS if (newsession) { OCISessionEnd(svc,err,newsession,OCI_DEFAULT); OCIHandleFree(newsession,OCI_HTYPE_SESSION); }#endif OCIHandleFree(trans,OCI_HTYPE_TRANS); OCISessionEnd(svc,err,session,OCI_DEFAULT); OCIHandleFree(session,OCI_HTYPE_SESSION); OCIServerDetach(srv,err,OCI_DEFAULT); // free the service, server and error handles OCIHandleFree(svc,OCI_HTYPE_SVCCTX); OCIHandleFree(srv,OCI_HTYPE_SERVER); OCIHandleFree(err,OCI_HTYPE_ERROR); OCIHandleFree(env,OCI_HTYPE_ENV);}#ifdef OCI_ATTR_PROXY_CREDENTIALSbool oracle8connection::changeUser(const char *newuser, const char *newpassword) { // if the database we're connected to doesn't // support proxy credentials, use the sqlrconnection // class's default changeUser() method if (!supportsproxycredentials) { return sqlrconnection_svr::changeUser(newuser,newpassword); } // delete any previously existing "newsessions" if (newsession) { OCISessionEnd(svc,err,newsession,OCI_DEFAULT); OCIHandleFree(newsession,OCI_HTYPE_SESSION); newsession=NULL; } // create a session handle for the new user if (OCIHandleAlloc((dvoid *)env,(dvoid **)&newsession, (ub4)OCI_HTYPE_SESSION, (size_t)0,(dvoid **)0)!=OCI_SUCCESS) { return false; } // set the user name OCIAttrSet((dvoid *)newsession,(ub4)OCI_HTYPE_SESSION, (dvoid *)newuser, (ub4)charstring::length(newuser), (ub4)OCI_ATTR_USERNAME,err); // don't set the password, use the proxy OCIAttrSet((dvoid *)newsession,(ub4)OCI_HTYPE_SESSION, (dvoid *)session,(ub4)0, (ub4)OCI_ATTR_PROXY_CREDENTIALS,err); // start the session if (OCISessionBegin(svc,err,newsession, OCI_CRED_PROXY,(ub4)OCI_DEFAULT)!=OCI_SUCCESS) { return false; } // switch to the new session if (OCIAttrSet((dvoid *)svc,(ub4)OCI_HTYPE_SVCCTX, (dvoid *)newsession,(ub4)0, (ub4)OCI_ATTR_SESSION,err)!=OCI_SUCCESS) { return false; } return true;}#endifbool oracle8connection::autoCommitOn() { statementmode=OCI_COMMIT_ON_SUCCESS; return true;}bool oracle8connection::autoCommitOff() { statementmode=OCI_DEFAULT; return true;}bool oracle8connection::commit() { return (OCITransCommit(svc,err,OCI_DEFAULT)==OCI_SUCCESS);}bool oracle8connection::rollback() { return (OCITransRollback(svc,err,OCI_DEFAULT)==OCI_SUCCESS);}const char *oracle8connection::pingQuery() { return "select 1 from dual";}const char *oracle8connection::identify() { return "oracle8";}const char *oracle8connection::dbVersion() { if (OCIServerVersion((dvoid *)svc,err, (text *)versionbuf,sizeof(versionbuf), OCI_HTYPE_SVCCTX)==OCI_SUCCESS) { return versionbuf; } return NULL;}oracle8cursor::oracle8cursor(sqlrconnection_svr *conn) : sqlrcursor_svr(conn) { stmt=NULL; stmttype=0; ncols=0; prepared=false; errormessage=NULL; oracle8conn=(oracle8connection *)conn;#ifdef HAVE_ORACLE_8i inbindlobcount=0; outbindlobcount=0;#endif inbindcount=0; outbindcount=0; curbindcount=0; for (uint16_t i=0; i<MAXVAR; i++) { inbindpp[i]=NULL; outbindpp[i]=NULL; curbindpp[i]=NULL; inintbindstring[i]=NULL; outintbindstring[i]=NULL; outintbind[i]=NULL; } desc=new describe[oracle8conn->maxselectlistsize]; columnnames=new char *[oracle8conn->maxselectlistsize]; def=new OCIDefine *[oracle8conn->maxselectlistsize]; def_lob=new OCILobLocator **[oracle8conn->maxselectlistsize]; def_buf=new ub1 *[oracle8conn->maxselectlistsize]; def_indp=new sb2 *[oracle8conn->maxselectlistsize]; def_col_retlen=new ub2 *[oracle8conn->maxselectlistsize]; def_col_retcode=new ub2 *[oracle8conn->maxselectlistsize]; for (uint16_t i=0; i<oracle8conn->maxselectlistsize; i++) { def_lob[i]=new OCILobLocator *[oracle8conn->fetchatonce]; for (uint32_t j=0; j<oracle8conn->fetchatonce; j++) { def_lob[i][j]=NULL; } def_buf[i]=new ub1[oracle8conn->fetchatonce* oracle8conn->maxitembuffersize]; def_indp[i]=new sb2[oracle8conn->fetchatonce]; def_col_retlen[i]=new ub2[oracle8conn->fetchatonce]; def_col_retcode[i]=new ub2[oracle8conn->fetchatonce]; def[i]=NULL; }#ifdef HAVE_ORACLE_8i createtemp.compile("(create|CREATE)[ \\t\\n\\r]+(global|GLOBAL)[ \\t\\n\\r]+(temporary|TEMPORARY)[ \\t\\n\\r]+(table|TABLE)[ \\t\\n\\r]+"); preserverows.compile("(on|ON)[ \\t\\n\\r]+(commit|COMMIT)[ \\t\\n\\r]+(preserve|PRESERVE)[ \\t\\n\\r]+(rows|ROWS)");#endif}oracle8cursor::~oracle8cursor() { delete errormessage; for (uint16_t i=0; i<oracle8conn->maxselectlistsize; i++) { delete[] def_col_retcode[i]; delete[] def_col_retlen[i]; delete[] def_indp[i]; delete[] def_lob[i]; delete[] def_buf[i]; } for (uint16_t i=0; i<inbindcount; i++) { delete[] inintbindstring[i]; } for (uint16_t i=0; i<outbindcount; i++) { delete[] outintbindstring[i]; } delete[] def_col_retcode; delete[] def_col_retlen; delete[] def_indp; delete[] def_lob; delete[] def_buf; delete[] def; delete[] desc; delete[] columnnames;}bool oracle8cursor::openCursor(uint16_t id) { // allocate a cursor handle stmt=NULL; if (OCIHandleAlloc((dvoid *)oracle8conn->env,(dvoid **)&stmt, OCI_HTYPE_STMT,(size_t)0, (dvoid **)0)!=OCI_SUCCESS) { return false; } // set the number of rows to prefetch if (OCIAttrSet((dvoid *)stmt,OCI_HTYPE_STMT, (dvoid *)&(oracle8conn->fetchatonce),(ub4)0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -