1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "odbc/OTools.hxx"
21 #include "odbc/OFunctions.hxx"
22 #include <com/sun/star/sdbc/DataType.hpp>
23 #include <osl/diagnose.h>
24 #include "odbc/OConnection.hxx"
25 #include "diagnose_ex.h"
26 #include <rtl/ustrbuf.hxx>
27 #include <boost/static_assert.hpp>
34 using namespace connectivity::odbc
;
35 using namespace com::sun::star::uno
;
36 using namespace com::sun::star::sdbc
;
37 using namespace com::sun::star::util
;
40 size_t sqlTypeLen ( SQLSMALLINT _nType
)
46 return sizeof(SQLSMALLINT
);
48 return sizeof(SQLUSMALLINT
);
51 return sizeof(SQLINTEGER
);
53 return sizeof(SQLUINTEGER
);
55 return sizeof(SQLREAL
);
57 OSL_ENSURE(sizeof(SQLDOUBLE
) == sizeof(SQLFLOAT
), "SQLDOUBLE/SQLFLOAT confusion");
58 return sizeof(SQLDOUBLE
);
60 return sizeof(SQLCHAR
);
63 return sizeof(SQLSCHAR
);
65 return sizeof(SQLCHAR
);
67 return sizeof(SQLBIGINT
);
69 return sizeof(SQLUBIGINT
);
70 /* UnixODBC gives this the same value as SQL_C_UBIGINT
72 return sizeof(BOOKMARK); */
75 return sizeof(SQL_DATE_STRUCT
);
78 return sizeof(SQL_TIME_STRUCT
);
79 case SQL_C_TYPE_TIMESTAMP
:
81 return sizeof(SQL_TIMESTAMP_STRUCT
);
83 return sizeof(SQL_NUMERIC_STRUCT
);
85 return sizeof(SQLGUID
);
86 case SQL_C_INTERVAL_YEAR
:
87 case SQL_C_INTERVAL_MONTH
:
88 case SQL_C_INTERVAL_DAY
:
89 case SQL_C_INTERVAL_HOUR
:
90 case SQL_C_INTERVAL_MINUTE
:
91 case SQL_C_INTERVAL_SECOND
:
92 case SQL_C_INTERVAL_YEAR_TO_MONTH
:
93 case SQL_C_INTERVAL_DAY_TO_HOUR
:
94 case SQL_C_INTERVAL_DAY_TO_MINUTE
:
95 case SQL_C_INTERVAL_DAY_TO_SECOND
:
96 case SQL_C_INTERVAL_HOUR_TO_MINUTE
:
97 case SQL_C_INTERVAL_HOUR_TO_SECOND
:
98 case SQL_C_INTERVAL_MINUTE_TO_SECOND
:
99 return sizeof(SQL_INTERVAL_STRUCT
);
100 // ** Variable-sized datatypes -> cannot predict length
104 // UnixODBC gives this the same value as SQL_C_BINARY
105 //case SQL_C_VARBOOKMARK:
106 // Unknown datatype -> cannot predict length
108 return static_cast<size_t>(-1);
114 void OTools::getValue( OConnection
* _pConnection
,
115 SQLHANDLE _aStatementHandle
,
116 sal_Int32 columnIndex
,
119 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
121 SQLLEN _nSize
) throw(::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
123 const size_t properSize
= sqlTypeLen(_nType
);
124 if ( properSize
== static_cast<size_t>(-1) )
125 SAL_WARN( "connectivity.drivers", "connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size");
128 OSL_ENSURE(static_cast<size_t>(_nSize
) == properSize
, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to");
129 if ( static_cast<size_t>(_nSize
) > properSize
)
131 SAL_WARN( "connectivity.drivers", "memory region is too big - trying to fudge it");
132 memset(_pValue
, 0, _nSize
);
134 // This is skewed in favour of integer types
135 _pValue
+= _nSize
- properSize
;
139 OSL_ENSURE(static_cast<size_t>(_nSize
) >= properSize
, "memory region is too small");
140 SQLLEN pcbValue
= SQL_NULL_DATA
;
141 OTools::ThrowException(_pConnection
,
142 (*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(_aStatementHandle
,
143 (SQLUSMALLINT
)columnIndex
,
148 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
,false);
149 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
152 void OTools::bindValue( OConnection
* _pConnection
,
153 SQLHANDLE _aStatementHandle
,
154 sal_Int32 columnIndex
,
156 SQLSMALLINT _nMaxLen
,
160 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
161 rtl_TextEncoding _nTextEncoding
,
162 bool _bUseOldTimeDate
) throw(::com::sun::star::sdbc::SQLException
, ::com::sun::star::uno::RuntimeException
)
165 SQLSMALLINT fSqlType
;
167 SQLLEN nMaxLen
= _nMaxLen
;
169 OTools::getBindTypes( false,
175 if (columnIndex
!= 0 && !_pValue
)
177 *pLen
= SQL_NULL_DATA
;
178 nRetcode
= (*(T3SQLBindCol
)_pConnection
->getOdbcFunction(ODBC3SQLBindCol
))(_aStatementHandle
,
179 (SQLUSMALLINT
)columnIndex
,
195 OString
aString(OUStringToOString(*(OUString
*)_pValue
,_nTextEncoding
));
197 *((OString
*)_pData
) = aString
;
198 _nMaxLen
= (SQLSMALLINT
)aString
.getLength();
201 _pData
= (void*)aString
.getStr();
204 *((sal_Int64
*)_pData
) = *(sal_Int64
*)_pValue
;
205 *pLen
= sizeof(sal_Int64
);
210 OString aString
= OString::number(*(double*)_pValue
);
211 _nMaxLen
= (SQLSMALLINT
)aString
.getLength();
213 *((OString
*)_pData
) = aString
;
215 _pData
= (void*)((OString
*)_pData
)->getStr();
219 *((sal_Int8
*)_pData
) = *(sal_Int8
*)_pValue
;
220 *pLen
= sizeof(sal_Int8
);
224 *((sal_Int16
*)_pData
) = *(sal_Int16
*)_pValue
;
225 *pLen
= sizeof(sal_Int16
);
228 *((sal_Int32
*)_pData
) = *(sal_Int32
*)_pValue
;
229 *pLen
= sizeof(sal_Int32
);
232 *((float*)_pData
) = *(float*)_pValue
;
233 *pLen
= sizeof(float);
237 *((double*)_pData
) = *(double*)_pValue
;
238 *pLen
= sizeof(double);
243 _pData
= (void*)((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getConstArray();
244 *pLen
= ((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getLength();
246 case SQL_LONGVARBINARY
:
248 _pData
= (void*)(sal_IntPtr
)(columnIndex
);
250 nLen
= ((const ::com::sun::star::uno::Sequence
< sal_Int8
> *)_pValue
)->getLength();
251 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
254 case SQL_LONGVARCHAR
:
256 _pData
= (void*)(sal_IntPtr
)(columnIndex
);
258 nLen
= ((OUString
*)_pValue
)->getLength();
259 *pLen
= (SQLLEN
)SQL_LEN_DATA_AT_EXEC(nLen
);
262 *pLen
= sizeof(DATE_STRUCT
);
263 *((DATE_STRUCT
*)_pData
) = *(DATE_STRUCT
*)_pValue
;
266 *pLen
= sizeof(TIME_STRUCT
);
267 *((TIME_STRUCT
*)_pData
) = *(TIME_STRUCT
*)_pValue
;
270 *pLen
= sizeof(TIMESTAMP_STRUCT
);
271 *((TIMESTAMP_STRUCT
*)_pData
) = *(TIMESTAMP_STRUCT
*)_pValue
;
279 nRetcode
= (*(T3SQLBindCol
)_pConnection
->getOdbcFunction(ODBC3SQLBindCol
))(_aStatementHandle
,
280 (SQLUSMALLINT
)columnIndex
,
288 OTools::ThrowException(_pConnection
,nRetcode
,_aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
291 void OTools::ThrowException(const OConnection
* _pConnection
,
292 const SQLRETURN _rRetCode
,
293 const SQLHANDLE _pContext
,
294 const SQLSMALLINT _nHandleType
,
295 const Reference
< XInterface
>& _xInterface
,
296 const bool _bNoFound
,
297 const rtl_TextEncoding _nTextEncoding
) throw(SQLException
)
302 case SQL_STILL_EXECUTING
:
305 case SQL_SUCCESS_WITH_INFO
:
307 case SQL_NO_DATA_FOUND
:
309 return; // no need to throw a exception
310 case SQL_ERROR
: break;
313 case SQL_INVALID_HANDLE
: SAL_WARN( "connectivity.drivers", "SdbODBC3_SetStatus: SQL_INVALID_HANDLE");
314 throw SQLException();
317 // Additional Information on the latest ODBC-functioncall available
318 // SQLError provides this Information.
320 SDB_ODBC_CHAR szSqlState
[5];
321 SQLINTEGER pfNativeError
;
322 SDB_ODBC_CHAR szErrorMessage
[SQL_MAX_MESSAGE_LENGTH
];
323 szErrorMessage
[0] = '\0';
324 SQLSMALLINT pcbErrorMsg
= 0;
326 // Information for latest operation:
327 // when hstmt != SQL_NULL_HSTMT is (Used from SetStatus in SdbCursor, SdbTable, ...),
328 // then the status of the latest statements will be fetched, without the Status of the last
329 // statements of this connection [what in this case will probably be the same, but the Reference
330 // Manual isn't totally clear in this...].
331 // corresponding for hdbc.
332 SQLRETURN n
= (*(T3SQLGetDiagRec
)_pConnection
->getOdbcFunction(ODBC3SQLGetDiagRec
))(_nHandleType
,_pContext
,1,
335 szErrorMessage
,sizeof szErrorMessage
- 1,&pcbErrorMsg
);
337 OSL_ENSURE(n
!= SQL_INVALID_HANDLE
,"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE");
338 OSL_ENSURE(n
== SQL_SUCCESS
|| n
== SQL_SUCCESS_WITH_INFO
|| n
== SQL_NO_DATA_FOUND
|| n
== SQL_ERROR
,"SdbODBC3_SetStatus: SQLError failed");
340 // For the Return Code of SQLError see ODBC 2.0 Programmer's Reference Page 287ff
341 throw SQLException( OUString((char *)szErrorMessage
,pcbErrorMsg
,_nTextEncoding
),
343 OUString((char *)szSqlState
,5,_nTextEncoding
),
350 Sequence
<sal_Int8
> OTools::getBytesValue(const OConnection
* _pConnection
,
351 const SQLHANDLE _aStatementHandle
,
352 const sal_Int32 columnIndex
,
353 const SQLSMALLINT _fSqlType
,
355 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
357 sal_Int8 aCharArray
[2048];
358 // First try to fetch the data with the little Buffer:
359 const SQLLEN nMaxLen
= sizeof aCharArray
;
360 SQLLEN pcbValue
= SQL_NO_TOTAL
;
361 Sequence
<sal_Int8
> aData
;
363 OSL_ENSURE( _fSqlType
!= SQL_CHAR
&& _fSqlType
!= SQL_VARCHAR
&& _fSqlType
!= SQL_LONGVARCHAR
&&
364 _fSqlType
!= SQL_WCHAR
&& _fSqlType
!= SQL_WVARCHAR
&& _fSqlType
!= SQL_WLONGVARCHAR
,
365 "connectivity::odbc::OTools::getBytesValue called with character _fSqlType");
367 while (pcbValue
== SQL_NO_TOTAL
|| pcbValue
> nMaxLen
)
369 OTools::ThrowException(_pConnection
,
370 (*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(
372 (SQLUSMALLINT
)columnIndex
,
374 (SQLPOINTER
)aCharArray
,
377 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
379 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
381 return Sequence
<sal_Int8
>();
384 // After the SQLGetData that wrote out to aCharArray the last byte of the data,
385 // pcbValue will not be SQL_NO_TOTAL -> we have a reliable count
386 if ( (pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxLen
) )
388 // we filled the buffer
389 nReadBytes
= nMaxLen
;
393 nReadBytes
= pcbValue
;
395 const sal_Int32 nLen
= aData
.getLength();
396 aData
.realloc(nLen
+ nReadBytes
);
397 memcpy(aData
.getArray() + nLen
, aCharArray
, nReadBytes
);
402 OUString
OTools::getStringValue(OConnection
* _pConnection
,
403 SQLHANDLE _aStatementHandle
,
404 sal_Int32 columnIndex
,
405 SQLSMALLINT _fSqlType
,
407 const Reference
< XInterface
>& _xInterface
,
408 rtl_TextEncoding _nTextEncoding
) throw(SQLException
, RuntimeException
)
410 OUStringBuffer aData
;
415 case SQL_WLONGVARCHAR
:
417 sal_Unicode waCharArray
[2048];
418 // we assume everyone (LibO & ODBC) uses UTF-16; see OPreparedStatement::setParameter
419 BOOST_STATIC_ASSERT(sizeof(sal_Unicode
) == 2);
420 BOOST_STATIC_ASSERT(sizeof(SQLWCHAR
) == 2);
421 BOOST_STATIC_ASSERT(sizeof(waCharArray
) % 2 == 0);
422 // Size == number of bytes, Len == number of UTF-16 code units
423 const SQLLEN nMaxSize
= sizeof(waCharArray
);
424 const SQLLEN nMaxLen
= sizeof(waCharArray
) / sizeof(sal_Unicode
);
425 BOOST_STATIC_ASSERT(nMaxLen
* sizeof(sal_Unicode
) == nMaxSize
);
427 // read the unicode data
428 SQLLEN pcbValue
= SQL_NO_TOTAL
;
429 while ((pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxSize
) )
431 OTools::ThrowException(_pConnection
,
432 (*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(
434 (SQLUSMALLINT
)columnIndex
,
437 (SQLLEN
)nMaxLen
*sizeof(sal_Unicode
),
439 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
440 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
445 OSL_ENSURE( (pcbValue
< 0) || (pcbValue
% 2 == 0),
446 "ODBC: SQLGetData of SQL_C_WCHAR returned odd number of bytes");
447 if ( (pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxSize
) )
449 // we filled the buffer; remove the terminating null character
450 nReadChars
= nMaxLen
-1;
451 if ( waCharArray
[nReadChars
] != 0)
453 SAL_WARN( "connectivity.drivers", "Buggy ODBC driver? Did not null-terminate (variable length) data!");
459 nReadChars
= pcbValue
/sizeof(sal_Unicode
);
462 aData
.append(waCharArray
, nReadChars
);
469 char aCharArray
[2048];
470 // read the unicode data
471 const SQLLEN nMaxLen
= sizeof(aCharArray
);
472 SQLLEN pcbValue
= SQL_NO_TOTAL
;
474 while ((pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxLen
) )
476 OTools::ThrowException(_pConnection
,
477 (*(T3SQLGetData
)_pConnection
->getOdbcFunction(ODBC3SQLGetData
))(
479 (SQLUSMALLINT
)columnIndex
,
484 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
485 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
490 if ( (pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxLen
) )
492 // we filled the buffer; remove the terminating null character
493 nReadChars
= nMaxLen
-1;
494 if ( aCharArray
[nReadChars
] != 0)
496 SAL_WARN( "connectivity.drivers", "Buggy ODBC driver? Did not null-terminate (variable length) data!");
502 nReadChars
= pcbValue
;
505 aData
.append(OUString(aCharArray
, nReadChars
, _nTextEncoding
));
512 return aData
.makeStringAndClear();
515 void OTools::GetInfo(OConnection
* _pConnection
,
516 SQLHANDLE _aConnectionHandle
,
519 const Reference
< XInterface
>& _xInterface
,
520 rtl_TextEncoding _nTextEncoding
) throw(SQLException
, RuntimeException
)
523 SQLSMALLINT nValueLen
=0;
524 OTools::ThrowException(_pConnection
,
525 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,aValue
,(sizeof aValue
)-1,&nValueLen
),
526 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
528 _rValue
= OUString(aValue
,nValueLen
,_nTextEncoding
);
531 void OTools::GetInfo(OConnection
* _pConnection
,
532 SQLHANDLE _aConnectionHandle
,
535 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
537 SQLSMALLINT nValueLen
;
538 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
539 OTools::ThrowException(_pConnection
,
540 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
541 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
544 void OTools::GetInfo(OConnection
* _pConnection
,
545 SQLHANDLE _aConnectionHandle
,
547 SQLUINTEGER
&_rValue
,
548 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
550 SQLSMALLINT nValueLen
;
551 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
552 OTools::ThrowException(_pConnection
,
553 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
554 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
557 void OTools::GetInfo(OConnection
* _pConnection
,
558 SQLHANDLE _aConnectionHandle
,
560 SQLUSMALLINT
&_rValue
,
561 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
563 SQLSMALLINT nValueLen
;
564 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
565 OTools::ThrowException(_pConnection
,
566 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
567 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
570 void OTools::GetInfo(OConnection
* _pConnection
,
571 SQLHANDLE _aConnectionHandle
,
574 const Reference
< XInterface
>& _xInterface
) throw(SQLException
, RuntimeException
)
576 SQLSMALLINT nValueLen
;
577 OTools::ThrowException(_pConnection
,
578 (*(T3SQLGetInfo
)_pConnection
->getOdbcFunction(ODBC3SQLGetInfo
))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
579 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
582 sal_Int32
OTools::MapOdbcType2Jdbc(SQLSMALLINT _nType
)
584 sal_Int32 nValue
= DataType::VARCHAR
;
588 nValue
= DataType::BIT
;
591 nValue
= DataType::TINYINT
;
594 nValue
= DataType::SMALLINT
;
597 nValue
= DataType::INTEGER
;
600 nValue
= DataType::BIGINT
;
603 nValue
= DataType::FLOAT
;
606 nValue
= DataType::REAL
;
609 nValue
= DataType::DOUBLE
;
612 nValue
= DataType::NUMERIC
;
615 nValue
= DataType::DECIMAL
;
619 nValue
= DataType::CHAR
;
623 nValue
= DataType::VARCHAR
;
625 case SQL_WLONGVARCHAR
:
626 case SQL_LONGVARCHAR
:
627 nValue
= DataType::LONGVARCHAR
;
631 nValue
= DataType::DATE
;
635 nValue
= DataType::TIME
;
637 case SQL_TYPE_TIMESTAMP
:
639 nValue
= DataType::TIMESTAMP
;
642 nValue
= DataType::BINARY
;
646 nValue
= DataType::VARBINARY
;
648 case SQL_LONGVARBINARY
:
649 nValue
= DataType::LONGVARBINARY
;
652 OSL_FAIL("Invalid type");
658 // Convert the JDBC SQL type to the correct ODBC type
660 SQLSMALLINT
OTools::jdbcTypeToOdbc(sal_Int32 jdbcType
)
662 // For the most part, JDBC types match ODBC types. We'll
663 // just convert the ones that we know are different
665 sal_Int32 odbcType
= jdbcType
;
675 case DataType::TIMESTAMP
:
676 odbcType
= SQL_TIMESTAMP
;
678 // ODBC doesn't have any notion of CLOB or BLOB
680 odbcType
= SQL_LONGVARCHAR
;
683 odbcType
= SQL_LONGVARBINARY
;
690 void OTools::getBindTypes(bool _bUseWChar
,
691 bool _bUseOldTimeDate
,
692 SQLSMALLINT _nOdbcType
,
694 SQLSMALLINT
& fSqlType
699 case SQL_CHAR
: if(_bUseWChar
)
701 fCType
= SQL_C_WCHAR
;
702 fSqlType
= SQL_WCHAR
;
710 case SQL_VARCHAR
: if(_bUseWChar
)
712 fCType
= SQL_C_WCHAR
;
713 fSqlType
= SQL_WVARCHAR
;
718 fSqlType
= SQL_VARCHAR
;
721 case SQL_LONGVARCHAR
: if(_bUseWChar
)
723 fCType
= SQL_C_WCHAR
;
724 fSqlType
= SQL_WLONGVARCHAR
;
729 fSqlType
= SQL_LONGVARCHAR
;
732 case SQL_DECIMAL
: fCType
= _bUseWChar
? SQL_C_WCHAR
: SQL_C_CHAR
;
733 fSqlType
= SQL_DECIMAL
; break;
734 case SQL_NUMERIC
: fCType
= _bUseWChar
? SQL_C_WCHAR
: SQL_C_CHAR
;
735 fSqlType
= SQL_NUMERIC
; break;
736 case SQL_BIT
: fCType
= SQL_C_TINYINT
;
737 fSqlType
= SQL_INTEGER
; break;
738 case SQL_TINYINT
: fCType
= SQL_C_TINYINT
;
739 fSqlType
= SQL_TINYINT
; break;
740 case SQL_SMALLINT
: fCType
= SQL_C_SHORT
;
741 fSqlType
= SQL_SMALLINT
; break;
742 case SQL_INTEGER
: fCType
= SQL_C_LONG
;
743 fSqlType
= SQL_INTEGER
; break;
744 case SQL_BIGINT
: fCType
= SQL_C_SBIGINT
;
745 fSqlType
= SQL_BIGINT
; break;
746 case SQL_FLOAT
: fCType
= SQL_C_FLOAT
;
747 fSqlType
= SQL_FLOAT
; break;
748 case SQL_REAL
: fCType
= SQL_C_DOUBLE
;
749 fSqlType
= SQL_REAL
; break;
750 case SQL_DOUBLE
: fCType
= SQL_C_DOUBLE
;
751 fSqlType
= SQL_DOUBLE
; break;
752 case SQL_BINARY
: fCType
= SQL_C_BINARY
;
753 fSqlType
= SQL_BINARY
; break;
755 fCType
= SQL_C_BINARY
;
756 fSqlType
= SQL_VARBINARY
; break;
757 case SQL_LONGVARBINARY
: fCType
= SQL_C_BINARY
;
758 fSqlType
= SQL_LONGVARBINARY
; break;
767 fCType
= SQL_C_TYPE_DATE
;
768 fSqlType
= SQL_TYPE_DATE
;
779 fCType
= SQL_C_TYPE_TIME
;
780 fSqlType
= SQL_TYPE_TIME
;
786 fCType
= SQL_C_TIMESTAMP
;
787 fSqlType
= SQL_TIMESTAMP
;
791 fCType
= SQL_C_TYPE_TIMESTAMP
;
792 fSqlType
= SQL_TYPE_TIMESTAMP
;
795 default: fCType
= SQL_C_BINARY
;
796 fSqlType
= SQL_LONGVARBINARY
; break;
801 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */