📄 vmodbc.cpp
字号:
// Get the display size in case this column gets
// converted to char
//
nRetCode = ::SQLColAttributes( m_hstmt,
(UWORD)( iIndex + 1 ),
SQL_COLUMN_DISPLAY_SIZE,
NULL,
sizeof( poColumnInfo->m_iDisplaySize ),
NULL,
&poColumnInfo->m_iDisplaySize );
if ( RC_NOTSUCCESSFUL( nRetCode ) )
{
DecodeSQLError( nRetCode,
m_hdbc,
m_hstmt,
__FILE__,
__LINE__ );
goto cleanup;
}
// Get the name of this column
//
nRetCode = ::SQLColAttributes( m_hstmt,
(UWORD)(iIndex + 1),
SQL_COLUMN_NAME,
&poColumnInfo->m_achColumnName,
sizeof( poColumnInfo->m_achColumnName ),
NULL,
NULL );
if ( RC_NOTSUCCESSFUL( nRetCode ) )
{
DecodeSQLError( nRetCode,
m_hdbc,
m_hstmt,
__FILE__,
__LINE__ );
goto cleanup;
}
// Get the name of the table containing this column
//
nRetCode = ::SQLColAttributes( m_hstmt,
(UWORD)( iIndex + 1 ),
SQL_COLUMN_TABLE_NAME,
&poColumnInfo->m_achFromTable,
sizeof( poColumnInfo->m_achFromTable ),
NULL,
NULL );
if ( RC_NOTSUCCESSFUL( nRetCode ) )
{
DecodeSQLError( nRetCode,
m_hdbc,
m_hstmt,
__FILE__,
__LINE__ );
goto cleanup;
}
// now that we have all the info we need on this column
// finish up by allocating storage for this column's local
// member variable and adding the finished CColumn to the
// the column list
//
if ( !AllocStorageForColumn( poColumnInfo ) )
{
goto cleanup;
}
if ( !MapColumnSQLTypeToCType( poColumnInfo ) )
{
goto cleanup;
}
AddColumnInfoToList( poColumnInfo );
}
bResult = true;
cleanup:
return bResult;
}
/* End of function "VMODBC::MakeColumnListFromQuery"
/*****************************************************************************/
/*****************************************************************************/
/*
FUNCTION NAME: VMODBC::DecodeSQLError
DESCRIPTION: does the work required to determine what kind of sql error
has occurred
INPUT: rc : the result code to examine
hdbc : connection context
hstmt : statement context
lpstrFile : file name of caller
uiLine : line number of caller
OUTPUT: none
RETURNS: void
*/
void VMODBC::DecodeSQLError( RETCODE rc,
HDBC hdbc,
HSTMT hstmt,
LPSTR lpstrFile,
UINT uiLine )
{
char achBuf[ 3 * ciMaxMsgSize ];
UCHAR achSqlState[ ciMaxMsgSize ];
UCHAR achErrorMsg[ ciMaxMsgSize ];
SDWORD iNativeError;
SWORD iLength;
int iTemp;
assert( lpstrFile != NULL );
switch( rc )
{
case SQL_NEED_DATA:
sprintf( achBuf, "%s %d %d",
lpstrFile,
uiLine,
"SQL function returned: SQL_NEED_DATA" );
break;
case SQL_NO_DATA_FOUND:
sprintf( achBuf, "%s %d %d",
lpstrFile,
uiLine,
"SQL function returned: SQL_NO_DATA_FOUND" );
m_bIsBOF = true;
m_bIsEOF = true;
m_bIsEmpty = true;
break;
case SQL_STILL_EXECUTING:
sprintf( achBuf, "%s %d %d",
lpstrFile,
uiLine,
"SQL function returned: SQL_STILL_EXECUTING" );
break;
case SQL_INVALID_HANDLE:
sprintf( achBuf, "%s %d %d",
lpstrFile,
uiLine,
"SQL function returned: SQL_INVALID_HANDLE" );
break;
default:
case SQL_ERROR:
iTemp = sprintf( achBuf,
"%s",
"SQL ERROR returned: \n" );
::SQLError( SQL_NULL_HENV,
hdbc,
hstmt,
achSqlState,
&iNativeError,
achErrorMsg,
ciMaxMsgSize,
&iLength );
iTemp += wsprintf( &achBuf[ iTemp ],
"SQL State: %s, ",
(char*)achSqlState );
iTemp += wsprintf( &achBuf[ iTemp ],
"msg: %s",
(char*)achErrorMsg );
break;
}
}
/* End of function "VMODBC::DecodeSQLError"
/*****************************************************************************/
/*****************************************************************************/
/*
FUNCTION NAME: VMODBC::AddColumnInfoToList
DESCRIPTION: adds the column information object to both internal column
lists, one mapped by column index, the other mapped by
column name
INPUT: poColumnInfo : pointer to column object to add
OUTPUT: class fields are modified
RETURNS: void
*/
void VMODBC::AddColumnInfoToList( VMColumnInfo* poColumnInfo )
{
m_oColumnsByIndex.push_back( poColumnInfo );
m_oColumnsByName.insert(
COLUMN_INFO_BY_NAME::value_type( std::string( poColumnInfo->m_achColumnName ),
poColumnInfo ) );
m_iColumnCount++;
}
/* End of function "VMODBC::AddColumnInfoToList"
/*****************************************************************************/
/*****************************************************************************/
/*
FUNCTION NAME: VMODBC::AllocStorageForColumn
DESCRIPTION: examines the column info object and uses the sql data type
of the column to allocate a local buffer of the proper
type
INPUT: poColumnInfo : pointer to column object to operate on
OUTPUT: poColumnInfo : data field is modified
RETURNS: true if worked, false if not
*/
bool VMODBC::AllocStorageForColumn( VMColumnInfo* poColumnInfo )
{
switch ( poColumnInfo->m_iSqlDataType )
{
// character family
//
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR:
//
// mjs: is this right for unicode as well?
//
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WLONGVARCHAR:
poColumnInfo->m_pvData = (void*) new VMString;
*((VMString*)poColumnInfo->m_pvData) = "";
break;
// Integer family
//
case SQL_BIT:
poColumnInfo->m_pvData = (void*) new BOOL;
*((BOOL*)poColumnInfo->m_pvData) = FALSE;
break;
case SQL_TINYINT:
poColumnInfo->m_pvData = (void*) new unsigned char;
*((unsigned char *)poColumnInfo->m_pvData) = '\0';
break;
case SQL_SMALLINT:
poColumnInfo->m_pvData = (void*) new int;
*((int*)poColumnInfo->m_pvData) = 0;
break;
case SQL_INTEGER:
poColumnInfo->m_pvData = (void*) new long;
*((long*)poColumnInfo->m_pvData) = 0;
break;
case SQL_BIGINT:
poColumnInfo->m_pvData = (void*) new _int64;
*((_int64*)poColumnInfo->m_pvData) = 0;
break;
// Floating-point type family and Fixed-point exact numerics.
//
case SQL_NUMERIC:
poColumnInfo->m_pvData = (void*) new double;
*((double*)poColumnInfo->m_pvData) = 0.0;
// poColumnInfo->m_pvData = (void*) new SQL_NUMERIC_STRUCT;
// memset( poColumnInfo->m_pvData, 0, sizeof( SQL_NUMERIC_STRUCT ) );
break;
// case SQL_DECIMAL:
case SQL_REAL:
case SQL_FLOAT:
poColumnInfo->m_pvData = (void*) new float;
*((float*)poColumnInfo->m_pvData) = (float) 0;
break;
case SQL_DECIMAL:
case SQL_DOUBLE:
poColumnInfo->m_pvData = (void*) new double;
*((double*)poColumnInfo->m_pvData) = 0.0;
break;
case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
poColumnInfo->m_pvData = (void*) new VMByteArray;
((VMByteArray*)poColumnInfo->m_pvData)->SetSize(1,1);
m_bShouldBind = false;
break;
// Date/Time family
//
case SQL_DATE:
poColumnInfo->m_pvData = (void*) new SQL_TIMESTAMP_STRUCT;
memset( poColumnInfo->m_pvData, 0, sizeof( SQL_TIMESTAMP_STRUCT ) );
break;
case SQL_TIME:
poColumnInfo->m_pvData = (void*) new SQL_TIME_STRUCT;
memset( poColumnInfo->m_pvData, 0, sizeof( SQL_TIME_STRUCT ) );
break;
case SQL_TIMESTAMP:
poColumnInfo->m_pvData = (void*) new SQL_TIMESTAMP_STRUCT;
memset( poColumnInfo->m_pvData, 0, sizeof( SQL_TIMESTAMP_STRUCT ) );
break;
case SQL_GUID:
poColumnInfo->m_pvData = (void*) new SQLGUID;
memset( poColumnInfo->m_pvData, 0, sizeof( SQLGUID ) );
break;
case SQL_INTERVAL_DAY:
case SQL_INTERVAL_DAY_TO_MINUTE:
case SQL_INTERVAL_HOUR:
case SQL_INTERVAL_DAY_TO_SECOND:
case SQL_INTERVAL_MINUTE:
case SQL_INTERVAL_HOUR_TO_MINUTE:
case SQL_INTERVAL_SECOND:
case SQL_INTERVAL_HOUR_TO_SECOND:
case SQL_INTERVAL_DAY_TO_HOUR:
case SQL_INTERVAL_MINUTE_TO_SECOND:
poColumnInfo->m_pvData = (void*) new VMString;
*((VMString*)poColumnInfo->m_pvData) = "";
break;
// We're in trouble if we arrive here
//
default:
assert( 0 );
return( false );
break;
}
return( true );
}
/* End of function "VMODBC::AllocStorageForColumn"
/*****************************************************************************/
/*****************************************************************************/
/*
FUNCTION NAME: VMODBC::MapColumnSQLTypeToCType
DESCRIPTION: examines the sql data type for the column object and then
marks the column object's c data type accordingly
INPUT: poColumnInfo : pointer to column object to examine and
set
OUTPUT: poColumnInfo : is modified
RETURNS: true if worked, false if not
*/
bool VMODBC::MapColumnSQLTypeToCType( VMColumnInfo* poColumnInfo )
{
switch ( poColumnInfo->m_iSqlDataType )
{
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR:
poColumnInfo->m_iCDataType = SQL_C_CHAR;
break;
// case SQL_NUMERIC:
// poColumnInfo->m_iCDataType = SQL_C_NUMERIC;
// break;
// case SQL_DECIMAL:
case SQL_FLOAT:
poColumnInfo->m_iCDataType = SQL_C_FLOAT;
break;
case SQL_BIGINT:
poColumnInfo->m_iCDataType = SQL_C_CHAR;
break;
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WLONGVARCHAR:
poColumnInfo->m_iCDataType = SQL_C_WCHAR;
break;
case SQL_BIT:
poColumnInfo->m_iCDataType = SQL_C_BIT;
break;
case SQL_TINYINT:
poColumnInfo->m_iCDataType = SQL_C_TINYINT;
break;
case SQL_SMALLINT:
poColumnInfo->m_iCDataType = SQL_C_SHORT;
break;
case SQL_INTEGER:
poColumnInfo->m_iCDataType = SQL_C_LONG;
break;
case SQL_REAL:
poColumnInfo->m_iCDataType = SQL_C_FLOAT;
break;
case SQL_NUMERIC:
// case SQL_FLOAT:
case SQL_DECIMAL:
case SQL_DOUBLE:
poColumnInfo->m_iCDataType = SQL_C_DOUBLE;
break;
case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
poColumnInfo->m_iCDataType = SQL_C_BINARY;
break;
case SQL_DATE:
poColumnInfo->m_iCDataType = SQL_C_TIMESTAMP;
break;
case SQL_TIME:
poColumnInfo->m_iCDataType = SQL_C_TIME;
break;
case SQL_TIMESTAMP:
poColumnInfo->m_iCDataType = SQL_C_TIMESTAMP;
break;
case SQL_GUID:
poColumnInfo->m_iCDataType = SQL_C_GUID;
break;
case SQL_INTERVAL_DAY:
case SQL_INTERVAL_DAY_TO_MINUTE:
case SQL_INTERVAL_HOUR:
case SQL_INTERVAL_DAY_TO_SECOND:
case SQL_INTERVAL_MINUTE:
case SQL_INTERVAL_HOUR_TO_MINUTE:
case SQL_INTERVAL_SECOND:
case SQL_INTERVAL_HOUR_TO_SECOND:
case SQL_INTERVAL_DAY_TO_HOUR:
case SQL_INTERVAL_MINUTE_TO_SECOND:
poColumnInfo->m_iCDataType = SQL_C_CHAR;
break;
// We're in trouble if we arrive here
//
default:
assert( 0 );
poColumnInfo->m_iCDataType = SQL_C_DEFAULT;
return( false );
break;
}
return( true );
}
/* End of function "VMODBC::MapColumnSQLTypeToCType"
/*****************************************************************************/
/*****************************************************************************/
/*
FUNCTION NAME: VMODBC::BindColumn
DESCRIPTION: does the work required to bind the data field in a column
object to the sql driver buffers for direct data exchange
INPUT: poColumnInfo : the column object to bind
OUTPUT: none
RETURNS: true if worked, false if not
*/
bool VMODBC::BindColumn( VMColumnInfo* poColumnInfo )
{
RETCODE nRetCode;
nRetCode = ::SQLBindCol( m_hstmt,
poColumnInfo->m_iColumnIndex,
poColumnInfo->m_iCDataType,
poColumnInfo->m_pvData,
sizeof( poColumnInfo->m_pvData ),
NULL );
if ( RC_NOTSUCCESSFUL( nRetCode ) )
{
DecodeSQLError( nRetCode,
m_hdbc,
m_hstmt,
__FILE__,
__LINE__ );
return( false );
}
return( true );
}
/* End of function "VMODBC::BindColumn"
/*****************************************************************************/
/*****************************************************************************/
/* Check-in history */
/*
*$Log: $
*/
/*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -