示例#1
0
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;
}
示例#2
0
RETCODE SQL_API _SQLExecStmtFromReq ( pODBCStmt pStmt, bool pPrepared ) {
    ////// this part should not be required if already prepared
    // release existing stmt contents
    //SQLFreeStmt ( pStmt, SQL_CLOSE );
    //////
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "================================================================" ) );
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "start exec the query: " ) );
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, pStmt->Stmt ) );
    std::unique_ptr<SQLResponse> p;
    
    try {
        p = restQuery ( pStmt->Stmt, pStmt->Conn->Server, pStmt->Conn->ServerPort, pStmt->Conn->UserName, pStmt->Conn->Password,
                        pStmt->Conn->Project );
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "The REST request succeed" ) );
    }
    
    catch ( const exception& e ) {
        std::stringstream ss;
        ss << "The REST query request failed, the error message is: " << e.what();
        std::string s = ss.str();
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_ERROR, s.c_str() ) );
        _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "_SQLExecStmtFromReq", "01000", -1, ( char* ) s.c_str() );
        return SQL_ERROR;
    }
    
    // feed stmt structure with response, stmt will take charge of deleting it
    if ( p == NULL ||  p->isException == true || PutRespToStmt ( ( pODBCStmt ) pStmt, std::move ( p ) ) != GOOD ) {
        return SQL_ERROR;
    }
    
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "Successfully done executing the query" ) );
    return SQL_SUCCESS;
}
示例#3
0
eGoodBad _SQLPutDiagRow ( SQLSMALLINT pHandleType, SQLHANDLE pHandle, StrPtr pFunc, StrPtr pState,
                          Long pNativeErrorCode, Long pRow, Long pCol, StrPtr pMsgArgs, ... ) {
    // note
    // this implementation of function takes take row/col as param
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLPutDiagRow called" ) );
    va_list             args;
    pODBCDiag        diag;
    pODBCDiagRow     r;
    __CHK_HANDLE ( pHandle, pHandleType, BAD );
    diag = _SQLGetDiagHandle ( pHandleType, pHandle );
    
    if ( !diag )
    { return BAD; }
    
    // get va_args
    va_start ( args, pMsgArgs );
    r = _SQLPutDiagRow ( diag, pFunc, pState, pNativeErrorCode, pMsgArgs, args );
    va_end ( args );
    
    if ( r ) {
        r->Row = pRow;
        r->Col = pCol;
        return GOOD;
    }
    
    return BAD;
}
示例#4
0
/*
     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;
}
示例#5
0
RETCODE SQL_API _SQLResetRowPos ( pODBCStmt pStmt ) {
    // note
    // there r 2 row pointers one is the start row for the current fetch and
    // the other is the end row after the current fetch
    // this function brings them together and moves them to the first row
    // after the cur end row
    // a block of rows which is fetched in one go is ROWSET while the full
    // result is called RESULTSET
    
    // check if there is some response of type resultset
    if (
        pStmt->IRD.RowDesc != NULL ) {
        // check if position is currently unknown
        if ( pStmt->CurRowsetEndRow == NULL && pStmt->CurRowsetEndRowPos == 0 ) {
            // position to first row ( both the pointers )
            pStmt->CurRowsetEndRowPos   = 1;
            pStmt->CurRowsetEndRow = GetIfExist ( pStmt->IRD.RowDesc->results, pStmt->CurRowsetEndRowPos );
        }
        
        // already positioned somewhere
        else if ( pStmt->CurRowsetEndRow != NULL ) {
            // position to next row
            pStmt->CurRowsetEndRowPos  += 1;
            pStmt->CurRowsetEndRow = GetIfExist ( pStmt->IRD.RowDesc->results, pStmt->CurRowsetEndRowPos );
        }
        
        // calibrate the first row with end row
        pStmt->CurRowsetStartRow    = pStmt->CurRowsetEndRow;
        pStmt->CurRowsetStartRowPos = pStmt->CurRowsetEndRowPos;
        
        // finally check if there is some data found
        if ( pStmt->CurRowsetStartRow == NULL ) {
            // put in diag
            _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "", "01000", -1, "SQLFetch - no data" );
            return SQL_NO_DATA;
        }
        
        else
        { return SQL_SUCCESS; }
    }
    
    else {
        // error situation
        _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "_SQLResetRowPos", "01000", -1, "no resultset" );
        return SQL_ERROR;
    }
}
示例#6
0
RETCODE SQL_API _SQLFetchMoveNext ( pODBCStmt pStmt ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLFetch MoveNext is called" ) );
    
    // check if there is some response of type resultset
    if (
        pStmt->IRD.RowDesc != NULL ) {
        // ------- THIS CASE SHOULD NOT OCCUR ----------
        
        // check if position is currently unknown
        if ( pStmt->CurRowsetStartRow == NULL && pStmt->CurRowsetStartRowPos == 0 ) {
            // position to first row ( both the pointers )
            pStmt->CurRowsetStartRowPos = 1;
            pStmt->CurRowsetStartRow    = GetIfExist ( pStmt->IRD.RowDesc->results, 1 );
            pStmt->CurRowsetEndRowPos   = 1;
            pStmt->CurRowsetEndRow      = GetIfExist ( pStmt->IRD.RowDesc->results, 1 );
        }
        
        // -----------------------------------------------
        
        // position to next row if already position is known
        else if ( pStmt->CurRowsetEndRow != NULL ) {
            // position to next row
            pStmt->CurRowsetEndRowPos  += 1;
            pStmt->CurRowsetEndRow      = GetIfExist ( pStmt->IRD.RowDesc->results, pStmt->CurRowsetEndRowPos );
        }
        
        // finally check if there is some data found
        if ( pStmt->CurRowsetEndRow == NULL ) {
            // put in diag
            _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "", "01000", -1, "SQLFetch - no data" );
            return SQL_NO_DATA;
        }
        
        else
        { return SQL_SUCCESS; }
    }
    
    else {
        // error situation
        _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "_SQLFetchMoveNext", "01000", -1, "no resultset" );
        return SQL_ERROR;
    }
}
示例#7
0
RETCODE SQL_API SQLExecute ( HSTMT pStmt ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLExecute called on: %d", pStmt ) );
    Word        x;
    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
    
    // check if prepared
    if ( ( ( pODBCStmt ) pStmt )->Prepared != 1 ) {
        _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLExecute", "01000", -1, "No prepared stmt" );
        return SQL_ERROR;
    }
    
    // excute the request
    x  = _SQLExecStmtFromReq ( ( pODBCStmt ) pStmt, 1 );
    return x;
}
示例#8
0
RETCODE SQL_API SQLCloseCursor ( SQLHSTMT pStmt ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLCloseCursor called" ) );
    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
    
    // check if there is some result
    if (
        ( ( pODBCStmt ) pStmt )->IRD.RowDesc != NULL ) {
        // free the results
        return SQLFreeStmt ( pStmt, SQL_CLOSE );
    }
    
    else {
        // error condition
        _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLCloseCursor", "24000", -1, "Invalid cursor state" );
        return SQL_ERROR;
    }
}
示例#9
0
RETCODE   TryFetchMetadata ( pODBCConn pgConn ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "start loading metadata..." ) );
    
    try {
        pgConn->meta = std::move ( restGetMeta ( pgConn->Server, pgConn->ServerPort, pgConn->UserName, pgConn->Password,
                                                 pgConn->Project ) );
    }
    
    catch ( const exception& e ) {
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_ERROR, "The REST request failed to get metadata" ) );
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_ERROR, e.what() ) );
        _SQLPutDiagRow ( SQL_HANDLE_DBC, pgConn, "SQLDriverConnect", "HY000", 1045, "Access denied. (using password: NO)" );
        return SQL_ERROR;
    }
    
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "End loading metadata" ) );
    return SQL_SUCCESS;
}
示例#10
0
RETCODE   TryAuthenticate ( pODBCConn pgConn ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "Start authenticating.." ) );
    
    try {
        bool authenticated = restAuthenticate ( pgConn->Server, pgConn->ServerPort, pgConn->UserName, pgConn->Password );
        
        if ( !authenticated )
        { throw exception ( "Username/Password incorrect." ); }
    }
    
    catch ( const exception& e ) {
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_ERROR, "The REST request failed to authenticate." ) );
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_ERROR, e.what() ) );
        _SQLPutDiagRow ( SQL_HANDLE_DBC, pgConn, "SQLDriverConnect", "HY000", 1045, "Access denied. (using password: NO)" );
        return SQL_ERROR;
    }
    
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "End authenticating" ) );
    return SQL_SUCCESS;
}
示例#11
0
RETCODE SQL_API SQLNumResultCols ( SQLHSTMT pStmt, SQLSMALLINT*  pColCountPtr ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLNumResultCols called" ) );
    SQLResponse* rowdesc;
    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
    // free diags
    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
    // caller safe
    * ( ( SQLSMALLINT* ) pColCountPtr ) = 0;
    // get the row desciptor
    rowdesc = ( ( pODBCStmt ) pStmt )->IRD.RowDesc.get();
    
    if ( rowdesc == NULL ) {
        _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLNumResultCols", "01000", -1, "no resultset or IRD" );
        return SQL_ERROR;
    }
    
    // count the number of columns
    * ( ( SQLSMALLINT* ) pColCountPtr ) = ( SQLSMALLINT ) ( rowdesc->columnMetas.size() );
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLNumResultCols called returned: %d",
                              * ( ( SQLSMALLINT* ) pColCountPtr ) ) );
    return SQL_SUCCESS;
}
示例#12
0
RETCODE SQL_API _SQLCopyCharData ( pODBCDiag pDiag, void* pTgtDataPtr, Long pDataBufSize, void* pSizePtr,
                                   Word pSizePtrSize, CStrPtr pSrcData, Long pSrcDataSize ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG,
                              "_SQLCopyCharData called,pDataBufSize %d, the src is %s, strlen(src) %d, pSrcDataSize %d", pDataBufSize, pSrcData,
                              strlen ( pSrcData ), pSrcDataSize ) );
    Long    n;
    
    // caller safe
    if ( pTgtDataPtr )
    { * ( ( StrPtr ) pTgtDataPtr ) = 0; }
    
    // DATA SIZE
    
    // check source data to compute size
    if ( pSrcData && _stricmp ( ( StrPtr ) pSrcData, "NULL" ) != 0 )
    { n = ( pSrcDataSize < 0 ) ? strlen ( ( StrPtr ) pSrcData ) : pSrcDataSize; }        // compute length based on whether null terminated
    
    else
    { n = 0; }
    
    // check if there is a holder for size
    if ( pSizePtr ) {
        // set size as per ptr type 16-bt or 32-bit
        if ( pSizePtrSize == 16 )
        { * ( ( Word* ) pSizePtr ) = ( Word ) n; }
        
        else
        { * ( ( Long* ) pSizePtr ) = n; }
    }
    
    // check if src data but no size holder
    else if ( pSrcData ) {
        // check if diag to be set
        if ( pDiag )
        { _SQLPutDiagRow ( pDiag, "_SQLCopyCharData", "01000", -1, "No holder for data size", NULL ); }
        
        __ODBCPOPMSG ( _ODBCPopMsg ( "_SQLCopyCharData - No holder for data size" ) );
        return SQL_ERROR;
    }
    
    // check if there is a target holder
    if ( pTgtDataPtr ) {
        // check if there is a source pointer
        if ( pSrcData ) {
            // does all of it fit with null char
            if ( pDataBufSize >= n + 1 ) {
                memcpy ( ( StrPtr ) pTgtDataPtr, pSrcData, n );
                ( ( StrPtr ) pTgtDataPtr ) [n] = 0;
                __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLCopyCharData has been called, the string(not truncated) is %s",
                                          pTgtDataPtr ) );
                return SQL_SUCCESS;
            }
            
            // all of it does not fit
            else {
                memcpy ( ( StrPtr ) pTgtDataPtr, pSrcData, pDataBufSize - 1 );
                ( ( StrPtr ) pTgtDataPtr ) [pDataBufSize - 1] = 0;
                __ODBCLOG ( _ODBCLogMsg ( LogLevel_WARN, "_SQLCopyCharData has been called, the target string is (truncated) %s",
                                          pTgtDataPtr ) );
                //return SQL_SUCCESS_WITH_INFO may cause error in tableau
                //if ( pDiag )
                //  _SQLPutDiagRow ( pDiag, "_SQLCopyCharData", "01000", -1, "string data truncated", NULL );
                //return SQL_SUCCESS_WITH_INFO;
                __ODBCLOG ( _ODBCLogMsg ( LogLevel_WARN, "string data truncated" ) );
                return SQL_SUCCESS;
            }
        }
        
        // tgt data but no src data
        else {
            // clear tgt
            * ( ( Char* ) pTgtDataPtr ) = 0;
            __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLCopyCharData has been called, the string is (empty) %s", pTgtDataPtr ) );
        }
    }
    
    return SQL_SUCCESS;
}
示例#13
0
SQLRETURN SQL_API _SQLDescribeCol_basic ( SQLHSTMT        pStmt,
                                          SQLUSMALLINT    pColNum,
                                          void*        pColNamePtr,
                                          SQLSMALLINT     pColNameSize,
                                          SQLSMALLINT*    pColNameSizePtr,
                                          SQLSMALLINT*    pDataTypePtr,
                                          SQLULEN*        pColSizePtr,
                                          SQLSMALLINT*    pDecimalDigitsPtr,
                                          SQLSMALLINT*    pNullablePtr ,
                                          bool isANSI
                                        ) {
    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, "SQLDescribeCol", "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, "SQLDescribeCol", "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, "SQLDescribeCol", "01000", -1, "Invalid col num" );
        return SQL_ERROR;
    }
    
    // COL-NAME ie title
    
    if ( pColNamePtr ) {
        _SQLGetIRDItemField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), col, pColNum, SQL_DESC_BASE_COLUMN_NAME, pColNamePtr,
                              pColNameSize, pColNameSizePtr ? &n : NULL, isANSI );
                              
        if ( pColNameSizePtr )
        { *pColNameSizePtr = ( Word ) n; }
        
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "name: %s", pColNamePtr ) );
    }
    
    // COL-DATA TYPE
    
    if ( pDataTypePtr ) {
        _SQLGetIRDItemField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), col, pColNum, SQL_DESC_CONCISE_TYPE, pDataTypePtr, -1,
                              NULL, isANSI );
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "data type: %d", *pDataTypePtr ) );
    }
    
    // COL-SIZE
    
    if ( pColSizePtr ) {
        _SQLGetIRDItemField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), col, pColNum, SQL_DESC_LENGTH, pColSizePtr, -1, NULL,
                              isANSI );
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "column size: %d", *pColSizePtr ) );
    }
    
    // COL-DECIMAL
    
    if ( pDecimalDigitsPtr ) {
        _SQLGetIRDItemField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), col, pColNum, SQL_DESC_SCALE, pDecimalDigitsPtr, -1, NULL,
                              isANSI );
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "decimal scale: %d", *pDecimalDigitsPtr ) );
    }
    
    // COL-NULLABLE
    
    if ( pNullablePtr ) {
        _SQLGetIRDItemField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), col, pColNum, SQL_DESC_NULLABLE, pNullablePtr, -1, NULL,
                              isANSI );
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "nullable: %d", *pNullablePtr ) );
    }
    
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLDescribeCol returned" ) );
    return SQL_SUCCESS;
}
示例#14
0
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;
}
示例#15
0
/*

    From msdn:

    SQLRETURN SQLBindCol(
    SQLHSTMT       StatementHandle,
    SQLUSMALLINT   ColumnNumber,
    SQLSMALLINT    TargetType,
    SQLPOINTER     TargetValuePtr,
    SQLLEN         BufferLength,
    SQLLEN *       StrLen_or_Ind);

*/
RETCODE SQL_API SQLBindCol ( SQLHSTMT        pStmt,
                             SQLUSMALLINT    pColNum,
                             SQLSMALLINT     pDataType,
                             SQLPOINTER      pDataPtr,
                             SQLLEN      pDataSize,
                             SQLLEN*         pDataSizePtr ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLBindCol called, ColNum: %d, TgtType: %d, ValuePtr: %d, Capacity: %d",
                              pColNum, pDataType, pDataPtr, pDataSize ) );
    pODBCARD         ard;                            // application row descriptor
    pARDItem     ardcol;                         // application row descriptor item
    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
    // free diags
    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
    // extract the appl. row descriptor from stmt
    ard = & ( ( ( pODBCStmt ) pStmt )->ARD );
    // get the specified column if already bound
    ardcol = _SQLGetARDItem ( ard, pColNum );
    
    // EXISTS
    
    if ( ardcol != NULL ) {
        // check if total unbind is required
        if ( pDataPtr == NULL && pDataSizePtr == NULL ) {
            // detach it from ARD link list
            _SQLDetachARDItem ( ard, ardcol );
            // free
            delete ardcol;
        }
        
        else  {
            // unbind/rebind col details
            _SQLSetARDItemField ( ard, ardcol, pColNum, SQL_DESC_DATA_PTR, pDataPtr, -1 );
            _SQLSetARDItemField ( ard, ardcol, pColNum, SQL_DESC_CONCISE_TYPE, ( void* ) pDataType, -1 );
            _SQLSetARDItemField ( ard, ardcol, pColNum, SQL_DESC_LENGTH, ( void* ) pDataSize, -1 );
            _SQLSetARDItemField ( ard, ardcol, pColNum, SQL_DESC_OCTET_LENGTH_PTR, pDataSizePtr, -1 );
            // reset the source data type
            ardcol->SrcDataType     = 0;
        }
        
        return SQL_SUCCESS;
    }
    
    // DOES NOT EXIST
    
    // check for bad params
    if ( pDataPtr == NULL && pDataSizePtr == NULL ) {
        _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLBindCol", "01000", -1, "Bad params" );
        return SQL_ERROR;
    }
    
    // check for bad params
    else if ( pDataSize < 0 ) {
        _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "SQLBindCol", "01000", -1, "Invalid buffer length" );
        return SQL_ERROR;
    }
    
    // CREATE
    // allocate a new col-item
    ardcol = new ARDItem;
    // reset
    _SQLSetARDItemFieldsDefault ( ardcol, pColNum );
    // set all values - bind
    _SQLSetARDItemField ( ard, ardcol, pColNum, SQL_DESC_DATA_PTR, pDataPtr, -1 );
    _SQLSetARDItemField ( ard, ardcol, pColNum, SQL_DESC_CONCISE_TYPE, ( void* ) pDataType, -1 );
    _SQLSetARDItemField ( ard, ardcol, pColNum, SQL_DESC_LENGTH, ( void* ) pDataSize, -1 );
    _SQLSetARDItemField ( ard, ardcol, pColNum, SQL_DESC_OCTET_LENGTH_PTR, pDataSizePtr, -1 );
    // attach it to link list
    _SQLAttachARDItem ( ard, ardcol );
    return SQL_SUCCESS;
}
示例#16
0
//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;
}
示例#17
0
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;
}
示例#18
0
RETCODE SQL_API _SQLFetchCol ( pODBCStmt pStmt,
                               pARDItem pARDCol, //ard
                               SQLResponse* pRowDesc,// ird
                               SQLRowContent* pRowData ) { //content
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLFetchCol called" ) );
    // note
    // this function checks the binding type and positions the pointer
    // for copying the data accordingly. It takes into account the
    // current row position in rowset, the initial min increment specified
    // by client and the size of the row or col buffer
    Long        i;
    Long        j;
    Long*       tgtsizeptr;                                         // target size ptr
    void*       tgtdataptr;                                         // target data ptr
    const wchar_t*     srcdata;                                            // source data
    SelectedColumnMeta*    coldesc;
    // COMPUTE DATA AND SIZE PTR
    // get the row pos in current rowset
    i = ( pStmt->CurRowsetEndRowPos - pStmt->CurRowsetStartRowPos );
    // compute min increment
    j = ( pStmt->ARD.BindOffsetPtr ) ? * ( pStmt->ARD.BindOffsetPtr ) : 0;
    
    // check the binding type
    if ( pStmt->ARD.BindTypeOrSize != SQL_BIND_BY_COLUMN ) {
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "ARD bindtypeorsize not euqal to SQL_BIND_BY_COLUMN" ) );
        // note
        Long k;
        // compute row-size increment
        k = ( pStmt->ARD.BindTypeOrSize );
        // compute target col and size ptr
        tgtdataptr = ( void* ) ( ( ( Char* ) ( pARDCol->DataPtr ) ) + j + ( i * k ) );
        tgtsizeptr = ( Long* ) ( ( ( Char* ) ( pARDCol->SizePtr ) ) + j + ( i * k ) );
    }
    
    // column-wise binding
    else {
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "ARD bindtypeorsize euqal to SQL_BIND_BY_COLUMN" ) );
        // move both data and size ptr in the array
        //TODO find out where the pARDCol->DataSize if set
        tgtdataptr = ( void* ) ( ( ( Char* ) ( pARDCol->DataPtr ) ) + j + ( i * pARDCol->DataSize ) ); // use based on data type
        tgtsizeptr = ( Long* ) ( ( ( Char* ) ( pARDCol->SizePtr ) ) + j + ( i * sizeof ( Long ) ) );
    }
    
    // PRECAUTION
    
    if ( tgtdataptr )   { * ( ( Char* ) tgtdataptr ) = 0; }
    
    if ( tgtsizeptr )   { * ( ( Long* ) tgtsizeptr ) = 0; }
    
    // COLLECT AND CHECK
    // get col desc for specified col ( response )
    coldesc = pRowDesc->columnMetas.at ( pARDCol->ColNum - 1 );
    //if ( coldesc == NULL ) {
    //  _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "_SQLFetchCol", "01000", -1, pStmt->CurRowsetEndRowPos, pARDCol->ColNum, "column not found in resultset for specified index" );
    //  return SQL_SUCCESS_WITH_INFO;                 // no col for specified index
    //}
    // get the col data for specfied col ( response )
    srcdata = pRowData->contents.at ( pARDCol->ColNum - 1 ).c_str();
    
    //coldata = SOAPGetChildElemX ( pRowData, pARDCol->ColNum );
    //if ( coldata == NULL ) {
    
    //  _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "_SQLFetchCol", "01000", -1, pStmt->CurRowsetEndRowPos, pARDCol->ColNum, "column not found in resultset for specified index" );
    //  return SQL_SUCCESS_WITH_INFO;                 // no col for specified index
    //}
    
    // get col value as string
    //srcdata = SOAPGetElemText ( coldata );
    
    // NULL DATA                                            // note: a text of NULL indicates NULL data from server
    
    // check if data is NULL
    if ( srcdata == NULL || _wcsicmp ( srcdata, L"NULL" ) == 0 ) {
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "srcdata is null" ) );
        
        // check if a size indicator is available
        if ( tgtsizeptr == NULL ) {
            _SQLPutDiagRow ( SQL_HANDLE_STMT, pStmt, "_SQLFetchCol", "22002", -1, pStmt->CurRowsetEndRowPos, pARDCol->ColNum,
                             "Indicator variable required but not supplied" );
            return SQL_SUCCESS_WITH_INFO;
        }
        
        // set to SQL_NULL_DATA
        else {
            // indicate null data
            * ( ( Long* ) tgtsizeptr ) = SQL_NULL_DATA;
            // added precaution for bad appl design
            /*  if ( tgtdataptr )
                memset ( tgtdataptr, 0, pARDCol->MaxSize );*/
            return SQL_SUCCESS;
        }
    }
    
    // check if info about src is also available in ARD col
    if ( pARDCol->SrcDataType == 0 )
    { GetIRDColDescInfo ( coldesc, & ( pARDCol->SrcDataType ), & ( pARDCol->SrcDataPrecision ), & ( pARDCol->SrcDataScale ), & ( pARDCol->SrcDataSize ) ); } // collect source data information in form comparable to appl
    
    // CONVERT AND TRANSFER
    //Important!!!
    //Notice the specification of different types
    //http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.odbc.doc/odbc72.htm
    RETCODE ret = _SQLColConvert ( pStmt, tgtdataptr, tgtsizeptr, srcdata, pARDCol, coldesc->isSigned );
    //char buffer[1024];
    //hexDump((char*)tgtdataptr,4,buffer,false);
    //__ODBCLOG(_ODBCLogMsg(LogLevel_DEBUG,buffer));
    //hexDump((char*)tgtdataptr,4,buffer,true);
    //__ODBCLOG(_ODBCLogMsg(LogLevel_DEBUG,buffer));
    return ret;
}
示例#19
0
//mhb added, for those ard that accept wchar
RETCODE SQL_API _SQLCopyWCharDataW ( pODBCDiag pDiag, void* pTgtDataPtr, Long pDataBufSize, void* pSizePtr,
                                     Word pSizePtrSize, const wchar_t* pSrcData, Long pSrcDataSize ) {
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLCopyWCharDataW called, pTgtDataPtr is null? %d, pSizePtr == null? %d",
                              pTgtDataPtr == NULL, pSizePtr == NULL ) );
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLCopyWCharDataW called, the src string is :" ) );
    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, pSrcData ) );
    Long    n;
    
    // caller safe
    if ( pTgtDataPtr )
    { * ( ( wchar_t* ) pTgtDataPtr ) = 0; }
    
    // DATA SIZE
    
    // check source data to compute size
    if ( pSrcData && _wcsicmp ( pSrcData, L"NULL" ) != 0 )
    { n = ( pSrcDataSize < 0 ) ?  wcslen ( pSrcData ) : pSrcDataSize; }         // compute length based on whether null terminated
    
    else
    { n = 0; }
    
    // check if there is a holder for size
    if ( pSizePtr ) {
        // set size as per ptr type 16-bt or 32-bit
        
        //should be number of characters
        if ( pSizePtrSize == 16 )
        { * ( ( Word* ) pSizePtr ) = ( Word ) ( 2 * n ); }
        
        else
        { * ( ( Long* ) pSizePtr ) = ( 2 * n ); }
        
        __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "pSizePtr is set to %d", n ) );
    }
    
    // check if src data but no size holder
    else if ( pSrcData ) {
        // check if diag to be set
        if ( pDiag )
        { _SQLPutDiagRow ( pDiag, "_SQLCopyWCharDataW", "01000", -1, "No holder for data size", NULL ); }
        
        __ODBCPOPMSG ( _ODBCPopMsg ( "_SQLCopyWCharDataW - No holder for data size" ) );
        return SQL_ERROR;
    }
    
    // DATA
    
    // check if there is a target holder
    if ( pTgtDataPtr ) {
        // check if there is a source pointer
        if ( pSrcData ) {
            // does all of it fit with null char
            if ( pDataBufSize >= ( n + 1 ) ) {
                memcpy ( ( StrPtr ) pTgtDataPtr, pSrcData, 2 * ( n + 1 ) );
                ( ( wchar_t* ) pTgtDataPtr ) [n] = '\0';
                //__ODBCLOG(_ODBCLogMsg(LogLevel_DEBUG,"_SQLCopyWCharDataW has been called, the target string(not truncated) is :"));
                //unique_ptr<char[]> temp2(wchar2char( (wchar_t*)pTgtDataPtr));
                //__ODBCLOG(_ODBCLogMsg(LogLevel_DEBUG,temp2.get()));
                return SQL_SUCCESS;
            }
            
            // all of it does not fit
            else {
                //if(pDataBufSize % 2 == 1)
                //  pDataBufSize -= 1;
                memcpy ( ( StrPtr ) pTgtDataPtr, pSrcData, 2 * ( pDataBufSize - 1 ) );
                ( ( wchar_t* ) pTgtDataPtr ) [pDataBufSize - 1] = 0;
                //__ODBCLOG(_ODBCLogMsg(LogLevel_WARN,"_SQLCopyWCharDataW has been called, the target string is(truncated) :"));
                unique_ptr<char[]> temp ( wchar2char ( ( wchar_t* ) pTgtDataPtr ) );
                //__ODBCLOG(_ODBCLogMsg(LogLevel_DEBUG, temp.get()));
                //return SQL_SUCCESS_WITH_INFO may cause error in tableau
                //if ( pDiag )
                //  _SQLPutDiagRow ( pDiag, "_SQLCopyWCharDataW", "01000", -1, "string data truncated", NULL );
                //return SQL_SUCCESS_WITH_INFO;
                __ODBCLOG ( _ODBCLogMsg ( LogLevel_WARN, "string data truncated" ) );
                return SQL_SUCCESS;
            }
        }
        
        // tgt data but no src data
        else {
            // clear tgt
            * ( ( wchar_t* ) pTgtDataPtr ) = 0;
            __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLCopyWCharDataW has been called, the string is (empty) %s",
                                      pTgtDataPtr ) );
        }
    }
    
    return SQL_SUCCESS;
}