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

📄 handlequery.c

📁 适合于Unix/Linux下的一个持久数据库连接池
💻 C
字号:
// Copyright (c) 1999-2001  David Muse// See the file COPYING for more information#include <sqlrconnection.h>int32_t sqlrconnection_svr::handleQuery(sqlrcursor_svr *cursor,					bool reexecute, bool bindcursor,					bool reallyexecute) {	#ifdef SERVER_DEBUG	debugPrint("connection",1,"handling query...");	#endif	if (!getQueryFromClient(cursor,reexecute,bindcursor)) {		#ifdef SERVER_DEBUG		debugPrint("connection",1,"failed to handle query");		#endif		return 0;	}	// loop here to handle down databases	for (;;) {		// process the query		if (processQuery(cursor,reexecute,bindcursor,reallyexecute)) {			// indicate that no error has occurred			clientsock->write((uint16_t)NO_ERROR);			// send the client the id of the 			// cursor that it's going to use			clientsock->write(cursor->id);			// tell the client that this is not a			// suspended result set			clientsock->write((uint16_t)NO_SUSPENDED_RESULT_SET);			// if the query processed 			// ok then send a result set			// header and return...			returnResultSetHeader(cursor);			// free memory used by binds			bindpool->free();			#ifdef SERVER_DEBUG			debugPrint("connection",1,"handle query succeeded");			#endif			return 1;		} else {			// If the query didn't process ok,			// handle the error.			// If handleError returns false then the error			// was a down database that has presumably			// come back up by now.  Loop back...			if (handleError(cursor)) {				return -1;			}		}	}}bool sqlrconnection_svr::getQueryFromClient(sqlrcursor_svr *cursor,					bool reexecute, bool bindcursor) {	// if we're not reexecuting and not using a bound cursor, get the query,	// if we're not using a bound cursor, get the input/output binds,	// get whether to send column info or not	return (((reexecute || bindcursor)?true:getQuery(cursor)) &&		((bindcursor)?true:		(getInputBinds(cursor) && getOutputBinds(cursor))) &&		getSendColumnInfo());}bool sqlrconnection_svr::getQuery(sqlrcursor_svr *cursor) {	#ifdef SERVER_DEBUG	debugPrint("connection",2,"getting query...");	#endif	// get the length of the query	if (clientsock->read(&cursor->querylength,				idleclienttimeout,0)!=sizeof(uint32_t)) {		#ifdef SERVER_DEBUG		debugPrint("connection",2,			"getting query failed: client sent bad query length size");		#endif		return false;	}	// bounds checking	if (cursor->querylength>maxquerysize) {		#ifdef SERVER_DEBUG		debugPrint("connection",2,			"getting query failed: client sent bad query size");		#endif		return false;	}	// read the query into the buffer	if ((uint32_t)(clientsock->read(cursor->querybuffer,						cursor->querylength,						idleclienttimeout,0))!=							cursor->querylength) {		#ifdef SERVER_DEBUG		debugPrint("connection",2,			"getting query failed: client sent short query");		#endif		return false;	}	cursor->querybuffer[cursor->querylength]=(char)NULL;	#ifdef SERVER_DEBUG	debugPrint("connection",3,"querylength:");	debugPrint("connection",4,(int32_t)cursor->querylength);	debugPrint("connection",3,"query:");	debugPrint("connection",0,cursor->querybuffer);	debugPrint("connection",2,"getting query succeeded");	#endif	return true;}bool sqlrconnection_svr::processQuery(sqlrcursor_svr *cursor,					bool reexecute, bool bindcursor,					bool reallyexecute) {	// Very important...	// Clean up data here instead of when aborting a result set, this	// allows for result sets that were suspended after the entire	// result set was fetched to still be able to return column data	// when resumed.	if (bindcursor) {		cursor->cleanUpData(false,true);	} else {		cursor->cleanUpData(true,true);	}	#ifdef SERVER_DEBUG	debugPrint("connection",2,"processing query...");	#endif	// if the reexecute flag is set, the query doesn't need to be prepared 	// again.	bool	success=false;	bool	doegress=true;	if (reexecute) {		#ifdef SERVER_DEBUG		debugPrint("connection",3,"re-executing...");		#endif		if (cursor->supportsNativeBinds()) {			if (cursor->sql_injection_detection_ingress(							cursor->querybuffer)) {				doegress=false;				success=true;			} else {				success=(cursor->handleBinds() && 					executeQueryUpdateStats(cursor,							cursor->querybuffer,							cursor->querylength,							reallyexecute));			}		} else {			stringbuffer	*newquery=cursor->fakeInputBinds(							cursor->querybuffer);			const char	*queryptr=(newquery)?						newquery->getString():						cursor->querybuffer;			uint32_t	querylen=(newquery)?						newquery->getStringLength():						cursor->querylength;			if (cursor->sql_injection_detection_ingress(queryptr)) {				doegress=false;				success=true;			} else {				success=executeQueryUpdateStats(cursor,							queryptr,							querylen,							reallyexecute);			}			delete newquery;		}	} else if (bindcursor) {		#ifdef SERVER_DEBUG		debugPrint("connection",3,"bind cursor...");		#endif		if (cursor->sql_injection_detection_ingress(						cursor->querybuffer)) {			doegress=false;			success=true;		} else {			success=executeQueryUpdateStats(cursor,							cursor->querybuffer,							cursor->querylength,							reallyexecute);		}	} else {		#ifdef SERVER_DEBUG		debugPrint("connection",3,"preparing/executing...");		#endif		if (cursor->sql_injection_detection_ingress(						cursor->querybuffer)) {			doegress=false;			success=true;		} else {			success=cursor->prepareQuery(cursor->querybuffer,							cursor->querylength);			if (success) {				if (cursor->supportsNativeBinds()) {					success=(cursor->handleBinds() &&						executeQueryUpdateStats(							cursor,							cursor->querybuffer,							cursor->querylength,							true));				} else {					stringbuffer	*newquery=						cursor->fakeInputBinds(							cursor->querybuffer);					const char	*queryptr=						(newquery)?						newquery->getString():						cursor->querybuffer;					uint32_t	querylen=						(newquery)?						newquery->getStringLength():						cursor->querylength;					bool	execquery=true;					if (queryptr!=cursor->querybuffer) {						if (cursor->						sql_injection_detection_ingress(							cursor->querybuffer)) {							doegress=false;							execquery=false;						}					}					if (execquery) {						success=executeQueryUpdateStats(								cursor,								queryptr,								querylen,true);					}					delete newquery;				}			}		}	}	if (doegress) {		cursor->sid_egress=cursor->sql_injection_detection_egress();	}	if (cursor->sid_egress) {		// FIXME: init this to false somewhere!		cursor->sql_injection_detection=true;	}	// was the query a commit or rollback?	commitOrRollback(cursor);	// On success, autocommit if necessary.	// Connection classes could override autoCommitOn() and autoCommitOff()	// to do database API-specific things, but will not set 	// checkautocommit, so this code won't get called at all for those 	// connections.	if (success && checkautocommit && isTransactional() && 			performautocommit && commitorrollback) {		#ifdef SERVER_DEBUG		debugPrint("connection",3,"commit necessary...");		#endif		success=commit();		commitorrollback=false;	}	#ifdef SERVER_DEBUG	if (success) {		debugPrint("connection",2,"processing query succeeded");	} else {		debugPrint("connection",2,"processing query failed");	}	debugPrint("connection",2,"done processing query");	#endif	return success;}void sqlrconnection_svr::commitOrRollback(sqlrcursor_svr *cursor) {	#ifdef SERVER_DEBUG	debugPrint("connection",2,"commit or rollback check...");	#endif	// if the query was a commit or rollback, set a flag indicating so	if (isTransactional()) {		if (cursor->queryIsCommitOrRollback()) {			#ifdef SERVER_DEBUG			debugPrint("connection",3,					"commit or rollback not needed");			#endif			commitorrollback=false;		} else if (cursor->queryIsNotSelect()) {			#ifdef SERVER_DEBUG			debugPrint("connection",3,					"commit or rollback needed");			#endif			commitorrollback=true;		}	}	#ifdef SERVER_DEBUG	debugPrint("connection",2,"done with commit or rollback check");	#endif}

⌨️ 快捷键说明

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