📄 isaclient.cpp
字号:
// 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 + -