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

Generated by: LCOV version 1.10