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

📄 isaclient.cpp

📁 通用的数据库中间库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// default indicator test: -1 is null value
/*virtual */
bool ISACursor::IndicatorIsNull(
	int/* nPos*/,	// 1-based
	SAValueRead &/*vr*/,
	ValueType_t/* eValueType*/,
	void *pInd, unsigned int nIndSize,
	void *pSize, unsigned int nSizeSize,
	unsigned int &nRealSize,
	int nBulkReadingBufPos) const
{
	bool bNull;
	switch(nIndSize)
	{
	case sizeof(char):
		bNull = ((char*)pInd)[nBulkReadingBufPos] == -1;
		break;
	case sizeof(short):
		bNull = ((short*)pInd)[nBulkReadingBufPos] == -1;
		break;
	case sizeof(long):
		bNull = ((long*)pInd)[nBulkReadingBufPos] == -1;
		break;
	default:
		assert(false);	// if none of above then should be overloaded
		bNull = true;
	}

	if(bNull)
		return true;

	switch(nSizeSize)
	{
	case sizeof(unsigned char):
		nRealSize = ((unsigned char*)pSize)[nBulkReadingBufPos];
		break;
	case sizeof(unsigned short):
		nRealSize = ((unsigned short*)pSize)[nBulkReadingBufPos];
		break;
	case sizeof(unsigned long):
		nRealSize = ((unsigned long*)pSize)[nBulkReadingBufPos];
		break;
	default:
		assert(false);	// if none of above then should be overloaded
	}

	return false;
}

void ISACursor::GetFieldBuffer(
	int nPos,	// 1-based
	void *&pValue,
	unsigned int &nFieldBufSize)
{
	if(!m_pSelectBuffer)
	{
		pValue = NULL;
		nFieldBufSize = 0;
		return;
	}

	void *pBuf = m_pSelectBuffer;
	for(int i = 0; i < nPos; ++i)
	{
		void *pInd;
		void *pSize;
		IncFieldBuffer(pBuf, pInd, pSize, nFieldBufSize, pValue);
	}
}

void ISACursor::IncParamBuffer(
	void *&pBuf,
	void *&pInd,
	void *&pSize,
	unsigned int &nDataBufSize,
	void *&pValue)
{
	nDataBufSize = *(unsigned int*)pBuf;
	((char*&)pBuf) += SA_Align16(sizeof(unsigned int));

	pInd = pBuf;
	((char*&)pBuf) += SA_Align16(m_nParamIndSize);

	pSize = pBuf;
	((char*&)pBuf) += SA_Align16(m_nParamSizeSize);

	pValue = pBuf;
	((char*&)pBuf) += SA_Align16(nDataBufSize);
}

void ISACursor::IncFieldBuffer(
	void *&pBuf,
	void *&pInd,
	void *&pSize,
	unsigned int &nDataBufSize,
	void *&pValue)
{
	nDataBufSize = *(unsigned int*)pBuf;
	((char*&)pBuf) += SA_Align16(sizeof(unsigned int));

	pInd = pBuf;
	((char*&)pBuf) += SA_Align16(m_nIndSize * m_nBulkReadingBufSize);

	pSize = pBuf;
	((char*&)pBuf) += SA_Align16(m_nSizeSize * m_nBulkReadingBufSize);

	pValue = pBuf;
	((char*&)pBuf) += SA_Align16(nDataBufSize * m_nBulkReadingBufSize);
}

