RETCODE SQL_API SQLExtendedFetch ( SQLHSTMT pStmt, SQLUSMALLINT pFetchOrientation, SQLINTEGER pFetchOffset, SQLUINTEGER* pRowCountPtr, SQLUSMALLINT* pRowStatusArray ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLExtendedFetch called, Stmt: %d, FO: %d, Offset: %d, Rcount: %d, RowStatus: %d", pStmt, pFetchOrientation, pFetchOffset, pRowCountPtr, pRowStatusArray ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLExtendedFetch is not implemented " ) ); return SQL_ERROR; Long n; __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR ); // free diags _SQLFreeDiag ( _DIAGSTMT ( pStmt ) ); // only fetch next supported if ( pFetchOrientation != SQL_FETCH_NEXT ) { __ODBCPOPMSG ( _ODBCPopMsg ( "SQLExtendedFetch option not supported, FetchOrientation: %d", pFetchOrientation ) ); return SQL_ERROR; } // check if number of rows explicitly specified if ( pFetchOffset <= 0 ) { n = ( ( pODBCStmt ) pStmt )->ARD.RowArraySize; } // use default rowset size as a fallback if ( n <= 0 ) { n = 1; } return _SQLFetch ( ( pODBCStmt ) pStmt, pFetchOrientation, n, pRowCountPtr, pRowStatusArray ); }
/* Kylin uses rest request for query executing, SQLPrepare does not do anything meaningful */ RETCODE SQL_API SQLPrepareW ( SQLHSTMT pStmt, SQLWCHAR* pStmtText, SQLINTEGER pTextLength ) { wchar_t* s; __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLPrepareW called on: %d", pStmt ) ); __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR ); _SQLFreeDiag ( _DIAGSTMT ( pStmt ) ); // precaution if ( pStmtText == NULL || ( pTextLength <= 0 && pTextLength != SQL_NTS ) ) { __ODBCPOPMSG ( _ODBCPopMsg ( "SQLPrepare - bad params" ) ); _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLPrepare", "01000", -1, "SQLPrepare - bad params" ); return SQL_ERROR; } // MANAGE STMT CONTENT // convert to full request, with zero termination ( as well as params - later ) if ( ProcessStmtForParams ( ( pODBCStmt ) pStmt, pStmtText, pTextLength, s ) == BAD ) { return SQL_ERROR; } // release existing stmt contents SQLFreeStmt ( pStmt, SQL_CLOSE ); // replace with new stmt string __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The query being prepared is :" ) ); __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, s ) ); ( ( pODBCStmt ) pStmt )->Stmt = s; ( ( pODBCStmt ) pStmt )->StmtLen = pTextLength; // MARK as prepared // set the flag ( ( pODBCStmt ) pStmt )->Prepared = 1; return SQL_SUCCESS; }
RETCODE SQL_API SQLPrepare ( SQLHSTMT pStmt, SQLCHAR* pStmtText, SQLINTEGER pTextLength ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLPrepare called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLPrepare not implemented, use SQLPrepareW" ) ); return SQL_ERROR; }
RETCODE SQL_API SQLPutData ( SQLHSTMT pStmt, SQLPOINTER pDataPtr, SQLINTEGER pDataSize ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLPutData called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLPutData not implemented" ) ); return SQL_ERROR; }
RETCODE SQL_API SQLFetchScroll ( SQLHSTMT pStatementHandle, SQLSMALLINT pFetchOrientation, SQLINTEGER pFetchOffset ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLFetchScroll called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLFetchScroll not implemented" ) ); return SQL_ERROR; }
eGoodBad GetDateFromString ( const char* pDateStr, struct tagDATE_STRUCT* pDateStruct ) { char val[5]; short x; short day, month; // length of source x = strlen ( pDateStr ); // 10 byte date yyyy-mm-dd, 8 byte date yyyymmdd if ( x == 8 || x == 10 ) { // calc pos of day and month in string if ( x == 8 ) { day = 6; month = 4; } else { day = 8; month = 5; } // convert day value pDateStruct->day = atoi ( pDateStr + day ); // copy and convert month strncpy ( val, pDateStr + month, 2 ); val[2] = 0; pDateStruct->month = atoi ( val ); strncpy ( val, pDateStr, 4 ); val[4] = 0; pDateStruct->year = atoi ( val ); return GOOD; } else { __ODBCPOPMSG ( _ODBCPopMsg ( "Invalid date string for conversion: %s", pDateStr ) ); return BAD; } }
RETCODE SQL_API SQLExecDirectW ( SQLHSTMT pStmt, SQLWCHAR* pStmtText, SQLINTEGER pTextLength ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLExecDirectW called on: %d", pStmt ) ); wchar_t* s; __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR ); _SQLFreeDiag ( _DIAGSTMT ( pStmt ) ); // precaution if ( pStmtText == NULL || ( pTextLength <= 0 && pTextLength != SQL_NTS ) ) { __ODBCPOPMSG ( _ODBCPopMsg ( "SQLExecDirect - bad params" ) ); _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLExecDirectW", "01000", -1, "bad params" ); return SQL_ERROR; } // convert to full request, with zero termination ( as well as params - later ) if ( ProcessStmtForParams ( ( pODBCStmt ) pStmt, ( wchar_t* ) pStmtText, pTextLength, s ) == BAD ) { return SQL_ERROR; } // release existing stmt contents SQLFreeStmt ( pStmt, SQL_CLOSE ); // replace with new stmt string ( ( pODBCStmt ) pStmt )->Stmt = s; ( ( pODBCStmt ) pStmt )->StmtLen = pTextLength; // mark it as prepared ( ( pODBCStmt ) pStmt )->Prepared = 1; // execute RETCODE code = SQLExecute ( pStmt ); __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLExecDirectW exited on with %d", code ) ); return code; }
RETCODE SQL_API SQLEndTran ( SQLSMALLINT pHandleType, SQLHANDLE pHandle, SQLSMALLINT pCompletionType ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLEndTran called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLEndTran not implemented" ) ); return SQL_ERROR; }
RETCODE SQL_API SQLSetPos ( SQLHSTMT pStmt, SQLUSMALLINT pRowNumber, SQLUSMALLINT pOperation, SQLUSMALLINT pLockType ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLSetPos called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLSetPos not implemented" ) ); return SQL_ERROR; }
//Timestamps in text files have to use the format yyyy-mm-dd hh:mm:ss[.f...] eGoodBad GetTimestampFromString ( const char* pStr, struct tagTIMESTAMP_STRUCT* pTimestampStruct ) { char val[10]; short x; short day, month, hour, minute, second, frag; // length of source x = strlen ( pStr ); const char* p = pStr; while ( ( *p != ' ' ) && ( p < val + x ) ) { p++; } if ( ( p - val ) != 8 ) { __ODBCPOPMSG ( _ODBCPopMsg ( "Invalid date string for conversion: %s", pStr ) ); return BAD; } month = 5; day = 8; hour = 11; minute = 14; second = 17; frag = 20; // convert day value strncpy ( val, pStr + day, 2 ); val[2] = 0; pTimestampStruct->day = atoi ( val ); // copy and convert month strncpy ( val, pStr + month, 2 ); val[2] = 0; pTimestampStruct->month = atoi ( val ); //convert year strncpy ( val, pStr, 4 ); val[4] = 0; pTimestampStruct->year = atoi ( val ); //convert hour strncpy ( val, pStr + hour, 2 ); val[2] = 0; pTimestampStruct->hour = atoi ( val ); //convert minute strncpy ( val, pStr + minute, 2 ); val[2] = 0; pTimestampStruct->minute = atoi ( val ); //convert second strncpy ( val, pStr + second, 2 ); val[2] = 0; pTimestampStruct->second = atoi ( val ); if ( x >= 21 ) { pTimestampStruct->fraction = atoi ( pStr + frag ); } else { pTimestampStruct->fraction = 0; } return GOOD; }
// ----------------------------------------------------------------------- // to get param descriptions for a specified bound param // ----------------------------------------------------------------------- RETCODE SQL_API SQLDescribeParam(SQLHSTMT pStmt, SQLUSMALLINT pParamNum, SQLSMALLINT* pDataTypePtr, SQLUINTEGER* pParamSizePtr, SQLSMALLINT* pDecimalDigitsPtr, SQLSMALLINT* pNullablePtr) { __ODBCLOG(_ODBCLogMsg(LogLevel_DEBUG, "SQLDescribeParam called")); __ODBCPOPMSG(_ODBCPopMsg("SQLDescribeParam not implemented")); return SQL_ERROR; }
RETCODE SQL_API SQLNativeSql ( SQLHDBC pConn, SQLCHAR* pInStmtText, SQLINTEGER pInStmtTextLen, SQLCHAR* pOutStmtText, SQLINTEGER pOutStmtTextLen, SQLINTEGER* pOutStmtTextLenPtr ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLNativeSql called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLNativeSql not implemented" ) ); return SQL_ERROR; }
RETCODE SQL_API SQLBrowseConnect ( SQLHDBC pConn, SQLCHAR* InConnectionString, SQLSMALLINT StringLength1, SQLCHAR* OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT* StringLength2Ptr ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLBrowseConnect called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLBrowseConnect - not implemented, use SQLDriverConnect" ) ); return SQL_ERROR; }
RETCODE SQL_API SQLGetData ( SQLHSTMT pStmt, SQLUSMALLINT pColNum, SQLSMALLINT pgtType, SQLPOINTER pDataPtr, SQLINTEGER pDataSize, SQLINTEGER* pDataSizePtr ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetData called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLGetData not implemented" ) ); return SQL_ERROR; }
// ----------------------------------------------------------------------- // to bind a buffer to a parameter marker in an SQL statement // ----------------------------------------------------------------------- RETCODE SQL_API SQLBindParameter(SQLHSTMT pStmt, SQLUSMALLINT pParamNum, SQLSMALLINT pIOType, SQLSMALLINT pValueType, SQLSMALLINT pParamType, SQLUINTEGER pColSize, SQLSMALLINT pDecimalDigits, SQLPOINTER pParamValuePtr, SQLINTEGER pParamValueSize, SQLINTEGER* pParamValueSizePtr) { __ODBCLOG(_ODBCLogMsg(LogLevel_DEBUG, "SQLBindParameter called")); __ODBCPOPMSG(_ODBCPopMsg("SQLBindParameter not implemented")); return SQL_ERROR; }
RETCODE SQL_API SQLConnect ( SQLHDBC pConn, SQLCHAR* pServerName, SQLSMALLINT pServerNameLen, SQLCHAR* pUserName, SQLSMALLINT pUserNameLen, SQLCHAR* pPassword, SQLSMALLINT pPasswordLen ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLConnect called" ) ); __CHK_HANDLE ( pConn, SQL_HANDLE_DBC, SQL_ERROR ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLConnect - not implemented, use SQLDriverConnect" ) ); return SQL_ERROR; _SQLFreeDiag ( _DIAGCONN ( pConn ) ); return ( SQL_SUCCESS ); }
SQLRETURN SQL_API SQLConnectW ( SQLHDBC hdbc, SQLWCHAR* szDSN, SQLSMALLINT cchDSN, SQLWCHAR* szUID, SQLSMALLINT cchUID, SQLWCHAR* szAuthStr, SQLSMALLINT cchAuthStr ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLConnectW called" ) ); __CHK_HANDLE ( hdbc, SQL_HANDLE_DBC, SQL_ERROR ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLConnectW - not implemented, use SQLDriverConnectW" ) ); return SQL_ERROR; _SQLFreeDiag ( _DIAGCONN ( hdbc ) ); return ( SQL_SUCCESS ); }
static eGoodBad PutDataToDlgDSNCfg1 ( pODBCConn pConn, HWND hDlg ) { BOOL x; // precaution if ( !pConn || !hDlg ) { __ODBCPOPMSG ( _ODBCPopMsg ( "PutDataToDlgDSNCfg1 - Bad params" ) ); return BAD; } // server name/IP if ( pConn->Server ) { x = SetDlgItemText ( hDlg, IDC_SERVER, pConn->Server ); } else { x = SetDlgItemText ( hDlg, IDC_SERVER, "" ); } if ( !x ) { return BAD; } // server port if ( pConn->ServerPort ) { x = SetDlgItemInt ( hDlg, IDC_PORT, pConn->ServerPort, FALSE ); } else { x = SetDlgItemInt ( hDlg, IDC_PORT, DEFAULT_PORT, FALSE ); } if ( !x ) { return BAD; } // user name if ( pConn->UserName ) { x = SetDlgItemText ( hDlg, IDC_UID, pConn->UserName ); } else { x = SetDlgItemText ( hDlg, IDC_UID, "" ); } if ( !x ) { return BAD; } // password if ( pConn->Password ) { x = SetDlgItemText ( hDlg, IDC_PWD, pConn->Password ); } else { x = SetDlgItemText ( hDlg, IDC_PWD, "" ); } if ( !x ) { return BAD; } return GOOD; }
static pODBCDiag _SQLGetDiagHandle ( SQLSMALLINT pHandleType, SQLHANDLE pHandle ) { // first extract the diag details switch ( pHandleType ) { case SQL_HANDLE_ENV: return & ( ( ( pODBCEnv ) pHandle )->Diag ); case SQL_HANDLE_DBC: return & ( ( ( pODBCConn ) pHandle )->Diag ); case SQL_HANDLE_STMT: return & ( ( ( pODBCStmt ) pHandle )->Diag ); default: __ODBCPOPMSG ( _ODBCPopMsg ( "SQLGetDiagRec was called with desciptor handle" ) ); return NULL; // ??? support for desc diag not available now } }
eGoodBad _SQLCheckDataType ( Word pDataType ) { switch ( pDataType ) { case SQL_CHAR : case SQL_VARCHAR : case SQL_WCHAR : case SQL_WVARCHAR : case SQL_C_SSHORT : case SQL_C_USHORT : case SQL_SMALLINT : case SQL_C_SLONG : case SQL_C_ULONG : case SQL_INTEGER : case SQL_NUMERIC : case SQL_DECIMAL : case SQL_FLOAT : case SQL_REAL : case SQL_DOUBLE : case SQL_TYPE_DATE : case SQL_TYPE_TIME : case SQL_TYPE_TIMESTAMP : case SQL_BIT : case SQL_DEFAULT : case SQL_C_SBIGINT : case SQL_C_UBIGINT : case SQL_C_TINYINT : case SQL_C_STINYINT : case SQL_C_UTINYINT : return GOOD; default : __ODBCPOPMSG ( _ODBCPopMsg ( "_SQLCheckDataType: Unknown data type: %d", pDataType ) ); return BAD; } }
RETCODE SQL_API SQLDriverConnect ( SQLHDBC pConn, SQLHWND pWndHandle, SQLCHAR* pInConnStr, SQLSMALLINT pInConnStrLen, SQLCHAR* pOutConnStr, SQLSMALLINT pOutConnStrLen, SQLSMALLINT* pOutConnStrLenPtr, SQLUSMALLINT pDriverCompletion ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The window handle is %d, the driver completion flag is %d", pWndHandle, pDriverCompletion ) ); pODBCConn pgConn = ( pODBCConn ) pConn; bool f; bool flgDriver, flgDSN; // flags for knowing if these key present in string bool flgServer, flgPort, flgUID, flgPWD, flgProj; // flags for knowing if these key present in string Word i, n; Word iKVInputPairs; // no of key value pairs as input Word iDriverPos, iDSNPos; // ??? can be eliminated by optimization of code Word iServerPos, iPortPos, iUIDPos, iPWDPos, iProjPos; // ??? can be eliminated by optimization of code struct ODBCKV* KVInput; // key value as input via function param struct ODBCKV* KV; // generic, temp if ( !pInConnStr ) { __ODBCPOPMSG ( _ODBCPopMsg ( "SQLDriverConnect: pInConnStr is required" ) ); return SQL_ERROR; } else { //__ODBCLOG(_ODBCLogMsg(LogLevel_DEBUG,"The passed-in Connection Str is %s",(char*)pInConnStr)); } __CHK_HANDLE ( pConn, SQL_HANDLE_DBC, SQL_ERROR ); _SQLFreeDiag ( _DIAGCONN ( pConn ) ); // caller safe if ( pOutConnStr ) { *pOutConnStr = 0; } if ( pOutConnStrLenPtr ) { *pOutConnStrLenPtr = 0; } // initializations KVInput = NULL; flgServer = FALSE; flgPort = FALSE; flgUID = FALSE; flgPWD = FALSE; flgProj = FALSE; // check if an in-string has been specified if ( pInConnStr ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "Parsing the in str" ) ); // split into key-value pairs if ( CvtStrToKeyValues ( ( StrPtr ) pInConnStr, pInConnStrLen, &iKVInputPairs, &KVInput ) != GOOD ) { return SQL_ERROR; } // first check if dsn keyword is present flgDSN = FindInKeyValues ( "DSN", NULL, KVInput, iKVInputPairs, &iDSNPos ); // look for driver only if DSN is absent else Driver is always ignored flgDriver = ( flgDSN ) ? FALSE : FindInKeyValues ( "DRIVER", NULL, KVInput, iKVInputPairs, &iDriverPos ); // if DSN is to be used, fetch its set of key values if ( flgDSN ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The in str is a dsn string" ) ); //connect by dsn SetCurrentDSN ( ( char* ) pInConnStr, "SQLDriverConnect" ); if ( LoadODBCINIDataToConn ( pgConn ) != GOOD ) { return SQL_ERROR; } } else if ( flgDriver ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The in str is a driver string" ) ); /************* debug for ( i = 0, n = iKVInputPairs, KV = KVInput; i < n; i++ ) fprintf ( stderr, "Index: %d, Key: %s, Value: %s\n", i, KV[i].key ? KV[i].key : "(nokey)", KV[i].value ? KV[i].value : "(no value)" ); *********/ // loop to parse both input key-values and DSN key-values & feed into struct for ( i = 0, n = iKVInputPairs, KV = KVInput; i < n; i++ ) { if ( !flgServer ) { flgServer = FindInKeyValues ( "SERVER", NULL, KV, n, &iServerPos ); if ( flgServer ) { CreateAndSetConnProp ( ( pODBCConn ) pConn, CONN_PROP_SERVER, KV[iServerPos].value ); } } if ( !flgPort ) { flgPort = FindInKeyValues ( "PORT", NULL, KV, n, &iPortPos ); if ( flgPort ) { CreateAndSetConnProp ( ( pODBCConn ) pConn, CONN_PROP_PORT, KV[iPortPos].value ); } } if ( !flgUID ) { flgUID = FindInKeyValues ( "UID", NULL, KV, n, &iUIDPos ); if ( flgUID ) { CreateAndSetConnProp ( ( pODBCConn ) pConn, CONN_PROP_UID, KV[iUIDPos].value ); __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "Log in as User : %s ", KV[iUIDPos].value ) ); } } if ( !flgPWD ) { flgPWD = FindInKeyValues ( "PWD", NULL, KV, n, &iPWDPos ); if ( flgPWD ) { CreateAndSetConnProp ( ( pODBCConn ) pConn, CONN_PROP_PWD, KV[iPWDPos].value ); } } if ( !flgProj ) { flgProj = FindInKeyValues ( "PROJECT", NULL, KV, n, &iProjPos ); if ( flgProj ) { CreateAndSetConnProp ( ( pODBCConn ) pConn, CONN_PROP_PROJECT, KV[iProjPos].value ); } } } } else { _SQLPutDiagRow ( SQL_HANDLE_DBC, pConn, "SQLDriverConnectW", "HY000", 1045, "Only DSN or driver connect is allowed" ); __ODBCPOPMSG ( _ODBCPopMsg ( "Only DSN or driver connect is allowed, instead of %s", pInConnStr ) ); return SQL_ERROR; } FreeGenODBCKeyValues ( KVInput, iKVInputPairs ); delete[] KVInput; } else if ( pDriverCompletion == SQL_DRIVER_NOPROMPT ) { // check if no-prompt forced __ODBCPOPMSG ( _ODBCPopMsg ( "No connection string && no prompt specified" ) ); _SQLPutDiagRow ( SQL_HANDLE_DBC, pConn, "SQLDriverConnectW", "HY000", 1045, "Access denied. (using UID: NO , using password: NO)" ); return SQL_ERROR; } RETCODE ret; // check if prompt required ie any info is missing if ( flgDriver && ( !flgServer || !flgPort || !flgUID || !flgPWD || !flgProj ) ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "Connection info imcomplete, prompt for input..." ) ); if ( flgUID && !flgPWD && pDriverCompletion == SQL_DRIVER_NOPROMPT ) { _SQLPutDiagRow ( SQL_HANDLE_DBC, pConn, "SQLDriverConnectW", "HY000", 1045, "Access denied for user 'root'@'kylin-tableau-clean.com' (using password: NO)" ); __ODBCLOG ( _ODBCLogMsg ( LogLevel_ERROR, "UID present but PWD absent, guessing it's on Tableau Server, return SQL ERROR" ) ); return SQL_ERROR; } //connect by driver // fetch entire connection information thru dialogs switch ( PromptForConnInfo ( pConn ) ) { case 0: // user-cancelled return SQL_NO_DATA_FOUND; default: break; } ret = SQL_SUCCESS; } else { ret = TryFetchMetadata ( pgConn ) ; if ( ret == SQL_ERROR ) { return ret; } } // OUT CONN STRING // build the out-connection string if required if ( pOutConnStr && pOutConnStrLen > 0 && pOutConnStrLenPtr ) { if ( flgDriver ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "Building out str..." ) ); // build the out conn string using key value pairs f = BuildConnStr ( ( StrPtr ) pOutConnStr, pOutConnStrLen, ( pODBCConn ) pConn, NULL, 0, NULL, 0 ); if ( !f ) { _SQLPutDiagRow ( SQL_HANDLE_DBC, pConn, "SQLDriverConnectW", "HY000", 1045, "Out connection string not complete" ); } } else { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "Copy in str to out str" ) ); strcpy ( ( char* ) pOutConnStr, ( char* ) pInConnStr ); } *pOutConnStrLenPtr = strlen ( ( StrPtr ) pOutConnStr ); __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The Length of Out Conn Str is %d", *pOutConnStrLenPtr ) ); } else { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "skip writing to the out put string" ) ); } return ret; }
eGoodBad SetConnProp ( pODBCConn pConn, Word pPropID, void* pPropValue ) { // note // this function does not create a copy of char data // it just transfers the pointer // numeric data is assumed to be a pointer // check property switch ( pPropID ) { case CONN_PROP_SERVER: // check if a new value has to be put if ( pPropValue ) { copyTrimmed ( & ( ( char* ) pConn->Server ), ( char* ) pPropValue ); } if ( pConn->Server == NULL || strlen ( pConn->Server ) == 0 ) { __ODBCPopMsg ( "Server cannot be empty" ); return BAD; } __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The server is set to %s", pConn->Server ) ); break; case CONN_PROP_PORT: // numeric values are passed as pointer to value if ( pPropValue ) { pConn->ServerPort = * ( ( ULong* ) pPropValue ); } if ( pConn->ServerPort == 0 ) { __ODBCPopMsg ( "ServerPort cannot be 0" ); return BAD; } __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The port is set to %d", pConn->ServerPort ) ); break; case CONN_PROP_UID: // check if a new value has to be put if ( pPropValue ) { copyTrimmed ( & ( ( char* ) pConn->UserName ), ( char* ) pPropValue ); } if ( pConn->UserName == NULL || strlen ( pConn->UserName ) == 0 ) { __ODBCPopMsg ( "UserName cannot be empty" ); return BAD; } __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The uid is set to %s", pConn->UserName ) ); break; case CONN_PROP_PWD: // check if a new value has to be put if ( pPropValue ) { copyTrimmed ( & ( ( char* ) pConn->Password ), ( char* ) pPropValue ); } if ( pConn->Password == NULL || strlen ( pConn->Password ) == 0 ) { __ODBCPopMsg ( "Password cannot be empty" ); return BAD; } break; case CONN_PROP_PROJECT: // check if a new value has to be put if ( pPropValue ) { copyTrimmed ( & ( ( char* ) pConn->Project ), ( char* ) pPropValue ); } if ( pConn->Project == NULL || strlen ( pConn->Project ) == 0 ) { __ODBCPopMsg ( "Project cannot be empty" ); return BAD; } break; default: __ODBCPOPMSG ( _ODBCPopMsg ( "Bad connection property" ) ); return BAD; } return GOOD; }
static eGoodBad GetDataFromDlgDSNCfg1 ( HWND hDlg, pODBCConn pConn ) { Long x; std::unique_ptr<char[]> n = NULL; eGoodBad status; // note // no error handling is currently being done for // GetDlgItemText/GetDlgItemInt/SetConnProp // generally should not be a problem // precaution if ( !pConn || !hDlg ) { __ODBCPOPMSG ( _ODBCPopMsg ( "GetDataFromDlgDSNCfg1 - Bad params" ) ); return BAD; } ////// server name/IP // get length of input text x = SendDlgItemMessage ( hDlg, IDC_SERVER, EM_LINELENGTH, 0, 0 ); if ( x > 0 ) { n = make_unique_str ( x ); // allocate space for holding the text GetDlgItemText ( hDlg, IDC_SERVER, n.get(), x + 1 ); // get text from dialog } else { n = NULL; } // no input // set value in struct status = SetConnProp ( pConn, CONN_PROP_SERVER, n.get() ); if ( status == BAD ) { return BAD; } ///// Port // get value x = GetDlgItemInt ( hDlg, IDC_PORT, NULL, FALSE ); // set value in struct status = SetConnProp ( pConn, CONN_PROP_PORT, &x ); if ( status == BAD ) { return BAD; } ////// User name // get length x = SendDlgItemMessage ( hDlg, IDC_UID, EM_LINELENGTH, 0, 0 ); if ( x > 0 ) { // allocate space n = make_unique_str ( x ); // allocate space for holding the text GetDlgItemText ( hDlg, IDC_UID, n.get(), x + 1 ); } else { n = NULL; } // set value in struct status = SetConnProp ( pConn, CONN_PROP_UID, n.get() ); if ( status == BAD ) { return BAD; } ////// Password // get length x = SendDlgItemMessage ( hDlg, IDC_PWD, EM_LINELENGTH, 0, 0 ); if ( x > 0 ) { // allocate space n = make_unique_str ( x ); // allocate space for holding the text GetDlgItemText ( hDlg, IDC_PWD, n.get(), x + 1 ); } else { n = NULL; } // set value in struct status = SetConnProp ( pConn, CONN_PROP_PWD, n.get() ); if ( status == BAD ) { return BAD; } return GOOD; }
RETCODE SQL_API SQLMoreResults ( HSTMT pStmt ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLMoreResults called" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLMoreResults not implemented" ) ); return SQL_ERROR; }
void _ODBCLogStart ( void ) { OutputDebugString ( "ODBCLogStart is called\n" ); // for DBMON StrPtr t; time_t ltime; // check if log file is open if ( gLogFile == -1 ) { OutputDebugString ( "Try to init the log file\n" ); // for DBMON if ( GetFileAttributes ( "c:\\kylin" ) == INVALID_FILE_ATTRIBUTES ) { if ( !CreateDirectory ( "c:\\kylin", NULL ) ) { if ( GetLastError() == ERROR_ALREADY_EXISTS ) { // directory already exists //good OutputDebugString ( "Log folder already exist, ? \n" ); // for DBMON } else { // creation failed due to some other reason OutputDebugString ( "Failed to creat log folder\n" ); // for DBMON throw; } } } else { OutputDebugString ( "Log folder already exist\n" ); // for DBMON } bool debugMode = fileExist ( "c:\\kylin\\debug" ) || fileExist ( "c:\\kylin\\debug.txt" ); if ( debugMode ) { currentLogLevel = LogLevel_DEBUG; OutputDebugString ( "Debug mode is on" ); // for DBMON } OutputDebugString ( "Try to open log file\n" ); // for DBMON time_t now = time ( 0 ); struct tm tstruct; char buffer[100]; tstruct = *localtime ( &now ); strftime ( buffer, 100, "%Y-%m-%d.%X", &tstruct ); for ( unsigned int i = 0 ; i < strlen ( buffer ); i++ ) { if ( buffer[i] == '.' || buffer[i] == ':' ) { buffer[i] = '-'; } } char file[256]; file[0] = '\0'; strcat ( file, "c:\\kylin\\odbc-" ); strcat ( file, buffer ); strcat ( file, ".log" ); printf ( file ); gLogFile = _open ( file, _O_CREAT | _O_APPEND | _O_RDWR, _S_IWRITE ); OutputDebugString ( "Finish to open log file\n" ); // for DBMON if ( gLogFile == -1 ) { OutputDebugString ( "Open Log file failed.\n" ); // for DBMON } else { OutputDebugString ( "Open Log file succeed, logs are written to log file now.\n" ); // for DBMON } // set the log start time time ( <ime ); t = ctime ( <ime ); _write ( gLogFile, "Log start: ", strlen ( "Log start: " ) ); _write ( gLogFile, t, strlen ( t ) ); _write ( gLogFile, "\n", 1 ); //if(t!=NULL) //delete[] t; } // check if file opened succesfully if ( gLogFile != -1 ) { ++ gLogUsage; } // increment log usage else { __ODBCPOPMSG ( ( __ODBCPopMsg ( "Log failed" ) ) ); } }
RETCODE SQL_API SQLGetDiagFieldW ( SQLSMALLINT pHandleType, SQLHANDLE pHandle, SQLSMALLINT pRecNum, SQLSMALLINT pFldID, SQLPOINTER pDataPtr, SQLSMALLINT pDataSize, SQLSMALLINT* pDataSizePtr ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetDiagFieldW called, HandleType: %d, RecNum: %d, InfoType: %d, BufLen: %d", pHandleType, pRecNum, pFldID, pDataSize ) ); bool c; pODBCDiag diag; pODBCDiagRow diagrow; SQLSMALLINT dummySize = 0;//used when pDataSizePtr is NULL if ( pDataSizePtr == NULL ) { pDataSizePtr = &dummySize; } __CHK_HANDLE ( pHandle, pHandleType, SQL_ERROR ); diag = _SQLGetDiagHandle ( pHandleType, pHandle ); if ( !diag ) { return SQL_ERROR; } // field may be in diag header c = FALSE; // check the field type - header fields switch ( pFldID ) { case SQL_DIAG_CURSOR_ROW_COUNT: case SQL_DIAG_ROW_COUNT: // rows affected by update/insert if ( pHandleType == SQL_HANDLE_STMT ) { if ( pDataPtr ) { * ( ( SQLLEN* ) pDataPtr ) = ( pHandle ) ? ( ( pODBCStmt ) pHandle )->RowCount : 0; } return SQL_SUCCESS; } else { return SQL_ERROR; } case SQL_DIAG_DYNAMIC_FUNCTION: if ( pHandleType == SQL_HANDLE_STMT ) { _SQLCopyWCharDataW ( diag, pDataPtr, pDataSize, pDataSizePtr, 16, ( ( pODBCStmt ) pHandle )->Stmt, ( ( pODBCStmt ) pHandle )->StmtLen ); return SQL_SUCCESS; } else { return SQL_ERROR; } return SQL_ERROR; case SQL_DIAG_DYNAMIC_FUNCTION_CODE: if ( pHandleType == SQL_HANDLE_STMT ) { if ( pDataPtr ) { * ( ( StrPtr ) pDataPtr ) = 1; } // ??? debug test only _SQLCopyWCharDataW ( diag, pDataPtr, pDataSize, pDataSizePtr, 16, ( ( pODBCStmt ) pHandle )->Stmt, ( ( ( pODBCStmt ) pHandle )->StmtLen ) ); return SQL_SUCCESS; } else { return SQL_ERROR; } case SQL_DIAG_NUMBER: { // number of rows in diag Word i; // check if there r any diag rows if ( diag->DiagRows ) { // loop to count the rows for ( i = 1, diagrow = diag->DiagRows; diagrow != NULL; diagrow = diagrow->Next, i ++ ); if ( pDataPtr ) { * ( ( Word* ) pDataPtr ) = i; } } else if ( pDataPtr ) { * ( ( Word* ) pDataPtr ) = 0; } return SQL_SUCCESS; } break; default: c = TRUE; } // check if only a header field was required if ( c == FALSE ) { return SQL_SUCCESS; } // check row and buffer if ( pRecNum <= 0 || pDataSize < 0 ) { __ODBCPOPMSG ( _ODBCPopMsg ( "GetDiagField xxx1" ) ); return SQL_ERROR; } // now get the desired row first if ( ( diagrow = _SQLGetDiagRowX ( diag, pRecNum ) ) == NULL ) { return SQL_NO_DATA; } // now set info as per the field required switch ( pFldID ) { case SQL_DIAG_CLASS_ORIGIN: _SQLCopyWCharData ( diag, pDataPtr, pDataSize, pDataSizePtr, 16, "ODBC 3.0", -1 ); break; case SQL_DIAG_COLUMN_NUMBER: // needs to be implemented if ( pDataPtr ) { * ( ( Long* ) pDataPtr ) = diagrow->Col; } break; case SQL_DIAG_CONNECTION_NAME: if ( pDataPtr ) { * ( ( char* ) pDataPtr ) = 0; } if ( pDataSizePtr ) { *pDataSizePtr = 0; } break; case SQL_DIAG_MESSAGE_TEXT: return _SQLCopyWCharData ( diag, pDataPtr, pDataSize, pDataSizePtr, 16, diagrow->Msg, -1 ); case SQL_DIAG_NATIVE: if ( pDataPtr ) { * ( ( Long* ) pDataPtr ) = diagrow->NativeErrorCode; } if ( pDataSizePtr ) { *pDataSizePtr = 0; } break; case SQL_DIAG_ROW_NUMBER: // needs to be implemented if ( pDataPtr ) { * ( ( Long* ) pDataPtr ) = diagrow->Row; } break; case SQL_DIAG_SERVER_NAME: { CStrPtr svr; // if handle type is connection if ( pHandleType == SQL_HANDLE_DBC ) { svr = ( ( pODBCConn ) pHandle )->Server; } else if ( pHandleType == SQL_HANDLE_STMT && ( ( pODBCStmt ) pHandle )->Conn ) { svr = ( ( pODBCStmt ) pHandle )->Conn->Server; } else { svr = ""; } return _SQLCopyWCharData ( diag, pDataPtr, pDataSize, pDataSizePtr, 16, svr, -1 ); } case SQL_DIAG_SQLSTATE: return _SQLCopyWCharData ( diag, pDataPtr, pDataSize, pDataSizePtr, 16, diagrow->State, -1 ); case SQL_DIAG_SUBCLASS_ORIGIN: // ??? dummy return _SQLCopyWCharData ( diag, pDataPtr, pDataSize, pDataSizePtr, 16, diagrow->State, -1 ); default: __ODBCPOPMSG ( _ODBCPopMsg ( "SQLGetDiagField called, HandleType: %d, RecNum: %d, InfoType: %d, BufLen: %d", pHandleType, pRecNum, pFldID, pDataSize ) ); return SQL_ERROR; } return SQL_SUCCESS; }
eGoodBad _SQLSetDataType ( pODBCDiag pDiag, Word pFldID, Word pFldValue, Word* pVerboseDataType, Word* pConciseDataType, Word* pDateTimeIntervalCode ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLSetDataType is called, pFldID:%d, pFldValue:%d", pFldID, pFldValue ) ); // note // the data type, concise data type, datetime interval code r interdependent // setting one of these changes the other. Word concise_type; Word verbose_type; Word datetime_interval; // initial values concise_type = pConciseDataType ? *pConciseDataType : 0; verbose_type = pVerboseDataType ? *pVerboseDataType : 0; datetime_interval = pDateTimeIntervalCode ? *pDateTimeIntervalCode : 0; // check if concise type has been specified if ( pFldID == SQL_DESC_CONCISE_TYPE ) { // set the concise type itself first concise_type = pFldValue; // based on concise type set the verbose type and datetime interval switch ( concise_type ) { case SQL_TYPE_DATE : //case SQL_C_TYPE_DATE: verbose_type = SQL_DATETIME; datetime_interval = SQL_CODE_DATE; break; case SQL_TYPE_TIME : //case SQL_C_TYPE_TIME: verbose_type = SQL_DATETIME; datetime_interval = SQL_CODE_TIME; break; case SQL_TYPE_TIMESTAMP : //case SQL_C_TYPE_TIMESTAMP: verbose_type = SQL_DATETIME; datetime_interval = SQL_CODE_TIMESTAMP; break; case SQL_INTERVAL_MONTH : //case SQL_C_INTERVAL_MONTH: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_MONTH; break; case SQL_INTERVAL_YEAR : //case SQL_C_INTERVAL_YEAR: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_YEAR; break; case SQL_INTERVAL_YEAR_TO_MONTH : //case SQL_C_INTERVAL_YEAR_TO_MONTH: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_YEAR_TO_MONTH; break; case SQL_INTERVAL_DAY : //case SQL_C_INTERVAL_DAY: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_DAY; break; case SQL_INTERVAL_HOUR : //case SQL_C_INTERVAL_HOUR: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_HOUR; break; case SQL_INTERVAL_MINUTE : //case SQL_C_INTERVAL_MINUTE: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_MINUTE; break; case SQL_INTERVAL_SECOND : //case SQL_C_INTERVAL_SECOND: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_SECOND; break; case SQL_INTERVAL_DAY_TO_HOUR : //case SQL_C_INTERVAL_DAY_TOHOUR: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_DAY_TO_HOUR; break; case SQL_INTERVAL_DAY_TO_MINUTE : //case SQL_C_INTERVAL_DAY_TO_MINUTE: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_DAY_TO_MINUTE; break; case SQL_INTERVAL_DAY_TO_SECOND : //case SQL_C_INTERVAL_DAY_TO_SECOND: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_DAY_TO_SECOND; break; case SQL_INTERVAL_HOUR_TO_MINUTE : //case SQL_C_INTERVAL_HOUR_TO_MINUTE: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_HOUR_TO_MINUTE; break; case SQL_INTERVAL_HOUR_TO_SECOND : //case SQL_C_INTERVAL_HOUR_TO_SECOND: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_HOUR_TO_SECOND; break; case SQL_INTERVAL_MINUTE_TO_SECOND : //case SQL_C_INTERVAL_MINUTE_TO_SECOND: verbose_type = SQL_INTERVAL; datetime_interval = SQL_CODE_MINUTE_TO_SECOND; break; default : // check if data type if valid if ( _SQLCheckDataType ( concise_type ) != GOOD ) { return BAD; } // concise type does not relate to datetime or interval // hence both concise and verbose type r equal verbose_type = concise_type; datetime_interval = 0; } } // check if verbose data type is being set else if ( pFldID == SQL_DESC_TYPE ) { // set the verbose type itself first verbose_type = pFldValue; // based on verbose type & datetime interval code determine concise type switch ( verbose_type ) { case SQL_INTERVAL : switch ( datetime_interval ) { case SQL_CODE_DATE : concise_type = SQL_TYPE_DATE; break; case SQL_CODE_TIME : concise_type = SQL_TYPE_TIME; break; case SQL_CODE_TIMESTAMP : concise_type = SQL_TYPE_TIMESTAMP; break; default : // interval should have been set __ODBCPOPMSG ( _ODBCPopMsg ( "_SQLSetDataType: Interval code not yet set for SQL_INTERVAL" ) ); return BAD; } break; case SQL_DATETIME : switch ( datetime_interval ) { case SQL_CODE_MONTH : concise_type = SQL_INTERVAL_MONTH; break; case SQL_CODE_YEAR : concise_type = SQL_INTERVAL_YEAR; break; case SQL_CODE_YEAR_TO_MONTH : concise_type = SQL_INTERVAL_YEAR_TO_MONTH; break; case SQL_CODE_DAY : concise_type = SQL_INTERVAL_DAY; break; case SQL_CODE_HOUR : concise_type = SQL_INTERVAL_HOUR; break; case SQL_CODE_MINUTE : concise_type = SQL_INTERVAL_MINUTE; break; case SQL_CODE_SECOND : concise_type = SQL_INTERVAL_SECOND; break; case SQL_CODE_DAY_TO_HOUR : concise_type = SQL_INTERVAL_DAY_TO_HOUR; break; case SQL_CODE_DAY_TO_MINUTE : concise_type = SQL_INTERVAL_DAY_TO_MINUTE; break; case SQL_CODE_DAY_TO_SECOND : concise_type = SQL_INTERVAL_DAY_TO_SECOND; break; case SQL_CODE_HOUR_TO_MINUTE : concise_type = SQL_INTERVAL_HOUR_TO_MINUTE; break; case SQL_CODE_HOUR_TO_SECOND : concise_type = SQL_INTERVAL_HOUR_TO_SECOND; break; case SQL_CODE_MINUTE_TO_SECOND : concise_type = SQL_INTERVAL_MINUTE_TO_SECOND; break; default : // interval should have been set __ODBCPOPMSG ( _ODBCPopMsg ( "_SQLSetDataType: Interval code not yet set for SQL_DATETIME" ) ); return BAD; } break; default : // check if data type if valid if ( _SQLCheckDataType ( verbose_type ) != GOOD ) { return BAD; } // verbose type does not relate to datetime or interval // hence both concise and verbose type r equal concise_type = verbose_type; datetime_interval = 0; break; } } else if ( pFldID == SQL_DESC_DATETIME_INTERVAL_CODE ) { // check if date interval code is valid if ( _SQLCheckIntervalCode ( pFldValue ) != GOOD ) { return BAD; } // set the datetime interval code, autonomously datetime_interval = pFldValue; } // unknown field to set else { __ODBCPOPMSG ( _ODBCPopMsg ( "_SQLSetDataType: Unknown field type" ) ); return BAD; } // pass back values to caller if ( pVerboseDataType ) { *pVerboseDataType = verbose_type; } if ( pConciseDataType ) { *pConciseDataType = concise_type; } if ( pDateTimeIntervalCode ) { *pDateTimeIntervalCode = datetime_interval; } return GOOD; }
RETCODE SQL_API SQLBulkOperations ( SQLHSTMT pStmt, SQLUSMALLINT pOperation ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLBulkOperations called\n" ) ); __ODBCPOPMSG ( _ODBCPopMsg ( "SQLBulkOperations not implemented" ) ); return SQL_ERROR; }
//mhb TODO, check if the sqltype defined here match from c# RETCODE SQL_API _SQLColConvert ( pODBCStmt pStmt, void* pTgtDataPtr, Long* pTgtDataSizePtr, const wchar_t* pSrcColData, pARDItem pARDCol, bool isSigned ) { //check out this for SQL data type to C data type mapping //http://msdn.microsoft.com/en-us/library/ms714556(v=vs.85).aspx // note // this function actually determines the conversion // required to transfer the data Word pSrcDataType = pARDCol->SrcDataType; Word pTgtDataType = pARDCol->DataConciseType; Long pTgtDataSize = pARDCol->DataSize; __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLColConvert called" ) ); __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The SrcDataType is %d, the TgtDataType is %d, the TgtDataSize is %d", pSrcDataType, pTgtDataType, pTgtDataSize ) ); // TARGET TYPE IS LEFT TO OUR DRIVER // check if target type is open if ( pTgtDataType == SQL_DEFAULT ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "pTgtDataType is SQL_DEFAULT, use default type mapping." ) ); // determine targettype based on data-source type // check out this http://msdn.microsoft.com/en-us/library/ms716298(v=vs.85).aspx for default type mapping switch ( pSrcDataType ) { case SQL_CHAR: pTgtDataType = SQL_C_CHAR; break; case SQL_VARCHAR: pTgtDataType = SQL_C_CHAR; break; case SQL_WCHAR: pTgtDataType = SQL_C_WCHAR; break; case SQL_WVARCHAR: pTgtDataType = SQL_C_WCHAR; break; case SQL_DECIMAL: pTgtDataType = SQL_C_CHAR; break; case SQL_BIT: pTgtDataType = SQL_C_BIT; break; case SQL_TINYINT: if ( isSigned ) { pTgtDataType = SQL_C_STINYINT; } else { pTgtDataType = SQL_C_UTINYINT; } break; case SQL_SMALLINT: if ( isSigned ) { pTgtDataType = SQL_C_SSHORT; } else { pTgtDataType = SQL_C_USHORT; } break; case SQL_INTEGER: if ( isSigned ) { pTgtDataType = SQL_C_SLONG; } else { pTgtDataType = SQL_C_ULONG; } break; case SQL_BIGINT: if ( isSigned ) { pTgtDataType = SQL_C_SBIGINT; } else { pTgtDataType = SQL_C_UBIGINT; } break; case SQL_FLOAT: pTgtDataType = SQL_C_FLOAT; break; case SQL_DOUBLE: pTgtDataType = SQL_C_DOUBLE; break; case SQL_TYPE_DATE: pTgtDataType = SQL_C_CHAR; break; case SQL_TYPE_TIME: pTgtDataType = SQL_C_CHAR; break; case SQL_TYPE_TIMESTAMP: pTgtDataType = SQL_C_CHAR; break; //case SQL_C_SLONG: //case SQL_C_ULONG: // unsigned long //case SQL_C_USHORT: //case SQL_C_SSHORT: //case SQL_NUMERIC: //case SQL_REAL: // pTgtDataType = pSrcDataType; // break; default: __ODBCPOPMSG ( _ODBCPopMsg ( "The data type %d not implemented", pSrcDataType ) ); return SQL_ERROR; break; } } else { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "pTgtDataType is NOT SQL_DEFAULT, it is %d", pTgtDataType ) ); } // TARGET TYPE IS CHAR // as an optimization, check if the application // or target data type is char. since the data from // server is already in char format. the data can // easily be transferred without incurring any // conversion overhead unique_ptr<char[]> pTextInAnsi ( wchar2char ( pSrcColData ) ); // check if char type if ( pTgtDataType == SQL_CHAR || pTgtDataType == SQL_VARCHAR ) { // only in case of src data being bool a conversion is required if ( pSrcDataType == SQL_BIT ) { // prepare a converted single char bool string Char src[2]; if ( pTextInAnsi.get() == NULL ) { src[0] = '0'; } else { src[0] = ( pTextInAnsi.get() [0] == 'T' || pTextInAnsi.get() [0] == '1' || pTextInAnsi.get() [0] == 't' ) ? '1' : '0'; } src[1] = 0; // transfer the bool string return _SQLCopyCharData ( _DIAGSTMT ( pStmt ), pTgtDataPtr, pARDCol->DataSize, pTgtDataSizePtr, 32, src, -1 ); } else { // transfer the string as it is return _SQLCopyCharData ( _DIAGSTMT ( pStmt ), pTgtDataPtr, pARDCol->DataSize, pTgtDataSizePtr, 32, pTextInAnsi.get(), -1 ); } } if ( pTgtDataType == SQL_WCHAR || pTgtDataType == SQL_WVARCHAR ) { return _SQLCopyWCharDataW ( _DIAGSTMT ( pStmt ), pTgtDataPtr, pARDCol->DataSize, pTgtDataSizePtr, 32, pSrcColData, -1 ); } // TARGET TYPE IS NOT CHAR // try using a numeric conversion switch ( _SQLCopyNumData ( _DIAGSTMT ( pStmt ), pTgtDataPtr, pTgtDataType, pTextInAnsi.get(), pSrcDataType , pTgtDataSizePtr ) ) { case -1: return SQL_ERROR; case 0: return SQL_SUCCESS; default: break; } // try using a date/time conversion switch ( _SQLCopyDateTimeData ( _DIAGSTMT ( pStmt ), pTgtDataPtr, pTgtDataType, pTextInAnsi.get(), pSrcDataType ) ) { case -1: return SQL_ERROR; case 0: return SQL_SUCCESS; default: break; } // try using SQL_BIT data type ie bool if ( pTgtDataType == SQL_BIT ) { __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "the target data type is SQL_C_BIT" ) ); // prepare a converted single char bool string if ( pTextInAnsi.get() == NULL ) { * ( ( char* ) pTgtDataPtr ) = 0; } else { * ( ( char* ) pTgtDataPtr ) = ( pTextInAnsi.get() [0] == 'T' || pTextInAnsi.get() [0] == '1' || pTextInAnsi.get() [0] == 't' ) ? 1 : 0; } return SQL_SUCCESS; } // error condition __ODBCPOPMSG ( _ODBCPopMsg ( "_SQLColConvert - Unknown data type, Target: %d, Source: %d", pTgtDataType, pSrcDataType ) ); _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "_SQLColConvert", "01000", -1, "Unknown data type, Target: %d, Source: %d", pTgtDataType, pSrcDataType ); return SQL_ERROR; }
RETCODE _SQLColAttribute_basic ( SQLHSTMT pStmt, SQLUSMALLINT pColNum, SQLUSMALLINT pFldID, SQLPOINTER pDataPtr, SQLSMALLINT pDataSize, SQLSMALLINT* pDataSizePtr, // in bytes SQLPOINTER pNumValuePtr ,// integer bool isANSI ) { //if returned data is numeric, feed this Long n; SQLResponse* ird; pIRDItem col; __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR ); // free diags _SQLFreeDiag ( _DIAGSTMT ( pStmt ) ); // precaution if ( pColNum == 0 ) { _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLColAttribute", "01000", -1, "bad params" ); return SQL_ERROR; } // get the row descriptor obtained with response ird = ( ( ( pODBCStmt ) pStmt )->IRD ).RowDesc.get(); // check if ( ird == NULL ) { _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLColAttribute", "01000", -1, "No resultset or no col descriptors" ); return SQL_ERROR; } // find the xth element/col col = _SQLGetIRDItem ( & ( ( ( pODBCStmt ) pStmt )->IRD ), pColNum ); // check if ( col == NULL ) { _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLColAttribute", "01000", -1, "Invalid col num" ); return SQL_ERROR; } // get value from descriptor as per field type switch ( pFldID ) { // numeric types clubbed together case SQL_DESC_AUTO_UNIQUE_VALUE: // is col auto-incrementing case SQL_DESC_CASE_SENSITIVE: // is col case-insensitive case SQL_DESC_TYPE: // verbose type case SQL_DESC_CONCISE_TYPE: // concise type case SQL_DESC_COUNT: // no.of highest bound column case SQL_DESC_LENGTH: case SQL_DESC_DISPLAY_SIZE: case SQL_DESC_OCTET_LENGTH: case SQL_DESC_FIXED_PREC_SCALE: case SQL_DESC_NULLABLE: case SQL_DESC_NUM_PREC_RADIX: case SQL_DESC_PRECISION: case SQL_DESC_SCALE: case SQL_DESC_SEARCHABLE: case SQL_DESC_UNNAMED: case SQL_DESC_UNSIGNED: case SQL_DESC_UPDATABLE: _SQLGetIRDItemField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), col, pColNum, pFldID, pNumValuePtr, -1, NULL , isANSI ); break; // char types clubbed together case SQL_DESC_BASE_TABLE_NAME: // table name for column case SQL_DESC_CATALOG_NAME: // database name case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_TYPE_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: _SQLGetIRDItemField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), col, pColNum, pFldID, pDataPtr, pDataSize, pDataSizePtr ? &n : NULL, isANSI ); if ( pDataSizePtr ) { *pDataSizePtr = ( Word ) n; } break; case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_LABEL: case SQL_DESC_NAME: // //// // as a special case the name length may be required without the actual name ////// StrPtr cname; Word cnamesize; if ( pDataPtr ) { cname = ( StrPtr ) pDataPtr; cnamesize = pDataSize; } else { cname = new Char[256]; // arbitary cnamesize = 255; } _SQLGetIRDItemField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), col, pColNum, pFldID, cname, cnamesize, pDataSizePtr ? &n : NULL, isANSI ); if ( pDataPtr == NULL ) { delete[] cname; } if ( pDataSizePtr ) { *pDataSizePtr = ( Word ) n; } break; default: __ODBCPOPMSG ( _ODBCPopMsg ( "SQLColAttribute unknown attr, ColNum: %d, FldID: %d\n", pColNum, pFldID ) ); return SQL_ERROR; } return SQL_SUCCESS; }