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

📄 infclient.cpp

📁 通用的数据库中间库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
public:	IinfCursor(		IinfConnection *pIinfConnection,		SACommand *pCommand);	virtual ~IinfCursor();	virtual bool IsOpened();	virtual void Open();	virtual void Close();	virtual void Prepare(		const SAString &sStmt,		SACommandType_t eCmdType,		int nPlaceHolderCount,		saPlaceHolder **ppPlaceHolders);	// binds parameters	void Bind(		int nPlaceHolderCount,		saPlaceHolder **ppPlaceHolders);	// executes statement	virtual void Execute(
		int nPlaceHolderCount,
		saPlaceHolder **ppPlaceHolders);
	// cleans up after execute if needed, so the statement can be reexecuted
	virtual void UnExecute();
	virtual void Cancel();	virtual bool ResultSetExists();	virtual void DescribeFields(
		DescribeFields_cb_t fn);
	virtual void SetSelectBuffers();	virtual bool FetchNext();
	virtual long GetRowsAffected();	virtual void ReadLongOrLOB(		ValueType_t eValueType,		SAValueRead &vr,		void *pValue,		unsigned int nFieldBufSize,		saLongOrLobReader_t fnReader,		unsigned int nReaderWantedPieceSize,		void *pAddlData);	virtual void DescribeParamSP();	virtual saCommandHandles *NativeHandles();};//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////IinfCursor::IinfCursor(	IinfConnection *pIinfConnection,	SACommand *pCommand) :	ISACursor(pIinfConnection, pCommand){}/*virtual */IinfCursor::~IinfCursor(){}/*virtual */unsigned int IinfCursor::InputBufferSize(	const SAParam &Param) const{	if(!Param.isNull())	{		switch(Param.DataType())		{		case SA_dtBool:
			return sizeof(unsigned char);	// SQL_C_BIT
		case SA_dtDateTime:			return sizeof(TIMESTAMP_STRUCT);		case SA_dtLongBinary:		case SA_dtLongChar:		case SA_dtBLob:		case SA_dtCLob:			return 0;		default:			break;		}	}		return ISACursor::InputBufferSize(Param);}/*virtual */SADataType_t IinfCursor::CnvtNativeToStd(	int dbtype,	int/* dbsubtype*/,	int/* dbsize*/,	int prec,	int scale) const{	SADataType_t eDataType = SA_dtUnknown;	switch(dbtype)	{	case SQL_CHAR:		// Character string of fixed length	case SQL_VARCHAR:	// Variable-length character string//	case SQL_WCHAR:		// Unicode character string of fixed length//	case SQL_WVARCHAR:	// Unicode variable-length character string		eDataType = SA_dtString;		break;	case SQL_BINARY:	case SQL_VARBINARY:		eDataType = SA_dtBytes;		break;	case SQL_LONGVARCHAR:	// Variable-length character data//	case SQL_WLONGVARCHAR:	// Variable-length character data		eDataType = SA_dtLongChar;		break;	case SQL_LONGVARBINARY: // Variable-length binary data		eDataType = SA_dtLongBinary;		break;	case SQL_DECIMAL:	case SQL_NUMERIC:		if(scale <= 0) {	// check for exact type			if(prec <= 5)				eDataType = SA_dtShort;			else if(prec <= 10)				eDataType = SA_dtLong;			else				eDataType = SA_dtDouble;		}		else			eDataType = SA_dtDouble;		break;	case SQL_SMALLINT:		eDataType = SA_dtShort;		break;	case SQL_INTEGER:		eDataType = SA_dtLong;		break;	case SQL_REAL:		eDataType = SA_dtDouble;		break;	case SQL_FLOAT:		eDataType = SA_dtDouble;		break;	case SQL_DOUBLE:		eDataType = SA_dtDouble;		break;	case SQL_BIT:	// Single bit binary data		eDataType = SA_dtBool;		break;	case SQL_TINYINT:		eDataType = SA_dtShort;		break;	case SQL_BIGINT:		eDataType = SA_dtDouble;		break;	case SQL_TIME:	case SQL_DATE:		// == SQL_DATETIME	case SQL_TIMESTAMP:	case SQL_TYPE_DATE:	case SQL_TYPE_TIME:	case SQL_TYPE_TIMESTAMP:		eDataType = SA_dtDateTime;		break;	default:		assert(false);	}	return eDataType;}int IinfCursor::CnvtStdToNativeValueType(SADataType_t eDataType) const{	SQLSMALLINT ValueType;	switch(eDataType)	{	case SA_dtUnknown:		throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_DATA_TYPE);	case SA_dtBool:
		ValueType = SQL_C_BIT;
		break;
	case SA_dtShort:		ValueType = SQL_C_SSHORT;		break;	case SA_dtLong:		ValueType = SQL_C_SLONG;		break;	case SA_dtDouble:		ValueType = SQL_C_DOUBLE;		break;	case SA_dtDateTime:		ValueType = SQL_C_TYPE_TIMESTAMP;		break;	case SA_dtString:		ValueType = SQL_C_CHAR;		break;	case SA_dtBytes:		ValueType = SQL_C_BINARY;		break;	case SA_dtLongBinary:	case SA_dtBLob:		ValueType = SQL_C_BINARY;		break;	case SA_dtLongChar:	case SA_dtCLob:		ValueType = SQL_C_CHAR;		break;	default:		ValueType = 0;		assert(false);	}	if(((IinfConnection*)m_pISAConnection)->m_nDriverODBCVer < 0x00030000)	{		switch(eDataType)		{			case SA_dtDateTime:				ValueType = SQL_C_TIMESTAMP;			default:				break;		}	}	return ValueType;}/*virtual */int IinfCursor::CnvtStdToNative(SADataType_t eDataType) const{	SQLSMALLINT dbtype;	switch(eDataType)	{	case SA_dtUnknown:		throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_DATA_TYPE);	case SA_dtBool:
		dbtype = SQL_BIT;
		break;
	case SA_dtShort:		dbtype = SQL_SMALLINT;		break;	case SA_dtLong:		dbtype = SQL_INTEGER;		break;	case SA_dtDouble:		dbtype = SQL_DOUBLE;		break;	case SA_dtDateTime:		dbtype = SQL_TYPE_TIMESTAMP;		break;	case SA_dtString:		dbtype = SQL_CHAR;		break;	case SA_dtBytes:		dbtype = SQL_BINARY;		break;	case SA_dtLongBinary:	case SA_dtBLob:		dbtype = SQL_LONGVARBINARY;		break;	case SA_dtLongChar:	case SA_dtCLob:		dbtype = SQL_LONGVARCHAR;		break;	default:		dbtype = 0;		assert(false);	}		return dbtype;}/*virtual */bool IinfCursor::IsOpened(){	return m_handles.m_hstmt != NULL;}/*virtual */void IinfCursor::Open(){	SafeAllocStmt();}void IinfCursor::SafeAllocStmt(){	assert(m_handles.m_hstmt == NULL);	if(g_infAPI.SQLAllocHandle)		IinfConnection::Check(g_infAPI.SQLAllocHandle(SQL_HANDLE_STMT, ((IinfConnection*)m_pISAConnection)->m_handles.m_hdbc, &m_handles.m_hstmt),			SQL_HANDLE_DBC, ((IinfConnection*)m_pISAConnection)->m_handles.m_hdbc);	else		IinfConnection::Check(g_infAPI.SQLAllocStmt(((IinfConnection*)m_pISAConnection)->m_handles.m_hdbc, &m_handles.m_hstmt),			SQL_HANDLE_DBC, ((IinfConnection*)m_pISAConnection)->m_handles.m_hdbc);
	assert(m_handles.m_hstmt != NULL);
}void IinfCursor::SafeFreeStmt(){	if(g_infAPI.SQLFreeHandle)		IinfConnection::Check(g_infAPI.SQLFreeHandle(SQL_HANDLE_STMT, m_handles.m_hstmt), SQL_HANDLE_STMT, m_handles.m_hstmt);	else		IinfConnection::Check(g_infAPI.SQLFreeStmt(m_handles.m_hstmt, SQL_DROP), SQL_HANDLE_STMT, m_handles.m_hstmt);	m_handles.m_hstmt = NULL;}/*virtual */void IinfCursor::Close(){	assert(m_handles.m_hstmt != NULL);	SafeFreeStmt();}/*virtual */ISACursor *IinfConnection::NewCursor(SACommand *m_pCommand){	return new IinfCursor(this, m_pCommand);}/*virtual */void IinfCursor::Prepare(	const SAString &sStmt,	SACommandType_t eCmdType,	int nPlaceHolderCount,	saPlaceHolder**	ppPlaceHolders){	SAString sStmtinf;	int nPos = 0;	int i;	switch(eCmdType)	{	case SA_CmdSQLStmt:		// replace bind variables with '?' place holder		for(i = 0; i < nPlaceHolderCount; i++)		{			sStmtinf += sStmt.Mid(nPos, ppPlaceHolders[i]->getStart()-nPos);			sStmtinf += "?";			nPos = ppPlaceHolders[i]->getEnd() + 1;		}		// copy tail		if(nPos < sStmt.GetLength())			sStmtinf += sStmt.Mid(nPos);		break;	case SA_CmdStoredProc:		sStmtinf = CallSubProgramSQL();		break;	default:		assert(false);	}	// a bit of clean up	IinfConnection::Check(g_infAPI.SQLFreeStmt(m_handles.m_hstmt, SQL_CLOSE), SQL_HANDLE_STMT, m_handles.m_hstmt);	IinfConnection::Check(g_infAPI.SQLFreeStmt(m_handles.m_hstmt, SQL_UNBIND), SQL_HANDLE_STMT, m_handles.m_hstmt);	IinfConnection::Check(g_infAPI.SQLFreeStmt(m_handles.m_hstmt, SQL_RESET_PARAMS), SQL_HANDLE_STMT, m_handles.m_hstmt);	IinfConnection::Check(g_infAPI.SQLPrepare(		m_handles.m_hstmt, (SQLTCHAR*)(const char*)sStmtinf, SQL_NTS), SQL_HANDLE_STMT, m_handles.m_hstmt);}SAString IinfCursor::CallSubProgramSQL(){	int nParams = m_pCommand->ParamCount();	SAString sSQL = "{";	// check for Return parameter	int i;	for(i = 0; i < nParams; ++i)	{		SAParam &Param = m_pCommand->ParamByIndex(i);		if(Param.ParamDirType() == SA_ParamReturn)		{			sSQL += "?=";			break;		}	}	sSQL += "call ";	sSQL += m_pCommand->CommandText();	// specify parameters	SAString sParams;	for(i = 0; i < nParams; ++i)	{		SAParam &Param = m_pCommand->ParamByIndex(i);		if(Param.ParamDirType() == SA_ParamReturn)			continue;		if(!sParams.IsEmpty())			sParams += ", ";		sParams += "?";	}
	// Informix specific: unlike other drivers
	// if SP with no parameters is called it should have "()"	sSQL += "(";
	if(!sParams.IsEmpty())	{		sSQL += sParams;	}	sSQL += ")";
	sSQL += "}";	return sSQL;}void IinfCursor::BindLongs(){	SQLRETURN retcode;	SQLPOINTER ValuePtr;	try	{		while((retcode = g_infAPI.SQLParamData(m_handles.m_hstmt, &ValuePtr)) == SQL_NEED_DATA)		{			SAParam *pParam = (SAParam *)ValuePtr;			unsigned int nActualWrite;			SAPieceType_t ePieceType = SA_FirstPiece;			void *pBuf;			while((nActualWrite = pParam->InvokeWriter(				ePieceType,				IinfConnection::MaxLongAtExecSize, pBuf)) != 0)			{				IinfConnection::Check(g_infAPI.SQLPutData(					m_handles.m_hstmt, pBuf, nActualWrite), SQL_HANDLE_STMT, m_handles.m_hstmt);				if(ePieceType == SA_LastPiece)					break;			}		}	}	catch(SAException&)	{		g_infAPI.SQLCancel(m_handles.m_hstmt);		throw;	}	IinfConnection::Check(retcode, SQL_HANDLE_STMT, m_handles.m_hstmt);}
/*virtual */
void IinfCursor::UnExecute()
{
}

void IinfCursor::Bind(
		int nPlaceHolderCount,
		saPlaceHolder**	ppPlaceHolders)
{
	// we should bind for every place holder ('?')
	AllocBindBuffer(nPlaceHolderCount, ppPlaceHolders,
		sizeof(SQLINTEGER), 0);
	void *pBuf = m_pParamBuffer;

	for(int i = 0; i < nPlaceHolderCount; ++i)
	{
		SAParam &Param = *ppPlaceHolders[i]->getParam();

		void *pInd;
		void *pSize;
		unsigned int nDataBufSize;
		void *pValue;
		IncParamBuffer(pBuf, pInd, pSize, nDataBufSize, pValue);

		SADataType_t eDataType = Param.DataType();
		SQLSMALLINT ParameterType = (SQLSMALLINT)(eDataType == SA_dtUnknown?
			SQL_CHAR : // some type should be set
			CnvtStdToNative(eDataType));
		SQLSMALLINT ValueType = (SQLSMALLINT)(eDataType == SA_dtUnknown?
			SQL_C_CHAR : // some type should be set
			CnvtStdToNativeValueType(eDataType));

		SQLINTEGER *StrLen_or_IndPtr = (SQLINTEGER *)pInd;
		SQLPOINTER ParameterValuePtr = (SQLPOINTER)pValue;
		SQLINTEGER BufferLength = (SQLINTEGER)nDataBufSize;
		SQLUINTEGER ColumnSize = Param.ParamSize();
		if(!ColumnSize)	// not set explicitly
			ColumnSize = BufferLength;

		SQLSMALLINT InputOutputType;
		switch(Param.ParamDirType())
		{
		case SA_ParamInput:
			InputOutputType = SQL_PARAM_INPUT;
			break;
		case SA_ParamOutput:
			InputOutputType = SQL_PARAM_OUTPUT;
			break;
		case SA_ParamInputOutput:
			InputOutputType = SQL_PARAM_INPUT_OUTPUT;
			break;
		default:
			assert(Param.ParamDirType() == SA_ParamReturn);
			InputOutputType = SQL_PARAM_OUTPUT;
		}

		if(isInputParam(Param))
		{
			if(Param.isNull())
				*StrLen_or_IndPtr = SQL_NULL_DATA;		// field is null
			else
				*StrLen_or_IndPtr = InputBufferSize(Param);	// field is not null

			if(!Param.isNull())
			{
				switch(eDataType)
				{
				case SA_dtUnknown:
					throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_PARAMETER_TYPE, (const char*)Param.Name());
				case SA_dtBool:
					assert(*StrLen_or_IndPtr == (SQLINTEGER)sizeof(unsigned char));
					*(unsigned char*)ParameterValuePtr = (unsigned char)Param.asBool();
					break;
				case SA_dtShort:
					assert(*StrLen_or_IndPtr == (SQLINTEGER)sizeof(short));
					*(short*)ParameterValuePtr = Param.asShort();
					break;
				case SA_dtLong:
					assert(*StrLen_or_IndPtr == (SQLINTEGER)sizeof(long));
					*(long*)ParameterValuePtr = Param.asLong();
					break;
				case SA_dtDouble:
					assert(*StrLen_or_IndPtr == (SQLINTEGER)sizeof(double));
					*(double*)ParameterValuePtr = Param.asDouble();
					break;
				case SA_dtDateTime:
					assert(*StrLen_or_IndPtr == (SQLINTEGER)sizeof(TIMESTAMP_STRUCT));
					IinfConnection::CnvtDateTimeToInternal(
						Param.asDateTime(),
						*(TIMESTAMP_STRUCT*)ParameterValuePtr);
					break;
				case SA_dtString:
					assert(*StrLen_or_IndPtr == Param.asString().GetLength());
					memcpy(ParameterValuePtr, (const char*)Param.asString(), *StrLen_or_IndPtr);
					break;
				case SA_dtBytes:
					assert(*StrLen_or_IndPtr == Param.asBytes().GetLength());
					memcpy(ParameterValuePtr, (const char*)Param.asBytes(), *StrLen_or_IndPtr);
					break;
				case SA_dtLongBinary:
				case SA_dtBLob:
				case SA_dtLongChar:
				case SA_dtCLob:
					assert(*StrLen_or_IndPtr == 0);
					break;
				default:
					ValueType = 0;
					ParameterType = 0;
					assert(false);
				}
			}
		}

		if(isLongOrLob(eDataType))
		{
			*StrLen_or_IndPtr = ((IinfConnection*)m_pISAConnection)->LenDataAtExec();
			IinfConnection::Check(g_infAPI.SQLBindParameter(
				m_handles.m_hstmt,
				(SQLUSMALLINT)(i+1), InputOutputType,

⌨️ 快捷键说明

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