diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2008-12-30 13:32:01 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2008-12-30 13:32:01 +0000 |
commit | 0416c98d433be40fe2e2d0199ebaa8d029e8e338 (patch) | |
tree | 8b781a46dcb4bc28ea9405e6c8591d7b1f9b21ea /connectivity/source/drivers/odbcbase/OTools.cxx | |
parent | 1de383819e70ec2816447d6b621695d178eeb9ee (diff) |
CWS-TOOLING: integrate CWS sb102
2008-12-11 16:18:12 +0100 sb r265332 : #i95065# cleanup, to make Windows linking work
2008-12-11 16:16:03 +0100 sb r265331 : #i95065# missing SAL_DLLPUBLIC_EXPORT
2008-12-09 17:40:28 +0100 sb r265122 : #i94469# move CJK specific configuration data to brand layer
2008-12-09 16:09:08 +0100 sb r265112 : #i96959# use PTHREAD_MUTEX_RECURSIVE on all platforms
2008-12-09 15:54:31 +0100 sb r265110 : #i95065# do not derive apphelper::LifeTimeGuard from osl::ResettableMutexGuard to avoid problems with VISIBILITY_HIDDEN=TRUE on MSC
2008-12-09 15:40:51 +0100 sb r265104 : #i95065# add VISIBILITY_HIDDEN=TRUE to connectivity/source/drivers/mozab
2008-12-09 15:36:21 +0100 sb r265102 : #i95501# updated SDK_HOME
2008-12-09 15:31:46 +0100 sb r265099 : typo (temppath vs. tmppath)
2008-12-08 11:48:08 +0100 sb r264979 : #i95065# removed spurious ExplicitCategoriesProvider.obj (ExplicitCategoriesProvider.cxx is not in this directory)
2008-12-07 19:41:07 +0100 sb r264960 : #i96994# erroneously doubled backslash caused visibility feature to be disabled for all GCC versions on Mac OS X
2008-12-06 23:54:49 +0100 sb r264948 : changes from trunk that CWS-TOOLING's rebase to DEV300:m37 (r264891) had missed, as files had been moved around on this CWS
2008-12-05 20:29:23 +0100 sb r264919 : #i85508# versions of flex apparently differ in whether input() resp. yyinput() returns zero or EOF upon end of file
2008-12-05 15:37:23 +0100 sb r264908 : #i95315# removed obsolete jut
2008-12-05 15:34:59 +0100 sb r264907 : #i95531# removed empty obsolete directories
2008-12-05 10:09:23 +0100 sb r264891 : CWS-TOOLING: rebase CWS sb102 to trunk@264807 (milestone: DEV300:m37)
2008-12-04 14:50:20 +0100 sb r264845 : #i95065# introduced VISIBILITY_HIDDEN makefile flag to reduce duplications; made additional libraries use VISIBILITY_HIDDEN=TRUE to avoid warnings with recent GCC 4 versions (had to split certain code directories to make changes that would otherwise erroneously affect multiple libraries built in the same makefile); changed connectivity::ORefVector to no longer derive from std::vector, as that caused problems with the MSC implementation of VISIBILITY_HIDDEN=TRUE; replaced uses of JNIEXPORT with SAL_DLLPUBLIC_EXPORT, as the former does not expand to visibility attributes on some platforms where the latter does
2008-12-03 11:29:38 +0100 sb r264759 : #i94583# remove unnecessary (and wrong) assertion check for rtl_getAppCommandArg return value (which is guaranteed to return osl_Process_E_None or not return at all)
2008-12-02 17:18:31 +0100 sb r264724 : #i96809# silenced GCC 4.3.2 warning
2008-12-02 13:29:34 +0100 sb r264695 : #i96797# make get_tmp_dir fail less often
2008-11-28 17:19:24 +0100 sb r264566 : #i95691# inadvertently missing from -c 264564
2008-11-28 17:07:50 +0100 sb r264564 : #i95691# only structs of exactly 1, 2, 4, or 8 bytes are returned through registers
2008-11-25 13:28:08 +0100 sb r264291 : #i96427# support for SAL_EXCEPTION_DLLPUBLIC_EXPORT (patch by np)
2008-11-21 14:45:22 +0100 sb r264140 : #i95428# added SAL_EXCEPTION_DLLPUBLIC_EXPORT and SAL_EXCEPTION_DLLPRIVATE
2008-11-19 13:19:37 +0100 sb r263984 : #i95525# removed erroneous application/octet-stream svn:mime-type properties
Diffstat (limited to 'connectivity/source/drivers/odbcbase/OTools.cxx')
-rw-r--r-- | connectivity/source/drivers/odbcbase/OTools.cxx | 932 |
1 files changed, 932 insertions, 0 deletions
diff --git a/connectivity/source/drivers/odbcbase/OTools.cxx b/connectivity/source/drivers/odbcbase/OTools.cxx new file mode 100644 index 000000000000..1b6ea0829926 --- /dev/null +++ b/connectivity/source/drivers/odbcbase/OTools.cxx @@ -0,0 +1,932 @@ +/************************************************************************ + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OTools.cxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_connectivity.hxx" +#include "odbc/OTools.hxx" +#include "odbc/OFunctions.hxx" +#include <com/sun/star/sdbc/DataType.hpp> +#include <osl/diagnose.h> +#include "odbc/OConnection.hxx" +#include "diagnose_ex.h" + +#include <string.h> +#include <string> +#include <algorithm> + +using namespace connectivity::odbc; +using namespace com::sun::star::uno; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::util; + +void OTools::getValue( OConnection* _pConnection, + SQLHANDLE _aStatementHandle, + sal_Int32 columnIndex, + SQLSMALLINT _nType, + sal_Bool &_bWasNull, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface, + void* _pValue, + SQLINTEGER _rSize) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + SQLINTEGER pcbValue = SQL_NULL_DATA; + OTools::ThrowException(_pConnection, + (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + _nType, + _pValue, + (SQLINTEGER)_rSize, + &pcbValue), + _aStatementHandle,SQL_HANDLE_STMT,_xInterface,sal_False); + _bWasNull = pcbValue == SQL_NULL_DATA; +} +// ----------------------------------------------------------------------------- +void OTools::bindParameter( OConnection* _pConnection, + SQLHANDLE _hStmt, + sal_Int32 nPos, + sal_Int8*& pDataBuffer, + sal_Int8* pLenBuffer, + SQLSMALLINT _nODBCtype, + sal_Bool _bUseWChar, + sal_Bool _bUseOldTimeDate, + const void* _pValue, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface, + rtl_TextEncoding _nTextEncoding) + throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + SQLRETURN nRetcode; + SWORD fSqlType; + SWORD fCType; + SDWORD nMaxLen = 0; + // void*& pData = pDataBuffer; + SQLINTEGER* pLen = (SQLINTEGER*)pLenBuffer; + SQLUINTEGER nColumnSize=0; + SQLSMALLINT nDecimalDigits=0; + + OTools::getBindTypes(_bUseWChar,_bUseOldTimeDate,_nODBCtype,fCType,fSqlType); + + OTools::bindData(_nODBCtype,_bUseWChar,pDataBuffer,pLen,_pValue,_nTextEncoding,nColumnSize); + if ((nColumnSize == 0) && (fSqlType == SQL_CHAR || fSqlType == SQL_VARCHAR || fSqlType == SQL_LONGVARCHAR)) + nColumnSize = 1; + + if(fSqlType == SQL_LONGVARCHAR || fSqlType == SQL_LONGVARBINARY) + memcpy(pDataBuffer,&nPos,sizeof(nPos)); + + // 20.09.2001 OJ: Problems with mysql. mysql returns only CHAR as parameter type + // nRetcode = (*(T3SQLDescribeParam)_pConnection->getOdbcFunction(ODBC3SQLDescribeParam))(_hStmt,(SQLUSMALLINT)nPos,&fSqlType,&nColumnSize,&nDecimalDigits,&nNullable); + + nRetcode = (*(T3SQLBindParameter)_pConnection->getOdbcFunction(ODBC3SQLBindParameter))(_hStmt, + (SQLUSMALLINT)nPos, + SQL_PARAM_INPUT, + fCType, + fSqlType, + nColumnSize, + nDecimalDigits, + pDataBuffer, + nMaxLen, + pLen); + + OTools::ThrowException(_pConnection,nRetcode,_hStmt,SQL_HANDLE_STMT,_xInterface); +} +// ----------------------------------------------------------------------------- +void OTools::bindData( SQLSMALLINT _nOdbcType, + sal_Bool _bUseWChar, + sal_Int8 *&_pData, + SQLINTEGER*& pLen, + const void* _pValue, + rtl_TextEncoding _nTextEncoding, + SQLUINTEGER& _nColumnSize) +{ + _nColumnSize = 0; + + switch (_nOdbcType) + { + case SQL_CHAR: + case SQL_VARCHAR: + if(_bUseWChar) + { + *pLen = SQL_NTS; + ::rtl::OUString sStr(*(::rtl::OUString*)_pValue); + _nColumnSize = sStr.getLength(); + *((rtl::OUString*)_pData) = sStr; + + // Zeiger auf Char* + _pData = (sal_Int8*)((rtl::OUString*)_pData)->getStr(); + } + else + { + ::rtl::OString aString(::rtl::OUStringToOString(*(::rtl::OUString*)_pValue,_nTextEncoding)); + *pLen = SQL_NTS; + _nColumnSize = aString.getLength(); + memcpy(_pData,aString.getStr(),aString.getLength()); + ((sal_Int8*)_pData)[aString.getLength()] = '\0'; + } + break; + + case SQL_BIGINT: + *((sal_Int64*)_pData) = *(sal_Int64*)_pValue; + *pLen = sizeof(sal_Int64); + _nColumnSize = *pLen; + break; + case SQL_DECIMAL: + case SQL_NUMERIC: + if(_bUseWChar) + { + ::rtl::OUString aString = rtl::OUString::valueOf(*(double*)_pValue); + _nColumnSize = aString.getLength(); + *pLen = _nColumnSize; + *((rtl::OUString*)_pData) = aString; + // Zeiger auf Char* + _pData = (sal_Int8*)((rtl::OUString*)_pData)->getStr(); + } + else + { + ::rtl::OString aString = ::rtl::OString::valueOf(*(double*)_pValue); + _nColumnSize = aString.getLength(); + *pLen = _nColumnSize; + memcpy(_pData,aString.getStr(),aString.getLength()); + ((sal_Int8*)_pData)[_nColumnSize] = '\0'; + } break; + case SQL_BIT: + case SQL_TINYINT: + *((sal_Int8*)_pData) = *(sal_Int8*)_pValue; + *pLen = sizeof(sal_Int8); + break; + + case SQL_SMALLINT: + *((sal_Int16*)_pData) = *(sal_Int16*)_pValue; + *pLen = sizeof(sal_Int16); + break; + case SQL_INTEGER: + *((sal_Int32*)_pData) = *(sal_Int32*)_pValue; + *pLen = sizeof(sal_Int32); + break; + case SQL_FLOAT: + *((float*)_pData) = *(float*)_pValue; + *pLen = sizeof(float); + break; + case SQL_REAL: + case SQL_DOUBLE: + *((double*)_pData) = *(double*)_pValue; + *pLen = sizeof(double); + break; + case SQL_BINARY: + case SQL_VARBINARY: + { + const ::com::sun::star::uno::Sequence< sal_Int8 >* pSeq = static_cast< const ::com::sun::star::uno::Sequence< sal_Int8 >* >(_pValue); + OSL_ENSURE(pSeq,"OTools::bindData: Sequence is null!"); + + if(pSeq) + { + // memcpy(_pData,pSeq->getConstArray(),pSeq->getLength()); + _pData = (sal_Int8*)((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getConstArray(); + *pLen = pSeq->getLength(); + } + // _pData = (sal_Int8*)((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getConstArray(); + // *pLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength(); + } + break; + case SQL_LONGVARBINARY: + { + sal_Int32 nLen = 0; + nLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength(); + *pLen = (SDWORD)SQL_LEN_DATA_AT_EXEC(nLen); + } + break; + case SQL_LONGVARCHAR: + { + sal_Int32 nLen = 0; + if(_bUseWChar) + nLen = sizeof(sal_Unicode) * ((::rtl::OUString*)_pValue)->getLength(); + else + { + ::rtl::OString aString(::rtl::OUStringToOString(*(::rtl::OUString*)_pValue,_nTextEncoding)); + nLen = aString.getLength(); + } + *pLen = (SDWORD)SQL_LEN_DATA_AT_EXEC(nLen); + } break; + case SQL_DATE: + *(DATE_STRUCT*)_pData = *(DATE_STRUCT*)_pValue; + *pLen = (SDWORD)sizeof(DATE_STRUCT); + _nColumnSize = 10; + break; + case SQL_TIME: + *(TIME_STRUCT*)_pData = *(TIME_STRUCT*)_pValue; + *pLen = (SDWORD)sizeof(TIME_STRUCT); + _nColumnSize = 8; + break; + case SQL_TIMESTAMP: + *(TIMESTAMP_STRUCT*)_pData = *(TIMESTAMP_STRUCT*)_pValue; + *pLen = (SDWORD)sizeof(TIMESTAMP_STRUCT); + _nColumnSize = 19; + break; + } +} +// ------------------------------------------------------------------------- +void OTools::bindValue( OConnection* _pConnection, + SQLHANDLE _aStatementHandle, + sal_Int32 columnIndex, + SQLSMALLINT _nType, + SQLSMALLINT _nMaxLen, + const void* _pValue, + void* _pData, + SQLINTEGER *pLen, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface, + rtl_TextEncoding _nTextEncoding, + sal_Bool _bUseOldTimeDate) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +{ + SQLRETURN nRetcode; + SQLSMALLINT fSqlType; + SQLSMALLINT fCType; + SQLSMALLINT nMaxLen = _nMaxLen; + + OTools::getBindTypes( sal_False, + _bUseOldTimeDate, + _nType, + fCType, + fSqlType); + + if (columnIndex != 0 && !_pValue) + { + *pLen = SQL_NULL_DATA; + nRetcode = (*(T3SQLBindCol)_pConnection->getOdbcFunction(ODBC3SQLBindCol))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + fCType, + _pData, + nMaxLen, + pLen + ); + } + else + { + try + { + switch (_nType) + { + case SQL_CHAR: + case SQL_VARCHAR: + //if(GetODBCConnection()->m_bUserWChar) +// { +// _nMaxLen = rCol.GetPrecision(); +// *pLen = SQL_NTS; +// *((rtl::OUString*)pData) = (rtl::OUString)_aValue; +// +// // Zeiger auf Char* +// pData = (void*)((rtl::OUString*)pData)->getStr(); +// } +// else + { + ::rtl::OString aString(::rtl::OUStringToOString(*(::rtl::OUString*)_pValue,_nTextEncoding)); + *pLen = SQL_NTS; + *((::rtl::OString*)_pData) = aString; + _nMaxLen = (SQLSMALLINT)aString.getLength(); + + // Zeiger auf Char* + _pData = (void*)aString.getStr(); + } break; + case SQL_BIGINT: + *((sal_Int64*)_pData) = *(sal_Int64*)_pValue; + *pLen = sizeof(sal_Int64); + break; + case SQL_DECIMAL: + case SQL_NUMERIC: + //if(GetODBCConnection()->m_bUserWChar) +// { +// rtl::OUString aString(rtl::OUString(SdbTools::ToString(ODbTypeConversion::toDouble(*pVariable),rCol.GetScale()))); +// *pLen = _nMaxLen; +// *((rtl::OUString*)_pData) = aString; +// // Zeiger auf Char* +// _pData = (void*)((rtl::OUString*)_pData)->getStr(); +// } +// else + { + ::rtl::OString aString = ::rtl::OString::valueOf(*(double*)_pValue); + _nMaxLen = (SQLSMALLINT)aString.getLength(); + *pLen = _nMaxLen; + *((::rtl::OString*)_pData) = aString; + // Zeiger auf Char* + _pData = (void*)((::rtl::OString*)_pData)->getStr(); + } break; + case SQL_BIT: + case SQL_TINYINT: + *((sal_Int8*)_pData) = *(sal_Int8*)_pValue; + *pLen = sizeof(sal_Int8); + break; + + case SQL_SMALLINT: + *((sal_Int16*)_pData) = *(sal_Int16*)_pValue; + *pLen = sizeof(sal_Int16); + break; + case SQL_INTEGER: + *((sal_Int32*)_pData) = *(sal_Int32*)_pValue; + *pLen = sizeof(sal_Int32); + break; + case SQL_FLOAT: + *((float*)_pData) = *(float*)_pValue; + *pLen = sizeof(float); + break; + case SQL_REAL: + case SQL_DOUBLE: + *((double*)_pData) = *(double*)_pValue; + *pLen = sizeof(double); + break; + case SQL_BINARY: + case SQL_VARBINARY: + // if (_pValue == ::getCppuType((const ::com::sun::star::uno::Sequence< sal_Int8 > *)0)) + { + _pData = (void*)((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getConstArray(); + *pLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength(); + } break; + case SQL_LONGVARBINARY: + { + _pData = (void*)(columnIndex); + sal_Int32 nLen = 0; + nLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength(); + *pLen = (SDWORD)SQL_LEN_DATA_AT_EXEC(nLen); + } + break; + case SQL_LONGVARCHAR: + { + _pData = (void*)(columnIndex); + sal_Int32 nLen = 0; + nLen = ((::rtl::OUString*)_pValue)->getLength(); + *pLen = (SDWORD)SQL_LEN_DATA_AT_EXEC(nLen); + } break; + case SQL_DATE: + *pLen = sizeof(DATE_STRUCT); + *((DATE_STRUCT*)_pData) = *(DATE_STRUCT*)_pValue; + break; + case SQL_TIME: + *pLen = sizeof(TIME_STRUCT); + *((TIME_STRUCT*)_pData) = *(TIME_STRUCT*)_pValue; + break; + case SQL_TIMESTAMP: + *pLen = sizeof(TIMESTAMP_STRUCT); + *((TIMESTAMP_STRUCT*)_pData) = *(TIMESTAMP_STRUCT*)_pValue; + } + } + catch ( ... ) + { + } + + nRetcode = (*(T3SQLBindCol)_pConnection->getOdbcFunction(ODBC3SQLBindCol))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + fCType, + _pData, + nMaxLen, + pLen + ); + } + + OTools::ThrowException(_pConnection,nRetcode,_aStatementHandle,SQL_HANDLE_STMT,_xInterface); +} +// ----------------------------------------------------------------------------- +void OTools::ThrowException(OConnection* _pConnection, + SQLRETURN _rRetCode, + SQLHANDLE _pContext, + SQLSMALLINT _nHandleType, + const Reference< XInterface >& _xInterface, + sal_Bool _bNoFound, + rtl_TextEncoding _nTextEncoding) throw(SQLException) +{ + switch(_rRetCode) + { + case SQL_NEED_DATA: + case SQL_STILL_EXECUTING: + case SQL_SUCCESS: + + case SQL_SUCCESS_WITH_INFO: + return; + case SQL_NO_DATA_FOUND: + if(_bNoFound) + return; // no need to throw a exception + case SQL_ERROR: break; + + + case SQL_INVALID_HANDLE: OSL_ENSURE(0,"SdbODBC3_SetStatus: SQL_INVALID_HANDLE"); + throw SQLException(); + } + + + // Zusaetliche Informationen zum letzten ODBC-Funktionsaufruf vorhanden. + // SQLError liefert diese Informationen. + + SDB_ODBC_CHAR szSqlState[5]; + SDWORD pfNativeError; + SDB_ODBC_CHAR szErrorMessage[SQL_MAX_MESSAGE_LENGTH]; + szErrorMessage[0] = '\0'; + SWORD pcbErrorMsg = 0; + + // Informationen zur letzten Operation: + // wenn hstmt != SQL_NULL_HSTMT ist (Benutzung von SetStatus in SdbCursor, SdbTable, ...), + // dann wird der Status des letzten Statements erfragt, sonst der Status des letzten + // Statements zu dieser Verbindung [was in unserem Fall wahrscheinlich gleichbedeutend ist, + // aber das Reference Manual drueckt sich da nicht so klar aus ...]. + // Entsprechend bei hdbc. + SQLRETURN n = (*(T3SQLGetDiagRec)_pConnection->getOdbcFunction(ODBC3SQLGetDiagRec))(_nHandleType,_pContext,1, + szSqlState, + &pfNativeError, + szErrorMessage,sizeof szErrorMessage - 1,&pcbErrorMsg); + OSL_UNUSED( n ); + OSL_ENSURE(n != SQL_INVALID_HANDLE,"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE"); + OSL_ENSURE(n == SQL_SUCCESS || n == SQL_SUCCESS_WITH_INFO || n == SQL_NO_DATA_FOUND || n == SQL_ERROR,"SdbODBC3_SetStatus: SQLError failed"); + + // Zum Return Code von SQLError siehe ODBC 2.0 Programmer's Reference Seite 287ff + throw SQLException( ::rtl::OUString((char *)szErrorMessage,pcbErrorMsg,_nTextEncoding), + _xInterface, + ::rtl::OUString((char *)szSqlState,5,_nTextEncoding), + pfNativeError, + Any() + ); + +} +// ------------------------------------------------------------------------- +Sequence<sal_Int8> OTools::getBytesValue(OConnection* _pConnection, + SQLHANDLE _aStatementHandle, + sal_Int32 columnIndex, + SWORD _fSqlType, + sal_Bool &_bWasNull, + const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException) +{ + char aCharArray[2048]; + // Erstmal versuchen, die Daten mit dem kleinen Puffer + // abzuholen: + SQLINTEGER nMaxLen = sizeof aCharArray - 1; + // GETDATA(SQL_C_CHAR,aCharArray,nMaxLen); + SQLINTEGER pcbValue = 0; + OTools::ThrowException(_pConnection,(*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + _fSqlType, + (SQLPOINTER)aCharArray, + (SQLINTEGER)nMaxLen, + &pcbValue), + _aStatementHandle,SQL_HANDLE_STMT,_xInterface); + + _bWasNull = pcbValue == SQL_NULL_DATA; + if(_bWasNull) + return Sequence<sal_Int8>(); + + SQLINTEGER nBytes = pcbValue != SQL_NO_TOTAL ? std::min(pcbValue, nMaxLen) : nMaxLen; + if ( ((pcbValue == SQL_NO_TOTAL) || pcbValue > nMaxLen) && aCharArray[nBytes-1] == 0 && nBytes > 0 ) + --nBytes; + Sequence<sal_Int8> aData((sal_Int8*)aCharArray, nBytes); + + + // Es handelt sich um Binaerdaten, um einen String, der fuer + // StarView zu lang ist oder der Treiber kann die Laenge der + // Daten nicht im voraus bestimmen - also als MemoryStream + // speichern. + while ((pcbValue == SQL_NO_TOTAL) || pcbValue > nMaxLen) + { + // Bei Strings wird der Puffer nie ganz ausgenutzt + // (das letzte Byte ist immer ein NULL-Byte, das + // aber bei pcbValue nicht mitgezaehlt wird) + if (pcbValue != SQL_NO_TOTAL && (pcbValue - nMaxLen) < nMaxLen) + nBytes = pcbValue - nMaxLen; + else + nBytes = nMaxLen; + + // Solange eine "truncation"-Warnung vorliegt, weiter Daten abholen + // GETDATA(SQL_C_CHAR,aCharArray, nLen + 1); + OTools::ThrowException(_pConnection,(*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + SQL_C_BINARY, + &aCharArray, + (SQLINTEGER)nBytes, + &pcbValue), + _aStatementHandle,SQL_HANDLE_STMT,_xInterface); + sal_Int32 nLen = aData.getLength(); + aData.realloc(nLen + nBytes); + memcpy(aData.getArray() + nLen, aCharArray, nBytes); + } + return aData; +} +// ------------------------------------------------------------------------- +::rtl::OUString OTools::getStringValue(OConnection* _pConnection, + SQLHANDLE _aStatementHandle, + sal_Int32 columnIndex, + SWORD _fSqlType, + sal_Bool &_bWasNull, + const Reference< XInterface >& _xInterface, + rtl_TextEncoding _nTextEncoding) throw(SQLException, RuntimeException) +{ + ::rtl::OUString aData; + switch(_fSqlType) + { + case SQL_WVARCHAR: + case SQL_WCHAR: + case SQL_WLONGVARCHAR: + { + sal_Unicode waCharArray[2048]; + // read the unicode data + sal_Int32 nMaxLen = (sizeof(waCharArray) / sizeof(sal_Unicode)) - 1; + // GETDATA(SQL_C_WCHAR, waCharArray, nMaxLen + sizeof(sal_Unicode)); + + SQLINTEGER pcbValue=0; + OTools::ThrowException(_pConnection,(*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + SQL_C_WCHAR, + &waCharArray, + (SQLINTEGER)nMaxLen*sizeof(sal_Unicode), + &pcbValue), + _aStatementHandle,SQL_HANDLE_STMT,_xInterface); + _bWasNull = pcbValue == SQL_NULL_DATA; + if(_bWasNull) + return ::rtl::OUString(); + // Bei Fehler bricht der GETDATA-Makro mit return ab, + // bei NULL mit break! + SQLINTEGER nLen = pcbValue != SQL_NO_TOTAL ? std::min(pcbValue, nMaxLen) : (nMaxLen-1); + waCharArray[nLen] = 0; + aData = ::rtl::OUString(waCharArray); + + // Es handelt sich um Binaerdaten, um einen String, der fuer + // StarView zu lang ist oder der Treiber kann die Laenge der + // Daten nicht im voraus bestimmen - also als MemoryStream + // speichern. + while ((pcbValue == SQL_NO_TOTAL ) || pcbValue > nMaxLen) + { + // Bei Strings wird der Puffer nie ganz ausgenutzt + // (das letzte Byte ist immer ein NULL-Byte, das + // aber bei pcbValue nicht mitgezaehlt wird) + if (pcbValue != SQL_NO_TOTAL && (pcbValue - nMaxLen) < nMaxLen) + nLen = pcbValue - nMaxLen; + else + nLen = nMaxLen; + + // Solange eine "truncation"-Warnung vorliegt, weiter Daten abholen + // GETDATA(SQL_C_CHAR,waCharArray, nLen + 1); + OTools::ThrowException(_pConnection,(*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + SQL_C_WCHAR, + &waCharArray, + (SQLINTEGER)nLen+1, + &pcbValue), + _aStatementHandle,SQL_HANDLE_STMT,_xInterface); + nLen = pcbValue != SQL_NO_TOTAL ? std::min(pcbValue, nMaxLen) : (nMaxLen-1); + waCharArray[nLen] = 0; + + aData += ::rtl::OUString(waCharArray); + } + } + break; + default: + { + char aCharArray[2048]; + // Erstmal versuchen, die Daten mit dem kleinen Puffer + // abzuholen: + SDWORD nMaxLen = sizeof aCharArray - 1; + // GETDATA(SQL_C_CHAR,aCharArray,nMaxLen); + SQLINTEGER pcbValue = 0; + OTools::ThrowException(_pConnection,(*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + SQL_C_CHAR, + &aCharArray, + (SQLINTEGER)nMaxLen, + &pcbValue), + _aStatementHandle,SQL_HANDLE_STMT,_xInterface); + _bWasNull = pcbValue == SQL_NULL_DATA; + if(_bWasNull) + return ::rtl::OUString(); + + SQLINTEGER nLen = pcbValue != SQL_NO_TOTAL ? std::min(pcbValue, nMaxLen) : (nMaxLen-1); + aCharArray[nLen] = 0; + if ( ((pcbValue == SQL_NO_TOTAL) || pcbValue > nMaxLen) && aCharArray[nLen-1] == 0 && nLen > 0 ) + --nLen; + aData = ::rtl::OUString((const sal_Char*)aCharArray,nLen, _nTextEncoding); + + // Es handelt sich um Binaerdaten, um einen String, der fuer + // StarView zu lang ist oder der Treiber kann die Laenge der + // Daten nicht im voraus bestimmen - also als MemoryStream + // speichern. + while ((pcbValue == SQL_NO_TOTAL) || pcbValue > nMaxLen) + { + // Solange eine "truncation"-Warnung vorliegt, weiter Daten abholen + // GETDATA(SQL_C_CHAR,aCharArray, nLen + 1); + OTools::ThrowException(_pConnection,(*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle, + (SQLUSMALLINT)columnIndex, + SQL_C_CHAR, + &aCharArray, + (SQLINTEGER)nMaxLen, + &pcbValue), + _aStatementHandle,SQL_HANDLE_STMT,_xInterface); + nLen = pcbValue != SQL_NO_TOTAL ? std::min(pcbValue, nMaxLen) : (nMaxLen-1); + if ( ((pcbValue == SQL_NO_TOTAL) || pcbValue > nMaxLen) && aCharArray[nLen-1] == 0 && nLen > 0 ) + --nLen; + aCharArray[nLen] = 0; + + aData += ::rtl::OUString((const sal_Char*)aCharArray,nLen,_nTextEncoding); + } + + // delete all blanks + // aData.EraseTrailingChars(); + } + } + + return aData; +} +// ------------------------------------------------------------------------- +void OTools::GetInfo(OConnection* _pConnection, + SQLHANDLE _aConnectionHandle, + SQLUSMALLINT _nInfo, + ::rtl::OUString &_rValue, + const Reference< XInterface >& _xInterface, + rtl_TextEncoding _nTextEncoding) throw(SQLException, RuntimeException) +{ + char aValue[512]; + SQLSMALLINT nValueLen=0; + OTools::ThrowException(_pConnection, + (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,aValue,(sizeof aValue)-1,&nValueLen), + _aConnectionHandle,SQL_HANDLE_DBC,_xInterface); + + _rValue = ::rtl::OUString(aValue,nValueLen,_nTextEncoding); +} +// ------------------------------------------------------------------------- +void OTools::GetInfo(OConnection* _pConnection, + SQLHANDLE _aConnectionHandle, + SQLUSMALLINT _nInfo, + sal_Int32 &_rValue, + const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException) +{ + SQLSMALLINT nValueLen; + _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION) + OTools::ThrowException(_pConnection, + (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen), + _aConnectionHandle,SQL_HANDLE_DBC,_xInterface); +} +// ------------------------------------------------------------------------- +void OTools::GetInfo(OConnection* _pConnection, + SQLHANDLE _aConnectionHandle, + SQLUSMALLINT _nInfo, + SQLUINTEGER &_rValue, + const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException) +{ + SQLSMALLINT nValueLen; + _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION) + OTools::ThrowException(_pConnection, + (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen), + _aConnectionHandle,SQL_HANDLE_DBC,_xInterface); +} +// ------------------------------------------------------------------------- +void OTools::GetInfo(OConnection* _pConnection, + SQLHANDLE _aConnectionHandle, + SQLUSMALLINT _nInfo, + SQLUSMALLINT &_rValue, + const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException) +{ + SQLSMALLINT nValueLen; + _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION) + OTools::ThrowException(_pConnection, + (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen), + _aConnectionHandle,SQL_HANDLE_DBC,_xInterface); +} +// ------------------------------------------------------------------------- +void OTools::GetInfo(OConnection* _pConnection, + SQLHANDLE _aConnectionHandle, + SQLUSMALLINT _nInfo, + sal_Bool &_rValue, + const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException) +{ + SQLSMALLINT nValueLen; + OTools::ThrowException(_pConnection, + (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen), + _aConnectionHandle,SQL_HANDLE_DBC,_xInterface); +} +// ------------------------------------------------------------------------- +sal_Int32 OTools::MapOdbcType2Jdbc(sal_Int32 _nType) +{ + sal_Int32 nValue = DataType::VARCHAR; + switch(_nType) + { + case SQL_BIT: + nValue = DataType::BIT; + break; + case SQL_TINYINT: + nValue = DataType::TINYINT; + break; + case SQL_SMALLINT: + nValue = DataType::SMALLINT; + break; + case SQL_INTEGER: + nValue = DataType::INTEGER; + break; + case SQL_BIGINT: + nValue = DataType::BIGINT; + break; + case SQL_FLOAT: + nValue = DataType::FLOAT; + break; + case SQL_REAL: + nValue = DataType::REAL; + break; + case SQL_DOUBLE: + nValue = DataType::DOUBLE; + break; + case SQL_NUMERIC: + nValue = DataType::NUMERIC; + break; + case SQL_DECIMAL: + nValue = DataType::DECIMAL; + break; + case SQL_WCHAR: + case SQL_CHAR: + nValue = DataType::CHAR; + break; + case SQL_WVARCHAR: + case SQL_VARCHAR: + nValue = DataType::VARCHAR; + break; + case SQL_WLONGVARCHAR: + case SQL_LONGVARCHAR: + nValue = DataType::LONGVARCHAR; + break; + case SQL_TYPE_DATE: + case SQL_DATE: + nValue = DataType::DATE; + break; + case SQL_TYPE_TIME: + case SQL_TIME: + nValue = DataType::TIME; + break; + case SQL_TYPE_TIMESTAMP: + case SQL_TIMESTAMP: + nValue = DataType::TIMESTAMP; + break; + case SQL_BINARY: + nValue = DataType::BINARY; + break; + case SQL_VARBINARY: + case SQL_GUID: + nValue = DataType::VARBINARY; + break; + case SQL_LONGVARBINARY: + nValue = DataType::LONGVARBINARY; + break; + default: + OSL_ASSERT(!"Invalid type"); + } + return nValue; +} +//-------------------------------------------------------------------- +// jdbcTypeToOdbc +// Convert the JDBC SQL type to the correct ODBC type +//-------------------------------------------------------------------- +sal_Int32 OTools::jdbcTypeToOdbc(sal_Int32 jdbcType) +{ + // For the most part, JDBC types match ODBC types. We'll + // just convert the ones that we know are different + + sal_Int32 odbcType = jdbcType; + + switch (jdbcType) + { + case DataType::DATE: + odbcType = SQL_DATE; + break; + case DataType::TIME: + odbcType = SQL_TIME; + break; + case DataType::TIMESTAMP: + odbcType = SQL_TIMESTAMP; + break; + } + + return odbcType; +} +//----------------------------------------------------------------------------- +void OTools::getBindTypes(sal_Bool _bUseWChar, + sal_Bool _bUseOldTimeDate, + SQLSMALLINT _nOdbcType, + SQLSMALLINT& fCType, + SQLSMALLINT& fSqlType + ) +{ + switch(_nOdbcType) + { + case SQL_CHAR: if(_bUseWChar) + { + fCType = SQL_C_WCHAR; + fSqlType = SQL_WCHAR; + } + else + { + fCType = SQL_C_CHAR; + fSqlType = SQL_CHAR; + } + break; + case SQL_VARCHAR: if(_bUseWChar) + { + fCType = SQL_C_WCHAR; + fSqlType = SQL_WVARCHAR; + } + else + { + fCType = SQL_C_CHAR; + fSqlType = SQL_VARCHAR; + } + break; + case SQL_LONGVARCHAR: if(_bUseWChar) + { + fCType = SQL_C_WCHAR; + fSqlType = SQL_WLONGVARCHAR; + } + else + { + fCType = SQL_C_CHAR; + fSqlType = SQL_LONGVARCHAR; + } + break; + case SQL_DECIMAL: fCType = _bUseWChar ? SQL_C_WCHAR : SQL_C_CHAR; + fSqlType = SQL_DECIMAL; break; + case SQL_NUMERIC: fCType = _bUseWChar ? SQL_C_WCHAR : SQL_C_CHAR; + fSqlType = SQL_NUMERIC; break; + case SQL_BIT: fCType = SQL_C_TINYINT; + fSqlType = SQL_INTEGER; break; + case SQL_TINYINT: fCType = SQL_C_TINYINT; + fSqlType = SQL_TINYINT; break; + case SQL_SMALLINT: fCType = SQL_C_SHORT; + fSqlType = SQL_SMALLINT; break; + case SQL_INTEGER: fCType = SQL_C_LONG; + fSqlType = SQL_INTEGER; break; + case SQL_BIGINT: fCType = SQL_C_SBIGINT; + fSqlType = SQL_BIGINT; break; + case SQL_FLOAT: fCType = SQL_C_FLOAT; + fSqlType = SQL_FLOAT; break; + case SQL_REAL: fCType = SQL_C_DOUBLE; + fSqlType = SQL_REAL; break; + case SQL_DOUBLE: fCType = SQL_C_DOUBLE; + fSqlType = SQL_DOUBLE; break; + case SQL_BINARY: fCType = SQL_C_BINARY; + fSqlType = SQL_BINARY; break; + case SQL_VARBINARY: + fCType = SQL_C_BINARY; + fSqlType = SQL_VARBINARY; break; + case SQL_LONGVARBINARY: fCType = SQL_C_BINARY; + fSqlType = SQL_LONGVARBINARY; break; + case SQL_DATE: + if(_bUseOldTimeDate) + { + fCType = SQL_C_DATE; + fSqlType = SQL_DATE; + } + else + { + fCType = SQL_C_TYPE_DATE; + fSqlType = SQL_TYPE_DATE; + } + break; + case SQL_TIME: + if(_bUseOldTimeDate) + { + fCType = SQL_C_TIME; + fSqlType = SQL_TIME; + } + else + { + fCType = SQL_C_TYPE_TIME; + fSqlType = SQL_TYPE_TIME; + } + break; + case SQL_TIMESTAMP: + if(_bUseOldTimeDate) + { + fCType = SQL_C_TIMESTAMP; + fSqlType = SQL_TIMESTAMP; + } + else + { + fCType = SQL_C_TYPE_TIMESTAMP; + fSqlType = SQL_TYPE_TIMESTAMP; + } + break; + default: fCType = SQL_C_BINARY; + fSqlType = SQL_LONGVARBINARY; break; + } +} + + |