Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / connectivity / source / drivers / odbc / OTools.cxx
blob70452dd7c4694fa07e7619bc8965b1760f533ea8
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/ustrbuf.hxx>
27 #include <boost/static_assert.hpp>
30 #include <string.h>
31 #include <string>
32 #include <algorithm>
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;
39 namespace {
40 size_t sqlTypeLen ( SQLSMALLINT _nType )
42 switch (_nType)
44 case SQL_C_SSHORT:
45 case SQL_C_SHORT:
46 return sizeof(SQLSMALLINT);
47 case SQL_C_USHORT:
48 return sizeof(SQLUSMALLINT);
49 case SQL_C_SLONG:
50 case SQL_C_LONG:
51 return sizeof(SQLINTEGER);
52 case SQL_C_ULONG:
53 return sizeof(SQLUINTEGER);
54 case SQL_C_FLOAT:
55 return sizeof(SQLREAL);
56 case SQL_C_DOUBLE:
57 OSL_ENSURE(sizeof(SQLDOUBLE) == sizeof(SQLFLOAT), "SQLDOUBLE/SQLFLOAT confusion");
58 return sizeof(SQLDOUBLE);
59 case SQL_C_BIT:
60 return sizeof(SQLCHAR);
61 case SQL_C_STINYINT:
62 case SQL_C_TINYINT:
63 return sizeof(SQLSCHAR);
64 case SQL_C_UTINYINT:
65 return sizeof(SQLCHAR);
66 case SQL_C_SBIGINT:
67 return sizeof(SQLBIGINT);
68 case SQL_C_UBIGINT:
69 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 return sizeof(SQL_DATE_STRUCT);
76 case SQL_C_TYPE_TIME:
77 case SQL_C_TIME:
78 return sizeof(SQL_TIME_STRUCT);
79 case SQL_C_TYPE_TIMESTAMP:
80 case SQL_C_TIMESTAMP:
81 return sizeof(SQL_TIMESTAMP_STRUCT);
82 case SQL_C_NUMERIC:
83 return sizeof(SQL_NUMERIC_STRUCT);
84 case SQL_C_GUID:
85 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 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 return static_cast<size_t>(-1);
114 void OTools::getValue( OConnection* _pConnection,
115 SQLHANDLE _aStatementHandle,
116 sal_Int32 columnIndex,
117 SQLSMALLINT _nType,
118 bool &_bWasNull,
119 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
120 void* _pValue,
121 SQLLEN _nSize) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
123 const size_t properSize = sqlTypeLen(_nType);
124 if ( properSize == static_cast<size_t>(-1) )
125 SAL_WARN( "connectivity.drivers", "connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size");
126 else
128 OSL_ENSURE(static_cast<size_t>(_nSize) == properSize, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to");
129 if ( static_cast<size_t>(_nSize) > properSize )
131 SAL_WARN( "connectivity.drivers", "memory region is too big - trying to fudge it");
132 memset(_pValue, 0, _nSize);
133 #ifdef OSL_BIGENDIAN
134 // This is skewed in favour of integer types
135 _pValue += _nSize - properSize;
136 #endif
139 OSL_ENSURE(static_cast<size_t>(_nSize) >= properSize, "memory region is too small");
140 SQLLEN pcbValue = SQL_NULL_DATA;
141 OTools::ThrowException(_pConnection,
142 (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle,
143 (SQLUSMALLINT)columnIndex,
144 _nType,
145 _pValue,
146 _nSize,
147 &pcbValue),
148 _aStatementHandle,SQL_HANDLE_STMT,_xInterface,false);
149 _bWasNull = pcbValue == SQL_NULL_DATA;
152 void OTools::bindValue( OConnection* _pConnection,
153 SQLHANDLE _aStatementHandle,
154 sal_Int32 columnIndex,
155 SQLSMALLINT _nType,
156 SQLSMALLINT _nMaxLen,
157 const void* _pValue,
158 void* _pData,
159 SQLLEN * const pLen,
160 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
161 rtl_TextEncoding _nTextEncoding,
162 bool _bUseOldTimeDate) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
164 SQLRETURN nRetcode;
165 SQLSMALLINT fSqlType;
166 SQLSMALLINT fCType;
167 SQLLEN nMaxLen = _nMaxLen;
169 OTools::getBindTypes( false,
170 _bUseOldTimeDate,
171 _nType,
172 fCType,
173 fSqlType);
175 if (columnIndex != 0 && !_pValue)
177 *pLen = SQL_NULL_DATA;
178 nRetcode = (*(T3SQLBindCol)_pConnection->getOdbcFunction(ODBC3SQLBindCol))(_aStatementHandle,
179 (SQLUSMALLINT)columnIndex,
180 fCType,
181 _pData,
182 nMaxLen,
183 pLen
186 else
190 switch (_nType)
192 case SQL_CHAR:
193 case SQL_VARCHAR:
195 OString aString(OUStringToOString(*(OUString*)_pValue,_nTextEncoding));
196 *pLen = SQL_NTS;
197 *((OString*)_pData) = aString;
198 _nMaxLen = (SQLSMALLINT)aString.getLength();
200 // Pointer on Char*
201 _pData = (void*)aString.getStr();
202 } break;
203 case SQL_BIGINT:
204 *((sal_Int64*)_pData) = *(sal_Int64*)_pValue;
205 *pLen = sizeof(sal_Int64);
206 break;
207 case SQL_DECIMAL:
208 case SQL_NUMERIC:
210 OString aString = OString::number(*(double*)_pValue);
211 _nMaxLen = (SQLSMALLINT)aString.getLength();
212 *pLen = _nMaxLen;
213 *((OString*)_pData) = aString;
214 // Pointer on Char*
215 _pData = (void*)((OString*)_pData)->getStr();
216 } break;
217 case SQL_BIT:
218 case SQL_TINYINT:
219 *((sal_Int8*)_pData) = *(sal_Int8*)_pValue;
220 *pLen = sizeof(sal_Int8);
221 break;
223 case SQL_SMALLINT:
224 *((sal_Int16*)_pData) = *(sal_Int16*)_pValue;
225 *pLen = sizeof(sal_Int16);
226 break;
227 case SQL_INTEGER:
228 *((sal_Int32*)_pData) = *(sal_Int32*)_pValue;
229 *pLen = sizeof(sal_Int32);
230 break;
231 case SQL_FLOAT:
232 *((float*)_pData) = *(float*)_pValue;
233 *pLen = sizeof(float);
234 break;
235 case SQL_REAL:
236 case SQL_DOUBLE:
237 *((double*)_pData) = *(double*)_pValue;
238 *pLen = sizeof(double);
239 break;
240 case SQL_BINARY:
241 case SQL_VARBINARY:
243 _pData = (void*)((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getConstArray();
244 *pLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength();
245 } break;
246 case SQL_LONGVARBINARY:
248 _pData = (void*)(sal_IntPtr)(columnIndex);
249 sal_Int32 nLen = 0;
250 nLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength();
251 *pLen = (SQLLEN)SQL_LEN_DATA_AT_EXEC(nLen);
253 break;
254 case SQL_LONGVARCHAR:
256 _pData = (void*)(sal_IntPtr)(columnIndex);
257 sal_Int32 nLen = 0;
258 nLen = ((OUString*)_pValue)->getLength();
259 *pLen = (SQLLEN)SQL_LEN_DATA_AT_EXEC(nLen);
260 } break;
261 case SQL_DATE:
262 *pLen = sizeof(DATE_STRUCT);
263 *((DATE_STRUCT*)_pData) = *(DATE_STRUCT*)_pValue;
264 break;
265 case SQL_TIME:
266 *pLen = sizeof(TIME_STRUCT);
267 *((TIME_STRUCT*)_pData) = *(TIME_STRUCT*)_pValue;
268 break;
269 case SQL_TIMESTAMP:
270 *pLen = sizeof(TIMESTAMP_STRUCT);
271 *((TIMESTAMP_STRUCT*)_pData) = *(TIMESTAMP_STRUCT*)_pValue;
272 break;
275 catch ( ... )
279 nRetcode = (*(T3SQLBindCol)_pConnection->getOdbcFunction(ODBC3SQLBindCol))(_aStatementHandle,
280 (SQLUSMALLINT)columnIndex,
281 fCType,
282 _pData,
283 nMaxLen,
284 pLen
288 OTools::ThrowException(_pConnection,nRetcode,_aStatementHandle,SQL_HANDLE_STMT,_xInterface);
291 void OTools::ThrowException(const OConnection* _pConnection,
292 const SQLRETURN _rRetCode,
293 const SQLHANDLE _pContext,
294 const SQLSMALLINT _nHandleType,
295 const Reference< XInterface >& _xInterface,
296 const bool _bNoFound,
297 const rtl_TextEncoding _nTextEncoding) throw(SQLException)
299 switch(_rRetCode)
301 case SQL_NEED_DATA:
302 case SQL_STILL_EXECUTING:
303 case SQL_SUCCESS:
305 case SQL_SUCCESS_WITH_INFO:
306 return;
307 case SQL_NO_DATA_FOUND:
308 if(_bNoFound)
309 return; // no need to throw a exception
310 case SQL_ERROR: break;
313 case SQL_INVALID_HANDLE: SAL_WARN( "connectivity.drivers", "SdbODBC3_SetStatus: SQL_INVALID_HANDLE");
314 throw SQLException();
317 // Additional Information on the latest ODBC-functioncall available
318 // SQLError provides this Information.
320 SDB_ODBC_CHAR szSqlState[5];
321 SQLINTEGER pfNativeError;
322 SDB_ODBC_CHAR szErrorMessage[SQL_MAX_MESSAGE_LENGTH];
323 szErrorMessage[0] = '\0';
324 SQLSMALLINT pcbErrorMsg = 0;
326 // Information for latest operation:
327 // when hstmt != SQL_NULL_HSTMT is (Used from SetStatus in SdbCursor, SdbTable, ...),
328 // then the status of the latest statements will be fetched, without the Status of the last
329 // statements of this connection [what in this case will probably be the same, but the Reference
330 // Manual isn't totally clear in this...].
331 // corresponding for hdbc.
332 SQLRETURN n = (*(T3SQLGetDiagRec)_pConnection->getOdbcFunction(ODBC3SQLGetDiagRec))(_nHandleType,_pContext,1,
333 szSqlState,
334 &pfNativeError,
335 szErrorMessage,sizeof szErrorMessage - 1,&pcbErrorMsg);
336 OSL_UNUSED( n );
337 OSL_ENSURE(n != SQL_INVALID_HANDLE,"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE");
338 OSL_ENSURE(n == SQL_SUCCESS || n == SQL_SUCCESS_WITH_INFO || n == SQL_NO_DATA_FOUND || n == SQL_ERROR,"SdbODBC3_SetStatus: SQLError failed");
340 // For the Return Code of SQLError see ODBC 2.0 Programmer's Reference Page 287ff
341 throw SQLException( OUString((char *)szErrorMessage,pcbErrorMsg,_nTextEncoding),
342 _xInterface,
343 OUString((char *)szSqlState,5,_nTextEncoding),
344 pfNativeError,
345 Any()
350 Sequence<sal_Int8> OTools::getBytesValue(const OConnection* _pConnection,
351 const SQLHANDLE _aStatementHandle,
352 const sal_Int32 columnIndex,
353 const SQLSMALLINT _fSqlType,
354 bool &_bWasNull,
355 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
357 sal_Int8 aCharArray[2048];
358 // First try to fetch the data with the little Buffer:
359 const SQLLEN nMaxLen = sizeof aCharArray;
360 SQLLEN pcbValue = SQL_NO_TOTAL;
361 Sequence<sal_Int8> aData;
363 OSL_ENSURE( _fSqlType != SQL_CHAR && _fSqlType != SQL_VARCHAR && _fSqlType != SQL_LONGVARCHAR &&
364 _fSqlType != SQL_WCHAR && _fSqlType != SQL_WVARCHAR && _fSqlType != SQL_WLONGVARCHAR,
365 "connectivity::odbc::OTools::getBytesValue called with character _fSqlType");
367 while (pcbValue == SQL_NO_TOTAL || pcbValue > nMaxLen)
369 OTools::ThrowException(_pConnection,
370 (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(
371 _aStatementHandle,
372 (SQLUSMALLINT)columnIndex,
373 _fSqlType,
374 (SQLPOINTER)aCharArray,
375 nMaxLen,
376 &pcbValue),
377 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
379 _bWasNull = pcbValue == SQL_NULL_DATA;
380 if(_bWasNull)
381 return Sequence<sal_Int8>();
383 SQLLEN nReadBytes;
384 // After the SQLGetData that wrote out to aCharArray the last byte of the data,
385 // pcbValue will not be SQL_NO_TOTAL -> we have a reliable count
386 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxLen) )
388 // we filled the buffer
389 nReadBytes = nMaxLen;
391 else
393 nReadBytes = pcbValue;
395 const sal_Int32 nLen = aData.getLength();
396 aData.realloc(nLen + nReadBytes);
397 memcpy(aData.getArray() + nLen, aCharArray, nReadBytes);
399 return aData;
402 OUString OTools::getStringValue(OConnection* _pConnection,
403 SQLHANDLE _aStatementHandle,
404 sal_Int32 columnIndex,
405 SQLSMALLINT _fSqlType,
406 bool &_bWasNull,
407 const Reference< XInterface >& _xInterface,
408 rtl_TextEncoding _nTextEncoding) throw(SQLException, RuntimeException)
410 OUStringBuffer aData;
411 switch(_fSqlType)
413 case SQL_WVARCHAR:
414 case SQL_WCHAR:
415 case SQL_WLONGVARCHAR:
417 sal_Unicode waCharArray[2048];
418 // we assume everyone (LibO & ODBC) uses UTF-16; see OPreparedStatement::setParameter
419 BOOST_STATIC_ASSERT(sizeof(sal_Unicode) == 2);
420 BOOST_STATIC_ASSERT(sizeof(SQLWCHAR) == 2);
421 BOOST_STATIC_ASSERT(sizeof(waCharArray) % 2 == 0);
422 // Size == number of bytes, Len == number of UTF-16 code units
423 const SQLLEN nMaxSize = sizeof(waCharArray);
424 const SQLLEN nMaxLen = sizeof(waCharArray) / sizeof(sal_Unicode);
425 BOOST_STATIC_ASSERT(nMaxLen * sizeof(sal_Unicode) == nMaxSize);
427 // read the unicode data
428 SQLLEN pcbValue = SQL_NO_TOTAL;
429 while ((pcbValue == SQL_NO_TOTAL ) || (pcbValue >= nMaxSize) )
431 OTools::ThrowException(_pConnection,
432 (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(
433 _aStatementHandle,
434 (SQLUSMALLINT)columnIndex,
435 SQL_C_WCHAR,
436 &waCharArray,
437 (SQLLEN)nMaxLen*sizeof(sal_Unicode),
438 &pcbValue),
439 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
440 _bWasNull = pcbValue == SQL_NULL_DATA;
441 if(_bWasNull)
442 return OUString();
444 SQLLEN nReadChars;
445 OSL_ENSURE( (pcbValue < 0) || (pcbValue % 2 == 0),
446 "ODBC: SQLGetData of SQL_C_WCHAR returned odd number of bytes");
447 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxSize) )
449 // we filled the buffer; remove the terminating null character
450 nReadChars = nMaxLen-1;
451 if ( waCharArray[nReadChars] != 0)
453 SAL_WARN( "connectivity.drivers", "Buggy ODBC driver? Did not null-terminate (variable length) data!");
454 ++nReadChars;
457 else
459 nReadChars = pcbValue/sizeof(sal_Unicode);
462 aData.append(waCharArray, nReadChars);
465 break;
467 default:
469 char aCharArray[2048];
470 // read the unicode data
471 const SQLLEN nMaxLen = sizeof(aCharArray);
472 SQLLEN pcbValue = SQL_NO_TOTAL;
474 while ((pcbValue == SQL_NO_TOTAL ) || (pcbValue >= nMaxLen) )
476 OTools::ThrowException(_pConnection,
477 (*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(
478 _aStatementHandle,
479 (SQLUSMALLINT)columnIndex,
480 SQL_C_CHAR,
481 &aCharArray,
482 nMaxLen,
483 &pcbValue),
484 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
485 _bWasNull = pcbValue == SQL_NULL_DATA;
486 if(_bWasNull)
487 return OUString();
489 SQLLEN nReadChars;
490 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxLen) )
492 // we filled the buffer; remove the terminating null character
493 nReadChars = nMaxLen-1;
494 if ( aCharArray[nReadChars] != 0)
496 SAL_WARN( "connectivity.drivers", "Buggy ODBC driver? Did not null-terminate (variable length) data!");
497 ++nReadChars;
500 else
502 nReadChars = pcbValue;
505 aData.append(OUString(aCharArray, nReadChars, _nTextEncoding));
508 break;
512 return aData.makeStringAndClear();
515 void OTools::GetInfo(OConnection* _pConnection,
516 SQLHANDLE _aConnectionHandle,
517 SQLUSMALLINT _nInfo,
518 OUString &_rValue,
519 const Reference< XInterface >& _xInterface,
520 rtl_TextEncoding _nTextEncoding) throw(SQLException, RuntimeException)
522 char aValue[512];
523 SQLSMALLINT nValueLen=0;
524 OTools::ThrowException(_pConnection,
525 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,aValue,(sizeof aValue)-1,&nValueLen),
526 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
528 _rValue = OUString(aValue,nValueLen,_nTextEncoding);
531 void OTools::GetInfo(OConnection* _pConnection,
532 SQLHANDLE _aConnectionHandle,
533 SQLUSMALLINT _nInfo,
534 sal_Int32 &_rValue,
535 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
537 SQLSMALLINT nValueLen;
538 _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
539 OTools::ThrowException(_pConnection,
540 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
541 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
544 void OTools::GetInfo(OConnection* _pConnection,
545 SQLHANDLE _aConnectionHandle,
546 SQLUSMALLINT _nInfo,
547 SQLUINTEGER &_rValue,
548 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
550 SQLSMALLINT nValueLen;
551 _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
552 OTools::ThrowException(_pConnection,
553 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
554 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
557 void OTools::GetInfo(OConnection* _pConnection,
558 SQLHANDLE _aConnectionHandle,
559 SQLUSMALLINT _nInfo,
560 SQLUSMALLINT &_rValue,
561 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
563 SQLSMALLINT nValueLen;
564 _rValue = 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
565 OTools::ThrowException(_pConnection,
566 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
567 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
570 void OTools::GetInfo(OConnection* _pConnection,
571 SQLHANDLE _aConnectionHandle,
572 SQLUSMALLINT _nInfo,
573 bool &_rValue,
574 const Reference< XInterface >& _xInterface) throw(SQLException, RuntimeException)
576 SQLSMALLINT nValueLen;
577 OTools::ThrowException(_pConnection,
578 (*(T3SQLGetInfo)_pConnection->getOdbcFunction(ODBC3SQLGetInfo))(_aConnectionHandle,_nInfo,&_rValue,sizeof _rValue,&nValueLen),
579 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
582 sal_Int32 OTools::MapOdbcType2Jdbc(SQLSMALLINT _nType)
584 sal_Int32 nValue = DataType::VARCHAR;
585 switch(_nType)
587 case SQL_BIT:
588 nValue = DataType::BIT;
589 break;
590 case SQL_TINYINT:
591 nValue = DataType::TINYINT;
592 break;
593 case SQL_SMALLINT:
594 nValue = DataType::SMALLINT;
595 break;
596 case SQL_INTEGER:
597 nValue = DataType::INTEGER;
598 break;
599 case SQL_BIGINT:
600 nValue = DataType::BIGINT;
601 break;
602 case SQL_FLOAT:
603 nValue = DataType::FLOAT;
604 break;
605 case SQL_REAL:
606 nValue = DataType::REAL;
607 break;
608 case SQL_DOUBLE:
609 nValue = DataType::DOUBLE;
610 break;
611 case SQL_NUMERIC:
612 nValue = DataType::NUMERIC;
613 break;
614 case SQL_DECIMAL:
615 nValue = DataType::DECIMAL;
616 break;
617 case SQL_WCHAR:
618 case SQL_CHAR:
619 nValue = DataType::CHAR;
620 break;
621 case SQL_WVARCHAR:
622 case SQL_VARCHAR:
623 nValue = DataType::VARCHAR;
624 break;
625 case SQL_WLONGVARCHAR:
626 case SQL_LONGVARCHAR:
627 nValue = DataType::LONGVARCHAR;
628 break;
629 case SQL_TYPE_DATE:
630 case SQL_DATE:
631 nValue = DataType::DATE;
632 break;
633 case SQL_TYPE_TIME:
634 case SQL_TIME:
635 nValue = DataType::TIME;
636 break;
637 case SQL_TYPE_TIMESTAMP:
638 case SQL_TIMESTAMP:
639 nValue = DataType::TIMESTAMP;
640 break;
641 case SQL_BINARY:
642 nValue = DataType::BINARY;
643 break;
644 case SQL_VARBINARY:
645 case SQL_GUID:
646 nValue = DataType::VARBINARY;
647 break;
648 case SQL_LONGVARBINARY:
649 nValue = DataType::LONGVARBINARY;
650 break;
651 default:
652 OSL_FAIL("Invalid type");
654 return nValue;
657 // jdbcTypeToOdbc
658 // Convert the JDBC SQL type to the correct ODBC type
660 SQLSMALLINT OTools::jdbcTypeToOdbc(sal_Int32 jdbcType)
662 // For the most part, JDBC types match ODBC types. We'll
663 // just convert the ones that we know are different
665 sal_Int32 odbcType = jdbcType;
667 switch (jdbcType)
669 case DataType::DATE:
670 odbcType = SQL_DATE;
671 break;
672 case DataType::TIME:
673 odbcType = SQL_TIME;
674 break;
675 case DataType::TIMESTAMP:
676 odbcType = SQL_TIMESTAMP;
677 break;
678 // ODBC doesn't have any notion of CLOB or BLOB
679 case DataType::CLOB:
680 odbcType = SQL_LONGVARCHAR;
681 break;
682 case DataType::BLOB:
683 odbcType = SQL_LONGVARBINARY;
684 break;
687 return odbcType;
690 void OTools::getBindTypes(bool _bUseWChar,
691 bool _bUseOldTimeDate,
692 SQLSMALLINT _nOdbcType,
693 SQLSMALLINT& fCType,
694 SQLSMALLINT& fSqlType
697 switch(_nOdbcType)
699 case SQL_CHAR: if(_bUseWChar)
701 fCType = SQL_C_WCHAR;
702 fSqlType = SQL_WCHAR;
704 else
706 fCType = SQL_C_CHAR;
707 fSqlType = SQL_CHAR;
709 break;
710 case SQL_VARCHAR: if(_bUseWChar)
712 fCType = SQL_C_WCHAR;
713 fSqlType = SQL_WVARCHAR;
715 else
717 fCType = SQL_C_CHAR;
718 fSqlType = SQL_VARCHAR;
720 break;
721 case SQL_LONGVARCHAR: if(_bUseWChar)
723 fCType = SQL_C_WCHAR;
724 fSqlType = SQL_WLONGVARCHAR;
726 else
728 fCType = SQL_C_CHAR;
729 fSqlType = SQL_LONGVARCHAR;
731 break;
732 case SQL_DECIMAL: fCType = _bUseWChar ? SQL_C_WCHAR : SQL_C_CHAR;
733 fSqlType = SQL_DECIMAL; break;
734 case SQL_NUMERIC: fCType = _bUseWChar ? SQL_C_WCHAR : SQL_C_CHAR;
735 fSqlType = SQL_NUMERIC; break;
736 case SQL_BIT: fCType = SQL_C_TINYINT;
737 fSqlType = SQL_INTEGER; break;
738 case SQL_TINYINT: fCType = SQL_C_TINYINT;
739 fSqlType = SQL_TINYINT; break;
740 case SQL_SMALLINT: fCType = SQL_C_SHORT;
741 fSqlType = SQL_SMALLINT; break;
742 case SQL_INTEGER: fCType = SQL_C_LONG;
743 fSqlType = SQL_INTEGER; break;
744 case SQL_BIGINT: fCType = SQL_C_SBIGINT;
745 fSqlType = SQL_BIGINT; break;
746 case SQL_FLOAT: fCType = SQL_C_FLOAT;
747 fSqlType = SQL_FLOAT; break;
748 case SQL_REAL: fCType = SQL_C_DOUBLE;
749 fSqlType = SQL_REAL; break;
750 case SQL_DOUBLE: fCType = SQL_C_DOUBLE;
751 fSqlType = SQL_DOUBLE; break;
752 case SQL_BINARY: fCType = SQL_C_BINARY;
753 fSqlType = SQL_BINARY; break;
754 case SQL_VARBINARY:
755 fCType = SQL_C_BINARY;
756 fSqlType = SQL_VARBINARY; break;
757 case SQL_LONGVARBINARY: fCType = SQL_C_BINARY;
758 fSqlType = SQL_LONGVARBINARY; break;
759 case SQL_DATE:
760 if(_bUseOldTimeDate)
762 fCType = SQL_C_DATE;
763 fSqlType = SQL_DATE;
765 else
767 fCType = SQL_C_TYPE_DATE;
768 fSqlType = SQL_TYPE_DATE;
770 break;
771 case SQL_TIME:
772 if(_bUseOldTimeDate)
774 fCType = SQL_C_TIME;
775 fSqlType = SQL_TIME;
777 else
779 fCType = SQL_C_TYPE_TIME;
780 fSqlType = SQL_TYPE_TIME;
782 break;
783 case SQL_TIMESTAMP:
784 if(_bUseOldTimeDate)
786 fCType = SQL_C_TIMESTAMP;
787 fSqlType = SQL_TIMESTAMP;
789 else
791 fCType = SQL_C_TYPE_TIMESTAMP;
792 fSqlType = SQL_TYPE_TIMESTAMP;
794 break;
795 default: fCType = SQL_C_BINARY;
796 fSqlType = SQL_LONGVARBINARY; break;
801 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */