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

📄 freetdsconnection.c

📁 适合于Unix/Linux下的一个持久数据库连接池
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (cursorquery.match(query)) {		// initiate a cursor command		cmd=cursorcmd;#ifdef FREETDS_SUPPORTS_CURSORS		if (ct_cursor(cursorcmd,CS_CURSOR_DECLARE,				(CS_CHAR *)cursorname,CS_NULLTERM,				(CS_CHAR *)query,length,				//CS_READ_ONLY)!=CS_SUCCEED) {				CS_UNUSED)!=CS_SUCCEED) {			return false;		}#endif	} else if (rpcquery.match(query)) {		// initiate an rpc command		isrpcquery=true;		cmd=languagecmd;#ifdef FREETDS_SUPPORTS_CURSORS		if (ct_command(languagecmd,CS_RPC_CMD,			(CS_CHAR *)rpcquery.getSubstringEnd(0),			length-rpcquery.getSubstringEndOffset(0),			CS_UNUSED)!=CS_SUCCEED) {			return false;		}#endif	} else {		// initiate a language command		cmd=languagecmd;#ifdef FREETDS_SUPPORTS_CURSORS		if (ct_command(languagecmd,CS_LANG_CMD,				(CS_CHAR *)query,length,				CS_UNUSED)!=CS_SUCCEED) {			return false;		}#endif	}	clean=false;	prepared=true;	return true;}bool freetdscursor::supportsNativeBinds() {#ifdef FREETDS_SUPPORTS_CURSORS	return true;#else	return false;#endif}void freetdscursor::checkRePrepare() {	// Sybase doesn't allow you to rebind and re-execute when using 	// ct_command.  You have to re-prepare too.  I'll make this transparent	// to the user.	if (!prepared) {		prepareQuery(query,length);	}}#ifdef FREETDS_SUPPORTS_CURSORSbool freetdscursor::inputBindString(const char *variable,						uint16_t variablesize,						const char *value,						uint16_t valuesize,						int16_t *isnull) {	checkRePrepare();	(CS_VOID)rawbuffer::zero(&parameter[paramindex],				sizeof(parameter[paramindex]));	if (charstring::isInteger(variable+1,variablesize-1)) {		parameter[paramindex].name[0]=(char)NULL;		parameter[paramindex].namelen=0;	} else {		charstring::copy(parameter[paramindex].name,variable);		parameter[paramindex].namelen=variablesize;	}	parameter[paramindex].datatype=CS_CHAR_TYPE;	parameter[paramindex].maxlength=CS_UNUSED;	parameter[paramindex].status=CS_INPUTVALUE;	parameter[paramindex].locale=NULL;	if (ct_param(cmd,&parameter[paramindex],		(CS_VOID *)value,valuesize,0)!=CS_SUCCEED) {		return false;	}	paramindex++;	return true;}bool freetdscursor::inputBindInteger(const char *variable,						uint16_t variablesize,						int64_t *value) {	checkRePrepare();	(CS_VOID)rawbuffer::zero(&parameter[paramindex],				sizeof(parameter[paramindex]));	if (charstring::isInteger(variable+1,variablesize-1)) {		parameter[paramindex].name[0]=(char)NULL;		parameter[paramindex].namelen=0;	} else {		charstring::copy(parameter[paramindex].name,variable);		parameter[paramindex].namelen=variablesize;	}	parameter[paramindex].datatype=CS_INT_TYPE;	parameter[paramindex].maxlength=CS_UNUSED;	parameter[paramindex].status=CS_INPUTVALUE;	parameter[paramindex].locale=NULL;	if (ct_param(cmd,&parameter[paramindex],		(CS_VOID *)value,sizeof(int64_t),0)!=CS_SUCCEED) {		return false;	}	paramindex++;	return true;}bool freetdscursor::inputBindDouble(const char *variable,						uint16_t variablesize,						double *value,						uint32_t precision,						uint32_t scale) {	checkRePrepare();	(CS_VOID)rawbuffer::zero(&parameter[paramindex],				sizeof(parameter[paramindex]));	if (charstring::isInteger(variable+1,variablesize-1)) {		parameter[paramindex].name[0]=(char)NULL;		parameter[paramindex].namelen=0;	} else {		charstring::copy(parameter[paramindex].name,variable);		parameter[paramindex].namelen=variablesize;	}	parameter[paramindex].datatype=CS_FLOAT_TYPE;	parameter[paramindex].maxlength=CS_UNUSED;	parameter[paramindex].status=CS_INPUTVALUE;	parameter[paramindex].precision=precision;	parameter[paramindex].scale=scale;	parameter[paramindex].locale=NULL;	if (ct_param(cmd,&parameter[paramindex],		(CS_VOID *)value,sizeof(double),0)!=CS_SUCCEED) {		return false;	}	paramindex++;	return true;}bool freetdscursor::outputBindString(const char *variable, 					uint16_t variablesize,					char *value, 					uint16_t valuesize, 					int16_t *isnull) {	checkRePrepare();	outbindtype[outbindindex]=CS_CHAR_TYPE;	outbindstrings[outbindindex]=value;	outbindstringlengths[outbindindex]=valuesize;	outbindindex++;	(CS_VOID)rawbuffer::zero(&parameter[paramindex],				sizeof(parameter[paramindex]));	if (charstring::isInteger(variable+1,variablesize-1)) {		parameter[paramindex].name[0]=(char)NULL;		parameter[paramindex].namelen=0;	} else {		charstring::copy(parameter[paramindex].name,variable);		parameter[paramindex].namelen=variablesize;	}	parameter[paramindex].datatype=CS_CHAR_TYPE;	parameter[paramindex].maxlength=valuesize;	parameter[paramindex].status=CS_RETURN;	parameter[paramindex].locale=NULL;	if (ct_param(cmd,&parameter[paramindex],			(CS_VOID *)NULL,0,			(CS_SMALLINT)*isnull)!=CS_SUCCEED) {		return false;	}	paramindex++;	return true;}bool freetdscursor::outputBindInteger(const char *variable,						uint16_t variablesize,						int64_t *value,						int16_t *isnull) {	checkRePrepare();	outbindtype[outbindindex]=CS_INT_TYPE;	outbindints[outbindindex]=value;	outbindindex++;	(CS_VOID)rawbuffer::zero(&parameter[paramindex],				sizeof(parameter[paramindex]));	if (charstring::isInteger(variable+1,variablesize-1)) {		parameter[paramindex].name[0]=(char)NULL;		parameter[paramindex].namelen=0;	} else {		charstring::copy(parameter[paramindex].name,variable);		parameter[paramindex].namelen=variablesize;	}	parameter[paramindex].datatype=CS_INT_TYPE;	parameter[paramindex].maxlength=CS_UNUSED;	parameter[paramindex].status=CS_RETURN;	parameter[paramindex].locale=NULL;	if (ct_param(cmd,&parameter[paramindex],			(CS_VOID *)NULL,0,			(CS_SMALLINT)*isnull)!=CS_SUCCEED) {		return false;	}	paramindex++;	return true;}bool freetdscursor::outputBindDouble(const char *variable,						uint16_t variablesize,						double *value,						uint32_t *precision,						uint32_t *scale,						int16_t *isnull) {	checkRePrepare();	outbindtype[outbindindex]=CS_FLOAT_TYPE;	outbinddoubles[outbindindex]=value;	outbindindex++;	(CS_VOID)rawbuffer::zero(&parameter[paramindex],				sizeof(parameter[paramindex]));	if (charstring::isInteger(variable+1,variablesize-1)) {		parameter[paramindex].name[0]=(char)NULL;		parameter[paramindex].namelen=0;	} else {		charstring::copy(parameter[paramindex].name,variable);		parameter[paramindex].namelen=variablesize;	}	parameter[paramindex].datatype=CS_FLOAT_TYPE;	parameter[paramindex].maxlength=CS_UNUSED;	parameter[paramindex].status=CS_RETURN;	parameter[paramindex].locale=NULL;	if (ct_param(cmd,&parameter[paramindex],			(CS_VOID *)NULL,0,			(CS_SMALLINT)*isnull)!=CS_SUCCEED) {		return false;	}	paramindex++;	return true;}#endifbool freetdscursor::executeQuery(const char *query, uint32_t length,							bool execute) {	// clear out any errors	if (freetdsconn->errorstring) {		freetdsconn->deadconnection=false;		delete freetdsconn->errorstring;		freetdsconn->errorstring=NULL;	}	if (ct_command(cmd,CS_LANG_CMD,			(CS_CHAR *)query,length,			CS_UNUSED)!=CS_SUCCEED) {		return false;	}	clean=false;	// initialize return values	ncols=0;	knowsaffectedrows=false;	affectedrows=0;	row=0;	maxrow=0;	totalrows=0;#ifdef FREETDS_SUPPORTS_CURSORS	if (cmd==cursorcmd) {		if (ct_cursor(cursorcmd,CS_CURSOR_ROWS,					NULL,CS_UNUSED,					NULL,CS_UNUSED,					(CS_INT)FETCH_AT_ONCE)!=CS_SUCCEED) {			return false;		}		if (ct_cursor(cursorcmd,CS_CURSOR_OPEN,					NULL,CS_UNUSED,					NULL,CS_UNUSED,					CS_UNUSED)!=CS_SUCCEED) {			return false;		}	}#endif	if (ct_send(cmd)!=CS_SUCCEED) {		cleanUpData(true,true);		return false;	}	for (;;) {		results=ct_results(cmd,&resultstype);		if (results==CS_FAIL ||			resultstype==CS_CMD_FAIL || resultstype==CS_CMD_DONE) {			cleanUpData(true,true);			return false;		}		if (cmd==languagecmd) {			if (isrpcquery) {				// For rpc commands, there could be several				// result sets - CS_STATUS_RESULT,				// maybe a CS_PARAM_RESULT and maybe a				// CS_ROW_RESULT, we're not guaranteed				// what order they'll come in though, what				// a pickle...				// For now, we care about the CS_PARAM_RESULT,				// or the CS_ROW_RESULT, whichever we get first,				// presumably there will only be 1 row in the				// CS_PARAM_RESULT...				if (resultstype==CS_PARAM_RESULT ||						resultstype==CS_ROW_RESULT) {					break;				}			} else {				// For non-rpc language commands (non-selects),				// there should be only one result set.				break;			}		} else if (resultstype==CS_ROW_RESULT ||#ifdef FREETDS_SUPPORTS_CURSORS					resultstype==CS_CURSOR_RESULT ||#endif					resultstype==CS_COMPUTE_RESULT) {			// For cursor commands (selects), each call to			// ct_cursor will have generated a result set.  There			// will be result sets for the CS_CURSOR_DECLARE,			// CS_CURSOR_ROWS and CS_CURSOR_OPEN calls.  We need to			// skip past the first 2, unless they failed.  If they			// failed, it will be caught above.			break;		}		// if we got here, then we don't want to process this result		// set, cancel it and move on to the next one...		if (ct_cancel(NULL,cmd,CS_CANCEL_CURRENT)==CS_FAIL) {			freetdsconn->deadconnection=true;			// FIXME: call ct_close(CS_FORCE_CLOSE)			return false;		}	}	checkForTempTable(query,length);	// reset the prepared flag	prepared=false;	// For queries which return rows or parameters (output bind variables),	// get the column count and bind columns.  For DML queries, get the	// affected row count.	// Affected row count is only supported in versio>=0.53 but appears	// to be broken in 0.61 as well	if (majorversion==0 && (minorversion<53 || minorversion==61)) {		knowsaffectedrows=false;	} else {		knowsaffectedrows=true;	}	// For queries which return rows or parameters (output bind variables),	// get the column count and bind columns.  For DML queries, get the	// affected row count.	bool	moneycolumn=false;	affectedrows=0;	if (resultstype==CS_ROW_RESULT ||#ifdef FREETDS_SUPPORTS_CURSORS			resultstype==CS_CURSOR_RESULT ||#endif			resultstype==CS_COMPUTE_RESULT ||			resultstype==CS_PARAM_RESULT) {		if (ct_res_info(cmd,CS_NUMDATA,(CS_VOID *)&ncols,				CS_UNUSED,(CS_INT *)NULL)!=CS_SUCCEED) {			return false;		}		if (ncols>MAX_SELECT_LIST_SIZE) {			ncols=MAX_SELECT_LIST_SIZE;		}		// bind columns		for (CS_INT i=0; i<ncols; i++) {			// dealing with money columns cause freetds < 0.53 to			// crash, take care of that here...			if (majorversion==0 && minorversion<53							&& !moneycolumn) {				CS_DATAFMT	moneytest;				ct_describe(cmd,i+1,&moneytest);				if (moneytest.datatype==CS_MONEY_TYPE ||					moneytest.datatype==CS_MONEY4_TYPE) {					moneycolumn=true;					if (freetdsconn->errorstring) {						delete freetdsconn->errorstring;					}					freetdsconn->errorstring=						new stringbuffer();					freetdsconn->errorstring->append(						"FreeTDS versions prior to ");					freetdsconn->errorstring->append( 						"0.53 do not support MONEY ");					freetdsconn->errorstring->append( 						"or SMALLMONEY datatypes. ");					freetdsconn->errorstring->append( 						"Please upgrade SQL Relay to ");					freetdsconn->errorstring->append( 						"a version compiled against ");					freetdsconn->errorstring->append( 						"FreeTDS >= 0.53 ");				}			}				// get the field as a null terminated character string			// no longer than MAX_ITEM_BUFFER_SIZE, override some			// other values that might have been set also			column[i].datatype=CS_CHAR_TYPE;			column[i].format=CS_FMT_NULLTERM;			column[i].maxlength=MAX_ITEM_BUFFER_SIZE;			column[i].scale=CS_UNUSED;			column[i].precision=CS_UNUSED;			column[i].status=CS_UNUSED;			column[i].count=FETCH_AT_ONCE;			column[i].usertype=CS_UNUSED;			column[i].locale=NULL;				// bind the columns for the fetches			if (ct_bind(cmd,i+1,&column[i],(CS_VOID *)data[i],				datalength[i],nullindicator[i])!=CS_SUCCEED) {				break;			}		}	} else if (resultstype==CS_CMD_SUCCEED && knowsaffectedrows) {		if (ct_res_info(cmd,CS_ROW_COUNT,(CS_VOID *)&affectedrows,					CS_UNUSED,(CS_INT *)NULL)!=CS_SUCCEED) {			return false;		} 	}	// If we got a moneycolumn (and version<0.53) then cancel the	// result set.  Otherwise FreeTDS will spew "unknown marker"	// errors to the screen when cleanUpData() is called.	if (moneycolumn) {		if (ct_cancel(NULL,cmd,CS_CANCEL_CURRENT)==CS_FAIL) {			freetdsconn->deadconnection=true;			// FIXME: call ct_close(CS_FORCE_CLOSE)			return false;		}		return false;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -