📄 odbcconnection.c
字号:
// Copyright (c) 1999-2001 David Muse// See the file COPYING for more information#include <odbcconnection.h>#include <rudiments/charstring.h>#include <config.h>#include <datatypes.h>#include <stdlib.h>//orbb#include <iconv.h>#include <wchar.h>#define USER_CODING "UTF8"int ucslen(char* str);char *conv_to_user_coding(char *inbuf);/*void to_log(char *msg){ FILE *f; f=fopen("/var/log/SQLRelay/log","a"); if(f) { fprintf(f,"%s\n",msg); fclose(f); }}void to_wlog(char *msg){ FILE *f; f=fopen("/var/log/SQLRelay/log","a"); if(f) { char *str_u=conv_to_user_coding(msg); fprintf(f,"%s\n",str_u); free(str_u); //int l=ucslen(msg); //fwrite(msg,2,l,f); //fprintf(f,"\n"); fclose(f); }}*///orbb//orbbchar *buffers[200];int nextbuf=0;int ucslen(char* str){ char *ptr=str; int res=0; while(!(*ptr==0 && *(ptr+1)==0)) { res++; ptr+=2; } return res;}char *conv_to_user_coding(char *inbuf){ char *outbuf; size_t insize = 0; char *wrptr; iconv_t cd; size_t avail; insize=ucslen(inbuf)*2; avail=insize+4; outbuf=(char*)malloc(avail); wrptr = (char *) outbuf; cd = iconv_open (USER_CODING, "UCS-2"); if (cd == (iconv_t) -1) { /* Something went wrong. */ perror ("error in iconv_open"); /* Terminate the output string. */ *outbuf = '\0'; return outbuf; } size_t nconv; char *inptr = inbuf; #ifdef ICONV_CONST_CHAR nconv = iconv (cd, (const char **)&inptr, &insize, &wrptr, &avail);#else nconv = iconv (cd, &inptr, &insize, &wrptr, &avail);#endif if (nconv == (size_t) -1) { printf("conv_to_user_coding: error in iconv\n"); } /* Terminate the output string. */ *(wrptr) = '\0'; if (nconv == (size_t) -1) { printf("wrptr='%s'\n",wrptr); } if (iconv_close (cd) != 0) perror ("iconv_close"); return outbuf;}char *conv_to_ucs(char *inbuf){ char *outbuf; size_t insize = 0; char *wrptr; iconv_t cd; size_t avail; insize=charstring::length(inbuf); avail=insize*2+4; outbuf=(char*)malloc(avail); wrptr = (char *) outbuf; cd = iconv_open ("UCS-2", USER_CODING); if(cd == (iconv_t) -1) { /* Something went wrong. */ perror ("error in iconv_open"); /* Terminate the output string. */ *outbuf = L'\0'; return outbuf; } size_t nconv; char *inptr = inbuf; #ifdef ICONV_CONST_CHAR nconv = iconv (cd, (const char **)&inptr, &insize, &wrptr, &avail);#else nconv = iconv (cd, &inptr, &insize, &wrptr, &avail);#endif if (nconv == (size_t) -1) { printf("conv_to_ucs: error in iconv\n"); } /* Terminate the output string. */ *((wchar_t *) wrptr) = L'\0'; if (nconv == (size_t) -1) { printf("inbuf='%s'\n",inbuf); } if (iconv_close (cd) != 0) perror ("error in iconv_close"); // FILE *ff;// char fname[200];// sprintf(fname,"/home/orbb/temp/result_conv_to_ucs.txt_%d",charstring::length(inbuf));// ff=fopen(fname,"wb");// fwrite(outbuf,1,wrptr-outbuf,ff);// fclose(ff); return outbuf;}//orbbuint16_t odbcconnection::getNumberOfConnectStringVars() { return NUM_CONNECT_STRING_VARS;}void odbcconnection::handleConnectString() { dsn=connectStringValue("dsn"); setUser(connectStringValue("user")); setPassword(connectStringValue("password")); const char *autocom=connectStringValue("autocommit"); setAutoCommitBehavior((autocom && !charstring::compareIgnoringCase(autocom,"yes")));}bool odbcconnection::logIn(bool printerrors) { // allocate environment handle#if (ODBCVER >= 0x0300) erg=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&env); if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { SQLFreeHandle(SQL_HANDLE_ENV,env); return false; } erg=SQLSetEnvAttr(env,SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3,0);#else erg=SQLAllocEnv(&env);#endif if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) {#if (ODBCVER >= 0x0300) SQLFreeHandle(SQL_HANDLE_ENV,env);#else SQLFreeEnv(env);#endif return false; } // allocate connection handle#if (ODBCVER >= 0x0300) erg=SQLAllocHandle(SQL_HANDLE_DBC,env,&dbc);#else erg=SQLAllocConnect(env,&dbc);#endif if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) {#if (ODBCVER >= 0x0300) SQLFreeHandle(SQL_HANDLE_ENV,env); SQLFreeHandle(SQL_HANDLE_DBC,dbc);#else SQLFreeConnect(dbc); SQLFreeEnv(env);#endif return false; } // set the connect timeout#if (ODBCVER >= 0x0300) SQLSetConnectAttr(dbc,SQL_LOGIN_TIMEOUT,(SQLPOINTER *)5,0);#endif // connect to the database// erg=SQLConnect(dbc,(SQLCHAR *)dsn,SQL_NTS,// (SQLCHAR *)getUser(),SQL_NTS,// (SQLCHAR *)getPassword(),SQL_NTS); //orbb //orbb char *user_asc=(char*)getUser(); char *password_asc=(char*)getPassword(); char *dsn_asc=(char*)dsn; char *user_ucs=(char*)conv_to_ucs(user_asc); char *password_ucs=(char*)conv_to_ucs(password_asc); char *dsn_ucs=(char*)conv_to_ucs(dsn_asc); erg=SQLConnectW(dbc,(SQLWCHAR *)dsn_ucs,SQL_NTS, (SQLWCHAR *)user_ucs,SQL_NTS, (SQLWCHAR *)password_ucs,SQL_NTS); if(user_ucs)free(user_ucs); if(password_ucs)free(password_ucs); if(dsn_ucs)free(dsn_ucs);//orbb if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) {#if (ODBCVER >= 0x0300) SQLFreeHandle(SQL_HANDLE_ENV,env); SQLFreeHandle(SQL_HANDLE_DBC,dbc);#else SQLFreeConnect(dbc); SQLFreeEnv(env);#endif return false; } return true;}sqlrcursor_svr *odbcconnection::initCursor() { return (sqlrcursor_svr *)new odbccursor((sqlrconnection_svr *)this);}void odbcconnection::deleteCursor(sqlrcursor_svr *curs) { delete (odbccursor *)curs;}void odbcconnection::logOut() { SQLDisconnect(dbc);#if (ODBCVER >= 0x0300) SQLFreeHandle(SQL_HANDLE_DBC,dbc); SQLFreeHandle(SQL_HANDLE_ENV,env);#else SQLFreeConnect(dbc); SQLFreeEnv(env);#endif}bool odbcconnection::ping() { return true;}const char *odbcconnection::identify() { return "odbc";}const char *odbcconnection::dbVersion() { SQLSMALLINT dbversionlen; SQLGetInfo(dbc,SQL_DBMS_VER, (SQLPOINTER)dbversion, (SQLSMALLINT)sizeof(dbversion), &dbversionlen); return dbversion;}#if (ODBCVER >= 0x0300)bool odbcconnection::autoCommitOn() { return (SQLSetConnectAttr(dbc,SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, sizeof(SQLINTEGER))==SQL_SUCCESS);}bool odbcconnection::autoCommitOff() { return (SQLSetConnectAttr(dbc,SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, sizeof(SQLINTEGER))==SQL_SUCCESS);}bool odbcconnection::commit() { return (SQLEndTran(SQL_HANDLE_ENV,env,SQL_COMMIT)==SQL_SUCCESS);}bool odbcconnection::rollback() { return (SQLEndTran(SQL_HANDLE_ENV,env,SQL_ROLLBACK)==SQL_SUCCESS);}#endifodbccursor::odbccursor(sqlrconnection_svr *conn) : sqlrcursor_svr(conn) { errormsg=NULL; odbcconn=(odbcconnection *)conn; stmt=NULL;}odbccursor::~odbccursor() { if (errormsg) { delete errormsg; }}bool odbccursor::prepareQuery(const char *query, uint32_t length) { if (stmt) {#if (ODBCVER >= 0x0300) SQLFreeHandle(SQL_HANDLE_STMT,stmt);#else SQLFreeStmt(stmt,SQL_DROP);#endif } // allocate the cursor#if (ODBCVER >= 0x0300) erg=SQLAllocHandle(SQL_HANDLE_STMT,odbcconn->dbc,&stmt);#else erg=SQLAllocStmt(odbcconn->dbc,&stmt);#endif if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { return false; }// this code is here in case unixodbc or iodbc ever // successfully support array fetches/*#if (ODBCVER >= 0x0300) // set the row array size erg=SQLSetStmtAttr(stmt,SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)FETCH_AT_ONCE,0); if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { return false; }#endif*/ // prepare the query// erg=SQLPrepare(stmt,(SQLCHAR *)query,length); //orbb //free allocated buffers while(nextbuf>0) { nextbuf--; if(buffers[nextbuf])free(buffers[nextbuf]); } char *query_ucs=conv_to_ucs((char*)query); erg=SQLPrepareW(stmt,(SQLWCHAR *)query_ucs,SQL_NTS); if(query_ucs)free(query_ucs);//orbb if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { return false; } return true;}bool odbccursor::inputBindString(const char *variable, uint16_t variablesize, const char *value, uint16_t valuesize, short *isnull) { //orbb char *value_ucs=conv_to_ucs((char*)value); valuesize=ucslen(value_ucs)*2; buffers[nextbuf]=value_ucs; nextbuf++; //orbb if (*isnull==SQL_NULL_DATA) { erg=SQLBindParameter(stmt, charstring::toInteger(variable+1), SQL_PARAM_INPUT, SQL_C_WCHAR,//orbb SQL_CHAR, 0, 0, (SQLPOINTER)value_ucs, //orbb valuesize, #ifdef SQLBINDPARAMETER_SQLLEN (SQLLEN *)isnull #else (SQLINTEGER *)isnull #endif ); } else { erg=SQLBindParameter(stmt, charstring::toInteger(variable+1), SQL_PARAM_INPUT, SQL_C_WCHAR,//orbb SQL_CHAR, 0, 0, (SQLPOINTER)value_ucs, //orbb valuesize, #ifdef SQLBINDPARAMETER_SQLLEN (SQLLEN *)NULL #else (SQLINTEGER *)NULL #endif ); } if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { return false; } return true;}bool odbccursor::inputBindInteger(const char *variable, uint16_t variablesize, int64_t *value) { erg=SQLBindParameter(stmt, charstring::toInteger(variable+1), SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, value, sizeof(int64_t), #ifdef SQLBINDPARAMETER_SQLLEN (SQLLEN *)NULL #elif defined(SQLBINDPARAMETER_SQLLEN) (unsigned long *)NULL #else (SQLINTEGER *)NULL #endif ); if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { return false; } return true;}bool odbccursor::inputBindDouble(const char *variable, uint16_t variablesize, double *value, uint32_t precision, uint32_t scale) { erg=SQLBindParameter(stmt, charstring::toInteger(variable+1), SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DECIMAL, precision, scale, value, sizeof(double), #ifdef SQLBINDPARAMETER_SQLLEN (SQLLEN *)NULL #elif defined(SQLBINDPARAMETER_SQLLEN) (unsigned long *)NULL #else (SQLINTEGER *)NULL #endif ); if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { return false; } return true;}bool odbccursor::outputBindString(const char *variable, uint16_t variablesize, const char *value, uint16_t valuesize, short *isnull) { erg=SQLBindParameter(stmt, charstring::toInteger(variable+1), SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR, 0, 0, (SQLPOINTER)value, valuesize, #ifdef SQLBINDPARAMETER_SQLLEN (SQLLEN *)isnull #elif defined(SQLBINDPARAMETER_SQLLEN) (unsigned long *)isnull #else (SQLINTEGER *)isnull #endif ); if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { return false; } return true;}bool odbccursor::outputBindInteger(const char *variable, uint16_t variablesize, int64_t *value, int16_t *isnull) { erg=SQLBindParameter(stmt, charstring::toInteger(variable+1), SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, value, sizeof(int64_t), #ifdef SQLBINDPARAMETER_SQLLEN (SQLLEN *)isnull #elif defined(SQLBINDPARAMETER_SQLLEN) (unsigned long *)isnull #else (SQLINTEGER *)isnull #endif ); if (erg!=SQL_SUCCESS && erg!=SQL_SUCCESS_WITH_INFO) { return false; } return true;}bool odbccursor::outputBindDouble(const char *variable, uint16_t variablesize, double *value, uint32_t *precision,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -