1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "odbc/OTools.hxx"
30 #include "odbc/OFunctions.hxx"
31 #include <com/sun/star/sdbc/DataType.hpp>
32 #include <osl/diagnose.h>
33 #include "odbc/OConnection.hxx"
34 #include "diagnose_ex.h"
35 #include <rtl/logfile.hxx>
36 #include <rtl/ustrbuf.hxx>
43 using namespace connectivity::odbc
;
44 using namespace com::sun::star::uno
;
45 using namespace com::sun::star::sdbc
;
46 using namespace com::sun::star::util
;
49 size_t sqlTypeLen ( SQLSMALLINT _nType
)
54 return sizeof(SQLCHAR
*);
56 return sizeof(SQLWCHAR
*);
59 return sizeof(SQLSMALLINT
);
61 return sizeof(SQLUSMALLINT
);
64 return sizeof(SQLINTEGER
);
66 return sizeof(SQLUINTEGER
);
68 return sizeof(SQLREAL
);
70 OSL_ENSURE(sizeof(SQLDOUBLE
) == sizeof(SQLFLOAT
), "SQLDOUBLE/SQLFLOAT confusion");
71 return sizeof(SQLDOUBLE
);
73 return sizeof(SQLCHAR
);
76 return sizeof(SQLSCHAR
);
78 return sizeof(SQLCHAR
);
80 return sizeof(SQLBIGINT
);
82 return sizeof(SQLUBIGINT
);
83 /* UnixODBC gives this the same value as SQL_C_UBIGINT
85 return sizeof(BOOKMARK); */
87 // UnixODBC gives these the same value
88 //case SQL_C_VARBOOKMARK:
89 return sizeof(SQLCHAR
*);
92 return sizeof(SQL_DATE_STRUCT
);
95 return sizeof(SQL_TIME_STRUCT
);
96 case SQL_C_TYPE_TIMESTAMP
:
98 return sizeof(SQL_TIMESTAMP_STRUCT
);
100 return sizeof(SQL_NUMERIC_STRUCT
);
102 return sizeof(SQLGUID
);
103 case SQL_C_INTERVAL_YEAR
:
104 case SQL_C_INTERVAL_MONTH
:
105 case SQL_C_INTERVAL_DAY
:
106 case SQL_C_INTERVAL_HOUR
:
107 case SQL_C_INTERVAL_MINUTE
:
108 case SQL_C_INTERVAL_SECOND
:
109 case SQL_C_INTERVAL_YEAR_TO_MONTH
:
110 case SQL_C_INTERVAL_DAY_TO_HOUR
:
111 case SQL_C_INTERVAL_DAY_TO_MINUTE
:
112 case SQL_C_INTERVAL_DAY_TO_SECOND
:
113 case SQL_C_INTERVAL_HOUR_TO_MINUTE
:
114 case SQL_C_INTERVAL_HOUR_TO_SECOND
:
115 case SQL_C_INTERVAL_MINUTE_TO_SECOND
:
116 return sizeof(SQL_INTERVAL_STRUCT
);
118 return static_cast<size_t>(-1);
124 void OTools::getValue( OConnection
* _pConnection
,
125 SQLHANDLE _aStatementHandle
,
126 sal_Int32 columnIndex
,
129 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
131 SQLLEN _nSize
) throw(::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
133 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::getValue" );
134 const size_t properSize
= sqlTypeLen(_nType
);
135 if ( properSize
== static_cast<size_t>(-1) )
136 OSL_FAIL("connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size");
139 OSL_ENSURE(static_cast<size_t>(_nSize
) == properSize
, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to");
140 if ( static_cast<size_t>(_nSize
) > properSize
)
142 OSL_FAIL("memory region is too big - trying to fudge it");
143 memset(_pValue
, 0, _nSize
);
145 // This is skewed in favour of integer types
146 _pValue
+= _nSize
- properSize
;
150 OSL_ENSURE(static_cast<size_t>(_nSize
) >= properSize
, "memory region is too small");
151 SQLLEN pcbValue
= SQL_NULL_DATA
;
152 OTools::ThrowException(_pConnection
,
153 (*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
154 (SQLUSMALLINT
)columnIndex
,
159 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
,sal_False
);
160 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
162 // -----------------------------------------------------------------------------
163 void OTools::bindParameter( OConnection
* _pConnection
,
166 sal_Int8
*& pDataBuffer
,
167 sal_Int8
* pLenBuffer
,
168 SQLSMALLINT _nODBCtype
,
170 sal_Bool _bUseOldTimeDate
,
172 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
173 rtl_TextEncoding _nTextEncoding
)
174 throw(::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
176 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::bindParameter" );
178 SQLSMALLINT fSqlType
;
181 SQLLEN
* pLen
= (SQLLEN
*)pLenBuffer
;
182 SQLULEN nColumnSize
=0;
183 SQLSMALLINT nDecimalDigits
=0;
186 OTools::getBindTypes(_bUseWChar
,_bUseOldTimeDate
,_nODBCtype
,fCType
,fSqlType
);
188 OTools::bindData(_nODBCtype
,_bUseWChar
,pDataBuffer
,pLen
,_pValue
,_nTextEncoding
,nColumnSize
, atExec
);
189 if ((nColumnSize
== 0) && (fSqlType
== SQL_CHAR
|| fSqlType
== SQL_VARCHAR
|| fSqlType
== SQL_LONGVARCHAR
))
193 memcpy(pDataBuffer
,&nPos
,sizeof(nPos
));
195 nRetcode
= (*(T3SQLBindParameter
)_pConnection
->getOdbcFunction(ODBC3SQLBindParameter
))(_hStmt
,
206 OTools::ThrowException(_pConnection
,nRetcode
,_hStmt
,SQL_HANDLE_STMT
,_xInterface
);
208 // -----------------------------------------------------------------------------
209 void OTools::bindData( SQLSMALLINT _nOdbcType
,
214 rtl_TextEncoding _nTextEncoding
,
215 SQLULEN
& _nColumnSize
,
218 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::bindData" );
230 ::rtl::OUString
sStr(*(::rtl::OUString
*)_pValue
);
231 _nColumnSize
= sStr
.getLength();
232 *((rtl::OUString
*)_pData
) = sStr
;
235 _pData
= (sal_Int8
*)((rtl::OUString
*)_pData
)->getStr();
239 ::rtl::OString
aString(::rtl::OUStringToOString(*(::rtl::OUString
*)_pValue
,_nTextEncoding
));
241 _nColumnSize
= aString
.getLength();
242 memcpy(_pData
,aString
.getStr(),aString
.getLength());
243 ((sal_Int8
*)_pData
)[aString
.getLength()] = '\0';
248 *((sal_Int64
*)_pData
) = *(sal_Int64
*)_pValue
;
249 *pLen
= sizeof(sal_Int64
);
250 _nColumnSize
= *pLen
;
256 ::rtl::OUString aString
= rtl::OUString::valueOf(*(double*)_pValue
);
257 _nColumnSize
= aString
.getLength();
258 *pLen
= _nColumnSize
;
259 *((rtl::OUString
*)_pData
) = aString
;
261 _pData
= (sal_Int8
*)((rtl::OUString
*)_pData
)->getStr();
265 ::rtl::OString aString
= ::rtl::OString::valueOf(*(double*)_pValue
);
266 _nColumnSize
= aString
.getLength();
267 *pLen
= _nColumnSize
;
268 memcpy(_pData
,aString
.getStr(),aString
.getLength());
269 ((sal_Int8
*)_pData
)[_nColumnSize
] = '\0';
273 *((sal_Int8
*)_pData
) = *(sal_Int8
*)_pValue
;
274 *pLen
= sizeof(sal_Int8
);
278 *((sal_Int16
*)_pData
) = *(sal_Int16
*)_pValue
;
279 *pLen
= sizeof(sal_Int16
);
282 *((sal_Int32
*)_pData
) = *(sal_Int32
*)_pValue
;
283 *pLen
= sizeof(sal_Int32
);
286 *((float*)_pData
) = *(float*)_pValue
;
287 *pLen
= sizeof(float);
291 *((double*)_pData
) = *(double*)_pValue
;
292 *pLen
= sizeof(double);
297 const ::com::sun::star::uno::Sequence
< sal_Int8
>* pSeq
= static_cast< const ::com::sun::star::uno::Sequence
< sal_Int8
>* >(_pValue
);
298 OSL_ENSURE(pSeq
,"OTools::bindData: Sequence is null!");
302 _pData
= (sal_Int8
*)pSeq
->getConstArray();
303 *pLen
= pSeq
->getLength();
307 case SQL_LONGVARBINARY
:
310 nLen
= ((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getLength();
311 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
315 case SQL_LONGVARCHAR
:
319 nLen
= sizeof(sal_Unicode
) * ((::rtl::OUString
*)_pValue
)->getLength();
322 ::rtl::OString
aString(::rtl::OUStringToOString(*(::rtl::OUString
*)_pValue
,_nTextEncoding
));
323 nLen
= aString
.getLength();
325 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
329 *(DATE_STRUCT
*)_pData
= *(DATE_STRUCT
*)_pValue
;
330 *pLen
= (SQLLEN
)sizeof(DATE_STRUCT
);
334 *(TIME_STRUCT
*)_pData
= *(TIME_STRUCT
*)_pValue
;
335 *pLen
= (SQLLEN
)sizeof(TIME_STRUCT
);
339 *(TIMESTAMP_STRUCT
*)_pData
= *(TIMESTAMP_STRUCT
*)_pValue
;
340 *pLen
= (SQLLEN
)sizeof(TIMESTAMP_STRUCT
);
345 // -------------------------------------------------------------------------
346 void OTools::bindValue( OConnection
* _pConnection
,
347 SQLHANDLE _aStatementHandle
,
348 sal_Int32 columnIndex
,
350 SQLSMALLINT _nMaxLen
,
354 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
355 rtl_TextEncoding _nTextEncoding
,
356 sal_Bool _bUseOldTimeDate
) throw(::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
358 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::bindValue" );
360 SQLSMALLINT fSqlType
;
362 SQLLEN nMaxLen
= _nMaxLen
;
364 OTools::getBindTypes( sal_False
,
370 if (columnIndex
!= 0 && !_pValue
)
372 *pLen
= SQL_NULL_DATA
;
373 nRetcode
= (*(T3SQLBindCol
)_pConnection
->getOdbcFunction(ODBC3SQLBindCol
))(_aStatementHandle
,
374 (SQLUSMALLINT
)columnIndex
,
390 ::rtl::OString
aString(::rtl::OUStringToOString(*(::rtl::OUString
*)_pValue
,_nTextEncoding
));
392 *((::rtl::OString
*)_pData
) = aString
;
393 _nMaxLen
= (SQLSMALLINT
)aString
.getLength();
396 _pData
= (void*)aString
.getStr();
399 *((sal_Int64
*)_pData
) = *(sal_Int64
*)_pValue
;
400 *pLen
= sizeof(sal_Int64
);
405 ::rtl::OString aString
= ::rtl::OString::valueOf(*(double*)_pValue
);
406 _nMaxLen
= (SQLSMALLINT
)aString
.getLength();
408 *((::rtl::OString
*)_pData
) = aString
;
410 _pData
= (void*)((::rtl::OString
*)_pData
)->getStr();
414 *((sal_Int8
*)_pData
) = *(sal_Int8
*)_pValue
;
415 *pLen
= sizeof(sal_Int8
);
419 *((sal_Int16
*)_pData
) = *(sal_Int16
*)_pValue
;
420 *pLen
= sizeof(sal_Int16
);
423 *((sal_Int32
*)_pData
) = *(sal_Int32
*)_pValue
;
424 *pLen
= sizeof(sal_Int32
);
427 *((float*)_pData
) = *(float*)_pValue
;
428 *pLen
= sizeof(float);
432 *((double*)_pData
) = *(double*)_pValue
;
433 *pLen
= sizeof(double);
438 _pData
= (void*)((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getConstArray();
439 *pLen
= ((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getLength();
441 case SQL_LONGVARBINARY
:
443 _pData
= (void*)(sal_IntPtr
)(columnIndex
);
445 nLen
= ((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getLength();
446 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
449 case SQL_LONGVARCHAR
:
451 _pData
= (void*)(sal_IntPtr
)(columnIndex
);
453 nLen
= ((::rtl::OUString
*)_pValue
)->getLength();
454 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
457 *pLen
= sizeof(DATE_STRUCT
);
458 *((DATE_STRUCT
*)_pData
) = *(DATE_STRUCT
*)_pValue
;
461 *pLen
= sizeof(TIME_STRUCT
);
462 *((TIME_STRUCT
*)_pData
) = *(TIME_STRUCT
*)_pValue
;
465 *pLen
= sizeof(TIMESTAMP_STRUCT
);
466 *((TIMESTAMP_STRUCT
*)_pData
) = *(TIMESTAMP_STRUCT
*)_pValue
;
474 nRetcode
= (*(T3SQLBindCol
)_pConnection
->getOdbcFunction(ODBC3SQLBindCol
))(_aStatementHandle
,
475 (SQLUSMALLINT
)columnIndex
,
483 OTools::ThrowException(_pConnection
,nRetcode
,_aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
485 // -----------------------------------------------------------------------------
486 void OTools::ThrowException(OConnection
* _pConnection
,
489 SQLSMALLINT _nHandleType
,
490 const Reference
< XInterface
>& _xInterface
,
492 rtl_TextEncoding _nTextEncoding
) throw(SQLException
)
497 case SQL_STILL_EXECUTING
:
500 case SQL_SUCCESS_WITH_INFO
:
502 case SQL_NO_DATA_FOUND
:
504 return; // no need to throw a exception
505 case SQL_ERROR
: break;
508 case SQL_INVALID_HANDLE
: OSL_FAIL("SdbODBC3_SetStatus: SQL_INVALID_HANDLE");
509 throw SQLException();
512 // Additional Information on the latest ODBC-functioncall available
513 // SQLError provides this Information.
514 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::ThrowException" );
516 SDB_ODBC_CHAR szSqlState
[5];
517 SQLINTEGER pfNativeError
;
518 SDB_ODBC_CHAR szErrorMessage
[SQL_MAX_MESSAGE_LENGTH
];
519 szErrorMessage
[0] = '\0';
520 SQLSMALLINT pcbErrorMsg
= 0;
522 // Information for latest operation:
523 // when hstmt != SQL_NULL_HSTMT is (Used from SetStatus in SdbCursor, SdbTable, ...),
524 // then the status of the latest statments will be fetched, without the Status of the last
525 // Statments of this connection [what in this case will probably be the same, but the Reference
526 // Manual isn't totally clear in this...].
527 // corresponding for hdbc.
528 SQLRETURN n
= (*(T3SQLGetDiagRec
)_pConnection
->getOdbcFunction(ODBC3SQLGetDiagRec
))(_nHandleType
,_pContext
,1,
531 szErrorMessage
,sizeof szErrorMessage
- 1,&pcbErrorMsg
);
533 OSL_ENSURE(n
!= SQL_INVALID_HANDLE
,"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE");
534 OSL_ENSURE(n
== SQL_SUCCESS
|| n
== SQL_SUCCESS_WITH_INFO
|| n
== SQL_NO_DATA_FOUND
|| n
== SQL_ERROR
,"SdbODBC3_SetStatus: SQLError failed");
536 // For the Return Code of SQLError see ODBC 2.0 Programmer's Reference Page 287ff
537 throw SQLException( ::rtl::OUString((char *)szErrorMessage
,pcbErrorMsg
,_nTextEncoding
),
539 ::rtl::OUString((char *)szSqlState
,5,_nTextEncoding
),
545 // -------------------------------------------------------------------------
546 Sequence
<sal_Int8
> OTools::getBytesValue(OConnection
* _pConnection
,
547 SQLHANDLE _aStatementHandle
,
548 sal_Int32 columnIndex
,
549 SQLSMALLINT _fSqlType
,
551 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
553 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::getBytesValue" );
554 char aCharArray
[2048];
555 // First try to fetch the data with the little Buffer:
556 SQLLEN nMaxLen
= sizeof aCharArray
- 1;
557 // GETDATA(SQL_C_CHAR,aCharArray,nMaxLen);
559 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
560 (SQLUSMALLINT
)columnIndex
,
562 (SQLPOINTER
)aCharArray
,
565 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
567 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
569 return Sequence
<sal_Int8
>();
571 SQLINTEGER nBytes
= pcbValue
!= SQL_NO_TOTAL
? std::min(pcbValue
, nMaxLen
) : nMaxLen
;
572 if ( ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
) && aCharArray
[nBytes
-1] == 0 && nBytes
> 0 )
574 Sequence
<sal_Int8
> aData((sal_Int8
*)aCharArray
, nBytes
);
576 // It is about Binariy Data, a String, that for StarView is to long or
577 // the driver kan't predict the length of the data - as well as save the
579 while ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
)
581 // At Strings the Buffer won't be completly used
582 // (The last Byte is always a NULL-Byte, however it won't be counted with pcbValue)
583 if (pcbValue
!= SQL_NO_TOTAL
&& (pcbValue
- nMaxLen
) < nMaxLen
)
584 nBytes
= pcbValue
- nMaxLen
;
588 // While there is a "truncation"-Warning, proceed with fetching Data.
589 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
590 (SQLUSMALLINT
)columnIndex
,
595 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
596 sal_Int32 nLen
= aData
.getLength();
597 aData
.realloc(nLen
+ nBytes
);
598 memcpy(aData
.getArray() + nLen
, aCharArray
, nBytes
);
602 // -------------------------------------------------------------------------
603 ::rtl::OUString
OTools::getStringValue(OConnection
* _pConnection
,
604 SQLHANDLE _aStatementHandle
,
605 sal_Int32 columnIndex
,
606 SQLSMALLINT _fSqlType
,
608 const Reference
< XInterface
>& _xInterface
,
609 rtl_TextEncoding _nTextEncoding
) throw(SQLException
, RuntimeException
)
611 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::getStringValue" );
612 ::rtl::OUStringBuffer aData
;
617 case SQL_WLONGVARCHAR
:
619 sal_Unicode waCharArray
[2048];
620 // read the unicode data
621 SQLLEN nMaxLen
= (sizeof(waCharArray
) / sizeof(sal_Unicode
)) - 1;
624 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
625 (SQLUSMALLINT
)columnIndex
,
628 (SQLLEN
)nMaxLen
*sizeof(sal_Unicode
),
630 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
631 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
633 return ::rtl::OUString();
634 // at failure the GETDATA-Makro will stop with returning,
635 // at NULL with break!
636 SQLLEN nRealSize
= 0;
638 nRealSize
= pcbValue
/ sizeof(sal_Unicode
);
639 SQLLEN nLen
= pcbValue
!= SQL_NO_TOTAL
? std::min(nRealSize
, nMaxLen
) : (nMaxLen
-1);
640 waCharArray
[nLen
] = 0;
641 aData
.append(waCharArray
,nLen
);
643 // It is about Binariy Data, a String, that for StarView is to long or
644 // the driver kan't predict the length of the data - as well as save the
646 while ((pcbValue
== SQL_NO_TOTAL
) || nLen
> nMaxLen
)
648 // At Strings the Buffer won't be completly used
649 // (The last Byte is always a NULL-Byte, however it won't be counted with pcbValue)
650 if (pcbValue
!= SQL_NO_TOTAL
&& (pcbValue
- nMaxLen
) < nMaxLen
)
651 nLen
= pcbValue
- nMaxLen
;
655 // While there is a "truncation"-Warning, proceed with fetching Data.
656 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
657 (SQLUSMALLINT
)columnIndex
,
662 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
665 nRealSize
= pcbValue
/ sizeof(sal_Unicode
);
666 nLen
= pcbValue
!= SQL_NO_TOTAL
? std::min(nRealSize
, nMaxLen
) : (nMaxLen
-1);
667 waCharArray
[nLen
] = 0;
669 aData
.append(::rtl::OUString(waCharArray
));
675 char aCharArray
[2048];
676 // First try to fetch the data with the little Buffer:
677 SQLLEN nMaxLen
= sizeof aCharArray
- 1;
679 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
680 (SQLUSMALLINT
)columnIndex
,
685 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
686 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
688 return ::rtl::OUString();
690 SQLLEN nLen
= pcbValue
!= SQL_NO_TOTAL
? std::min(pcbValue
, nMaxLen
) : (nMaxLen
-1);
691 aCharArray
[nLen
] = 0;
692 if ( ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
) && aCharArray
[nLen
-1] == 0 && nLen
> 0 )
694 aData
.append(::rtl::OUString((const sal_Char
*)aCharArray
,nLen
, _nTextEncoding
));
696 // It is about Binary Data, a String, that for StarView is too long or
697 // the driver can't predict the length of the data - as well as save the
699 while ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
)
701 // While there is a "truncation"-Warning, proceed with fetching Data.
702 OTools::ThrowException(_pConnection
,(*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
703 (SQLUSMALLINT
)columnIndex
,
708 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
709 nLen
= pcbValue
!= SQL_NO_TOTAL
? std::min(pcbValue
, nMaxLen
) : (nMaxLen
-1);
710 if ( ((pcbValue
== SQL_NO_TOTAL
) || pcbValue
> nMaxLen
) && aCharArray
[nLen
-1] == 0 && nLen
> 0 )
712 aCharArray
[nLen
] = 0;
714 aData
.append(::rtl::OUString((const sal_Char
*)aCharArray
,nLen
,_nTextEncoding
));
720 return aData
.makeStringAndClear();
722 // -------------------------------------------------------------------------
723 void OTools::GetInfo(OConnection
* _pConnection
,
724 SQLHANDLE _aConnectionHandle
,
726 ::rtl::OUString
&_rValue
,
727 const Reference
< XInterface
>& _xInterface
,
728 rtl_TextEncoding _nTextEncoding
) throw(SQLException
, RuntimeException
)
731 SQLSMALLINT nValueLen
=0;
732 OTools::ThrowException(_pConnection
,
733 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,aValue
,(sizeof aValue
)-1,&nValueLen
),
734 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
736 _rValue
= ::rtl::OUString(aValue
,nValueLen
,_nTextEncoding
);
738 // -------------------------------------------------------------------------
739 void OTools::GetInfo(OConnection
* _pConnection
,
740 SQLHANDLE _aConnectionHandle
,
743 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
745 SQLSMALLINT nValueLen
;
746 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
747 OTools::ThrowException(_pConnection
,
748 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
749 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
751 // -------------------------------------------------------------------------
752 void OTools::GetInfo(OConnection
* _pConnection
,
753 SQLHANDLE _aConnectionHandle
,
755 SQLUINTEGER
&_rValue
,
756 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
758 SQLSMALLINT nValueLen
;
759 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
760 OTools::ThrowException(_pConnection
,
761 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
762 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
764 // -------------------------------------------------------------------------
765 void OTools::GetInfo(OConnection
* _pConnection
,
766 SQLHANDLE _aConnectionHandle
,
768 SQLUSMALLINT
&_rValue
,
769 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
771 SQLSMALLINT nValueLen
;
772 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
773 OTools::ThrowException(_pConnection
,
774 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
775 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
777 // -------------------------------------------------------------------------
778 void OTools::GetInfo(OConnection
* _pConnection
,
779 SQLHANDLE _aConnectionHandle
,
782 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
784 SQLSMALLINT nValueLen
;
785 OTools::ThrowException(_pConnection
,
786 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
787 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
789 // -------------------------------------------------------------------------
790 sal_Int32
OTools::MapOdbcType2Jdbc(sal_Int32 _nType
)
792 sal_Int32 nValue
= DataType::VARCHAR
;
796 nValue
= DataType::BIT
;
799 nValue
= DataType::TINYINT
;
802 nValue
= DataType::SMALLINT
;
805 nValue
= DataType::INTEGER
;
808 nValue
= DataType::BIGINT
;
811 nValue
= DataType::FLOAT
;
814 nValue
= DataType::REAL
;
817 nValue
= DataType::DOUBLE
;
820 nValue
= DataType::NUMERIC
;
823 nValue
= DataType::DECIMAL
;
827 nValue
= DataType::CHAR
;
831 nValue
= DataType::VARCHAR
;
833 case SQL_WLONGVARCHAR
:
834 case SQL_LONGVARCHAR
:
835 nValue
= DataType::LONGVARCHAR
;
839 nValue
= DataType::DATE
;
843 nValue
= DataType::TIME
;
845 case SQL_TYPE_TIMESTAMP
:
847 nValue
= DataType::TIMESTAMP
;
850 nValue
= DataType::BINARY
;
854 nValue
= DataType::VARBINARY
;
856 case SQL_LONGVARBINARY
:
857 nValue
= DataType::LONGVARBINARY
;
860 OSL_ASSERT(!"Invalid type");
864 //--------------------------------------------------------------------
866 // Convert the JDBC SQL type to the correct ODBC type
867 //--------------------------------------------------------------------
868 sal_Int32
OTools::jdbcTypeToOdbc(sal_Int32 jdbcType
)
870 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::jdbcTypeToOdbc" );
871 // For the most part, JDBC types match ODBC types. We'll
872 // just convert the ones that we know are different
874 sal_Int32 odbcType
= jdbcType
;
884 case DataType::TIMESTAMP
:
885 odbcType
= SQL_TIMESTAMP
;
891 //-----------------------------------------------------------------------------
892 void OTools::getBindTypes(sal_Bool _bUseWChar
,
893 sal_Bool _bUseOldTimeDate
,
894 SQLSMALLINT _nOdbcType
,
896 SQLSMALLINT
& fSqlType
899 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "odbc", "Ocke.Janssen@sun.com", "OTools::getBindTypes" );
902 case SQL_CHAR
: if(_bUseWChar
)
904 fCType
= SQL_C_WCHAR
;
905 fSqlType
= SQL_WCHAR
;
913 case SQL_VARCHAR
: if(_bUseWChar
)
915 fCType
= SQL_C_WCHAR
;
916 fSqlType
= SQL_WVARCHAR
;
921 fSqlType
= SQL_VARCHAR
;
924 case SQL_LONGVARCHAR
: if(_bUseWChar
)
926 fCType
= SQL_C_WCHAR
;
927 fSqlType
= SQL_WLONGVARCHAR
;
932 fSqlType
= SQL_LONGVARCHAR
;
935 case SQL_DECIMAL
: fCType
= _bUseWChar
? SQL_C_WCHAR
: SQL_C_CHAR
;
936 fSqlType
= SQL_DECIMAL
; break;
937 case SQL_NUMERIC
: fCType
= _bUseWChar
? SQL_C_WCHAR
: SQL_C_CHAR
;
938 fSqlType
= SQL_NUMERIC
; break;
939 case SQL_BIT
: fCType
= SQL_C_TINYINT
;
940 fSqlType
= SQL_INTEGER
; break;
941 case SQL_TINYINT
: fCType
= SQL_C_TINYINT
;
942 fSqlType
= SQL_TINYINT
; break;
943 case SQL_SMALLINT
: fCType
= SQL_C_SHORT
;
944 fSqlType
= SQL_SMALLINT
; break;
945 case SQL_INTEGER
: fCType
= SQL_C_LONG
;
946 fSqlType
= SQL_INTEGER
; break;
947 case SQL_BIGINT
: fCType
= SQL_C_SBIGINT
;
948 fSqlType
= SQL_BIGINT
; break;
949 case SQL_FLOAT
: fCType
= SQL_C_FLOAT
;
950 fSqlType
= SQL_FLOAT
; break;
951 case SQL_REAL
: fCType
= SQL_C_DOUBLE
;
952 fSqlType
= SQL_REAL
; break;
953 case SQL_DOUBLE
: fCType
= SQL_C_DOUBLE
;
954 fSqlType
= SQL_DOUBLE
; break;
955 case SQL_BINARY
: fCType
= SQL_C_BINARY
;
956 fSqlType
= SQL_BINARY
; break;
958 fCType
= SQL_C_BINARY
;
959 fSqlType
= SQL_VARBINARY
; break;
960 case SQL_LONGVARBINARY
: fCType
= SQL_C_BINARY
;
961 fSqlType
= SQL_LONGVARBINARY
; break;
970 fCType
= SQL_C_TYPE_DATE
;
971 fSqlType
= SQL_TYPE_DATE
;
982 fCType
= SQL_C_TYPE_TIME
;
983 fSqlType
= SQL_TYPE_TIME
;
989 fCType
= SQL_C_TIMESTAMP
;
990 fSqlType
= SQL_TIMESTAMP
;
994 fCType
= SQL_C_TYPE_TIMESTAMP
;
995 fSqlType
= SQL_TYPE_TIMESTAMP
;
998 default: fCType
= SQL_C_BINARY
;
999 fSqlType
= SQL_LONGVARBINARY
; break;
1004 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */