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