void ISACursor::ConvertValue(
	int nPos,	// 1 - based
	unsigned int nIndSize,
	void *pNull,
	unsigned int nSizeSize,
	void *pSize,
	unsigned int nBufSize,
	void *pValue,
	ValueType_t eValueType,
	SAValueRead &vr,
	int nBulkReadingBufPos)
{
	unsigned int nRealSize;
	if(IndicatorIsNull(
		nPos,
		vr,
		eValueType,
		pNull, nIndSize,
		pSize, nSizeSize,
		nRealSize,
		nBulkReadingBufPos))
	{
		*vr.m_pbNull = true;
		return;
	}

	const void *pData = (char*)pValue + nBulkReadingBufPos * nBufSize;

	*vr.m_pbNull = false;

	SADataType_t eDataType;
	switch(eValueType)
	{
	case ISA_FieldValue:
		eDataType = ((SAField&)vr).FieldType();
		break;
	default:
		assert(eValueType == ISA_ParamValue);
		eDataType = ((SAParam&)vr).ParamType();
	}
	switch(eDataType)
	{
	case SA_dtUnknown:
		throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_DATA_TYPE);
	case SA_dtBool:
		vr.m_eDataType = SA_dtBool;
		switch(nRealSize)
		{
		case sizeof(char):
			*(bool*)vr.m_pScalar = *(char*)pData != 0;
			break;
		case sizeof(short):
			*(bool*)vr.m_pScalar = *(short*)pData != 0;
			break;
		case sizeof(long):
			*(bool*)vr.m_pScalar = *(long*)pData != 0;
			break;
		default:
			assert(false);
			break;
		}
		break;
	case SA_dtShort:
		assert(nRealSize <= sizeof(short));	// <= because we do not have SA_dtChar
		vr.m_eDataType = SA_dtShort;
		*(short*)vr.m_pScalar = *(short*)pData;
		break;
	case SA_dtLong:
		assert(nRealSize == sizeof(long));
		vr.m_eDataType = SA_dtLong;
		*(long*)vr.m_pScalar = *(long*)pData;
		break;
	case SA_dtDouble:
		assert(nRealSize == sizeof(double));
		vr.m_eDataType = SA_dtDouble;
		*(double*)vr.m_pScalar = *(double*)pData;
		break;
	case SA_dtDateTime:
		assert(nRealSize <= nBufSize);	// size can be variable, e.g. in SQLBase
		vr.m_eDataType = SA_dtDateTime;
		m_pISAConnection->CnvtInternalToDateTime(
			*vr.m_pDateTime,
			pData, nRealSize);
		break;
	case SA_dtString:
		assert(nRealSize <= nBufSize);
		vr.m_eDataType = SA_dtString;
		ConvertString(*vr.m_pString, pData, nRealSize);
		break;
	case SA_dtBytes:
		assert(nRealSize <= nBufSize);
		vr.m_eDataType = SA_dtBytes;
		*vr.m_pString =
			SAString((const void*)pData, nRealSize);
		break;
	case SA_dtLongBinary:
		vr.m_eDataType = SA_dtLongBinary;
		break;
	case SA_dtLongChar:
		vr.m_eDataType = SA_dtLongChar;
		break;
	case SA_dtBLob:
		vr.m_eDataType = SA_dtBLob;
		break;
	case SA_dtCLob:
		vr.m_eDataType = SA_dtCLob;
		break;
	case SA_dtCursor:
		vr.m_eDataType = SA_dtCursor;
		m_pISAConnection->CnvtInternalToCursor(
			vr.m_pCursor, pData);
		break;
	default:
		assert(false);	// unknown type
	}
}

// default implementation assumes that data for
// string is in multibyte format always
// (in both Unicode and multi-byte builds)
// it also assumes that nRealSize is always in bytes not characters
// Should be overloaded by clients if this is not true
/*virtual */
void ISACursor::ConvertString(SAString &String, const void *pData, unsigned int nRealSize)
{
	String = SAString((const char*)pData, nRealSize);
}

void ISACursor::GetParamBuffer(
	const SAParam &SrcParam,
	void *&pValue, unsigned int &nDataBufSize)
{
	void *pBuf = m_pParamBuffer;
	for(int i = 0; i < m_pCommand->ParamCount(); ++i)
	{
		SAParam &Param = m_pCommand->ParamByIndex(i);

		void *pNull;
		void *pSize;
		IncParamBuffer(pBuf, pNull, pSize, nDataBufSize, pValue);

		if(&SrcParam == &Param)
			break;
	}
}

int ISACursor::OutputParamPos(int nParamPos)
{
	assert(nParamPos <= m_pCommand->ParamCount());
	int nPos = 0;
	for(int i = 0; i < nParamPos; ++i)
	{
		SAParam &Param = m_pCommand->ParamByIndex(i);
		if(Param.ParamDirType() == SA_ParamOutput ||
			Param.ParamDirType() == SA_ParamInputOutput)
			++nPos;
	}

	return nPos;
}

