Repository: trafodion Updated Branches: refs/heads/master 40cd13b8a -> bcce340bb
Windows ODBC LOB support Project: http://git-wip-us.apache.org/repos/asf/trafodion/repo Commit: http://git-wip-us.apache.org/repos/asf/trafodion/commit/f70b19c1 Tree: http://git-wip-us.apache.org/repos/asf/trafodion/tree/f70b19c1 Diff: http://git-wip-us.apache.org/repos/asf/trafodion/diff/f70b19c1 Branch: refs/heads/master Commit: f70b19c1a1a2612c44718c428864d522b7fb473a Parents: 2c5f480 Author: Weixin-Xu <[email protected]> Authored: Mon May 21 16:31:33 2018 +0800 Committer: Weixin-Xu <[email protected]> Committed: Mon May 21 17:03:52 2018 +0800 ---------------------------------------------------------------------- win-odbc64/Common/TransportBase.h | 2 + win-odbc64/Common/marshalingdrvr_drvr.cpp | 123 ++++++++ win-odbc64/Common/marshalingdrvr_drvr.h | 27 ++ win-odbc64/Krypton/generated_incs/odbc_cl.h | 52 ++++ .../odbcclient/drvr35/Interface/odbcs_drvr.cpp | 227 ++++++++++++++ .../odbcclient/drvr35/Interface/odbcs_drvr.h | 24 ++ win-odbc64/odbcclient/drvr35/cconnect.cpp | 3 + win-odbc64/odbcclient/drvr35/cconnect.h | 4 + win-odbc64/odbcclient/drvr35/cdesc.cpp | 24 +- win-odbc64/odbcclient/drvr35/cstmt.cpp | 309 +++++++++++++++++++ win-odbc64/odbcclient/drvr35/cstmt.h | 27 ++ win-odbc64/odbcclient/drvr35/ctosqlconv.cpp | 12 + win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj | 4 +- .../odbcclient/drvr35/drvr35_os.vcxproj.filters | 6 + win-odbc64/odbcclient/drvr35/drvrglobal.cpp | 5 +- win-odbc64/odbcclient/drvr35/drvrnet.cpp | 12 + win-odbc64/odbcclient/drvr35/drvrnet.h | 21 ++ win-odbc64/odbcclient/drvr35/lob.cpp | 79 +++++ win-odbc64/odbcclient/drvr35/lob.h | 38 +++ win-odbc64/odbcclient/drvr35/netstmt.cpp | 95 ++++++ win-odbc64/odbcclient/drvr35/sqltocconv.cpp | 28 +- win-odbc64/odbcclient/drvr35/sqltocconv.h | 4 +- win-odbc64/sql/cli/sqlcli.h | 4 + 23 files changed, 1123 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/Common/TransportBase.h ---------------------------------------------------------------------- diff --git a/win-odbc64/Common/TransportBase.h b/win-odbc64/Common/TransportBase.h index 4b24fa0..0ec7e60 100644 --- a/win-odbc64/Common/TransportBase.h +++ b/win-odbc64/Common/TransportBase.h @@ -134,6 +134,8 @@ enum SRVR_API { SRVR_API_SQLFASTEXECDIRECT, //OK WMS SRVR_API_SQLFASTFETCH_PERF, //OK WMS SRVR_API_GETSEGMENTS, //OK WMS + SRVR_API_EXTRACTLOB, //OK LOB + SRVR_API_UPDATELOB, //OK LOB SRVR_API_LASTAPI //Add new APIs before this }; http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/Common/marshalingdrvr_drvr.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/Common/marshalingdrvr_drvr.cpp b/win-odbc64/Common/marshalingdrvr_drvr.cpp index 4cffe0e..01bcc59 100644 --- a/win-odbc64/Common/marshalingdrvr_drvr.cpp +++ b/win-odbc64/Common/marshalingdrvr_drvr.cpp @@ -2743,7 +2743,130 @@ odbc_SQLDrvr_Execute_param_pst_( } /* odbc_SQLDrvr_Execute_param_pst_() */ +CEE_status +odbc_SQLDrvr_ExtractLob_param_pst_( + /* In */ CInterface * pSystem + , /* In */ IDL_char * & buffer + , /* In */ long & message_length + , /* In */ IDL_long extractType + , /* In */ IDL_string lobHandle + , /* In */ IDL_long lobHandleLen + , /* In */ IDL_long lobHandleCharset + , /* In */ IDL_long extractlen + ) +{ + IDL_char *curptr = NULL; + IDL_long wlength = 0; + IDL_long charSet = 0; + + //extractType + wlength += sizeof(IDL_short); + + //lobHandleLen + wlength += sizeof(IDL_long); + if (lobHandle != NULL) + { + wlength += lobHandleLen; + wlength += sizeof(IDL_long); + } + + wlength += sizeof(IDL_long); + + message_length = wlength; + buffer = pSystem->w_allocate(message_length); + if (buffer == NULL) + { + return CEE_ALLOCFAIL; + } + curptr = buffer; + + if (pSystem->swap() == SWAP_YES) + { + LONG_swap(&extractType); + LONG_swap(&lobHandleLen); + LONG_swap(&charSet); + LONG_swap(&extractlen); + } + + IDL_long_copy(&extractType, curptr); + + IDL_long_copy(&lobHandleLen, curptr); + if (lobHandle != NULL) + { + IDL_charArray_copy(lobHandle, curptr); + IDL_long_copy(&charSet, curptr); + } + + IDL_long_copy(&extractlen, curptr); + + return CEE_SUCCESS; +} +CEE_status +odbc_SQLDrvr_UpdateLob_param_pst_( + /* In */ CInterface * pSystem + , /* In */ IDL_char * & buffer + , /* In */ long & message_length + , /* In */ IDL_long updataType + , /* In */ IDL_string lobHandle + , /* In */ IDL_long lobHandleLen + , /* In */ IDL_long lobHandleCharset + , /* In */ IDL_long_long totalLength + , /* In */ IDL_long_long offset + , /* In */ BYTE * data + , /* In */ IDL_long_long pos + , /* In */ IDL_long_long length +) +{ + IDL_char *curptr = NULL; + IDL_long wlength = 0; + IDL_long lobHandleLength = 0; + + wlength += sizeof(IDL_long); + + wlength += sizeof(lobHandleLength); + if (lobHandle != NULL) + { + lobHandleLength = strlen(lobHandle) + 1; + wlength += lobHandleLength; + wlength += sizeof(lobHandleCharset); + } + + wlength += sizeof(IDL_long_long) * 3; + wlength += length; + + message_length = wlength; + buffer = pSystem->w_allocate(message_length); + if (buffer == NULL) + { + return CEE_ALLOCFAIL; + } + + curptr = buffer; + + if (pSystem->swap() == SWAP_YES) + { + LONGLONG_swap(&totalLength); + LONGLONG_swap(&offset); + LONGLONG_swap(&length); + } + + IDL_long_copy(&updataType, curptr); + IDL_long_copy(&lobHandleLength, curptr); + if (lobHandle != NULL) + { + IDL_charArray_copy(lobHandle, curptr); + IDL_long_copy(&lobHandleCharset, curptr); + } + + IDL_long_long_copy(&totalLength, curptr); + IDL_long_long_copy(&offset, curptr); + IDL_long_long_copy(&length, curptr); + + IDL_byteArray_copy(data, length, curptr); + + return CEE_SUCCESS; +} /************************************************************************************************************ * * * Keeping these functions around for the collapsed driver - get rid of these when it is not needed anymore * http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/Common/marshalingdrvr_drvr.h ---------------------------------------------------------------------- diff --git a/win-odbc64/Common/marshalingdrvr_drvr.h b/win-odbc64/Common/marshalingdrvr_drvr.h index 8163852..d3c7578 100644 --- a/win-odbc64/Common/marshalingdrvr_drvr.h +++ b/win-odbc64/Common/marshalingdrvr_drvr.h @@ -195,6 +195,33 @@ odbc_SQLDrvr_EndTransaction_param_pst_( , /* In */ IDL_unsigned_short transactionOpt ); +CEE_status +odbc_SQLDrvr_ExtractLob_param_pst_( + /* In */ CInterface * pSystem + , /* In */ IDL_char * & buffer + , /* In */ long & message_length + , /* In */ IDL_long extractType + , /* In */ IDL_string lobHandle + , /* In */ IDL_long lobHandleLen + , /* In */ IDL_long lobHandleCharset + , /* In */ IDL_long extractlen +); + +CEE_status +odbc_SQLDrvr_UpdateLob_param_pst_( + /* In */ CInterface * pSystem + , /* In */ IDL_char * & buffer + , /* In */ long & message_length + , /* In */ IDL_long updataType + , /* In */ IDL_string lobHandle + , /* In */ IDL_long lobHandleLen + , /* In */ IDL_long lobHandleCharset + , /* In */ IDL_long_long totalLength + , /* In */ IDL_long_long offset + , /* In */ BYTE * data + , /* In */ IDL_long_long pos + , /* In */ IDL_long_long length +); /************************************************************************************************************ * * * Keeping these functions around for the collapsed driver - get rid of these when it is not needed anymore * http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/Krypton/generated_incs/odbc_cl.h ---------------------------------------------------------------------- diff --git a/win-odbc64/Krypton/generated_incs/odbc_cl.h b/win-odbc64/Krypton/generated_incs/odbc_cl.h index 04f28c9..0835de6 100644 --- a/win-odbc64/Krypton/generated_incs/odbc_cl.h +++ b/win-odbc64/Krypton/generated_incs/odbc_cl.h @@ -2408,6 +2408,58 @@ odbc_SQLSvc_ExecuteCall( , /* Out */ ERROR_DESC_LIST_def *sqlWarning ); +/*************************************** +* Operation 'odbc_SQLsrvr_ExtractLob' +* *************************************/ + +/* +* Exception number constants for +* operation 'odbc_SQLsrvr_ExtractLob' +*/ +#define odbc_SQLSvc_ExtractLob_ParamError_exn_ 1 +#define odbc_SQLSvc_ExtractLob_InvalidConnection_exn_ 2 +#define odbc_SQLSvc_ExtractLob_SQLError_exn_ 3 +#define odbc_SQLSvc_ExtractLob_SQLInvalidhandle_exn_ 4 +#define obdc_SQLSvc_ExtractLob_AllocLOBDataError_exn_ 5 + +/* +* Exception struct for +* Operation "odbc_SQLSrvr_ExtractLob" +*/ +struct odbc_SQLsvc_ExtractLob_exc_ { + IDL_long exception_nr; + IDL_long exception_detail; + union { + odbc_SQLSvc_ParamError ParamError; + odbc_SQLSvc_SQLError SQLError; + } u; +}; + +/*************************************** +* Operation 'odbc_SQLsvc_UpdateLob' +***************************************/ +/* +* Exceptoin number constants for +* operation 'odbc_SQLSvc_UpdateLob' +*/ +#define odbc_SQLSvc_UpdateLob_ParamError_exn_ 1 +#define odbc_SQLSvc_UpdateLob_InvalidConnect_exn_ 2 +#define odbc_SQLSvc_UpdateLob_SQLError_exn_ 3 +#define odbc_SQLSvc_UpdateLob_SQLInvalidhandle_exn_ 4 + +/* +* Exception struct for +* Operation "odbc_SQLSvc_UpdateLob" +*/ +struct odbc_SQLSvc_UpdateLob_exc_ { + IDL_long exception_nr; + IDL_long exception_detail; + union { + odbc_SQLSvc_ParamError ParamError; + odbc_SQLSvc_SQLError SQLError; + } u; +}; + /* * CIN description of interface 'odbc_SQLSvc' */ http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.cpp b/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.cpp index 8228734..a8e11f2 100644 --- a/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.cpp +++ b/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.cpp @@ -2356,6 +2356,233 @@ odbc_SQLDrvr_Execute_pst_( } // odbc_SQLDrvr_Execute_pst_() +extern "C" CEE_status +odbc_SQLDrvr_ExtractLOB_pst_( + /* In */ CEE_tag_def tag_ + , /* In */ IDL_short extractType + , /* In */ IDL_string lobHandle + , /* In */ IDL_long lobHandleLen + , /* In */ IDL_long &extractLen + , /* Out */ struct odbc_SQLsvc_ExtractLob_exc_ *exception_ + , /* Out */ BYTE *& extractData +) +{ + bool sts; + + CEE_status retcode; + IDL_long wlength, rlength; + IDL_char *wbuffer, *rbuffer; + + IDL_long sqlWarningOrErrorLength = 0; + IDL_char *curptr; + IDL_long msg_total_len = 0; + + IDL_long lobHandleCharset = 1; + + SRVR_CALL_CONTEXT *srvrCallContext = (SRVR_CALL_CONTEXT *)tag_; + CStmt * pStatement = (CStmt *)srvrCallContext->sqlHandle; + CConnect *pConnection = pStatement->getConnectHandle(); + + retcode = odbc_SQLDrvr_ExtractLob_param_pst_( + pConnection->m_srvrTCPIPSystem + , wbuffer + , wlength + , extractType + , lobHandle + , lobHandleLen + , lobHandleCharset + , extractLen + ); + + sts = OpenIO(pConnection->m_srvrTCPIPSystem, srvrCallContext->SQLSvc_ObjRef); + if (sts == false) + return MAP_SRVR_ERRORS(pConnection); + + sts = DoIO(pConnection->m_srvrTCPIPSystem, wbuffer, wlength, rbuffer, rlength, pConnection, pStatement); + if (sts == false) + return MAP_SRVR_ERRORS(pConnection); + + // process output parameters + + char swap = pConnection->m_srvrTCPIPSystem->swap(); + msg_total_len = 0; + curptr = rbuffer; + + // + // exception_ + // + + IDL_long ExceptionLength; + + // + // exception_ ->exception_nr + // + exception_->exception_nr = *(IDL_long*)(curptr + msg_total_len); + msg_total_len += sizeof(exception_->exception_nr); + LONG_swap(&exception_->exception_nr, swap); + + // + // exception_ ->exception_detail + // + exception_->exception_detail = *(IDL_long*)(curptr + msg_total_len); + msg_total_len += sizeof(exception_->exception_detail); + LONG_swap(&exception_->exception_detail, swap); + + switch (exception_->exception_nr) + { + case odbc_SQLSvc_ExtractLob_ParamError_exn_: + ExceptionLength = *(IDL_long *)(curptr + msg_total_len); + msg_total_len += sizeof(ExceptionLength); + LONG_swap(&ExceptionLength); + + if (ExceptionLength > 0) + { + exception_->u.ParamError.ParamDesc = (IDL_char *)(curptr + msg_total_len); + msg_total_len += ExceptionLength; + } + break; + + case odbc_SQLSvc_ExtractLob_SQLError_exn_: + retcode = copy_ERROR_DESC_LIST(&exception_->u.SQLError.errorList, curptr, msg_total_len, swap); + if (retcode != CEE_SUCCESS) + return retcode; + break; + + case odbc_SQLSvc_ExtractLob_InvalidConnection_exn_: + case odbc_SQLSvc_ExtractLob_SQLInvalidhandle_exn_: + break; + default: + break; + } + extractType = *(IDL_short *)(curptr + msg_total_len); + msg_total_len += sizeof(IDL_short); + SHORT_swap(&extractType, swap); + + switch (extractType) + { + case 0: + extractLen = *(IDL_long_long *)(curptr + msg_total_len); + break; + case 1: + extractLen = *(IDL_long_long *)(curptr + msg_total_len); + msg_total_len += sizeof(IDL_long_long); + extractData = (BYTE *)(curptr + msg_total_len); + default: + break; + } + + return CEE_SUCCESS; +} + + +extern "C" CEE_status +odbc_SQLDrvr_UpdateLob_pst_( + /* In */ CEE_tag_def tag_ + , /* In */ IDL_long updataType + , /* In */ IDL_string lobHandle + , /* In */ IDL_long lobHandleLen + , /* In */ IDL_long_long totalLength + , /* In */ IDL_long_long offset + , /* In */ IDL_long_long pos + , /* In */ IDL_long_long length + , /* In */ BYTE * &data + , /* Out */ struct odbc_SQLSvc_UpdateLob_exc_ *exception_ +) +{ + bool sts; + + CEE_status retcode; + IDL_long wlength, rlength; + IDL_char *wbuffer, *rbuffer; + + IDL_long sqlWarningOrErrorLength = 0; + IDL_char *curptr; + IDL_long msg_total_len = 0; + + IDL_long lobHandleCharset = 1; + + SRVR_CALL_CONTEXT *srvrCallContext = (SRVR_CALL_CONTEXT *)tag_; + CStmt * pStatement = (CStmt *)srvrCallContext->sqlHandle; + CConnect *pConnection = pStatement->getConnectHandle(); + + pConnection->m_srvrTCPIPSystem->odbcAPI = SRVR_API_UPDATELOB; + pConnection->m_srvrTCPIPSystem->dialogueId = srvrCallContext->dialogueId; + pConnection->m_srvrTCPIPSystem->dwTimeout = srvrCallContext->statementTimeout; + + retcode = odbc_SQLDrvr_UpdateLob_param_pst_( + pConnection->m_srvrTCPIPSystem + , wbuffer + , wlength + , updataType + , lobHandle + , lobHandleLen + , lobHandleCharset + , totalLength + , offset + , data + , pos + , length + ); + + sts = OpenIO(pConnection->m_srvrTCPIPSystem, srvrCallContext->SQLSvc_ObjRef); + if (sts == false) + return MAP_SRVR_ERRORS(pConnection); + + sts = DoIO(pConnection->m_srvrTCPIPSystem, wbuffer, wlength, rbuffer, rlength, pConnection, pStatement); + if (sts == false) + return MAP_SRVR_ERRORS(pConnection); + + char swap = pConnection->m_srvrTCPIPSystem->swap(); + msg_total_len = 0; + curptr = rbuffer; + + // + // exception_ + // + + IDL_long ExceptionLength; + + // + // exception_ ->exception_nr + // + exception_->exception_nr = *(IDL_long*)(curptr + msg_total_len); + msg_total_len += sizeof(exception_->exception_nr); + LONG_swap(&exception_->exception_nr, swap); + + // + // exception_ ->exception_detail + // + exception_->exception_detail = *(IDL_long*)(curptr + msg_total_len); + msg_total_len += sizeof(exception_->exception_detail); + LONG_swap(&exception_->exception_detail, swap); + + switch (exception_->exception_nr) + { + case odbc_SQLSvc_UpdateLob_ParamError_exn_: + ExceptionLength += *(IDL_long *)(curptr + msg_total_len); + msg_total_len += sizeof(ExceptionLength); + LONG_swap(&ExceptionLength); + if (ExceptionLength > 0) + { + exception_->u.ParamError.ParamDesc = (IDL_char *)(curptr + msg_total_len); + msg_total_len += ExceptionLength; + } + break; + case odbc_SQLSvc_UpdateLob_InvalidConnect_exn_: + retcode = copy_ERROR_DESC_LIST(&exception_->u.SQLError.errorList, curptr, msg_total_len, swap); + if (retcode != CEE_SUCCESS) + return retcode; + case odbc_SQLSvc_UpdateLob_SQLError_exn_: + case odbc_SQLSvc_UpdateLob_SQLInvalidhandle_exn_: + break; + + default: + break; + } + + return CEE_SUCCESS; +} + //----------------------------------------------------------------- CEE_status MAP_SRVR_ERRORS(CConnect *pConnection) http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.h ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.h b/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.h index 7b044f9..c5a1a4f 100644 --- a/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.h +++ b/win-odbc64/odbcclient/drvr35/Interface/odbcs_drvr.h @@ -138,4 +138,28 @@ odbc_SQLDrvr_EndTransaction_pst_( , /* Out */ ERROR_DESC_LIST_def *sqlWarning ); +extern "C" CEE_status +odbc_SQLDrvr_ExtractLOB_pst_( + /* In */ CEE_tag_def tag_ + , /* In */ IDL_short extractType + , /* In */ IDL_string lobHandle + , /* In */ IDL_long lobHandleLen + , /* In */ IDL_long &extractLen + , /* Out */ struct odbc_SQLsvc_ExtractLob_exc_ *exception_ + , /* Out */ BYTE *&extractData +); + +extern "C" CEE_status +odbc_SQLDrvr_UpdateLob_pst_( + /* In */ CEE_tag_def tag_ + , /* In */ IDL_long updataType + , /* In */ IDL_string lobHandle + , /* In */ IDL_long lobHandleLen + , /* In */ IDL_long_long totalLength + , /* In */ IDL_long_long offset + , /* In */ IDL_long_long pos + , /* In */ IDL_long_long length + , /* In */ BYTE * &data + , /* Out */ struct odbc_SQLSvc_UpdateLob_exc_ *exception_ +); #endif /* ODBCS_DRVR_H */ http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/cconnect.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/cconnect.cpp b/win-odbc64/odbcclient/drvr35/cconnect.cpp index 32102c9..8bb4120 100644 --- a/win-odbc64/odbcclient/drvr35/cconnect.cpp +++ b/win-odbc64/odbcclient/drvr35/cconnect.cpp @@ -56,6 +56,9 @@ CConnect::CConnect(SQLHANDLE InputHandle) : CHandle(SQL_HANDLE_DBC, InputHandle) InitializeCriticalSection(&m_CSTransmision); m_IgnoreCancel = false; m_StartNode = -1; + + lobHandleSave = NULL; + lobHandleLenSave = 0; } CConnect::~CConnect() http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/cconnect.h ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/cconnect.h b/win-odbc64/odbcclient/drvr35/cconnect.h index 4bfe1df..39df0ed 100644 --- a/win-odbc64/odbcclient/drvr35/cconnect.h +++ b/win-odbc64/odbcclient/drvr35/cconnect.h @@ -277,6 +277,10 @@ private: SQLUINTEGER m_SecurityMode; bool m_RetryEncryption; + //hold the lob handle from last select for insert >16m + IDL_string lobHandleSave; + IDL_long lobHandleLenSave; + void reset(bool clearE=true); friend class CStmt; friend class CDesc; http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/cdesc.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/cdesc.cpp b/win-odbc64/odbcclient/drvr35/cdesc.cpp index 73b6326..443529a 100644 --- a/win-odbc64/odbcclient/drvr35/cdesc.cpp +++ b/win-odbc64/odbcclient/drvr35/cdesc.cpp @@ -503,6 +503,13 @@ unsigned long CDescRec::setDescRec(short DescMode, SQLItemDesc_def *SQLItemDesc) m_DescLength = 6 + m_DescDatetimeIntervalPrecision; m_DescPrecision = 0; break; + case TYPE_BLOB: + case TYPE_CLOB: + strcpy((char*)m_DescLiteralPrefix, "'"); + strcpy((char*)m_DescLiteralSuffix, "'"); + m_DescLength = SQLItemDesc->maxLen; + m_DescPrecision = m_DescLength; + break; default: return IDS_HY_021; } @@ -598,6 +605,10 @@ unsigned long CDescRec::setDescRec(short DescMode, SQLItemDesc_def *SQLItemDesc) // m_SQLOctetLength = SQLItemDesc->maxLen+3; // m_DescSearchable = SQL_PRED_SEARCHABLE; // break; + case SQLTYPECODE_BLOB: + case SQLTYPECODE_CLOB: + m_SQLOctetLength = SQLItemDesc->maxLen + 4; + break; default: m_SQLOctetLength = SQLItemDesc->maxLen; m_DescSearchable = SQL_PRED_BASIC; @@ -645,6 +656,8 @@ unsigned long CDescRec::setDescRec(short DescMode, SQLItemDesc_def *SQLItemDesc) case SQL_LONGVARCHAR: case SQL_WCHAR: case SQL_WVARCHAR: + case TYPE_BLOB: + case TYPE_CLOB: m_DescDatetimeIntervalPrecision = m_DescLength; break; case SQL_INTERVAL_SECOND: @@ -2819,7 +2832,9 @@ SQLRETURN CDesc::CopyData(CHandle *pHandle, { descRecPtr->m_SQLCharset=IRDDescRecPtr->m_SQLCharset; descRecPtr->setTranslateOption(descRecPtr->m_DescConciseType); - retCode = ConvertSQLToC(m_ODBCAppVersion, + retCode = ConvertSQLToC(m_ConnectHandle, + m_InputHandle, + m_ODBCAppVersion, DataLang, SQLDataType, IRDDescRecPtr->m_ODBCDataType, @@ -3210,7 +3225,8 @@ SQLRETURN CDesc::ExtendedCopyData(CHandle *pHandle, { descRecPtr->m_SQLCharset=IRDDescRecPtr->m_SQLCharset; descRecPtr->setTranslateOption(descRecPtr->m_DescConciseType); - retCode = ConvertSQLToC(//pStatement->getODBCAppVersion(), + retCode = ConvertSQLToC(m_ConnectHandle, + m_InputHandle, m_ODBCAppVersion, DataLang, SQLDataType, @@ -3342,7 +3358,9 @@ unsigned long CDesc::GetData(SQLValue_def *SQLValue, else { descRecPtr->setTranslateOption(TargetType); - retCode = ConvertSQLToC(m_ODBCAppVersion, + retCode = ConvertSQLToC(m_ConnectHandle, + m_InputHandle, + m_ODBCAppVersion, DataLang, SQLValue->dataType, descRecPtr->m_ODBCDataType, http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/cstmt.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/cstmt.cpp b/win-odbc64/odbcclient/drvr35/cstmt.cpp index 3dce053..67c453d 100644 --- a/win-odbc64/odbcclient/drvr35/cstmt.cpp +++ b/win-odbc64/odbcclient/drvr35/cstmt.cpp @@ -1063,6 +1063,15 @@ SQLRETURN CStmt::SendSQLCommand(BOOL SkipProcess, SQLCHAR *StatementText, else m_StmtType = TYPE_UNKNOWN; } + else if (_strnicmp(token, "LOBUPDATE", 9) == 0) + { + if (m_SrvrCallContext.u.extractLobParams.lobHandle == NULL) + { + return SQL_ERROR; + } + m_CurrentOdbcAPI = SRVR_API_UPDATELOB; + return SQL_NEED_DATA; + } else { @@ -3039,6 +3048,28 @@ SQLRETURN CStmt::ParamData(SQLPOINTER *ValuePtrPtr) BOOL SkipProcess = FALSE; SQLRETURN rc; + //insert >16m lob + if (m_CurrentOdbcAPI == SRVR_API_UPDATELOB) + { + if (m_ConnectHandle->lobHandleLenSave == 0) + return SQL_ERROR; + + if (m_StmtState == STMT_PARAM_DATA_NOT_CALLED) + { + m_CurrentParamStatus = SQL_WAITING_FOR_DATA; + return SQL_NEED_DATA; + } + else + { + rc = UpdateLob(0, m_ConnectHandle->lobHandleSave, m_ConnectHandle->lobHandleLenSave, 0, 0, 0, m_DataAtExecData.dataValue._length, (BYTE *)m_DataAtExecData.dataValue._buffer); + m_ConnectHandle->lobHandleLenSave == 0; + free(m_ConnectHandle->lobHandleSave); + m_ConnectHandle->lobHandleSave = NULL; + return rc; + } + + } + m_CurrentOdbcAPI = SQL_API_SQLPARAMDATA; if (m_AsyncEnable == SQL_ASYNC_ENABLE_ON) { @@ -3123,6 +3154,47 @@ SQLRETURN CStmt::PutData(SQLPOINTER DataPtr, SQLINTEGER StrLen; SQLSMALLINT ParameterType; + if (m_CurrentOdbcAPI == SRVR_API_UPDATELOB) + { + if (m_CurrentParamStatus == SQL_WAITING_FOR_DATA) + { + if (m_DataAtExecData.dataValue._buffer != NULL) + { + delete m_DataAtExecData.dataValue._buffer; + m_DataAtExecData.dataValue._buffer = NULL; + m_DataAtExecData.dataValue._length = 0; + } + m_CurrentParamStatus = SQL_RECEIVING_DATA; + } + else + { + OctetLength = m_DataAtExecData.dataValue._length; + } + + if (StrLen_or_Ind == SQL_NTS) + StrLen = strlen((const char *)DataPtr); + else + StrLen = StrLen_or_Ind; + + OctetLength += StrLen; + AllocDataPtr = new BYTE[OctetLength]; + + if (m_DataAtExecData.dataValue._buffer != NULL) + { + memcpy((unsigned char *)AllocDataPtr, (unsigned char*)m_DataAtExecData.dataValue._buffer, m_DataAtExecData.dataValue._length); + delete m_DataAtExecData.dataValue._buffer; + m_DataAtExecData.dataValue._buffer = NULL; + } + + m_DataAtExecData.dataValue._buffer = (unsigned char *)AllocDataPtr; + memcpy(m_DataAtExecData.dataValue._buffer + m_DataAtExecData.dataValue._length, DataPtr, StrLen); + + m_DataAtExecData.dataValue._length = OctetLength; + m_StmtState = STMT_PUT_DATA_CALLED; + + return rc; + } + m_CurrentOdbcAPI = SQL_API_SQLPUTDATA; clearError(); if (m_CurrentParam == -1) @@ -3505,6 +3577,12 @@ BOOL CStmt::setFetchOutputPerf(SQL_DataValue_def*& outputDataValue, long rowsFet memOffSet += SQLMaxLength + 2; } break; + case SQLTYPECODE_BLOB: + case SQLTYPECODE_CLOB: + memOffSet = ((memOffSet + 2 - 1) >> 1) << 1; + VarOffSet = memOffSet; + memOffSet += SQLMaxLength + 2; + break; case SQLTYPECODE_INTERVAL: VarOffSet = memOffSet; memOffSet += SQLMaxLength; @@ -4879,3 +4957,234 @@ long CStmt::getColumnOffset(short columnNumber) totalLength = ((totalLength + 4 - 1) >> 2) << 2; return *(long*)(&m_outputDataValue._buffer[totalLength + columnOffset]); } + +SQLRETURN CStmt::SendExtractLob(IDL_short extractType, + IDL_string lobHandle, + IDL_long lobHandleLen, + IDL_long &extractLen, + BYTE * &extractData) +{ + SQLRETURN rc = SQL_SUCCESS; + + m_SrvrCallContext.odbcAPI = SRVR_API_EXTRACTLOB; + m_SrvrCallContext.sqlHandle = this; + m_SrvrCallContext.SQLSvc_ObjRef = m_ConnectHandle->getSrvrObjRef(); + m_SrvrCallContext.ASSvc_ObjRef = NULL; + m_SrvrCallContext.eventHandle = m_StmtEvent; + m_SrvrCallContext.dialogueId = m_ConnectHandle->getDialogueId(); + m_SrvrCallContext.connectionTimeout = m_ConnectHandle->getConnectionTimeout(); + m_SrvrCallContext.u.fetchParams.queryTimeout = m_QueryTimeout; + m_SrvrCallContext.u.extractLobParams.extractType = extractType; + m_SrvrCallContext.u.extractLobParams.lobHandle = lobHandle; + m_SrvrCallContext.u.extractLobParams.lobHandleLen = lobHandleLen; + m_SrvrCallContext.u.extractLobParams.extractLen = extractLen; + m_SrvrCallContext.u.extractLobParams.extractData = extractData; + + if (m_AsyncEnable == SQL_ASYNC_ENABLE_ON) + { + if ((m_AsyncThread = (HANDLE)_beginthreadex(NULL, 0, ThreadControlProc, + &m_SrvrCallContext, CREATE_SUSPENDED, &m_ThreadAddr)) == 0) + { + setNTError(m_ConnectHandle->getErrorMsgLang(), "SendExtractLob - _beginthreadex()"); + rc = SQL_ERROR; + } + ResumeThread(m_AsyncThread); + rc = SQL_STILL_EXECUTING; + Sleep(0); + } + else + { + if ((m_SyncThread = (HANDLE)_beginthreadex(NULL, 0, ThreadControlProc, + &m_SrvrCallContext, CREATE_SUSPENDED, &m_ThreadAddr)) == 0) + { + setNTError(m_ConnectHandle->getErrorMsgLang(), "SendExtractLob - _beginthreadex()"); + rc = SQL_ERROR; + } + else + { + ResumeThread(m_SyncThread); + WaitForSingleObject(m_SyncThread, INFINITE); + GetExitCodeThread(m_SyncThread, &m_ThreadStatus); + rc = m_ThreadStatus; + CloseHandle(m_SyncThread); + m_SyncThread = NULL; + } + } + + if (rc == SQL_SUCCESS) + { + extractLen = m_SrvrCallContext.u.extractLobParams.extractLen; + extractData = m_SrvrCallContext.u.extractLobParams.extractData; + + if (m_ConnectHandle->lobHandleSave != NULL) + free(m_ConnectHandle->lobHandleSave); + + m_ConnectHandle->lobHandleSave = (IDL_string)malloc(lobHandleLen); + memcpy(m_ConnectHandle->lobHandleSave, lobHandle, lobHandleLen); + m_ConnectHandle->lobHandleLenSave = lobHandleLen; + } + + return rc; +} + +SQLRETURN CStmt::ExtractLob(IDL_short extractType, + IDL_string lobHandle, + IDL_long lobHandleLen, + IDL_long &extractLen, + BYTE * &extractData) +{ + SQLRETURN rc = SQL_SUCCESS; + BOOL SkipProcess = FALSE; + + m_CurrentOdbcAPI = SRVR_API_EXTRACTLOB; + if (m_AsyncEnable == SQL_ASYNC_ENABLE_ON) + { + if (m_AsyncThread != NULL) + { + if (GetExitCodeThread(m_AsyncThread, &m_ThreadStatus)) + { + if (m_ThreadStatus == STILL_ACTIVE) + rc = SQL_STILL_EXECUTING; + else + { + CloseHandle(m_AsyncThread); + m_AsyncThread = NULL; + if (m_AsyncCanceled == TRUE) + rc = SQL_ERROR; + else + rc = m_ThreadStatus; + } + } + else + { + CloseHandle(m_AsyncThread); + m_AsyncThread = NULL; + setNTError(m_ConnectHandle->getErrorMsgLang(), "Fetch - GetExitCodeThread()"); + rc = SQL_ERROR; + } + } + else + { + if (m_ThreadStatus == SQL_STILL_EXECUTING) + SkipProcess = TRUE; + rc = SendExtractLob(extractType, lobHandle, lobHandleLen, extractLen, extractData); + } + } + else + rc = SendExtractLob(extractType, lobHandle, lobHandleLen, extractLen, extractData); + + return rc; +} + +SQLRETURN CStmt::SendUpdateLob(IDL_long updateType, + IDL_string lobHandle, + IDL_long lobHandleLen, + IDL_long_long totalLength, + IDL_long_long offset, + IDL_long_long pos, + IDL_long_long length, + BYTE * data) +{ + SQLRETURN rc = SQL_SUCCESS; + + m_SrvrCallContext.odbcAPI = SRVR_API_UPDATELOB; + m_SrvrCallContext.sqlHandle = this; + m_SrvrCallContext.SQLSvc_ObjRef = m_ConnectHandle->getSrvrObjRef(); + m_SrvrCallContext.ASSvc_ObjRef = NULL; + m_SrvrCallContext.eventHandle = m_StmtEvent; + m_SrvrCallContext.dialogueId = m_ConnectHandle->getDialogueId(); + m_SrvrCallContext.connectionTimeout = m_ConnectHandle->getConnectionTimeout(); + m_SrvrCallContext.u.fetchParams.queryTimeout = m_QueryTimeout; + m_SrvrCallContext.u.updateLobParams.updateType = updateType; + m_SrvrCallContext.u.updateLobParams.lobHandle = lobHandle; + m_SrvrCallContext.u.updateLobParams.lobHandleLen = lobHandleLen; + m_SrvrCallContext.u.updateLobParams.totalLength = totalLength; + m_SrvrCallContext.u.updateLobParams.offset = offset; + m_SrvrCallContext.u.updateLobParams.pos = pos; + m_SrvrCallContext.u.updateLobParams.length = length; + m_SrvrCallContext.u.updateLobParams.data = data; + + if (m_AsyncEnable == SQL_ASYNC_ENABLE_ON) + { + if ((m_AsyncThread = (HANDLE)_beginthreadex(NULL, 0, ThreadControlProc, + &m_SrvrCallContext, CREATE_SUSPENDED, &m_ThreadAddr)) == 0) + { + setNTError(m_ConnectHandle->getErrorMsgLang(), "SendExtractLob - _beginthreadex()"); + rc = SQL_ERROR; + } + ResumeThread(m_AsyncThread); + rc = SQL_STILL_EXECUTING; + Sleep(0); + } + else + { + if ((m_SyncThread = (HANDLE)_beginthreadex(NULL, 0, ThreadControlProc, + &m_SrvrCallContext, CREATE_SUSPENDED, &m_ThreadAddr)) == 0) + { + setNTError(m_ConnectHandle->getErrorMsgLang(), "SendExtractLob - _beginthreadex()"); + rc = SQL_ERROR; + } + else + { + ResumeThread(m_SyncThread); + WaitForSingleObject(m_SyncThread, INFINITE); + GetExitCodeThread(m_SyncThread, &m_ThreadStatus); + rc = m_ThreadStatus; + CloseHandle(m_SyncThread); + m_SyncThread = NULL; + } + } + + return rc; +} + +SQLRETURN CStmt::UpdateLob(IDL_long updateType, + IDL_string lobHandle, + IDL_long lobHandleLen, + IDL_long_long totalLength, + IDL_long_long offset, + IDL_long_long pos, + IDL_long_long length, + BYTE * data) +{ + SQLRETURN rc = SQL_SUCCESS; + BOOL SkipProcess = FALSE; + + if (m_AsyncEnable == SQL_ASYNC_ENABLE_ON) + { + if (m_AsyncThread != NULL) + { + if (GetExitCodeThread(m_AsyncThread, &m_ThreadStatus)) + { + if (m_ThreadStatus == STILL_ACTIVE) + rc = SQL_STILL_EXECUTING; + else + { + CloseHandle(m_AsyncThread); + m_AsyncThread = NULL; + if (m_AsyncCanceled == TRUE) + rc = SQL_ERROR; + else + rc = m_ThreadStatus; + } + } + else + { + CloseHandle(m_AsyncThread); + m_AsyncThread = NULL; + setNTError(m_ConnectHandle->getErrorMsgLang(), "Fetch - GetExitCodeThread()"); + rc = SQL_ERROR; + } + } + else + { + if (m_ThreadStatus == SQL_STILL_EXECUTING) + SkipProcess = TRUE; + rc = SendUpdateLob(updateType, lobHandle, lobHandleLen, totalLength, offset, pos, length, data); + } + } + else + rc = SendUpdateLob(updateType, lobHandle, lobHandleLen, totalLength, offset, pos, length, data); + + return rc; +} http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/cstmt.h ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/cstmt.h b/win-odbc64/odbcclient/drvr35/cstmt.h index 5bb2d20..98d4ea4 100644 --- a/win-odbc64/odbcclient/drvr35/cstmt.h +++ b/win-odbc64/odbcclient/drvr35/cstmt.h @@ -245,6 +245,33 @@ public: SQLRETURN SetPos(SQLUSMALLINT RowNumber, SQLUSMALLINT Operation, SQLUSMALLINT LockType); + SQLRETURN CStmt::SendExtractLob(IDL_short extractType, + IDL_string lobHandle, + IDL_long lobHandleLen, + IDL_long &extractLen, + BYTE *& extractData); + + SQLRETURN ExtractLob(IDL_short extractType, + IDL_string lobHandle, + IDL_long lobHandleLen, + IDL_long &extractLen, + BYTE * &extractData); + SQLRETURN SendUpdateLob(IDL_long updateType, + IDL_string lobHandle, + IDL_long lobHandleLen, + IDL_long_long totalLength, + IDL_long_long offset, + IDL_long_long pos, + IDL_long_long length, + BYTE * data); + SQLRETURN UpdateLob(IDL_long updateType, + IDL_string lobHandle, + IDL_long lobHandleLen, + IDL_long_long totalLength, + IDL_long_long offset, + IDL_long_long pos, + IDL_long_long length, + BYTE * data); SQLRETURN setDescRec(const SQLItemDescList_def *IPDDescList, const SQLItemDescList_def *IRDDescList); inline BOOL getHeartBeatEnable() {return m_ConnectHandle->getHeartBeatEnable();}; http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp b/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp index d62ea29..1d338b6 100644 --- a/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp +++ b/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp @@ -275,6 +275,18 @@ unsigned long ODBC::ConvertCToSQL(SQLINTEGER ODBCAppVersion, if (errorMsg) *errorMsg = '\0'; + + if (SQLDataType == SQLTYPECODE_BLOB || SQLDataType == SQLTYPECODE_CLOB) + { + SQLINTEGER lob_len; + if (srcLength == SQL_NTS) + lob_len = strlen((const char *)srcDataPtr); + else + lob_len = srcLength; + memcpy((char *)targetDataPtr, &lob_len, sizeof(lob_len)); + memcpy((char *)targetDataPtr + 4, (const char *)srcDataPtr, targetLength > srcLength ? srcLength : targetLength); + return SQL_SUCCESS; + } //if (targetPrecision < 19) if (((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision <= 18)) || http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj b/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj index 0194e10..8613089 100755 --- a/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj +++ b/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj @@ -296,6 +296,7 @@ pause</Command> <ClCompile Include="drvrglobal.cpp" /> <ClCompile Include="drvrnet.cpp" /> <ClCompile Include="..\..\Common\ExpConvMxcs.cpp" /> + <ClCompile Include="lob.cpp" /> <ClCompile Include="netcommon.cpp" /> <ClCompile Include="netconnect.cpp" /> <ClCompile Include="netstmt.cpp" /> @@ -351,6 +352,7 @@ pause</Command> <ClInclude Include="drvrnet.h" /> <ClInclude Include="..\..\Common\DrvrSrvr.h" /> <ClInclude Include="..\..\Common\OdbcMsg.h" /> + <ClInclude Include="lob.h" /> <ClInclude Include="resource.h" /> <ClInclude Include="sqlconnect.h" /> <ClInclude Include="sqldesc.h" /> @@ -382,4 +384,4 @@ pause</Command> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> +</Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj.filters ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj.filters b/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj.filters index b7d1b70..40f4850 100644 --- a/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj.filters +++ b/win-odbc64/odbcclient/drvr35/drvr35_os.vcxproj.filters @@ -164,6 +164,9 @@ <ClCompile Include="..\..\Common\Compression.cpp"> <Filter>Interface Files</Filter> </ClCompile> + <ClCompile Include="lob.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ResourceCompile Include="drvr35.rc"> @@ -300,6 +303,9 @@ <ClInclude Include="..\..\Common\Compression.h"> <Filter>Interface Header Files</Filter> </ClInclude> + <ClInclude Include="lob.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <CustomBuildStep Include="drvr35.def"> http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/drvrglobal.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/drvrglobal.cpp b/win-odbc64/odbcclient/drvr35/drvrglobal.cpp index 730eb11..7f3950f 100755 --- a/win-odbc64/odbcclient/drvr35/drvrglobal.cpp +++ b/win-odbc64/odbcclient/drvr35/drvrglobal.cpp @@ -30,6 +30,7 @@ #include "DiagFunctions.h" #include <errno.h> #include "StaticLocking.h" +#include "DrvrSrvr.h" // Declare the global variable @@ -48,7 +49,9 @@ DWORD gTlsIndex_ErrorBuffer = TLS_OUT_OF_INDEXES; DATATYPE_TABLE gSQLDatatypeMap[] = { // conciseType, verboseType, datetimeIntervalCode, columnSizeAttr, decimalDigitsAttr, displaySizeAttr, octetLength, defaultType, typeName - {SQL_CHAR, SQL_CHAR, 0, SQL_DESC_LENGTH, 0, SQL_DESC_LENGTH, SQL_DESC_LENGTH, SQL_C_CHAR, "CHAR"}, + {TYPE_BLOB, SQL_CHAR, 0, SQL_DESC_LENGTH, 0, SQL_DESC_LENGTH, SQL_DESC_LENGTH, SQL_C_CHAR, "BLOB" }, + {TYPE_CLOB, SQL_CHAR, 0, SQL_DESC_LENGTH, 0, SQL_DESC_LENGTH, SQL_DESC_LENGTH, SQL_C_CHAR, "CLOB" }, + {SQL_CHAR, SQL_CHAR, 0, SQL_DESC_LENGTH, 0, SQL_DESC_LENGTH, SQL_DESC_LENGTH, SQL_C_CHAR, "CHAR"}, {SQL_VARCHAR, SQL_VARCHAR, 0, SQL_DESC_LENGTH, 0, SQL_DESC_LENGTH, SQL_DESC_LENGTH, SQL_C_CHAR, "VARCHAR"}, {SQL_LONGVARCHAR, SQL_LONGVARCHAR, 0, SQL_DESC_LENGTH, 0, SQL_DESC_LENGTH, SQL_DESC_LENGTH, SQL_C_CHAR, "LONG VARCHAR"}, {SQL_DECIMAL, SQL_DECIMAL, 0, SQL_DESC_PRECISION, SQL_DESC_SCALE, SQL_DESC_PRECISION, SQL_DESC_PRECISION, SQL_C_CHAR, "DECIMAL"}, http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/drvrnet.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/drvrnet.cpp b/win-odbc64/odbcclient/drvr35/drvrnet.cpp index 05d2f59..99bc0ec 100644 --- a/win-odbc64/odbcclient/drvr35/drvrnet.cpp +++ b/win-odbc64/odbcclient/drvr35/drvrnet.cpp @@ -77,6 +77,8 @@ UINT __stdcall ThreadControlProc(LPVOID pParam) case SQL_API_SQLCOLUMNPRIVILEGES: case SQL_API_SQLTABLEPRIVILEGES: case SQL_API_SQLFOREIGNKEYS: + case SRVR_API_EXTRACTLOB: + case SRVR_API_UPDATELOB: pStatement = (CStmt*)srvrCallContext->sqlHandle; pConnection = pStatement->getConnectHandle(); break; @@ -134,6 +136,16 @@ UINT __stdcall ThreadControlProc(LPVOID pParam) rc = SQLFETCH_(srvrCallContext); break; + case SRVR_API_EXTRACTLOB: + pConnection->m_srvrTCPIPSystem->odbcAPI = SRVR_API_EXTRACTLOB; + rc = EXTRACTLOB(srvrCallContext); + break; + + case SRVR_API_UPDATELOB: + pConnection->m_srvrTCPIPSystem->odbcAPI = SRVR_API_UPDATELOB; + rc = UPDATELOB(srvrCallContext); + break; + case SQL_API_SQLFREESTMT: rc = FREESTATEMENT(srvrCallContext); break; http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/drvrnet.h ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/drvrnet.h b/win-odbc64/odbcclient/drvr35/drvrnet.h index 04c0ca9..fa14cda 100644 --- a/win-odbc64/odbcclient/drvr35/drvrnet.h +++ b/win-odbc64/odbcclient/drvr35/drvrnet.h @@ -119,6 +119,25 @@ typedef struct SRVR_CALL_CONTEXT SQLUINTEGER valueNum; SQLPOINTER valueStr; } setConnectParams; + struct EXTRACTLOB_PARAMS + { + IDL_short extractType; + IDL_string lobHandle; + IDL_long lobHandleLen; + IDL_long extractLen; + BYTE * extractData; + } extractLobParams; + struct UPDATELOB_PARAMS + { + IDL_long updateType; + IDL_string lobHandle; + IDL_long lobHandleLen; + IDL_long_long totalLength; + IDL_long_long offset; + IDL_long_long pos; + IDL_long_long length; + BYTE * data; + } updateLobParams; SQLSMALLINT completionType; } u; @@ -145,6 +164,8 @@ extern "C" SQLRETURN SMDCATALOGS(SRVR_CALL_CONTEXT *srvrCallContext); extern "C" SQLRETURN SQLPREPARE_(SRVR_CALL_CONTEXT *srvrCallContext); extern "C" SQLRETURN SQLFETCH_(SRVR_CALL_CONTEXT *srvrCallContext); extern "C" SQLRETURN SQLEXECUTE_(SRVR_CALL_CONTEXT *srvrCallContext); +extern "C" SQLRETURN EXTRACTLOB(SRVR_CALL_CONTEXT *srvrCallContext); +extern "C" SQLRETURN UPDATELOB(SRVR_CALL_CONTEXT *srvrCallContext); extern "C" SQLRETURN checkNetStmt(SRVR_CALL_CONTEXT *srvrCallContext,CEE_status sts, char* procname); http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/lob.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/lob.cpp b/win-odbc64/odbcclient/drvr35/lob.cpp new file mode 100644 index 0000000..77f2a4b --- /dev/null +++ b/win-odbc64/odbcclient/drvr35/lob.cpp @@ -0,0 +1,79 @@ +/********************************************************************** +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ +********************************************************************/ +/************************************************************************** +**************************************************************************/ +// +// + +#include "lob.h" +#include "cconnect.h" +#include "cstmt.h" + +namespace ODBC { + IDL_long getLobLength(CConnect *m_ConnectHandle, SQLHANDLE InputHandle, IDL_string lobHandle, IDL_long lobHandleLen) + { + SQLHSTMT hstmt; + m_ConnectHandle->AllocHandle(SQL_HANDLE_STMT, InputHandle, &hstmt); + + IDL_long totalLength; + BYTE * data; + CStmt *pStatement = (CStmt *)hstmt; + pStatement->ExtractLob(0, + lobHandle, lobHandleLen, totalLength, data); + pStatement->Close(SQL_CLOSE); + return totalLength; + } + + bool getLobData(CConnect *m_ConnectHandle, SQLHANDLE InputHandle, IDL_string lobHandle, IDL_long lobHandleLen, SQLPOINTER target, IDL_long &length) + { + SQLHSTMT hstmt; + m_ConnectHandle->AllocHandle(SQL_HANDLE_STMT, InputHandle, &hstmt); + + IDL_long totalLength = 0; + BYTE * data; + CStmt *pStatement = (CStmt *)hstmt; + IDL_long extractLen = length; + + if (pStatement->ExtractLob(1, + lobHandle, lobHandleLen, extractLen, data) != SQL_SUCCESS) + { + pStatement->Close(SQL_CLOSE); + return false; + } + + if (length > extractLen) + { + memcpy(target, data, extractLen); + length = extractLen; + } + else + { + length = 0; + } + + pStatement->Close(SQL_CLOSE); + + return true; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/lob.h ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/lob.h b/win-odbc64/odbcclient/drvr35/lob.h new file mode 100644 index 0000000..1b65522 --- /dev/null +++ b/win-odbc64/odbcclient/drvr35/lob.h @@ -0,0 +1,38 @@ +/********************************************************************** +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ +********************************************************************/ +/************************************************************************** +**************************************************************************/ +// +// + +#ifndef _LOB_DEFINED +#define _LOB_DEFINED +#include "cconnect.h" +namespace ODBC { + bool getLobData(CConnect *m_ConnectHandle, SQLHANDLE InputHandle, IDL_string lobHandle, IDL_long lobHandleLen, SQLPOINTER target, IDL_long &length); + + IDL_long getLobLength(CConnect *m_ConnectHandle, SQLHANDLE InputHandle, IDL_string lobHandle, IDL_long lobHandleLen); + +}; + +#endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/netstmt.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/netstmt.cpp b/win-odbc64/odbcclient/drvr35/netstmt.cpp index 38e09c4..0168916 100644 --- a/win-odbc64/odbcclient/drvr35/netstmt.cpp +++ b/win-odbc64/odbcclient/drvr35/netstmt.cpp @@ -1159,3 +1159,98 @@ SQLRETURN SQLEXECUTE_(SRVR_CALL_CONTEXT *srvrCallContext) } /* SQLEXECUTE_() */ + +SQLRETURN EXTRACTLOB(SRVR_CALL_CONTEXT *srvrCallContext) +{ + CEE_status sts; + SQLRETURN rc = SQL_SUCCESS; + + struct odbc_SQLsvc_ExtractLob_exc_ exception_ = { 0, 0, 0 }; + BYTE *sqlWarningOrError = 0; + + CStmt * pStatement = (CStmt *)srvrCallContext->sqlHandle; + + sts = odbc_SQLDrvr_ExtractLOB_pst_( + srvrCallContext, + srvrCallContext->u.extractLobParams.extractType, + srvrCallContext->u.extractLobParams.lobHandle, + srvrCallContext->u.extractLobParams.lobHandleLen, + srvrCallContext->u.extractLobParams.extractLen, + &exception_, + srvrCallContext->u.extractLobParams.extractData + ); + + pStatement->setExceptionErrors(exception_.exception_nr, exception_.exception_detail); + switch (exception_.exception_nr) + { + case CEE_SUCCESS: + break; + case odbc_SQLSvc_ExtractLob_SQLError_exn_: + pStatement->setDiagRec(&exception_.u.SQLError); + break; + case odbc_SQLSvc_ExtractLob_InvalidConnection_exn_: + pStatement->setDiagRec(SERVER_ERROR, IDS_08_S01); + break; + case odbc_SQLSvc_ExtractLob_ParamError_exn_: + pStatement->setDiagRec(SERVER_ERROR, IDS_HY_C00, exception_.exception_nr, + exception_.u.ParamError.ParamDesc, NULL, + SQL_ROW_NUMBER_UNKNOWN, SQL_COLUMN_NUMBER_UNKNOWN, 1, pStatement->getSrvrIdentity()); + break; + case odbc_SQLSvc_ExtractLob_SQLInvalidhandle_exn_: + break; + default: + pStatement->sendCDInfo(exception_.exception_nr); + pStatement->setDiagRec(exception_.exception_nr, "EXTRACTLOB", pStatement->getSrvrIdentity()); + break; + } + return rc; +} + +SQLRETURN UPDATELOB(SRVR_CALL_CONTEXT *srvrCallContext) +{ + CEE_status sts; + SQLRETURN rc = SQL_SUCCESS; + + struct odbc_SQLSvc_UpdateLob_exc_ exception_ = { 0, 0, 0 }; + BYTE *sqlWarningOrError = 0; + + CStmt * pStatement = (CStmt *)srvrCallContext->sqlHandle; + + sts = odbc_SQLDrvr_UpdateLob_pst_( + srvrCallContext, + srvrCallContext->u.updateLobParams.updateType, + srvrCallContext->u.updateLobParams.lobHandle, + srvrCallContext->u.updateLobParams.lobHandleLen, + srvrCallContext->u.updateLobParams.totalLength, + srvrCallContext->u.updateLobParams.offset, + srvrCallContext->u.updateLobParams.pos, + srvrCallContext->u.updateLobParams.length, + srvrCallContext->u.updateLobParams.data, + &exception_ + ); + + pStatement->setExceptionErrors(exception_.exception_nr, exception_.exception_detail); + switch (exception_.exception_nr) + { + case CEE_SUCCESS: + break; + case odbc_SQLSvc_UpdateLob_SQLError_exn_: + pStatement->setDiagRec(&exception_.u.SQLError); + break; + case odbc_SQLSvc_UpdateLob_InvalidConnect_exn_: + pStatement->setDiagRec(SERVER_ERROR, IDS_08_S01); + break; + case odbc_SQLSvc_UpdateLob_ParamError_exn_: + pStatement->setDiagRec(SERVER_ERROR, IDS_HY_C00, exception_.exception_nr, + exception_.u.ParamError.ParamDesc, NULL, + SQL_ROW_NUMBER_UNKNOWN, SQL_COLUMN_NUMBER_UNKNOWN, 1, pStatement->getSrvrIdentity()); + break; + case odbc_SQLSvc_UpdateLob_SQLInvalidhandle_exn_: + break; + default: + pStatement->sendCDInfo(exception_.exception_nr); + pStatement->setDiagRec(exception_.exception_nr, "UPDATELOB", pStatement->getSrvrIdentity()); + break; + } + return rc; +} http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/sqltocconv.cpp ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/sqltocconv.cpp b/win-odbc64/odbcclient/drvr35/sqltocconv.cpp index e597135..062cca3 100755 --- a/win-odbc64/odbcclient/drvr35/sqltocconv.cpp +++ b/win-odbc64/odbcclient/drvr35/sqltocconv.cpp @@ -32,6 +32,7 @@ #include "nskieee.h" #include "DiagFunctions.h" #include "csconvert.h" +#include "lob.h" #include <errno.h> #define MAXCHARLEN 32768 //32K @@ -153,7 +154,9 @@ unsigned long ODBC::BigNum_To_Ascii_Helper(char * source, // totalReturnedLength is a Input/Output parameter // *totalReturnedLength = Offset in Input // srcLength includes NULL for SQL_CHAR Type, hence srcLength is srcLength-1 for SQL_CHAR fields -unsigned long ODBC::ConvertSQLToC(SQLINTEGER ODBCAppVersion, +unsigned long ODBC::ConvertSQLToC(CConnect *m_ConnectHandle, + SQLHANDLE InputHandle, + SQLINTEGER ODBCAppVersion, DWORD DataLangId, SQLSMALLINT SQLDataType, SQLSMALLINT ODBCDataType, @@ -373,6 +376,29 @@ unsigned long ODBC::ConvertSQLToC(SQLINTEGER ODBCAppVersion, if (srcDataPtr == NULL) return IDS_HY_000; + if (SQLDataType == SQLTYPECODE_BLOB || SQLDataType == SQLTYPECODE_CLOB) + { + if (srcPrecision >= 0xFFFFFFF) + { + DataLen = *(int *)srcDataPtr; + DataPtr = (char *)srcDataPtr + 4; + } + else + { + DataLen = *(USHORT *)srcDataPtr; + DataPtr = (char *)srcDataPtr + 2; + } + + IDL_long dataRead = targetLength; + if (getLobData(m_ConnectHandle, InputHandle, (IDL_string)DataPtr, DataLen, targetDataPtr, dataRead) != true) + return SQL_ERROR; + + if (targetStrLenPtr != NULL) + *targetStrLenPtr = dataRead; + + if (dataRead <= 0) return SQL_NO_DATA; + return SQL_SUCCESS; + } // if(charsetSupport) LangId = LANG_NEUTRAL; http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/odbcclient/drvr35/sqltocconv.h ---------------------------------------------------------------------- diff --git a/win-odbc64/odbcclient/drvr35/sqltocconv.h b/win-odbc64/odbcclient/drvr35/sqltocconv.h index 00d4eaf..6ef1fe2 100644 --- a/win-odbc64/odbcclient/drvr35/sqltocconv.h +++ b/win-odbc64/odbcclient/drvr35/sqltocconv.h @@ -33,7 +33,9 @@ namespace ODBC { -unsigned long ConvertSQLToC(SQLINTEGER ODBCAppVersion, +unsigned long ConvertSQLToC(CConnect *ConnectHandle, + SQLHANDLE InputHandle, + SQLINTEGER ODBCAppVersion, DWORD DataLangId, SQLSMALLINT SQLDataType, SQLSMALLINT ODBCDataType, http://git-wip-us.apache.org/repos/asf/trafodion/blob/f70b19c1/win-odbc64/sql/cli/sqlcli.h ---------------------------------------------------------------------- diff --git a/win-odbc64/sql/cli/sqlcli.h b/win-odbc64/sql/cli/sqlcli.h index fc964fb..478c3fb 100644 --- a/win-odbc64/sql/cli/sqlcli.h +++ b/win-odbc64/sql/cli/sqlcli.h @@ -418,6 +418,10 @@ enum SQLTYPE_CODE { /* SQL/MP stype VARCHAR with length prefix: Tandem Extension */ SQLTYPECODE_VARCHAR_WITH_LENGTH = -601, + /* BLOB TYPE */ + SQLTYPECODE_BLOB = -602, + SQLTYPECODE_CLOB = -603, + /* LONG VARCHAR/ODBC CHARACTER VARYING */ SQLTYPECODE_VARCHAR_LONG = -1, /* ## NEGATIVE??? */
