1 /************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: OTools.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "odbc/OTools.hxx"
34 #include "odbc/OFunctions.hxx"
35 #include <com/sun/star/sdbc/DataType.hpp>
36 #include <osl/diagnose.h>
37 #include "odbc/OConnection.hxx"
38 #include "diagnose_ex.h"
39 #include <rtl/logfile.hxx>
40 #include <rtl/ustrbuf.hxx>
47 using namespace connectivity::odbc
;
48 using namespace com::sun::star::uno
;
49 using namespace com::sun::star::sdbc
;
50 using namespace com::sun::star::util
;
52 void OTools::getValue( OConnection
* _pConnection
,
53 SQLHANDLE _aStatementHandle
,
54 sal_Int32 columnIndex
,
57 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
59 SQLLEN _nSize
) throw(::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
61 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::getValue" );
62 SQLLEN pcbValue
= SQL_NULL_DATA
;
63 OTools::ThrowException(_pConnection
,
64 (*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
65 (SQLUSMALLINT
)columnIndex
,
70 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
,sal_False
);
71 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
73 // -----------------------------------------------------------------------------
74 void OTools::bindParameter( OConnection
* _pConnection
,
77 sal_Int8
*& pDataBuffer
,
79 SQLSMALLINT _nODBCtype
,
81 sal_Bool _bUseOldTimeDate
,
83 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
84 rtl_TextEncoding _nTextEncoding
)
85 throw(::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
87 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::bindParameter" );
92 // void*& pData = pDataBuffer;
93 SQLLEN
* pLen
= (SQLLEN
*)pLenBuffer
;
94 SQLULEN nColumnSize
=0;
95 SQLSMALLINT nDecimalDigits
=0;
97 OTools::getBindTypes(_bUseWChar
,_bUseOldTimeDate
,_nODBCtype
,fCType
,fSqlType
);
99 OTools::bindData(_nODBCtype
,_bUseWChar
,pDataBuffer
,pLen
,_pValue
,_nTextEncoding
,nColumnSize
);
100 if ((nColumnSize
== 0) && (fSqlType
== SQL_CHAR
|| fSqlType
== SQL_VARCHAR
|| fSqlType
== SQL_LONGVARCHAR
))
103 if(fSqlType
== SQL_LONGVARCHAR
|| fSqlType
== SQL_LONGVARBINARY
)
104 memcpy(pDataBuffer
,&nPos
,sizeof(nPos
));
106 // 20.09.2001 OJ: Problems with mysql. mysql returns only CHAR as parameter type
107 // nRetcode = (*(T3SQLDescribeParam)_pConnection->getOdbcFunction(ODBC3SQLDescribeParam))(_hStmt,(SQLUSMALLINT)nPos,&fSqlType,&nColumnSize,&nDecimalDigits,&nNullable);
109 nRetcode
= (*(T3SQLBindParameter
)_pConnection
->getOdbcFunction(ODBC3SQLBindParameter
))(_hStmt
,
120 OTools::ThrowException(_pConnection
,nRetcode
,_hStmt
,SQL_HANDLE_STMT
,_xInterface
);
122 // -----------------------------------------------------------------------------
123 void OTools::bindData( SQLSMALLINT _nOdbcType
,
128 rtl_TextEncoding _nTextEncoding
,
129 SQLULEN
& _nColumnSize
)
131 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::bindData" );
141 ::rtl::OUString
sStr(*(::rtl::OUString
*)_pValue
);
142 _nColumnSize
= sStr
.getLength();
143 *((rtl::OUString
*)_pData
) = sStr
;
146 _pData
= (sal_Int8
*)((rtl::OUString
*)_pData
)->getStr();
150 ::rtl::OString
aString(::rtl::OUStringToOString(*(::rtl::OUString
*)_pValue
,_nTextEncoding
));
152 _nColumnSize
= aString
.getLength();
153 memcpy(_pData
,aString
.getStr(),aString
.getLength());
154 ((sal_Int8
*)_pData
)[aString
.getLength()] = '\0';
159 *((sal_Int64
*)_pData
) = *(sal_Int64
*)_pValue
;
160 *pLen
= sizeof(sal_Int64
);
161 _nColumnSize
= *pLen
;
167 ::rtl::OUString aString
= rtl::OUString::valueOf(*(double*)_pValue
);
168 _nColumnSize
= aString
.getLength();
169 *pLen
= _nColumnSize
;
170 *((rtl::OUString
*)_pData
) = aString
;
172 _pData
= (sal_Int8
*)((rtl::OUString
*)_pData
)->getStr();
176 ::rtl::OString aString
= ::rtl::OString::valueOf(*(double*)_pValue
);
177 _nColumnSize
= aString
.getLength();
178 *pLen
= _nColumnSize
;
179 memcpy(_pData
,aString
.getStr(),aString
.getLength());
180 ((sal_Int8
*)_pData
)[_nColumnSize
] = '\0';
184 *((sal_Int8
*)_pData
) = *(sal_Int8
*)_pValue
;
185 *pLen
= sizeof(sal_Int8
);
189 *((sal_Int16
*)_pData
) = *(sal_Int16
*)_pValue
;
190 *pLen
= sizeof(sal_Int16
);
193 *((sal_Int32
*)_pData
) = *(sal_Int32
*)_pValue
;
194 *pLen
= sizeof(sal_Int32
);
197 *((float*)_pData
) = *(float*)_pValue
;
198 *pLen
= sizeof(float);
202 *((double*)_pData
) = *(double*)_pValue
;
203 *pLen
= sizeof(double);
208 const ::com::sun::star::uno::Sequence
< sal_Int8
>* pSeq
= static_cast< const ::com::sun::star::uno::Sequence
< sal_Int8
>* >(_pValue
);
209 OSL_ENSURE(pSeq
,"OTools::bindData: Sequence is null!");
213 // memcpy(_pData,pSeq->getConstArray(),pSeq->getLength());
214 _pData
= (sal_Int8
*)((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getConstArray();
215 *pLen
= pSeq
->getLength();
217 // _pData = (sal_Int8*)((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getConstArray();
218 // *pLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength();
221 case SQL_LONGVARBINARY
:
224 nLen
= ((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getLength();
225 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
228 case SQL_LONGVARCHAR
:
232 nLen
= sizeof(sal_Unicode
) * ((::rtl::OUString
*)_pValue
)->getLength();
235 ::rtl::OString
aString(::rtl::OUStringToOString(*(::rtl::OUString
*)_pValue
,_nTextEncoding
));
236 nLen
= aString
.getLength();
238 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
241 *(DATE_STRUCT
*)_pData
= *(DATE_STRUCT
*)_pValue
;
242 *pLen
= (SQLLEN
)sizeof(DATE_STRUCT
);
246 *(TIME_STRUCT
*)_pData
= *(TIME_STRUCT
*)_pValue
;
247 *pLen
= (SQLLEN
)sizeof(TIME_STRUCT
);
251 *(TIMESTAMP_STRUCT
*)_pData
= *(TIMESTAMP_STRUCT
*)_pValue
;
252 *pLen
= (SQLLEN
)sizeof(TIMESTAMP_STRUCT
);
257 // -------------------------------------------------------------------------
258 void OTools::bindValue( OConnection
* _pConnection
,
259 SQLHANDLE _aStatementHandle
,
260 sal_Int32 columnIndex
,
262 SQLSMALLINT _nMaxLen
,
266 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
267 rtl_TextEncoding _nTextEncoding
,
268 sal_Bool _bUseOldTimeDate
) throw(::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
270 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::bindValue" );
272 SQLSMALLINT fSqlType
;
274 SQLLEN nMaxLen
= _nMaxLen
;
276 OTools::getBindTypes( sal_False
,
282 if (columnIndex
!= 0 && !_pValue
)
284 *pLen
= SQL_NULL_DATA
;
285 nRetcode
= (*(T3SQLBindCol
)_pConnection
->getOdbcFunction(ODBC3SQLBindCol
))(_aStatementHandle
,
286 (SQLUSMALLINT
)columnIndex
,
301 //if(GetODBCConnection()->m_bUserWChar)
303 // _nMaxLen = rCol.GetPrecision();
305 // *((rtl::OUString*)pData) = (rtl::OUString)_aValue;
307 // // Zeiger auf Char*
308 // pData = (void*)((rtl::OUString*)pData)->getStr();
312 ::rtl::OString
aString(::rtl::OUStringToOString(*(::rtl::OUString
*)_pValue
,_nTextEncoding
));
314 *((::rtl::OString
*)_pData
) = aString
;
315 _nMaxLen
= (SQLSMALLINT
)aString
.getLength();
318 _pData
= (void*)aString
.getStr();
321 *((sal_Int64
*)_pData
) = *(sal_Int64
*)_pValue
;
322 *pLen
= sizeof(sal_Int64
);
326 //if(GetODBCConnection()->m_bUserWChar)
328 // rtl::OUString aString(rtl::OUString(SdbTools::ToString(ODbTypeConversion::toDouble(*pVariable),rCol.GetScale())));
330 // *((rtl::OUString*)_pData) = aString;
331 // // Zeiger auf Char*
332 // _pData = (void*)((rtl::OUString*)_pData)->getStr();
336 ::rtl::OString aString
= ::rtl::OString::valueOf(*(double*)_pValue
);
337 _nMaxLen
= (SQLSMALLINT
)aString
.getLength();
339 *((::rtl::OString
*)_pData
) = aString
;
341 _pData
= (void*)((::rtl::OString
*)_pData
)->getStr();
345 *((sal_Int8
*)_pData
) = *(sal_Int8
*)_pValue
;
346 *pLen
= sizeof(sal_Int8
);
350 *((sal_Int16
*)_pData
) = *(sal_Int16
*)_pValue
;
351 *pLen
= sizeof(sal_Int16
);
354 *((sal_Int32
*)_pData
) = *(sal_Int32
*)_pValue
;
355 *pLen
= sizeof(sal_Int32
);
358 *((float*)_pData
) = *(float*)_pValue
;
359 *pLen
= sizeof(float);
363 *((double*)_pData
) = *(double*)_pValue
;
364 *pLen
= sizeof(double);
368 // if (_pValue == ::getCppuType((const ::com::sun::star::uno::Sequence< sal_Int8 > *)0))
370 _pData
= (void*)((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getConstArray();
371 *pLen
= ((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getLength();
373 case SQL_LONGVARBINARY
:
375 _pData
= (void*)(columnIndex
);
377 nLen
= ((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getLength();
378 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
381 case SQL_LONGVARCHAR
:
383 _pData
= (void*)(columnIndex
);
385 nLen
= ((::rtl::OUString
*)_pValue
)->getLength();
386 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
389 *pLen
= sizeof(DATE_STRUCT
);
390 *((DATE_STRUCT
*)_pData
) = *(DATE_STRUCT
*)_pValue
;
393 *pLen
= sizeof(TIME_STRUCT
);
394 *((TIME_STRUCT
*)_pData
) = *(TIME_STRUCT
*)_pValue
;
397 *pLen
= sizeof(TIMESTAMP_STRUCT
);
398 *((TIMESTAMP_STRUCT
*)_pData
) = *(TIMESTAMP_STRUCT
*)_pValue
;
405 nRetcode
= (*(T3SQLBindCol
)_pConnection
->getOdbcFunction(ODBC3SQLBindCol
))(_aStatementHandle
,
406 (SQLUSMALLINT
)columnIndex
,
414 OTools::ThrowException(_pConnection
,nRetcode
,_aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
416 // -----------------------------------------------------------------------------
417 void OTools::ThrowException(OConnection
* _pConnection
,
420 SQLSMALLINT _nHandleType
,
421 const Reference
< XInterface
>& _xInterface
,
423 rtl_TextEncoding _nTextEncoding
) throw(SQLException
)
428 case SQL_STILL_EXECUTING
:
431 case SQL_SUCCESS_WITH_INFO
:
433 case SQL_NO_DATA_FOUND
:
435 return; // no need to throw a exception
436 case SQL_ERROR
: break;
439 case SQL_INVALID_HANDLE
: OSL_ENSURE(0,"SdbODBC3_SetStatus: SQL_INVALID_HANDLE");
440 throw SQLException();
444 // Zusaetliche Informationen zum letzten ODBC-Funktionsaufruf vorhanden.
445 // SQLError liefert diese Informationen.
446 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::ThrowException" );
448 SDB_ODBC_CHAR szSqlState
[5];
449 SQLINTEGER pfNativeError
;
450 SDB_ODBC_CHAR szErrorMessage
[SQL_MAX_MESSAGE_LENGTH
];
451 szErrorMessage
[0] = '\0';
452 SQLSMALLINT pcbErrorMsg
= 0;
454 // Informationen zur letzten Operation:
455 // wenn hstmt != SQL_NULL_HSTMT ist (Benutzung von SetStatus in SdbCursor, SdbTable, ...),
456 // dann wird der Status des letzten Statements erfragt, sonst der Status des letzten
457 // Statements zu dieser Verbindung [was in unserem Fall wahrscheinlich gleichbedeutend ist,
458 // aber das Reference Manual drueckt sich da nicht so klar aus ...].
459 // Entsprechend bei hdbc.
460 SQLRETURN n
= (*(T3SQLGetDiagRec
)_pConnection
->getOdbcFunction(ODBC3SQLGetDiagRec
))(_nHandleType
,_pContext
,1,
463 szErrorMessage
,sizeof szErrorMessage
- 1,&pcbErrorMsg
);
465 OSL_ENSURE(n
!= SQL_INVALID_HANDLE
,"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE");
466 OSL_ENSURE(n
== SQL_SUCCESS
|| n
== SQL_SUCCESS_WITH_INFO
|| n
== SQL_NO_DATA_FOUND
|| n
== SQL_ERROR
,"SdbODBC3_SetStatus: SQLError failed");
468 // Zum Return Code von SQLError siehe ODBC 2.0 Programmer's Reference Seite 287ff
469 throw SQLException( ::rtl::OUString((char *)szErrorMessage
,pcbErrorMsg
,_nTextEncoding
),
471 ::rtl::OUString((char *)szSqlState
,5,_nTextEncoding
),
477 // -------------------------------------------------------------------------
478 Sequence
<sal_Int8
> OTools::getBytesValue(OConnection
* _pConnection
,
479 SQLHANDLE _aStatementHandle
,
480 sal_Int32 columnIndex
,
481 SQLSMALLINT _fSqlType
,
483 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
485 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::getBytesValue" );
486 char aCharArray
[2048];
487 // Erstmal versuchen, die Daten mit dem kleinen Puffer
489 SQLLEN nMaxLen
= sizeof aCharArray
- 1;
490 // GETDATA(SQL_C_CHAR,aCharArray,nMaxLen);
492 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
493 (SQLUSMALLINT
)columnIndex
,
495 (SQLPOINTER
)aCharArray
,
498 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
500 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
502 return Sequence
<sal_Int8
>();
504 SQLINTEGER nBytes
= pcbValue
!= SQL_NO_TOTAL
? std::min(pcbValue
, nMaxLen
) : nMaxLen
;
505 if ( ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
) && aCharArray
[nBytes
-1] == 0 && nBytes
> 0 )
507 Sequence
<sal_Int8
> aData((sal_Int8
*)aCharArray
, nBytes
);
510 // Es handelt sich um Binaerdaten, um einen String, der fuer
511 // StarView zu lang ist oder der Treiber kann die Laenge der
512 // Daten nicht im voraus bestimmen - also als MemoryStream
514 while ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
)
516 // Bei Strings wird der Puffer nie ganz ausgenutzt
517 // (das letzte Byte ist immer ein NULL-Byte, das
518 // aber bei pcbValue nicht mitgezaehlt wird)
519 if (pcbValue
!= SQL_NO_TOTAL
&& (pcbValue
- nMaxLen
) < nMaxLen
)
520 nBytes
= pcbValue
- nMaxLen
;
524 // Solange eine "truncation"-Warnung vorliegt, weiter Daten abholen
525 // GETDATA(SQL_C_CHAR,aCharArray, nLen + 1);
526 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
527 (SQLUSMALLINT
)columnIndex
,
532 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
533 sal_Int32 nLen
= aData
.getLength();
534 aData
.realloc(nLen
+ nBytes
);
535 memcpy(aData
.getArray() + nLen
, aCharArray
, nBytes
);
539 // -------------------------------------------------------------------------
540 ::rtl::OUString
OTools::getStringValue(OConnection
* _pConnection
,
541 SQLHANDLE _aStatementHandle
,
542 sal_Int32 columnIndex
,
543 SQLSMALLINT _fSqlType
,
545 const Reference
< XInterface
>& _xInterface
,
546 rtl_TextEncoding _nTextEncoding
) throw(SQLException
, RuntimeException
)
548 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::getStringValue" );
549 ::rtl::OUStringBuffer aData
;
554 case SQL_WLONGVARCHAR
:
556 sal_Unicode waCharArray
[2048];
557 // read the unicode data
558 SQLLEN nMaxLen
= (sizeof(waCharArray
) / sizeof(sal_Unicode
)) - 1;
559 // GETDATA(SQL_C_WCHAR, waCharArray, nMaxLen + sizeof(sal_Unicode));
562 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
563 (SQLUSMALLINT
)columnIndex
,
566 (SQLLEN
)nMaxLen
*sizeof(sal_Unicode
),
568 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
569 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
571 return ::rtl::OUString();
572 // Bei Fehler bricht der GETDATA-Makro mit return ab,
573 // bei NULL mit break!
574 SQLLEN nRealSize
= 0;
576 nRealSize
= pcbValue
/ sizeof(sal_Unicode
);
577 SQLLEN nLen
= pcbValue
!= SQL_NO_TOTAL
? std::min(nRealSize
, nMaxLen
) : (nMaxLen
-1);
578 waCharArray
[nLen
] = 0;
579 aData
.append(waCharArray
,nLen
);
581 // Es handelt sich um Binaerdaten, um einen String, der fuer
582 // StarView zu lang ist oder der Treiber kann die Laenge der
583 // Daten nicht im voraus bestimmen - also als MemoryStream
585 while ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
)
587 // Bei Strings wird der Puffer nie ganz ausgenutzt
588 // (das letzte Byte ist immer ein NULL-Byte, das
589 // aber bei pcbValue nicht mitgezaehlt wird)
590 if (pcbValue
!= SQL_NO_TOTAL
&& (pcbValue
- nMaxLen
) < nMaxLen
)
591 nLen
= pcbValue
- nMaxLen
;
595 // Solange eine "truncation"-Warnung vorliegt, weiter Daten abholen
596 // GETDATA(SQL_C_CHAR,waCharArray, nLen + 1);
597 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
598 (SQLUSMALLINT
)columnIndex
,
603 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
606 nRealSize
= pcbValue
/ sizeof(sal_Unicode
);
607 nLen
= pcbValue
!= SQL_NO_TOTAL
? std::min(nRealSize
, nMaxLen
) : (nMaxLen
-1);
608 waCharArray
[nLen
] = 0;
610 aData
.append(::rtl::OUString(waCharArray
));
616 char aCharArray
[2048];
617 // Erstmal versuchen, die Daten mit dem kleinen Puffer
619 SQLLEN nMaxLen
= sizeof aCharArray
- 1;
620 // GETDATA(SQL_C_CHAR,aCharArray,nMaxLen);
622 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
623 (SQLUSMALLINT
)columnIndex
,
628 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
629 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
631 return ::rtl::OUString();
633 SQLLEN nLen
= pcbValue
!= SQL_NO_TOTAL
? std::min(pcbValue
, nMaxLen
) : (nMaxLen
-1);
634 aCharArray
[nLen
] = 0;
635 if ( ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
) && aCharArray
[nLen
-1] == 0 && nLen
> 0 )
637 aData
.append(::rtl::OUString((const sal_Char
*)aCharArray
,nLen
, _nTextEncoding
));
639 // Es handelt sich um Binaerdaten, um einen String, der fuer
640 // StarView zu lang ist oder der Treiber kann die Laenge der
641 // Daten nicht im voraus bestimmen - also als MemoryStream
643 while ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
)
645 // Solange eine "truncation"-Warnung vorliegt, weiter Daten abholen
646 // GETDATA(SQL_C_CHAR,aCharArray, nLen + 1);
647 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
648 (SQLUSMALLINT
)columnIndex
,
653 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
654 nLen
= pcbValue
!= SQL_NO_TOTAL
? std::min(pcbValue
, nMaxLen
) : (nMaxLen
-1);
655 if ( ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
) && aCharArray
[nLen
-1] == 0 && nLen
> 0 )
657 aCharArray
[nLen
] = 0;
659 aData
.append(::rtl::OUString((const sal_Char
*)aCharArray
,nLen
,_nTextEncoding
));
663 // aData.EraseTrailingChars();
667 return aData
.makeStringAndClear();
669 // -------------------------------------------------------------------------
670 void OTools::GetInfo(OConnection
* _pConnection
,
671 SQLHANDLE _aConnectionHandle
,
673 ::rtl::OUString
&_rValue
,
674 const Reference
< XInterface
>& _xInterface
,
675 rtl_TextEncoding _nTextEncoding
) throw(SQLException
, RuntimeException
)
678 SQLSMALLINT nValueLen
=0;
679 OTools::ThrowException(_pConnection
,
680 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,aValue
,(sizeof aValue
)-1,&nValueLen
),
681 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
683 _rValue
= ::rtl::OUString(aValue
,nValueLen
,_nTextEncoding
);
685 // -------------------------------------------------------------------------
686 void OTools::GetInfo(OConnection
* _pConnection
,
687 SQLHANDLE _aConnectionHandle
,
690 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
692 SQLSMALLINT nValueLen
;
693 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
694 OTools::ThrowException(_pConnection
,
695 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
696 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
698 // -------------------------------------------------------------------------
699 void OTools::GetInfo(OConnection
* _pConnection
,
700 SQLHANDLE _aConnectionHandle
,
702 SQLUINTEGER
&_rValue
,
703 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
705 SQLSMALLINT nValueLen
;
706 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
707 OTools::ThrowException(_pConnection
,
708 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
709 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
711 // -------------------------------------------------------------------------
712 void OTools::GetInfo(OConnection
* _pConnection
,
713 SQLHANDLE _aConnectionHandle
,
715 SQLUSMALLINT
&_rValue
,
716 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
718 SQLSMALLINT nValueLen
;
719 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
720 OTools::ThrowException(_pConnection
,
721 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
722 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
724 // -------------------------------------------------------------------------
725 void OTools::GetInfo(OConnection
* _pConnection
,
726 SQLHANDLE _aConnectionHandle
,
729 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
731 SQLSMALLINT nValueLen
;
732 OTools::ThrowException(_pConnection
,
733 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
734 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
736 // -------------------------------------------------------------------------
737 sal_Int32
OTools::MapOdbcType2Jdbc(sal_Int32 _nType
)
739 sal_Int32 nValue
= DataType::VARCHAR
;
743 nValue
= DataType::BIT
;
746 nValue
= DataType::TINYINT
;
749 nValue
= DataType::SMALLINT
;
752 nValue
= DataType::INTEGER
;
755 nValue
= DataType::BIGINT
;
758 nValue
= DataType::FLOAT
;
761 nValue
= DataType::REAL
;
764 nValue
= DataType::DOUBLE
;
767 nValue
= DataType::NUMERIC
;
770 nValue
= DataType::DECIMAL
;
774 nValue
= DataType::CHAR
;
778 nValue
= DataType::VARCHAR
;
780 case SQL_WLONGVARCHAR
:
781 case SQL_LONGVARCHAR
:
782 nValue
= DataType::LONGVARCHAR
;
786 nValue
= DataType::DATE
;
790 nValue
= DataType::TIME
;
792 case SQL_TYPE_TIMESTAMP
:
794 nValue
= DataType::TIMESTAMP
;
797 nValue
= DataType::BINARY
;
801 nValue
= DataType::VARBINARY
;
803 case SQL_LONGVARBINARY
:
804 nValue
= DataType::LONGVARBINARY
;
807 OSL_ASSERT(!"Invalid type");
811 //--------------------------------------------------------------------
813 // Convert the JDBC SQL type to the correct ODBC type
814 //--------------------------------------------------------------------
815 sal_Int32
OTools::jdbcTypeToOdbc(sal_Int32 jdbcType
)
817 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::jdbcTypeToOdbc" );
818 // For the most part, JDBC types match ODBC types. We'll
819 // just convert the ones that we know are different
821 sal_Int32 odbcType
= jdbcType
;
831 case DataType::TIMESTAMP
:
832 odbcType
= SQL_TIMESTAMP
;
838 //-----------------------------------------------------------------------------
839 void OTools::getBindTypes(sal_Bool _bUseWChar
,
840 sal_Bool _bUseOldTimeDate
,
841 SQLSMALLINT _nOdbcType
,
843 SQLSMALLINT
& fSqlType
846 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::getBindTypes" );
849 case SQL_CHAR
: if(_bUseWChar
)
851 fCType
= SQL_C_WCHAR
;
852 fSqlType
= SQL_WCHAR
;
860 case SQL_VARCHAR
: if(_bUseWChar
)
862 fCType
= SQL_C_WCHAR
;
863 fSqlType
= SQL_WVARCHAR
;
868 fSqlType
= SQL_VARCHAR
;
871 case SQL_LONGVARCHAR
: if(_bUseWChar
)
873 fCType
= SQL_C_WCHAR
;
874 fSqlType
= SQL_WLONGVARCHAR
;
879 fSqlType
= SQL_LONGVARCHAR
;
882 case SQL_DECIMAL
: fCType
= _bUseWChar
? SQL_C_WCHAR
: SQL_C_CHAR
;
883 fSqlType
= SQL_DECIMAL
; break;
884 case SQL_NUMERIC
: fCType
= _bUseWChar
? SQL_C_WCHAR
: SQL_C_CHAR
;
885 fSqlType
= SQL_NUMERIC
; break;
886 case SQL_BIT
: fCType
= SQL_C_TINYINT
;
887 fSqlType
= SQL_INTEGER
; break;
888 case SQL_TINYINT
: fCType
= SQL_C_TINYINT
;
889 fSqlType
= SQL_TINYINT
; break;
890 case SQL_SMALLINT
: fCType
= SQL_C_SHORT
;
891 fSqlType
= SQL_SMALLINT
; break;
892 case SQL_INTEGER
: fCType
= SQL_C_LONG
;
893 fSqlType
= SQL_INTEGER
; break;
894 case SQL_BIGINT
: fCType
= SQL_C_SBIGINT
;
895 fSqlType
= SQL_BIGINT
; break;
896 case SQL_FLOAT
: fCType
= SQL_C_FLOAT
;
897 fSqlType
= SQL_FLOAT
; break;
898 case SQL_REAL
: fCType
= SQL_C_DOUBLE
;
899 fSqlType
= SQL_REAL
; break;
900 case SQL_DOUBLE
: fCType
= SQL_C_DOUBLE
;
901 fSqlType
= SQL_DOUBLE
; break;
902 case SQL_BINARY
: fCType
= SQL_C_BINARY
;
903 fSqlType
= SQL_BINARY
; break;
905 fCType
= SQL_C_BINARY
;
906 fSqlType
= SQL_VARBINARY
; break;
907 case SQL_LONGVARBINARY
: fCType
= SQL_C_BINARY
;
908 fSqlType
= SQL_LONGVARBINARY
; break;
917 fCType
= SQL_C_TYPE_DATE
;
918 fSqlType
= SQL_TYPE_DATE
;
929 fCType
= SQL_C_TYPE_TIME
;
930 fSqlType
= SQL_TYPE_TIME
;
936 fCType
= SQL_C_TIMESTAMP
;
937 fSqlType
= SQL_TIMESTAMP
;
941 fCType
= SQL_C_TYPE_TIMESTAMP
;
942 fSqlType
= SQL_TYPE_TIMESTAMP
;
945 default: fCType
= SQL_C_BINARY
;
946 fSqlType
= SQL_LONGVARBINARY
; break;