📄 infclient.cpp
字号:
ValueType,
ParameterType,
0, // ColumnSize
0, // DecimalDigits
&Param, // ParameterValuePtr - context
0, // Buffer length
StrLen_or_IndPtr), SQL_HANDLE_STMT, m_handles.m_hstmt);
}
else
{
IinfConnection::Check(g_infAPI.SQLBindParameter(
m_handles.m_hstmt,
(SQLUSMALLINT)(i+1), InputOutputType,
ValueType,
ParameterType,
ColumnSize,
0,
ParameterValuePtr,
BufferLength,
StrLen_or_IndPtr), SQL_HANDLE_STMT, m_handles.m_hstmt);
}
}
}
/*virtual */void IinfCursor::Execute(
int nPlaceHolderCount,
saPlaceHolder **ppPlaceHolders){ if(nPlaceHolderCount)
Bind(nPlaceHolderCount, ppPlaceHolders);
SQLRETURN rc; IinfConnection::Check(g_infAPI.SQLFreeStmt(m_handles.m_hstmt, SQL_CLOSE), SQL_HANDLE_STMT, m_handles.m_hstmt); rc = g_infAPI.SQLExecute(m_handles.m_hstmt); if(rc != SQL_NEED_DATA) { if(rc != SQL_NO_DATA) IinfConnection::Check(rc, SQL_HANDLE_STMT, m_handles.m_hstmt); } else BindLongs();
ConvertOutputParams(); // if any
}
/*virtual */
void IinfCursor::Cancel()
{
IinfConnection::Check(g_infAPI.SQLCancel(
m_handles.m_hstmt), SQL_HANDLE_STMT, m_handles.m_hstmt);
}
/*virtual */bool IinfCursor::ResultSetExists(){ SQLSMALLINT ColumnCount; IinfConnection::Check(g_infAPI.SQLNumResultCols(m_handles.m_hstmt, &ColumnCount), SQL_HANDLE_STMT, m_handles.m_hstmt); return ColumnCount > 0;}/*virtual */
void IinfCursor::DescribeFields(
DescribeFields_cb_t fn)
{
SQLSMALLINT ColumnCount;
IinfConnection::Check(g_infAPI.SQLNumResultCols(m_handles.m_hstmt, &ColumnCount), SQL_HANDLE_STMT, m_handles.m_hstmt);
for(SQLSMALLINT nField = 1; nField <= ColumnCount; ++nField)
{
SQLCHAR sColName[1024];
SQLSMALLINT nColLen;
SQLSMALLINT DataType;
SQLUINTEGER ColumnSize;
SQLSMALLINT Nullable;
SQLSMALLINT DecimalDigits;
IinfConnection::Check(g_infAPI.SQLDescribeCol(
m_handles.m_hstmt,
nField,
sColName,
sizeof(sColName),
&nColLen,
&DataType,
&ColumnSize,
&DecimalDigits,
&Nullable), SQL_HANDLE_STMT, m_handles.m_hstmt);
(m_pCommand->*fn)(
SAString((const char*)sColName, nColLen),
CnvtNativeToStd(DataType, 0, nColLen, ColumnSize, DecimalDigits),
(int)DataType,
ColumnSize,
ColumnSize,
DecimalDigits,
Nullable == SQL_NO_NULLS);
}
}
/*virtual */long IinfCursor::GetRowsAffected(){ assert(m_handles.m_hstmt != NULL); SQLINTEGER RowCount = -1; IinfConnection::Check(g_infAPI.SQLRowCount(m_handles.m_hstmt, &RowCount), SQL_HANDLE_STMT, m_handles.m_hstmt); return RowCount;}/*virtual */unsigned int IinfCursor::OutputBufferSize( SADataType_t eDataType, unsigned int nDataSize) const{ switch(eDataType) { case SA_dtBool:
return sizeof(unsigned char); // SQL_C_BIT
case SA_dtString: return nDataSize+1; // always allocate space for NULL case SA_dtDateTime: return sizeof(TIMESTAMP_STRUCT); case SA_dtLongBinary: case SA_dtLongChar: return 0; default: break; } return ISACursor::OutputBufferSize(eDataType, nDataSize);}/*virtual */void IinfCursor::SetFieldBuffer( int nCol, // 1-based void *pInd, unsigned int nIndSize, void * /*pSize*/, unsigned int/* nSizeSize*/, void *pValue, unsigned int nBufSize){ assert(nIndSize == sizeof(SQLINTEGER));
if(nIndSize != sizeof(SQLINTEGER))
return; SAField &Field = m_pCommand->Field(nCol); SQLSMALLINT TargetType = (SQLSMALLINT)CnvtStdToNativeValueType(Field.FieldType()); bool bLong = false; switch(Field.FieldType()) { case SA_dtUnknown: throw SAException(SA_Library_Error, -1, -1, IDS_UNKNOWN_COLUMN_TYPE, (const char*)Field.Name()); case SA_dtBool:
TargetType = SQL_C_BIT;
break;
case SA_dtShort: assert(nBufSize == sizeof(short)); break; case SA_dtLong: assert(nBufSize == sizeof(long)); break; case SA_dtDouble: assert(nBufSize == sizeof(double)); break; case SA_dtDateTime: assert(nBufSize == sizeof(TIMESTAMP_STRUCT)); break; case SA_dtBytes:
assert(nBufSize == (unsigned int)Field.FieldSize());
break;
case SA_dtString: assert(nBufSize == (unsigned int)Field.FieldSize()+1); break; case SA_dtLongBinary: assert(nBufSize == 0); bLong = true; break; case SA_dtLongChar: assert(nBufSize == 0); bLong = true; break; default: TargetType = 0; assert(false); // unknown type } if(!bLong) IinfConnection::Check( g_infAPI.SQLBindCol(m_handles.m_hstmt, (SQLUSMALLINT)nCol, TargetType, pValue, nBufSize, (SQLINTEGER*)pInd), SQL_HANDLE_STMT, m_handles.m_hstmt);}/*virtual */void IinfCursor::SetSelectBuffers(){ // use default helpers AllocSelectBuffer(sizeof(SQLINTEGER), 0);}/*virtual */bool IinfCursor::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{ assert(nIndSize == sizeof(SQLINTEGER));
if(nIndSize != sizeof(SQLINTEGER))
return true; if(*(SQLINTEGER*)pInd >= 0) nRealSize = *(SQLINTEGER*)pInd; bool bLong = false; SQLSMALLINT TargetType = 0; SQLINTEGER StrLen_or_IndPtr; bool bAddSpaceForNull = 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_dtLongBinary: bLong = true; TargetType = SQL_C_BINARY; bAddSpaceForNull = false; break; case SA_dtLongChar: bLong = true; TargetType = SQL_C_CHAR; bAddSpaceForNull = true; break; default: break; } if(bLong) { // also try to get long size nRealSize = 0; char Buf[1]; IinfConnection::Check(g_infAPI.SQLGetData( m_handles.m_hstmt, (SQLUSMALLINT)nPos, TargetType, Buf, bAddSpaceForNull? 1:0, &StrLen_or_IndPtr), SQL_HANDLE_STMT, m_handles.m_hstmt); if(StrLen_or_IndPtr >= 0) nRealSize = StrLen_or_IndPtr; return StrLen_or_IndPtr == SQL_NULL_DATA; } return *(SQLINTEGER*)pInd == SQL_NULL_DATA;}/*virtual */bool IinfCursor::FetchNext(){ SQLRETURN rc = g_infAPI.SQLFetch(m_handles.m_hstmt); if(rc != SQL_NO_DATA) { IinfConnection::Check(rc, SQL_HANDLE_STMT, m_handles.m_hstmt); // use default helpers ConvertSelectBufferToFields(0); } return rc != SQL_NO_DATA;}
/*virtual */void IinfCursor::ReadLongOrLOB( ValueType_t eValueType, SAValueRead &vr, void * /*pValue*/, unsigned int/* nBufSize*/, saLongOrLobReader_t fnReader, unsigned int nReaderWantedPieceSize, void *pAddlData){ if(eValueType == ISA_FieldValue) { SAField &Field = (SAField &)vr; SQLSMALLINT TargetType; SQLINTEGER StrLen_or_IndPtr; SQLRETURN rc; bool bAddSpaceForNull; switch(Field.FieldType()) { case SA_dtLongBinary: TargetType = SQL_C_BINARY; bAddSpaceForNull = false; break; case SA_dtLongChar: TargetType = SQL_C_CHAR; bAddSpaceForNull = true; break; default: TargetType = 0; bAddSpaceForNull = false; assert(false); } // try to get long size unsigned int nLongSize = 0; char Buf[1]; rc = g_infAPI.SQLGetData( m_handles.m_hstmt, (SQLUSMALLINT)Field.Pos(), TargetType, Buf, bAddSpaceForNull? 1:0, &StrLen_or_IndPtr); if(rc != SQL_NO_DATA) { IinfConnection::Check(rc, SQL_HANDLE_STMT, m_handles.m_hstmt); if(StrLen_or_IndPtr >= 0) nLongSize = StrLen_or_IndPtr; } unsigned char* pBuf; unsigned int nPortionSize = vr.PrepareReader( nLongSize, IinfConnection::MaxLongAtExecSize, pBuf, fnReader, nReaderWantedPieceSize, pAddlData, bAddSpaceForNull); assert(nPortionSize <= IinfConnection::MaxLongAtExecSize); SAPieceType_t ePieceType = SA_FirstPiece; unsigned int nTotalRead = 0; do { if(nLongSize) // known nPortionSize = sa_min(nPortionSize, nLongSize - nTotalRead); rc = g_infAPI.SQLGetData( m_handles.m_hstmt, (SQLUSMALLINT)Field.Pos(), TargetType, pBuf, nPortionSize + (bAddSpaceForNull? 1:0), &StrLen_or_IndPtr); assert(nPortionSize || rc == SQL_NO_DATA); if(rc != SQL_NO_DATA) { IinfConnection::Check(rc, SQL_HANDLE_STMT, m_handles.m_hstmt); unsigned int NumBytes = ((StrLen_or_IndPtr > (int)nPortionSize) || (StrLen_or_IndPtr == SQL_NO_TOTAL))? nPortionSize : StrLen_or_IndPtr; nTotalRead += NumBytes; vr.InvokeReader(ePieceType, pBuf, NumBytes); } else { ePieceType = SA_LastPiece; vr.InvokeReader(ePieceType, pBuf, 0); }
if(ePieceType == SA_FirstPiece)
ePieceType = SA_NextPiece;
} while(rc != SQL_NO_DATA); } else { assert(eValueType == ISA_ParamValue); assert(false); }}/*virtual */void IinfCursor::DescribeParamSP(){ SAString sText = m_pCommand->CommandText(); SAString sSchemaName; SAString sProcName; int n = sText.Find('.'); sSchemaName = sText.Left(n); sProcName = sText.Mid(n+1); SACommand cmd(m_pISAConnection->getSAConnection()); cmd.Open(); infCommandHandles *pHandles = (infCommandHandles *)cmd.NativeHandles(); IinfConnection::Check(g_infAPI.SQLProcedureColumns( pHandles->m_hstmt, NULL, 0, sSchemaName.IsEmpty()? (SQLCHAR *)SQL_ALL_SCHEMAS : (SQLCHAR *)(const char*)sSchemaName, SQL_NTS, (SQLCHAR *)(const char*)sProcName, SQL_NTS, (SQLCHAR *)NULL, 0), SQL_HANDLE_STMT, pHandles->m_hstmt); while(cmd.FetchNext()) {// SAString sCat = cmd.Field(1); // "PROCEDURE_CAT"// SAString sSchem = cmd.Field(2); // "PROCEDURE_SCHEM"// SAString sProc = cmd.Field(3); // "PROCEDURE_NAME" SAString sCol = cmd.Field(4); // "COLUMN_NAME" short nColType = cmd.Field(5); // "COLUMN_TYPE" short nDataType = cmd.Field(6); // "DATA_TYPE"// SAString sType = cmd.Field(7); // "TYPE_NAME" long nColSize = cmd.Field(8).isNull()? 0 : (long)cmd.Field(8); // "COLUMN_SIZE" long nBufferLength = cmd.Field(9).isNull()? 0 : (long)cmd.Field(9); // "BUFFER_LENGTH" short nDecDigits = cmd.Field(10).isNull()? (short)0 : (short)cmd.Field(10); // "DECIMAL_DIGITS"// short nNumPrecPadix = cmd.Field(11).isNull()? 0 : (short)cmd.Field(11);// "NUM_PREC_RADIX"// short nNullable = cmd.Field(12).isNull()? 0 : (short)cmd.Field(12); // "NULLABLE" SAParamDirType_t eDirType; switch(nColType) { case SQL_PARAM_INPUT: eDirType = SA_ParamInput; break; case SQL_PARAM_INPUT_OUTPUT: eDirType = SA_ParamInputOutput; break; case SQL_PARAM_OUTPUT: eDirType = SA_ParamOutput; break; case SQL_RETURN_VALUE: eDirType = SA_ParamReturn; break; case SQL_PARAM_TYPE_UNKNOWN: case SQL_RESULT_COL: continue; default: assert(false); continue; } SADataType_t eParamType = CnvtNativeToStd(nDataType, 0, nBufferLength, nColSize, nDecDigits); SAString sParamName; if(sCol.IsEmpty()) { assert(eDirType == SA_ParamOutput); eDirType = SA_ParamReturn; sParamName = "RETURN_VALUE"; } else sParamName = sCol; m_pCommand->CreateParam(sParamName, eParamType, nDataType, nColSize, eDirType); }}/*virtual */saAPI *IinfConnection::NativeAPI() const{ return &g_infAPI;}/*virtual */saConnectionHandles *IinfConnection::NativeHandles(){ return &m_handles;}/*virtual */saCommandHandles *IinfCursor::NativeHandles(){ return &m_handles;}/*virtual */void IinfConnection::setIsolationLevel( SAIsolationLevel_t eIsolationLevel){ Commit(); issueIsolationLevel(eIsolationLevel);}void IinfConnection::SafeSetConnectOption( SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength){ if(g_infAPI.SQLSetConnectAttr) Check(g_infAPI.SQLSetConnectAttr( m_handles.m_hdbc, Attribute, ValuePtr, StringLength), SQL_HANDLE_DBC, m_handles.m_hdbc); else Check(g_infAPI.SQLSetConnectOption( m_handles.m_hdbc, SQLUSMALLINT(Attribute), SQLUINTEGER(ValuePtr)), SQL_HANDLE_DBC, m_handles.m_hdbc);}void IinfConnection::issueIsolationLevel( SAIsolationLevel_t eIsolationLevel){ long isolation; switch(eIsolationLevel) { case SA_ReadUncommitted: isolation = SQL_TXN_READ_UNCOMMITTED; break; case SA_ReadCommitted: isolation = SQL_TXN_READ_COMMITTED; break; case SA_RepeatableRead: isolation = SQL_TXN_REPEATABLE_READ; break; case SA_Serializable: isolation = SQL_TXN_SERIALIZABLE; break; default: assert(false); return; } SafeSetConnectOption( SQL_ATTR_TXN_ISOLATION, SQLPOINTER(isolation), 0);}/*virtual */void IinfConnection::setAutoCommit( SAAutoCommit_t eAutoCommit){ SQLUINTEGER nAutoCommit; switch(eAutoCommit) { case SA_AutoCommitOff: nAutoCommit = SQL_AUTOCOMMIT_OFF; break; case SA_AutoCommitOn: nAutoCommit = SQL_AUTOCOMMIT_ON; break; default: assert(false); return; } SafeSetConnectOption( SQL_ATTR_AUTOCOMMIT, SQLPOINTER(nAutoCommit), 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -