⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 odbcconnection.c

📁 适合于Unix/Linux下的一个持久数据库连接池
💻 C
📖 第 1 页 / 共 2 页
字号:
// 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 + -