LCOV - code coverage report
Current view: top level - connectivity/source/drivers/odbc - OTools.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 314 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "odbc/OTools.hxx"
      21             : #include "odbc/OFunctions.hxx"
      22             : #include <com/sun/star/sdbc/DataType.hpp>
      23             : #include <osl/diagnose.h>
      24             : #include "odbc/OConnection.hxx"
      25             : #include "diagnose_ex.h"
      26             : #include <rtl/ustrbuf.hxx>
      27             : 
      28             : #include <appendsqlwchars.hxx>
      29             : 
      30             : #include <string.h>
      31             : #include <string>
      32             : #include <algorithm>
      33             : 
      34             : using namespace connectivity::odbc;
      35             : using namespace com::sun::star::uno;
      36             : using namespace com::sun::star::sdbc;
      37             : using namespace com::sun::star::util;
      38             : 
      39             : namespace {
      40           0 : size_t sqlTypeLen ( SQLSMALLINT _nType )
      41             : {
      42           0 :     switch (_nType)
      43             :     {
      44             :     case SQL_C_SSHORT:
      45             :     case SQL_C_SHORT:
      46           0 :         return sizeof(SQLSMALLINT);
      47             :     case SQL_C_USHORT:
      48           0 :         return sizeof(SQLUSMALLINT);
      49             :     case SQL_C_SLONG:
      50             :     case SQL_C_LONG:
      51           0 :         return sizeof(SQLINTEGER);
      52             :     case SQL_C_ULONG:
      53           0 :         return sizeof(SQLUINTEGER);
      54             :     case SQL_C_FLOAT:
      55           0 :         return sizeof(SQLREAL);
      56             :     case SQL_C_DOUBLE:
      57             :         OSL_ENSURE(sizeof(SQLDOUBLE) == sizeof(SQLFLOAT), "SQLDOUBLE/SQLFLOAT confusion");
      58           0 :         return sizeof(SQLDOUBLE);
      59             :     case SQL_C_BIT:
      60           0 :         return sizeof(SQLCHAR);
      61             :     case SQL_C_STINYINT:
      62             :     case SQL_C_TINYINT:
      63           0 :         return sizeof(SQLSCHAR);
      64             :     case SQL_C_UTINYINT:
      65           0 :         return sizeof(SQLCHAR);
      66             :     case SQL_C_SBIGINT:
      67           0 :         return sizeof(SQLBIGINT);
      68             :     case SQL_C_UBIGINT:
      69           0 :         return sizeof(SQLUBIGINT);
      70             :     /* UnixODBC gives this the same value as SQL_C_UBIGINT
      71             :     case SQL_C_BOOKMARK:
      72             :         return sizeof(BOOKMARK); */
      73             :     case SQL_C_TYPE_DATE:
      74             :     case SQL_C_DATE:
      75           0 :         return sizeof(SQL_DATE_STRUCT);
      76             :     case SQL_C_TYPE_TIME:
      77             :     case SQL_C_TIME:
      78           0 :         return sizeof(SQL_TIME_STRUCT);
      79             :     case SQL_C_TYPE_TIMESTAMP:
      80             :     case SQL_C_TIMESTAMP:
      81           0 :         return sizeof(SQL_TIMESTAMP_STRUCT);
      82             :     case SQL_C_NUMERIC:
      83           0 :         return sizeof(SQL_NUMERIC_STRUCT);
      84             :     case SQL_C_GUID:
      85           0 :         return sizeof(SQLGUID);
      86             :     case SQL_C_INTERVAL_YEAR:
      87             :     case SQL_C_INTERVAL_MONTH:
      88             :     case SQL_C_INTERVAL_DAY:
      89             :     case SQL_C_INTERVAL_HOUR:
      90             :     case SQL_C_INTERVAL_MINUTE:
      91             :     case SQL_C_INTERVAL_SECOND:
      92             :     case SQL_C_INTERVAL_YEAR_TO_MONTH:
      93             :     case SQL_C_INTERVAL_DAY_TO_HOUR:
      94             :     case SQL_C_INTERVAL_DAY_TO_MINUTE:
      95             :     case SQL_C_INTERVAL_DAY_TO_SECOND:
      96             :     case SQL_C_INTERVAL_HOUR_TO_MINUTE:
      97             :     case SQL_C_INTERVAL_HOUR_TO_SECOND:
      98             :     case SQL_C_INTERVAL_MINUTE_TO_SECOND:
      99           0 :         return sizeof(SQL_INTERVAL_STRUCT);
     100             :     // ** Variable-sized datatypes -> cannot predict length
     101             :     case SQL_C_CHAR:
     102             :     case SQL_C_WCHAR:
     103             :     case SQL_C_BINARY:
     104             :     // UnixODBC gives this the same value as SQL_C_BINARY
     105             :     //case SQL_C_VARBOOKMARK:
     106             :     // Unknown datatype -> cannot predict length
     107             :     default:
     108           0 :         return static_cast<size_t>(-1);
     109             :     }
     110             : }
     111             : }
     112             : 
     113             : 
     114           0 : void OTools::getValue(  OConnection* _pConnection,
     115             :                         SQLHANDLE _aStatementHandle,
     116             :                         sal_Int32 columnIndex,
     117             :                         SQLSMALLINT _nType,
     118             :                         bool &_bWasNull,
     119             :                         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
     120             :                         void* _pValue,
     121             :                         SQLLEN _nSize) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
     122             : {
     123           0 :     const size_t properSize = sqlTypeLen(_nType);
     124           0 :     if ( properSize == static_cast<size_t>(-1) )
     125             :         SAL_WARN( "connectivity.drivers", "connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size");
     126             :     else
     127             :     {
     128             :         OSL_ENSURE(static_cast<size_t>(_nSize) == properSize, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to");
     129           0 :         if ( static_cast<size_t>(_nSize) > properSize )
     130             :         {
     131             :             SAL_WARN( "connectivity.drivers", "memory region is too big - trying to fudge it");
     132           0 :             memset(_pValue, 0, _nSize);
     133             : #ifdef OSL_BIGENDIAN
     134             :             // This is skewed in favour of integer types
     135             :             _pValue += _nSize - properSize;
     136             : #endif
     137             :         }
     138             :     }
     139             :     OSL_ENSURE(static_cast<size_t>(_nSize) >= properSize, "memory region is too small");
     140           0 :     SQLLEN pcbValue = SQL_NULL_DATA;
     141             :     OTools::ThrowException(_pConnection,
     142           0 :                             (*reinterpret_cast<T3SQLGetData>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetData)))(_aStatementHandle,
     143             :                                         (SQLUSMALLINT)columnIndex,
     144             :                                         _nType,
     145             :                                         _pValue,
     146             :                                         _nSize,
     147           0 :                                         &pcbValue),
     148           0 :                             _aStatementHandle,SQL_HANDLE_STMT,_xInterface,false);
     149           0 :     _bWasNull = pcbValue == SQL_NULL_DATA;
     150           0 : }
     151             : 
     152           0 : void OTools::bindValue( OConnection* _pConnection,
     153             :                         SQLHANDLE _aStatementHandle,
     154             :                         sal_Int32 columnIndex,
     155             :                         SQLSMALLINT _nType,
     156             :                         SQLSMALLINT _nMaxLen,
     157             :                         const void* _pValue,
     158             :                         void* _pData,
     159             :                         SQLLEN * const pLen,
     160             :                         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
     161             :                         rtl_TextEncoding _nTextEncoding,
     162             :                         bool _bUseOldTimeDate) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
     163             : {
     164             :     SQLRETURN nRetcode;
     165             :     SQLSMALLINT   fSqlType;
     166             :     SQLSMALLINT   fCType;
     167           0 :     SQLLEN nMaxLen = _nMaxLen;
     168             : 
     169             :     OTools::getBindTypes(   false,
     170             :                             _bUseOldTimeDate,
     171             :                             _nType,
     172             :                             fCType,
     173           0 :                             fSqlType);
     174             : 
     175           0 :     if (columnIndex != 0 && !_pValue)
     176             :     {
     177           0 :         *pLen = SQL_NULL_DATA;
     178           0 :         nRetcode = (*reinterpret_cast<T3SQLBindCol>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::BindCol)))(_aStatementHandle,
     179             :                                 (SQLUSMALLINT)columnIndex,
     180             :                                 fCType,
     181             :                                 _pData,
     182             :                                 nMaxLen,
     183             :                                 pLen
     184           0 :                                 );
     185             :     }
     186             :     else
     187             :     {
     188             :         try
     189             :         {
     190           0 :             switch (_nType)
     191             :             {
     192             :                 case SQL_CHAR:
     193             :                 case SQL_VARCHAR:
     194             :                 {
     195           0 :                     OString aString(OUStringToOString(*static_cast<OUString const *>(_pValue),_nTextEncoding));
     196           0 :                     *pLen = SQL_NTS;
     197           0 :                     *static_cast<OString*>(_pData) = aString;
     198           0 :                     _nMaxLen = (SQLSMALLINT)aString.getLength();
     199             : 
     200             :                     // Pointer on Char*
     201           0 :                     _pData = const_cast<char *>(aString.getStr());
     202           0 :                 }   break;
     203             :                 case SQL_BIGINT:
     204           0 :                     *static_cast<sal_Int64*>(_pData) = *static_cast<sal_Int64 const *>(_pValue);
     205           0 :                     *pLen = sizeof(sal_Int64);
     206           0 :                     break;
     207             :                 case SQL_DECIMAL:
     208             :                 case SQL_NUMERIC:
     209             :                 {
     210           0 :                     OString aString = OString::number(*static_cast<double const *>(_pValue));
     211           0 :                     _nMaxLen = (SQLSMALLINT)aString.getLength();
     212           0 :                     *pLen = _nMaxLen;
     213           0 :                     *static_cast<OString*>(_pData) = aString;
     214             :                     // Pointer on Char*
     215           0 :                     _pData = const_cast<char *>(static_cast<OString*>(_pData)->getStr());
     216           0 :                 }   break;
     217             :                 case SQL_BIT:
     218             :                 case SQL_TINYINT:
     219           0 :                     *static_cast<sal_Int8*>(_pData) = *static_cast<sal_Int8 const *>(_pValue);
     220           0 :                     *pLen = sizeof(sal_Int8);
     221           0 :                     break;
     222             : 
     223             :                 case SQL_SMALLINT:
     224           0 :                     *static_cast<sal_Int16*>(_pData) = *static_cast<sal_Int16 const *>(_pValue);
     225           0 :                     *pLen = sizeof(sal_Int16);
     226           0 :                     break;
     227             :                 case SQL_INTEGER:
     228           0 :                     *static_cast<sal_Int32*>(_pData) = *static_cast<sal_Int32 const *>(_pValue);
     229           0 :                     *pLen = sizeof(sal_Int32);
     230           0 :                     break;
     231             :                 case SQL_FLOAT:
     232           0 :                     *static_cast<float*>(_pData) = *static_cast<float const *>(_pValue);
     233           0 :                     *pLen = sizeof(float);
     234           0 :                     break;
     235             :                 case SQL_REAL:
     236             :                 case SQL_DOUBLE:
     237           0 :                     *static_cast<double*>(_pData) = *static_cast<double const *>(_pValue);
     238           0 :                     *pLen = sizeof(double);
     239           0 :                     break;
     240             :                 case SQL_BINARY:
     241             :                 case SQL_VARBINARY:
     242             :                     {
     243           0 :                         _pData = const_cast<sal_Int8 *>(static_cast<const ::com::sun::star::uno::Sequence< sal_Int8 > *>(_pValue)->getConstArray());
     244           0 :                         *pLen = static_cast<const ::com::sun::star::uno::Sequence< sal_Int8 > *>(_pValue)->getLength();
     245           0 :                     }   break;
     246             :                 case SQL_LONGVARBINARY:
     247             :                 {
     248           0 :                     _pData = reinterpret_cast<void*>(columnIndex);
     249           0 :                     sal_Int32 nLen = 0;
     250           0 :                     nLen = static_cast<const ::com::sun::star::uno::Sequence< sal_Int8 > *>(_pValue)->getLength();
     251           0 :                     *pLen = (SQLLEN)SQL_LEN_DATA_AT_EXEC(nLen);
     252             :                 }
     253           0 :                     break;
     254             :                 case SQL_LONGVARCHAR:
     255             :                 {
     256           0 :                     _pData = reinterpret_cast<void*>(columnIndex);
     257           0 :                     sal_Int32 nLen = 0;
     258           0 :                     nLen = static_cast<OUString const *>(_pValue)->getLength();
     259           0 :                     *pLen = (SQLLEN)SQL_LEN_DATA_AT_EXEC(nLen);
     260           0 :                 }   break;
     261             :                 case SQL_DATE:
     262           0 :                     *pLen = sizeof(DATE_STRUCT);
     263           0 :                     *static_cast<DATE_STRUCT*>(_pData) = *static_cast<DATE_STRUCT const *>(_pValue);
     264           0 :                     break;
     265             :                 case SQL_TIME:
     266           0 :                     *pLen = sizeof(TIME_STRUCT);
     267           0 :                     *static_cast<TIME_STRUCT*>(_pData) = *static_cast<TIME_STRUCT const *>(_pValue);
     268           0 :                     break;
     269             :                 case SQL_TIMESTAMP:
     270           0 :                     *pLen = sizeof(TIMESTAMP_STRUCT);
     271           0 :                     *static_cast<TIMESTAMP_STRUCT*>(_pData) = *static_cast<TIMESTAMP_STRUCT const *>(_pValue);
     272           0 :                     break;
     273             :             }
     274             :         }
     275           0 :         catch ( ... )
     276             :         {
     277             :         }
     278             : 
     279           0 :         nRetcode = (*reinterpret_cast<T3SQLBindCol>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::BindCol)))(_aStatementHandle,
     280             :                                 (SQLUSMALLINT)columnIndex,
     281             :                                 fCType,
     282             :                                 _pData,
     283             :                                 nMaxLen,
     284             :                                 pLen
     285           0 :                                 );
     286             :     }
     287             : 
     288           0 :     OTools::ThrowException(_pConnection,nRetcode,_aStatementHandle,SQL_HANDLE_STMT,_xInterface);
     289           0 : }
     290             : 
     291           0 : void OTools::ThrowException(const OConnection* _pConnection,
     292             :                             const SQLRETURN _rRetCode,
     293             :                             const SQLHANDLE _pContext,
     294             :                             const SQLSMALLINT _nHandleType,
     295             :                             const Reference< XInterface >& _xInterface,
     296             :                             const bool _bNoFound,
     297             :                             const rtl_TextEncoding _nTextEncoding) throw(SQLException)
     298             : {
     299           0 :     switch(_rRetCode)
     300             :     {
     301             :         case SQL_NEED_DATA:
     302             :         case SQL_STILL_EXECUTING:
     303             :         case SQL_SUCCESS:
     304             : 
     305             :         case SQL_SUCCESS_WITH_INFO:
     306           0 :                         return;
     307             :         case SQL_NO_DATA_FOUND:
     308           0 :                                 if(_bNoFound)
     309           0 :                                     return; // no need to throw a exception
     310           0 :         case SQL_ERROR:             break;
     311             : 
     312             : 
     313             :         case SQL_INVALID_HANDLE:    SAL_WARN( "connectivity.drivers", "SdbODBC3_SetStatus: SQL_INVALID_HANDLE");
     314           0 :                                     throw SQLException();
     315             :     }
     316             : 
     317             :     // Additional Information on the latest ODBC-functioncall available
     318             :     // SQLError provides this Information.
     319             : 
     320             :     SDB_ODBC_CHAR szSqlState[5];
     321             :     SQLINTEGER pfNativeError;
     322             :     SDB_ODBC_CHAR szErrorMessage[SQL_MAX_MESSAGE_LENGTH];
     323           0 :     szErrorMessage[0] = '\0';
     324           0 :     SQLSMALLINT pcbErrorMsg = 0;
     325             : 
     326             :     // Information for latest operation:
     327             :     // when hstmt != SQL_NULL_HSTMT is (Used from SetStatus in SdbCursor, SdbTable, ...),
     328             :     // then the status of the latest statements will be fetched, without the Status of the last
     329             :     // statements of this connection [what in this case will probably be the same, but the Reference
     330             :     // Manual isn't totally clear in this...].
     331             :     // corresponding for hdbc.
     332           0 :     SQLRETURN n = (*reinterpret_cast<T3SQLGetDiagRec>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetDiagRec)))(_nHandleType,_pContext,1,
     333             :                          szSqlState,
     334             :                          &pfNativeError,
     335           0 :                          szErrorMessage,sizeof szErrorMessage - 1,&pcbErrorMsg);
     336             :     OSL_UNUSED( n );
     337             :     OSL_ENSURE(n != SQL_INVALID_HANDLE,"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE");
     338             :     OSL_ENSURE(n == SQL_SUCCESS || n == SQL_SUCCESS_WITH_INFO || n == SQL_NO_DATA_FOUND || n == SQL_ERROR,"SdbODBC3_SetStatus: SQLError failed");
     339             : 
     340             :     // For the Return Code of SQLError see ODBC 2.0 Programmer's Reference Page 287ff
     341             :     throw SQLException( OUString(reinterpret_cast<char *>(szErrorMessage), pcbErrorMsg, _nTextEncoding),
     342             :                                     _xInterface,
     343             :                                     OUString(reinterpret_cast<char *>(szSqlState), 5, _nTextEncoding),
     344             :                                     pfNativeError,
     345             :                                     Any()
     346           0 :                                 );
     347             : 
     348             : }
     349             : 
     350           0 : Sequence<sal_Int8> OTools::getBytesValue(const OConnection* _pConnection,
     351             :                                          const SQLHANDLE _aStatementHandle,
     352             :                                          const sal_Int32 columnIndex,
     353             :                                          const SQLSMALLINT _fSqlType,
     354             :                                          bool &_bWasNull,
     355             :                                          const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
     356             : {
     357             :     sal_Int8 aCharArray[2048];
     358             :     // First try to fetch the data with the little Buffer:
     359           0 :     const SQLLEN nMaxLen = sizeof aCharArray;
     360           0 :     SQLLEN pcbValue = SQL_NO_TOTAL;
     361           0 :     Sequence<sal_Int8> aData;
     362             : 
     363             :     OSL_ENSURE( _fSqlType != SQL_CHAR  && _fSqlType != SQL_VARCHAR  && _fSqlType != SQL_LONGVARCHAR &&
     364             :                 _fSqlType != SQL_WCHAR && _fSqlType != SQL_WVARCHAR && _fSqlType != SQL_WLONGVARCHAR,
     365             :                 "connectivity::odbc::OTools::getBytesValue called with character _fSqlType");
     366             : 
     367           0 :     while (pcbValue == SQL_NO_TOTAL || pcbValue > nMaxLen)
     368             :     {
     369             :         OTools::ThrowException(_pConnection,
     370           0 :                                (*reinterpret_cast<T3SQLGetData>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetData)))(
     371             :                                    _aStatementHandle,
     372             :                                    (SQLUSMALLINT)columnIndex,
     373             :                                    _fSqlType,
     374             :                                    static_cast<SQLPOINTER>(aCharArray),
     375             :                                    nMaxLen,
     376           0 :                                    &pcbValue),
     377           0 :                                _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
     378             : 
     379           0 :         _bWasNull = pcbValue == SQL_NULL_DATA;
     380           0 :         if(_bWasNull)
     381           0 :             return Sequence<sal_Int8>();
     382             : 
     383             :         SQLLEN nReadBytes;
     384             :         // After the SQLGetData that wrote out to aCharArray the last byte of the data,
     385             :         // pcbValue will not be SQL_NO_TOTAL -> we have a reliable count
     386           0 :         if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxLen) )
     387             :         {
     388             :             // we filled the buffer
     389           0 :             nReadBytes = nMaxLen;
     390             :         }
     391             :         else
     392             :         {
     393           0 :             nReadBytes = pcbValue;
     394             :         }
     395           0 :         const sal_Int32 nLen = aData.getLength();
     396           0 :         aData.realloc(nLen + nReadBytes);
     397           0 :         memcpy(aData.getArray() + nLen, aCharArray, nReadBytes);
     398             :     }
     399           0 :     return aData;
     400             : }
     401             : 
     402           0 : OUString OTools::getStringValue(OConnection* _pConnection,
     403             :                                        SQLHANDLE _aStatementHandle,
     404             :                                        sal_Int32 columnIndex,
     405             :                                        SQLSMALLINT _fSqlType,
     406             :                                        bool &_bWasNull,
     407             :                                        const Reference< XInterface >& _xInterface,
     408             :                                        const rtl_TextEncoding _nTextEncoding) throw(SQLException, RuntimeException)
     409             : {
     410           0 :     OUStringBuffer aData;
     411           0 :     switch(_fSqlType)
     412             :     {
     413             :     case SQL_WVARCHAR:
     414             :     case SQL_WCHAR:
     415             :     case SQL_WLONGVARCHAR:
     416             :     {
     417             :         SQLWCHAR waCharArray[2048];
     418             :         static_assert(sizeof(waCharArray) % sizeof(SQLWCHAR) == 0, "must fit in evenly");
     419             :         static_assert(sizeof(SQLWCHAR) == 2 || sizeof(SQLWCHAR) == 4, "must be 2 or 4");
     420             :         // Size == number of bytes, Len == number of UTF-16 or UCS4 code units
     421           0 :         const SQLLEN nMaxSize = sizeof(waCharArray);
     422           0 :         const SQLLEN nMaxLen  = sizeof(waCharArray) / sizeof(SQLWCHAR);
     423             :         static_assert(nMaxLen * sizeof(SQLWCHAR) == nMaxSize, "sizes must match");
     424             : 
     425             :         // read the unicode data
     426           0 :         SQLLEN pcbValue = SQL_NO_TOTAL;
     427           0 :         while ((pcbValue == SQL_NO_TOTAL ) || (pcbValue >= nMaxSize) )
     428             :         {
     429             :             OTools::ThrowException(_pConnection,
     430           0 :                                    (*reinterpret_cast<T3SQLGetData>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetData)))(
     431             :                                        _aStatementHandle,
     432             :                                        (SQLUSMALLINT)columnIndex,
     433             :                                        SQL_C_WCHAR,
     434             :                                        &waCharArray,
     435           0 :                                        (SQLLEN)nMaxLen*sizeof(sal_Unicode),
     436           0 :                                        &pcbValue),
     437           0 :                                    _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
     438           0 :             _bWasNull = pcbValue == SQL_NULL_DATA;
     439           0 :             if(_bWasNull)
     440           0 :                 return OUString();
     441             : 
     442             :             SQLLEN nReadChars;
     443             :             OSL_ENSURE( (pcbValue < 0) || (pcbValue % 2 == 0),
     444             :                         "ODBC: SQLGetData of SQL_C_WCHAR returned odd number of bytes");
     445           0 :             if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxSize) )
     446             :             {
     447             :                 // we filled the buffer; remove the terminating null character
     448           0 :                 nReadChars = nMaxLen-1;
     449           0 :                 if ( waCharArray[nReadChars] != 0)
     450             :                 {
     451             :                     SAL_WARN( "connectivity.drivers", "Buggy ODBC driver? Did not null-terminate (variable length) data!");
     452           0 :                     ++nReadChars;
     453           0 :                 }
     454             :             }
     455             :             else
     456             :             {
     457           0 :                 nReadChars = pcbValue/sizeof(SQLWCHAR);
     458             :             }
     459             : 
     460           0 :             appendSQLWCHARs(aData, waCharArray, nReadChars);
     461             :         }
     462           0 :         break;
     463             :     }
     464             :     default:
     465             :     {
     466             :         char aCharArray[2048];
     467             :         // read the unicode data
     468           0 :         const SQLLEN nMaxLen = sizeof(aCharArray);
     469           0 :         SQLLEN pcbValue = SQL_NO_TOTAL;
     470             : 
     471           0 :         while ((pcbValue == SQL_NO_TOTAL ) || (pcbValue >= nMaxLen) )
     472             :         {
     473             :             OTools::ThrowException(_pConnection,
     474           0 :                                    (*reinterpret_cast<T3SQLGetData>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetData)))(
     475             :                                        _aStatementHandle,
     476             :                                        (SQLUSMALLINT)columnIndex,
     477             :                                        SQL_C_CHAR,
     478             :                                        &aCharArray,
     479             :                                        nMaxLen,
     480           0 :                                        &pcbValue),
     481           0 :                                    _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
     482           0 :             _bWasNull = pcbValue == SQL_NULL_DATA;
     483           0 :             if(_bWasNull)
     484           0 :                 return OUString();
     485             : 
     486             :             SQLLEN nReadChars;
     487           0 :             if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxLen) )
     488             :             {
     489             :                 // we filled the buffer; remove the terminating null character
     490           0 :                 nReadChars = nMaxLen-1;
     491           0 :                 if ( aCharArray[nReadChars] != 0)
     492             :                 {
     493             :                     SAL_WARN( "connectivity.drivers", "Buggy ODBC driver? Did not null-terminate (variable length) data!");
     494           0 :                     ++nReadChars;
     495           0 :                 }
     496             :             }
     497             :             else
     498             :             {
     499           0 :                 nReadChars = pcbValue;
     500             :             }
     501             : 
     502           0 :             aData.append(OUString(aCharArray, nReadChars, _nTextEncoding));
     503             : 
     504             :         }
     505           0 :         break;
     506             :     }
     507             :     }
     508             : 
     509           0 :     return aData.makeStringAndClear();
     510             : }
     511             : 
     512           0 : void OTools::GetInfo(OConnection* _pConnection,
     513             :                      SQLHANDLE _aConnectionHandle,
     514             :                      SQLUSMALLINT _nInfo,
     515             :                      OUString &_rValue,
     516             :                      const Reference< XInterface >& _xInterface,
     517             :                      rtl_TextEncoding _nTextEncoding) throw(SQLException, RuntimeException)
     518             : {
     519             :     char aValue[512];
     520           0 :     SQLSMALLINT nValueLen=0;
     521             :     OTools::ThrowException(_pConnection,
     522           0 :         (*reinterpret_cast<T3SQLGetInfo>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetInfo)))(_aConnectionHandle,_nInfo,aValue,(sizeof aValue)-1,&nValueLen),
     523           0 :         _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
     524             : 
     525           0 :     _rValue = OUString(aValue,nValueLen,_nTextEncoding);
     526           0 : }
     527             : 
     528           0 : void OTools::GetInfo(OConnection* _pConnection,
     529             :                      SQLHANDLE _aConnectionHandle,
     530             :                      SQLUSMALLINT _nInfo,
     531             :                      sal_Int32 &_rValue,
     532             :                      const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
     533             : {
     534             :     SQLSMALLINT nValueLen;
     535           0 :     _rValue = 0;    // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
     536             :     OTools::ThrowException(_pConnection,
     537           0 :         (*reinterpret_cast<T3SQLGetInfo>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetInfo)))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
     538           0 :         _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
     539           0 : }
     540             : 
     541           0 : void OTools::GetInfo(OConnection* _pConnection,
     542             :                      SQLHANDLE _aConnectionHandle,
     543             :                      SQLUSMALLINT _nInfo,
     544             :                      SQLUINTEGER &_rValue,
     545             :                      const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
     546             : {
     547             :     SQLSMALLINT nValueLen;
     548           0 :     _rValue = 0;    // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
     549             :     OTools::ThrowException(_pConnection,
     550           0 :         (*reinterpret_cast<T3SQLGetInfo>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetInfo)))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
     551           0 :         _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
     552           0 : }
     553             : 
     554           0 : void OTools::GetInfo(OConnection* _pConnection,
     555             :                      SQLHANDLE _aConnectionHandle,
     556             :                      SQLUSMALLINT _nInfo,
     557             :                      SQLUSMALLINT &_rValue,
     558             :                      const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
     559             : {
     560             :     SQLSMALLINT nValueLen;
     561           0 :     _rValue = 0;    // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
     562             :     OTools::ThrowException(_pConnection,
     563           0 :         (*reinterpret_cast<T3SQLGetInfo>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetInfo)))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
     564           0 :         _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
     565           0 : }
     566             : 
     567           0 : void OTools::GetInfo(OConnection* _pConnection,
     568             :                      SQLHANDLE _aConnectionHandle,
     569             :                      SQLUSMALLINT _nInfo,
     570             :                      bool &_rValue,
     571             :                      const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
     572             : {
     573             :     SQLSMALLINT nValueLen;
     574             :     OTools::ThrowException(_pConnection,
     575           0 :                             (*reinterpret_cast<T3SQLGetInfo>(_pConnection->getOdbcFunction(ODBC3SQLFunctionId::GetInfo)))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
     576           0 :                             _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
     577           0 : }
     578             : 
     579           0 : sal_Int32 OTools::MapOdbcType2Jdbc(SQLSMALLINT _nType)
     580             : {
     581           0 :     sal_Int32 nValue = DataType::VARCHAR;
     582           0 :     switch(_nType)
     583             :     {
     584             :         case SQL_BIT:
     585           0 :             nValue = DataType::BIT;
     586           0 :             break;
     587             :         case SQL_TINYINT:
     588           0 :             nValue = DataType::TINYINT;
     589           0 :             break;
     590             :         case SQL_SMALLINT:
     591           0 :             nValue = DataType::SMALLINT;
     592           0 :             break;
     593             :         case SQL_INTEGER:
     594           0 :             nValue = DataType::INTEGER;
     595           0 :             break;
     596             :         case SQL_BIGINT:
     597           0 :             nValue = DataType::BIGINT;
     598           0 :             break;
     599             :         case SQL_FLOAT:
     600           0 :             nValue = DataType::FLOAT;
     601           0 :             break;
     602             :         case SQL_REAL:
     603           0 :             nValue = DataType::REAL;
     604           0 :             break;
     605             :         case SQL_DOUBLE:
     606           0 :             nValue = DataType::DOUBLE;
     607           0 :             break;
     608             :         case SQL_NUMERIC:
     609           0 :             nValue = DataType::NUMERIC;
     610           0 :             break;
     611             :         case SQL_DECIMAL:
     612           0 :             nValue = DataType::DECIMAL;
     613           0 :             break;
     614             :         case SQL_WCHAR:
     615             :         case SQL_CHAR:
     616           0 :             nValue = DataType::CHAR;
     617           0 :             break;
     618             :         case SQL_WVARCHAR:
     619             :         case SQL_VARCHAR:
     620           0 :             nValue = DataType::VARCHAR;
     621           0 :             break;
     622             :         case SQL_WLONGVARCHAR:
     623             :         case SQL_LONGVARCHAR:
     624           0 :             nValue = DataType::LONGVARCHAR;
     625           0 :             break;
     626             :         case SQL_TYPE_DATE:
     627             :         case SQL_DATE:
     628           0 :             nValue = DataType::DATE;
     629           0 :             break;
     630             :         case SQL_TYPE_TIME:
     631             :         case SQL_TIME:
     632           0 :             nValue = DataType::TIME;
     633           0 :             break;
     634             :         case SQL_TYPE_TIMESTAMP:
     635             :         case SQL_TIMESTAMP:
     636           0 :             nValue = DataType::TIMESTAMP;
     637           0 :             break;
     638             :         case SQL_BINARY:
     639           0 :             nValue = DataType::BINARY;
     640           0 :             break;
     641             :         case SQL_VARBINARY:
     642             :         case SQL_GUID:
     643           0 :             nValue = DataType::VARBINARY;
     644           0 :             break;
     645             :         case SQL_LONGVARBINARY:
     646           0 :             nValue = DataType::LONGVARBINARY;
     647           0 :             break;
     648             :         default:
     649             :             OSL_FAIL("Invalid type");
     650             :     }
     651           0 :     return nValue;
     652             : }
     653             : 
     654             : // jdbcTypeToOdbc
     655             : // Convert the JDBC SQL type to the correct ODBC type
     656             : 
     657           0 : SQLSMALLINT OTools::jdbcTypeToOdbc(sal_Int32 jdbcType)
     658             : {
     659             :     // For the most part, JDBC types match ODBC types.  We'll
     660             :     // just convert the ones that we know are different
     661             : 
     662           0 :     sal_Int32 odbcType = jdbcType;
     663             : 
     664           0 :     switch (jdbcType)
     665             :     {
     666             :     case DataType::DATE:
     667           0 :         odbcType = SQL_DATE;
     668           0 :         break;
     669             :     case DataType::TIME:
     670           0 :         odbcType = SQL_TIME;
     671           0 :         break;
     672             :     case DataType::TIMESTAMP:
     673           0 :         odbcType = SQL_TIMESTAMP;
     674           0 :         break;
     675             :     // ODBC doesn't have any notion of CLOB or BLOB
     676             :     case DataType::CLOB:
     677           0 :         odbcType = SQL_LONGVARCHAR;
     678           0 :         break;
     679             :     case DataType::BLOB:
     680           0 :         odbcType = SQL_LONGVARBINARY;
     681           0 :         break;
     682             :     }
     683             : 
     684           0 :     return odbcType;
     685             : }
     686             : 
     687           0 : void OTools::getBindTypes(bool _bUseWChar,
     688             :                           bool _bUseOldTimeDate,
     689             :                           SQLSMALLINT _nOdbcType,
     690             :                           SQLSMALLINT& fCType,
     691             :                           SQLSMALLINT& fSqlType
     692             :                           )
     693             : {
     694           0 :     switch(_nOdbcType)
     695             :     {
     696           0 :         case SQL_CHAR:              if(_bUseWChar)
     697             :                                     {
     698           0 :                                         fCType   = SQL_C_WCHAR;
     699           0 :                                         fSqlType = SQL_WCHAR;
     700             :                                     }
     701             :                                     else
     702             :                                     {
     703           0 :                                         fCType   = SQL_C_CHAR;
     704           0 :                                         fSqlType = SQL_CHAR;
     705             :                                     }
     706           0 :                                     break;
     707           0 :         case SQL_VARCHAR:           if(_bUseWChar)
     708             :                                     {
     709           0 :                                         fCType   = SQL_C_WCHAR;
     710           0 :                                         fSqlType = SQL_WVARCHAR;
     711             :                                     }
     712             :                                     else
     713             :                                     {
     714           0 :                                         fCType   = SQL_C_CHAR;
     715           0 :                                         fSqlType = SQL_VARCHAR;
     716             :                                     }
     717           0 :                                     break;
     718           0 :         case SQL_LONGVARCHAR:       if(_bUseWChar)
     719             :                                     {
     720           0 :                                         fCType   = SQL_C_WCHAR;
     721           0 :                                         fSqlType = SQL_WLONGVARCHAR;
     722             :                                     }
     723             :                                     else
     724             :                                     {
     725           0 :                                         fCType   = SQL_C_CHAR;
     726           0 :                                         fSqlType = SQL_LONGVARCHAR;
     727             :                                     }
     728           0 :                                     break;
     729           0 :         case SQL_DECIMAL:           fCType      = _bUseWChar ? SQL_C_WCHAR : SQL_C_CHAR;
     730           0 :                                     fSqlType    = SQL_DECIMAL; break;
     731           0 :         case SQL_NUMERIC:           fCType      = _bUseWChar ? SQL_C_WCHAR : SQL_C_CHAR;
     732           0 :                                     fSqlType    = SQL_NUMERIC; break;
     733           0 :         case SQL_BIT:               fCType      = SQL_C_TINYINT;
     734           0 :                                     fSqlType    = SQL_INTEGER; break;
     735           0 :         case SQL_TINYINT:           fCType      = SQL_C_TINYINT;
     736           0 :                                     fSqlType    = SQL_TINYINT; break;
     737           0 :         case SQL_SMALLINT:          fCType      = SQL_C_SHORT;
     738           0 :                                     fSqlType    = SQL_SMALLINT; break;
     739           0 :         case SQL_INTEGER:           fCType      = SQL_C_LONG;
     740           0 :                                     fSqlType    = SQL_INTEGER; break;
     741           0 :         case SQL_BIGINT:            fCType      = SQL_C_SBIGINT;
     742           0 :                                     fSqlType    = SQL_BIGINT; break;
     743           0 :         case SQL_FLOAT:             fCType      = SQL_C_FLOAT;
     744           0 :                                     fSqlType    = SQL_FLOAT; break;
     745           0 :         case SQL_REAL:              fCType      = SQL_C_DOUBLE;
     746           0 :                                     fSqlType    = SQL_REAL; break;
     747           0 :         case SQL_DOUBLE:            fCType      = SQL_C_DOUBLE;
     748           0 :                                     fSqlType    = SQL_DOUBLE; break;
     749           0 :         case SQL_BINARY:            fCType      = SQL_C_BINARY;
     750           0 :                                     fSqlType    = SQL_BINARY; break;
     751             :         case SQL_VARBINARY:
     752           0 :                                     fCType      = SQL_C_BINARY;
     753           0 :                                     fSqlType    = SQL_VARBINARY; break;
     754           0 :         case SQL_LONGVARBINARY:     fCType      = SQL_C_BINARY;
     755           0 :                                     fSqlType    = SQL_LONGVARBINARY; break;
     756             :         case SQL_DATE:
     757           0 :                                     if(_bUseOldTimeDate)
     758             :                                     {
     759           0 :                                         fCType      = SQL_C_DATE;
     760           0 :                                         fSqlType    = SQL_DATE;
     761             :                                     }
     762             :                                     else
     763             :                                     {
     764           0 :                                         fCType      = SQL_C_TYPE_DATE;
     765           0 :                                         fSqlType    = SQL_TYPE_DATE;
     766             :                                     }
     767           0 :                                     break;
     768             :         case SQL_TIME:
     769           0 :                                     if(_bUseOldTimeDate)
     770             :                                     {
     771           0 :                                         fCType      = SQL_C_TIME;
     772           0 :                                         fSqlType    = SQL_TIME;
     773             :                                     }
     774             :                                     else
     775             :                                     {
     776           0 :                                         fCType      = SQL_C_TYPE_TIME;
     777           0 :                                         fSqlType    = SQL_TYPE_TIME;
     778             :                                     }
     779           0 :                                     break;
     780             :         case SQL_TIMESTAMP:
     781           0 :                                     if(_bUseOldTimeDate)
     782             :                                     {
     783           0 :                                         fCType      = SQL_C_TIMESTAMP;
     784           0 :                                         fSqlType    = SQL_TIMESTAMP;
     785             :                                     }
     786             :                                     else
     787             :                                     {
     788           0 :                                         fCType      = SQL_C_TYPE_TIMESTAMP;
     789           0 :                                         fSqlType    = SQL_TYPE_TIMESTAMP;
     790             :                                     }
     791           0 :                                     break;
     792           0 :         default:                        fCType      = SQL_C_BINARY;
     793           0 :                                         fSqlType    = SQL_LONGVARBINARY; break;
     794             :     }
     795           0 : }
     796             : 
     797             : 
     798             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11