fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / connectivity / source / drivers / odbcbase / OTools.cxx
blob4f85184060b600ae778be96f4b88dbaff951e7b4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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/logfile.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <boost/static_assert.hpp>
31 #include <string.h>
32 #include <string>
33 #include <algorithm>
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;
40 namespace {
41 size_t sqlTypeLen ( SQLSMALLINT _nType )
43 switch (_nType)
45 case SQL_C_SSHORT:
46 case SQL_C_SHORT:
47 return sizeof(SQLSMALLINT);
48 case SQL_C_USHORT:
49 return sizeof(SQLUSMALLINT);
50 case SQL_C_SLONG:
51 case SQL_C_LONG:
52 return sizeof(SQLINTEGER);
53 case SQL_C_ULONG:
54 return sizeof(SQLUINTEGER);
55 case SQL_C_FLOAT:
56 return sizeof(SQLREAL);
57 case SQL_C_DOUBLE:
58 OSL_ENSURE(sizeof(SQLDOUBLE) == sizeof(SQLFLOAT), "SQLDOUBLE/SQLFLOAT confusion");
59 return sizeof(SQLDOUBLE);
60 case SQL_C_BIT:
61 return sizeof(SQLCHAR);
62 case SQL_C_STINYINT:
63 case SQL_C_TINYINT:
64 return sizeof(SQLSCHAR);
65 case SQL_C_UTINYINT:
66 return sizeof(SQLCHAR);
67 case SQL_C_SBIGINT:
68 return sizeof(SQLBIGINT);
69 case SQL_C_UBIGINT:
70 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 return sizeof(SQL_DATE_STRUCT);
77 case SQL_C_TYPE_TIME:
78 case SQL_C_TIME:
79 return sizeof(SQL_TIME_STRUCT);
80 case SQL_C_TYPE_TIMESTAMP:
81 case SQL_C_TIMESTAMP:
82 return sizeof(SQL_TIMESTAMP_STRUCT);
83 case SQL_C_NUMERIC:
84 return sizeof(SQL_NUMERIC_STRUCT);
85 case SQL_C_GUID:
86 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 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 return static_cast<size_t>(-1);
115 void OTools::getValue( OConnection* _pConnection,
116 SQLHANDLE _aStatementHandle,
117 sal_Int32 columnIndex,
118 SQLSMALLINT _nType,
119 sal_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)
124 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::getValue" );
125 const size_t properSize = sqlTypeLen(_nType);
126 if ( properSize == static_cast<size_t>(-1) )
127 OSL_FAIL("connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size");
128 else
130 OSL_ENSURE(static_cast<size_t>(_nSize) == properSize, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to");
131 if ( static_cast<size_t>(_nSize) > properSize )
133 OSL_FAIL("memory region is too big - trying to fudge it");
134 memset(_pValue, 0, _nSize);
135 #ifdef OSL_BIGENDIAN
136 // This is skewed in favour of integer types
137 _pValue += _nSize - properSize;
138 #endif
141 OSL_ENSURE(static_cast<size_t>(_nSize) >= properSize, "memory region is too small");
142 SQLLEN pcbValue = SQL_NULL_DATA;
143 OTools::ThrowException(_pConnection,
144 (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle,
145 (SQLUSMALLINT)columnIndex,
146 _nType,
147 _pValue,
148 _nSize,
149 &pcbValue),
150 _aStatementHandle,SQL_HANDLE_STMT,_xInterface,sal_False);
151 _bWasNull = pcbValue == SQL_NULL_DATA;
153 // -------------------------------------------------------------------------
154 void OTools::bindValue( OConnection* _pConnection,
155 SQLHANDLE _aStatementHandle,
156 sal_Int32 columnIndex,
157 SQLSMALLINT _nType,
158 SQLSMALLINT _nMaxLen,
159 const void* _pValue,
160 void* _pData,
161 SQLLEN * const pLen,
162 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
163 rtl_TextEncoding _nTextEncoding,
164 sal_Bool _bUseOldTimeDate) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
166 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::bindValue" );
167 SQLRETURN nRetcode;
168 SQLSMALLINT fSqlType;
169 SQLSMALLINT fCType;
170 SQLLEN nMaxLen = _nMaxLen;
172 OTools::getBindTypes( sal_False,
173 _bUseOldTimeDate,
174 _nType,
175 fCType,
176 fSqlType);
178 if (columnIndex != 0 && !_pValue)
180 *pLen = SQL_NULL_DATA;
181 nRetcode = (*(T3SQLBindCol)_pConnection->getOdbcFunction(ODBC3SQLBindCol))(_aStatementHandle,
182 (SQLUSMALLINT)columnIndex,
183 fCType,
184 _pData,
185 nMaxLen,
186 pLen
189 else
193 switch (_nType)
195 case SQL_CHAR:
196 case SQL_VARCHAR:
198 OString aString(OUStringToOString(*(OUString*)_pValue,_nTextEncoding));
199 *pLen = SQL_NTS;
200 *((OString*)_pData) = aString;
201 _nMaxLen = (SQLSMALLINT)aString.getLength();
203 // Pointer on Char*
204 _pData = (void*)aString.getStr();
205 } break;
206 case SQL_BIGINT:
207 *((sal_Int64*)_pData) = *(sal_Int64*)_pValue;
208 *pLen = sizeof(sal_Int64);
209 break;
210 case SQL_DECIMAL:
211 case SQL_NUMERIC:
213 OString aString = OString::valueOf(*(double*)_pValue);
214 _nMaxLen = (SQLSMALLINT)aString.getLength();
215 *pLen = _nMaxLen;
216 *((OString*)_pData) = aString;
217 // Pointer on Char*
218 _pData = (void*)((OString*)_pData)->getStr();
219 } break;
220 case SQL_BIT:
221 case SQL_TINYINT:
222 *((sal_Int8*)_pData) = *(sal_Int8*)_pValue;
223 *pLen = sizeof(sal_Int8);
224 break;
226 case SQL_SMALLINT:
227 *((sal_Int16*)_pData) = *(sal_Int16*)_pValue;
228 *pLen = sizeof(sal_Int16);
229 break;
230 case SQL_INTEGER:
231 *((sal_Int32*)_pData) = *(sal_Int32*)_pValue;
232 *pLen = sizeof(sal_Int32);
233 break;
234 case SQL_FLOAT:
235 *((float*)_pData) = *(float*)_pValue;
236 *pLen = sizeof(float);
237 break;
238 case SQL_REAL:
239 case SQL_DOUBLE:
240 *((double*)_pData) = *(double*)_pValue;
241 *pLen = sizeof(double);
242 break;
243 case SQL_BINARY:
244 case SQL_VARBINARY:
246 _pData = (void*)((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getConstArray();
247 *pLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength();
248 } break;
249 case SQL_LONGVARBINARY:
251 _pData = (void*)(sal_IntPtr)(columnIndex);
252 sal_Int32 nLen = 0;
253 nLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength();
254 *pLen = (SQLLEN)SQL_LEN_DATA_AT_EXEC(nLen);
256 break;
257 case SQL_LONGVARCHAR:
259 _pData = (void*)(sal_IntPtr)(columnIndex);
260 sal_Int32 nLen = 0;
261 nLen = ((OUString*)_pValue)->getLength();
262 *pLen = (SQLLEN)SQL_LEN_DATA_AT_EXEC(nLen);
263 } break;
264 case SQL_DATE:
265 *pLen = sizeof(DATE_STRUCT);
266 *((DATE_STRUCT*)_pData) = *(DATE_STRUCT*)_pValue;
267 break;
268 case SQL_TIME:
269 *pLen = sizeof(TIME_STRUCT);
270 *((TIME_STRUCT*)_pData) = *(TIME_STRUCT*)_pValue;
271 break;
272 case SQL_TIMESTAMP:
273 *pLen = sizeof(TIMESTAMP_STRUCT);
274 *((TIMESTAMP_STRUCT*)_pData) = *(TIMESTAMP_STRUCT*)_pValue;
275 break;
278 catch ( ... )
282 nRetcode = (*(T3SQLBindCol)_pConnection->getOdbcFunction(ODBC3SQLBindCol))(_aStatementHandle,
283 (SQLUSMALLINT)columnIndex,
284 fCType,
285 _pData,
286 nMaxLen,
287 pLen
291 OTools::ThrowException(_pConnection,nRetcode,_aStatementHandle,SQL_HANDLE_STMT,_xInterface);
293 // -----------------------------------------------------------------------------
294 void OTools::ThrowException(const OConnection* _pConnection,
295 const SQLRETURN _rRetCode,
296 const SQLHANDLE _pContext,
297 const SQLSMALLINT _nHandleType,
298 const Reference< XInterface >& _xInterface,
299 const sal_Bool _bNoFound,
300 const rtl_TextEncoding _nTextEncoding) throw(SQLException)
302 switch(_rRetCode)
304 case SQL_NEED_DATA:
305 case SQL_STILL_EXECUTING:
306 case SQL_SUCCESS:
308 case SQL_SUCCESS_WITH_INFO:
309 return;
310 case SQL_NO_DATA_FOUND:
311 if(_bNoFound)
312 return; // no need to throw a exception
313 case SQL_ERROR: break;
316 case SQL_INVALID_HANDLE: OSL_FAIL("SdbODBC3_SetStatus: SQL_INVALID_HANDLE");
317 throw SQLException();
320 // Additional Information on the latest ODBC-functioncall available
321 // SQLError provides this Information.
322 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::ThrowException" );
324 SDB_ODBC_CHAR szSqlState[5];
325 SQLINTEGER pfNativeError;
326 SDB_ODBC_CHAR szErrorMessage[SQL_MAX_MESSAGE_LENGTH];
327 szErrorMessage[0] = '\0';
328 SQLSMALLINT pcbErrorMsg = 0;
330 // Information for latest operation:
331 // when hstmt != SQL_NULL_HSTMT is (Used from SetStatus in SdbCursor, SdbTable, ...),
332 // then the status of the latest statements will be fetched, without the Status of the last
333 // statements of this connection [what in this case will probably be the same, but the Reference
334 // Manual isn't totally clear in this...].
335 // corresponding for hdbc.
336 SQLRETURN n = (*(T3SQLGetDiagRec)_pConnection->getOdbcFunction(ODBC3SQLGetDiagRec))(_nHandleType,_pContext,1,
337 szSqlState,
338 &pfNativeError,
339 szErrorMessage,sizeof szErrorMessage - 1,&pcbErrorMsg);
340 OSL_UNUSED( n );
341 OSL_ENSURE(n != SQL_INVALID_HANDLE,"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE");
342 OSL_ENSURE(n == SQL_SUCCESS || n == SQL_SUCCESS_WITH_INFO || n == SQL_NO_DATA_FOUND || n == SQL_ERROR,"SdbODBC3_SetStatus: SQLError failed");
344 // For the Return Code of SQLError see ODBC 2.0 Programmer's Reference Page 287ff
345 throw SQLException( OUString((char *)szErrorMessage,pcbErrorMsg,_nTextEncoding),
346 _xInterface,
347 OUString((char *)szSqlState,5,_nTextEncoding),
348 pfNativeError,
349 Any()
353 // -------------------------------------------------------------------------
354 Sequence<sal_Int8> OTools::getBytesValue(const OConnection* _pConnection,
355 const SQLHANDLE _aStatementHandle,
356 const sal_Int32 columnIndex,
357 const SQLSMALLINT _fSqlType,
358 sal_Bool &_bWasNull,
359 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
361 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::getBytesValue" );
362 sal_Int8 aCharArray[2048];
363 // First try to fetch the data with the little Buffer:
364 const SQLLEN nMaxLen = sizeof aCharArray;
365 SQLLEN pcbValue = SQL_NO_TOTAL;
366 Sequence<sal_Int8> aData;
368 OSL_ENSURE( _fSqlType != SQL_CHAR && _fSqlType != SQL_VARCHAR && _fSqlType != SQL_LONGVARCHAR &&
369 _fSqlType != SQL_WCHAR && _fSqlType != SQL_WVARCHAR && _fSqlType != SQL_WLONGVARCHAR,
370 "connectivity::odbc::OTools::getBytesValue called with character _fSqlType");
372 while (pcbValue == SQL_NO_TOTAL || pcbValue > nMaxLen)
374 OTools::ThrowException(_pConnection,
375 (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(
376 _aStatementHandle,
377 (SQLUSMALLINT)columnIndex,
378 _fSqlType,
379 (SQLPOINTER)aCharArray,
380 nMaxLen,
381 &pcbValue),
382 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
384 _bWasNull = pcbValue == SQL_NULL_DATA;
385 if(_bWasNull)
386 return Sequence<sal_Int8>();
388 SQLLEN nReadBytes;
389 // After the SQLGetData that wrote out to aCharArray the last byte of the data,
390 // pcbValue will not be SQL_NO_TOTAL -> we have a reliable count
391 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxLen) )
393 // we filled the buffer
394 nReadBytes = nMaxLen;
396 else
398 nReadBytes = pcbValue;
400 const sal_Int32 nLen = aData.getLength();
401 aData.realloc(nLen + nReadBytes);
402 memcpy(aData.getArray() + nLen, aCharArray, nReadBytes);
404 return aData;
406 // -------------------------------------------------------------------------
407 OUString OTools::getStringValue(OConnection* _pConnection,
408 SQLHANDLE _aStatementHandle,
409 sal_Int32 columnIndex,
410 SQLSMALLINT _fSqlType,
411 sal_Bool &_bWasNull,
412 const Reference< XInterface >& _xInterface,
413 rtl_TextEncoding _nTextEncoding) throw(SQLException, RuntimeException)
415 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::getStringValue" );
416 OUStringBuffer aData;
417 switch(_fSqlType)
419 case SQL_WVARCHAR:
420 case SQL_WCHAR:
421 case SQL_WLONGVARCHAR:
423 sal_Unicode waCharArray[2048];
424 // we assume everyone (LibO & ODBC) uses UTF-16; see OPreparedStatement::setParameter
425 BOOST_STATIC_ASSERT(sizeof(sal_Unicode) == 2);
426 BOOST_STATIC_ASSERT(sizeof(SQLWCHAR) == 2);
427 BOOST_STATIC_ASSERT(sizeof(waCharArray) % 2 == 0);
428 // Size == number of bytes, Len == number of UTF-16 code units
429 const SQLLEN nMaxSize = sizeof(waCharArray);
430 const SQLLEN nMaxLen = sizeof(waCharArray) / sizeof(sal_Unicode);
431 BOOST_STATIC_ASSERT(nMaxLen * sizeof(sal_Unicode) == nMaxSize);
433 // read the unicode data
434 SQLLEN pcbValue = SQL_NO_TOTAL;
435 while ((pcbValue == SQL_NO_TOTAL ) || (pcbValue >= nMaxSize) )
437 OTools::ThrowException(_pConnection,
438 (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(
439 _aStatementHandle,
440 (SQLUSMALLINT)columnIndex,
441 SQL_C_WCHAR,
442 &waCharArray,
443 (SQLLEN)nMaxLen*sizeof(sal_Unicode),
444 &pcbValue),
445 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
446 _bWasNull = pcbValue == SQL_NULL_DATA;
447 if(_bWasNull)
448 return OUString();
450 SQLLEN nReadChars;
451 OSL_ENSURE( (pcbValue < 0) || (pcbValue % 2 == 0),
452 "ODBC: SQLGetData of SQL_C_WCHAR returned odd number of bytes");
453 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxSize) )
455 // we filled the buffer; remove the terminating null character
456 nReadChars = nMaxLen-1;
457 if ( waCharArray[nReadChars] != 0)
459 OSL_FAIL("Buggy ODBC driver? Did not null-terminate (variable length) data!");
460 ++nReadChars;
463 else
465 nReadChars = pcbValue/sizeof(sal_Unicode);
468 aData.append(waCharArray, nReadChars);
471 break;
473 default:
475 char aCharArray[2048];
476 // read the unicode data
477 const SQLLEN nMaxLen = sizeof(aCharArray);
478 SQLLEN pcbValue = SQL_NO_TOTAL;
480 while ((pcbValue == SQL_NO_TOTAL ) || (pcbValue >= nMaxLen) )
482 OTools::ThrowException(_pConnection,
483 (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(
484 _aStatementHandle,
485 (SQLUSMALLINT)columnIndex,
486 SQL_C_CHAR,
487 &aCharArray,
488 nMaxLen,
489 &pcbValue),
490 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
491 _bWasNull = pcbValue == SQL_NULL_DATA;
492 if(_bWasNull)
493 return OUString();
495 SQLLEN nReadChars;
496 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxLen) )
498 // we filled the buffer; remove the terminating null character
499 nReadChars = nMaxLen-1;
500 if ( aCharArray[nReadChars] != 0)
502 OSL_FAIL("Buggy ODBC driver? Did not null-terminate (variable length) data!");
503 ++nReadChars;
506 else
508 nReadChars = pcbValue;
511 aData.append(OUString(aCharArray, nReadChars, _nTextEncoding));
514 break;
518 return aData.makeStringAndClear();
520 // -------------------------------------------------------------------------
521 void OTools::GetInfo(OConnection* _pConnection,
522 SQLHANDLE _aConnectionHandle,
523 SQLUSMALLINT _nInfo,
524 OUString &_rValue,
525 const Reference< XInterface >& _xInterface,
526 rtl_TextEncoding _nTextEncoding) throw(SQLException, RuntimeException)
528 char aValue[512];
529 SQLSMALLINT nValueLen=0;
530 OTools::ThrowException(_pConnection,
531 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,aValue,(sizeof aValue)-1,&nValueLen),
532 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
534 _rValue = OUString(aValue,nValueLen,_nTextEncoding);
536 // -------------------------------------------------------------------------
537 void OTools::GetInfo(OConnection* _pConnection,
538 SQLHANDLE _aConnectionHandle,
539 SQLUSMALLINT _nInfo,
540 sal_Int32 &_rValue,
541 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
543 SQLSMALLINT nValueLen;
544 _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
545 OTools::ThrowException(_pConnection,
546 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
547 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
549 // -------------------------------------------------------------------------
550 void OTools::GetInfo(OConnection* _pConnection,
551 SQLHANDLE _aConnectionHandle,
552 SQLUSMALLINT _nInfo,
553 SQLUINTEGER &_rValue,
554 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
556 SQLSMALLINT nValueLen;
557 _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
558 OTools::ThrowException(_pConnection,
559 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
560 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
562 // -------------------------------------------------------------------------
563 void OTools::GetInfo(OConnection* _pConnection,
564 SQLHANDLE _aConnectionHandle,
565 SQLUSMALLINT _nInfo,
566 SQLUSMALLINT &_rValue,
567 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
569 SQLSMALLINT nValueLen;
570 _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
571 OTools::ThrowException(_pConnection,
572 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
573 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
575 // -------------------------------------------------------------------------
576 void OTools::GetInfo(OConnection* _pConnection,
577 SQLHANDLE _aConnectionHandle,
578 SQLUSMALLINT _nInfo,
579 sal_Bool &_rValue,
580 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
582 SQLSMALLINT nValueLen;
583 OTools::ThrowException(_pConnection,
584 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
585 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
587 // -------------------------------------------------------------------------
588 sal_Int32 OTools::MapOdbcType2Jdbc(SQLSMALLINT _nType)
590 sal_Int32 nValue = DataType::VARCHAR;
591 switch(_nType)
593 case SQL_BIT:
594 nValue = DataType::BIT;
595 break;
596 case SQL_TINYINT:
597 nValue = DataType::TINYINT;
598 break;
599 case SQL_SMALLINT:
600 nValue = DataType::SMALLINT;
601 break;
602 case SQL_INTEGER:
603 nValue = DataType::INTEGER;
604 break;
605 case SQL_BIGINT:
606 nValue = DataType::BIGINT;
607 break;
608 case SQL_FLOAT:
609 nValue = DataType::FLOAT;
610 break;
611 case SQL_REAL:
612 nValue = DataType::REAL;
613 break;
614 case SQL_DOUBLE:
615 nValue = DataType::DOUBLE;
616 break;
617 case SQL_NUMERIC:
618 nValue = DataType::NUMERIC;
619 break;
620 case SQL_DECIMAL:
621 nValue = DataType::DECIMAL;
622 break;
623 case SQL_WCHAR:
624 case SQL_CHAR:
625 nValue = DataType::CHAR;
626 break;
627 case SQL_WVARCHAR:
628 case SQL_VARCHAR:
629 nValue = DataType::VARCHAR;
630 break;
631 case SQL_WLONGVARCHAR:
632 case SQL_LONGVARCHAR:
633 nValue = DataType::LONGVARCHAR;
634 break;
635 case SQL_TYPE_DATE:
636 case SQL_DATE:
637 nValue = DataType::DATE;
638 break;
639 case SQL_TYPE_TIME:
640 case SQL_TIME:
641 nValue = DataType::TIME;
642 break;
643 case SQL_TYPE_TIMESTAMP:
644 case SQL_TIMESTAMP:
645 nValue = DataType::TIMESTAMP;
646 break;
647 case SQL_BINARY:
648 nValue = DataType::BINARY;
649 break;
650 case SQL_VARBINARY:
651 case SQL_GUID:
652 nValue = DataType::VARBINARY;
653 break;
654 case SQL_LONGVARBINARY:
655 nValue = DataType::LONGVARBINARY;
656 break;
657 default:
658 OSL_ASSERT(!"Invalid type");
660 return nValue;
662 //--------------------------------------------------------------------
663 // jdbcTypeToOdbc
664 // Convert the JDBC SQL type to the correct ODBC type
665 //--------------------------------------------------------------------
666 SQLSMALLINT OTools::jdbcTypeToOdbc(sal_Int32 jdbcType)
668 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::jdbcTypeToOdbc" );
669 // For the most part, JDBC types match ODBC types. We'll
670 // just convert the ones that we know are different
672 sal_Int32 odbcType = jdbcType;
674 switch (jdbcType)
676 case DataType::DATE:
677 odbcType = SQL_DATE;
678 break;
679 case DataType::TIME:
680 odbcType = SQL_TIME;
681 break;
682 case DataType::TIMESTAMP:
683 odbcType = SQL_TIMESTAMP;
684 break;
685 // ODBC doesn't have any notion of CLOB or BLOB
686 case DataType::CLOB:
687 odbcType = SQL_LONGVARCHAR;
688 break;
689 case DataType::BLOB:
690 odbcType = SQL_LONGVARBINARY;
691 break;
694 return odbcType;
696 //-----------------------------------------------------------------------------
697 void OTools::getBindTypes(sal_Bool _bUseWChar,
698 sal_Bool _bUseOldTimeDate,
699 SQLSMALLINT _nOdbcType,
700 SQLSMALLINT& fCType,
701 SQLSMALLINT& fSqlType
704 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::getBindTypes" );
705 switch(_nOdbcType)
707 case SQL_CHAR: if(_bUseWChar)
709 fCType = SQL_C_WCHAR;
710 fSqlType = SQL_WCHAR;
712 else
714 fCType = SQL_C_CHAR;
715 fSqlType = SQL_CHAR;
717 break;
718 case SQL_VARCHAR: if(_bUseWChar)
720 fCType = SQL_C_WCHAR;
721 fSqlType = SQL_WVARCHAR;
723 else
725 fCType = SQL_C_CHAR;
726 fSqlType = SQL_VARCHAR;
728 break;
729 case SQL_LONGVARCHAR: if(_bUseWChar)
731 fCType = SQL_C_WCHAR;
732 fSqlType = SQL_WLONGVARCHAR;
734 else
736 fCType = SQL_C_CHAR;
737 fSqlType = SQL_LONGVARCHAR;
739 break;
740 case SQL_DECIMAL: fCType = _bUseWChar ? SQL_C_WCHAR : SQL_C_CHAR;
741 fSqlType = SQL_DECIMAL; break;
742 case SQL_NUMERIC: fCType = _bUseWChar ? SQL_C_WCHAR : SQL_C_CHAR;
743 fSqlType = SQL_NUMERIC; break;
744 case SQL_BIT: fCType = SQL_C_TINYINT;
745 fSqlType = SQL_INTEGER; break;
746 case SQL_TINYINT: fCType = SQL_C_TINYINT;
747 fSqlType = SQL_TINYINT; break;
748 case SQL_SMALLINT: fCType = SQL_C_SHORT;
749 fSqlType = SQL_SMALLINT; break;
750 case SQL_INTEGER: fCType = SQL_C_LONG;
751 fSqlType = SQL_INTEGER; break;
752 case SQL_BIGINT: fCType = SQL_C_SBIGINT;
753 fSqlType = SQL_BIGINT; break;
754 case SQL_FLOAT: fCType = SQL_C_FLOAT;
755 fSqlType = SQL_FLOAT; break;
756 case SQL_REAL: fCType = SQL_C_DOUBLE;
757 fSqlType = SQL_REAL; break;
758 case SQL_DOUBLE: fCType = SQL_C_DOUBLE;
759 fSqlType = SQL_DOUBLE; break;
760 case SQL_BINARY: fCType = SQL_C_BINARY;
761 fSqlType = SQL_BINARY; break;
762 case SQL_VARBINARY:
763 fCType = SQL_C_BINARY;
764 fSqlType = SQL_VARBINARY; break;
765 case SQL_LONGVARBINARY: fCType = SQL_C_BINARY;
766 fSqlType = SQL_LONGVARBINARY; break;
767 case SQL_DATE:
768 if(_bUseOldTimeDate)
770 fCType = SQL_C_DATE;
771 fSqlType = SQL_DATE;
773 else
775 fCType = SQL_C_TYPE_DATE;
776 fSqlType = SQL_TYPE_DATE;
778 break;
779 case SQL_TIME:
780 if(_bUseOldTimeDate)
782 fCType = SQL_C_TIME;
783 fSqlType = SQL_TIME;
785 else
787 fCType = SQL_C_TYPE_TIME;
788 fSqlType = SQL_TYPE_TIME;
790 break;
791 case SQL_TIMESTAMP:
792 if(_bUseOldTimeDate)
794 fCType = SQL_C_TIMESTAMP;
795 fSqlType = SQL_TIMESTAMP;
797 else
799 fCType = SQL_C_TYPE_TIMESTAMP;
800 fSqlType = SQL_TYPE_TIMESTAMP;
802 break;
803 default: fCType = SQL_C_BINARY;
804 fSqlType = SQL_LONGVARBINARY; break;
809 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */