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