void ISACursor::ConvertOutputParams()
{
	int nOutputs = 0;
	void *pBuf = m_pParamBuffer;
	for(int i = 0; i < m_pCommand->ParamCount(); ++i)
	{
		SAParam &Param = m_pCommand->ParamByIndex(i);

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

		if(!isOutputParam(Param))
			continue;

		int nPos;
		if(Param.ParamDirType() == SA_ParamReturn)
			nPos = 0;
		else
			nPos = ++nOutputs;

		SADataType_t eParamType = Param.ParamType();
		if(eParamType == SA_dtUnknown)
			throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_PARAMETER_TYPE, (const SAChar*)Param.Name());

		ConvertValue(
			nPos,
			m_nParamIndSize, pNull,
			m_nParamSizeSize, pSize,
			nDataBufSize, pValue,
			ISA_ParamValue,	Param, 0);

		if(!Param.isNull() && isLongOrLob(eParamType))
			ConvertLongOrLOB(ISA_ParamValue, Param, pValue, nDataBufSize);
	}
}

void ISACursor::ConvertSelectBufferToFields(int nBulkReadingBufPos)
{
	int cFieldCount = m_pCommand->FieldCount();
	void *pBuf = m_pSelectBuffer;
	for(int iField = 1; iField <= cFieldCount ; ++iField)
	{
		SAField &Field = m_pCommand->Field(iField);
		SADataType_t eFieldType = Field.FieldType();
		if(eFieldType == SA_dtUnknown)
			throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_COLUMN_TYPE, (const SAChar*)Field.Name());

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

		ConvertValue(
			iField,
			m_nIndSize, pInd,
			m_nSizeSize, pSize,
			nDataBufSize, pValue,
			ISA_FieldValue, Field, nBulkReadingBufPos);

		if(!Field.isNull() && isLongOrLob(eFieldType))
			ConvertLongOrLOB(ISA_FieldValue, Field, pValue, nDataBufSize);
	}
}

/*virtual */
void ISACursor::ConvertLongOrLOB(
	ValueType_t eValueType,
	SAValueRead &vr,
	void *pValue,
	unsigned int nBufSize)
{
	SADataType_t eDataType;
	switch(eValueType)
	{
	case ISA_FieldValue:
		eDataType = ((SAField&)vr).FieldType();
		break;
	default:
		assert(eValueType == ISA_ParamValue);
		eDataType = ((SAParam&)vr).ParamType();
	}
	switch(eDataType)
	{
	case SA_dtLongBinary:
	case SA_dtLongChar:
	case SA_dtBLob:
	case SA_dtCLob:
		if(vr.LongOrLobReaderMode() == SA_LongOrLobReaderDefault)
			ReadLongOrLOB(eValueType, vr, pValue, nBufSize,
			saDefaultLongOrLobReader, 0, NULL);
		break;
	default:
		assert(false);
	}
}

int ISACursor::FieldCount(int nCount, ...) const
{
	int nFields = 0;

	va_list argList;
	va_start(argList, nCount);
	
	for(int i = 0; i < nCount; i++)
	{
		// int is OK		// need a cast here since va_arg only		// takes fully promoted types		SADataType_t eDataType = (SADataType_t)va_arg(argList, int);
		for(int j = 0; j < m_pCommand->FieldCount(); j++)
			if(m_pCommand->Field(j+1).FieldType() == eDataType)
				++nFields;
	}

	va_end(argList);
	return nFields;
}

short ISACursor::ParamDirCount(
	int nPlaceHolderCount,
	saPlaceHolder **ppPlaceHolders,
	int nCount, ...) const
{
	short nPlaceHolders = 0;

	va_list argList;
	va_start(argList, nCount);

	for(int i = 0; i < nCount; i++)
	{
		// int is OK		// need a cast here since va_arg only		// takes fully promoted types		SAParamDirType_t eType = (SAParamDirType_t)va_arg(argList, int);
		for(int j = 0; j < nPlaceHolderCount; j++)
			if(ppPlaceHolders[j]->getParam()->ParamDirType() == eType)
				++nPlaceHolders;
	}

	va_end(argList);
	return nPlaceHolders;
}

/*static */
bool ISACursor::isLong(SADataType_t eDataType)
{
	switch(eDataType)
	{
	case SA_dtLongBinary:
	case SA_dtLongChar:
		return true;
	default:
		break;
	}

	return false;

⌨️ 快捷键说明

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