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

Generated by: LCOV version 1.10