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 <osl/endian.h>
25 #include <odbc/OConnection.hxx>
26 #include <rtl/ustrbuf.hxx>
27 #include <sal/log.hxx>
33 using namespace connectivity::odbc
;
34 using namespace com::sun::star::uno
;
35 using namespace com::sun::star::sdbc
;
36 using namespace com::sun::star::util
;
39 size_t sqlTypeLen ( SQLSMALLINT _nType
)
45 return sizeof(SQLSMALLINT
);
47 return sizeof(SQLUSMALLINT
);
50 return sizeof(SQLINTEGER
);
52 return sizeof(SQLUINTEGER
);
54 return sizeof(SQLREAL
);
56 static_assert(sizeof(SQLDOUBLE
) == sizeof(SQLFLOAT
), "SQLDOUBLE/SQLFLOAT confusion");
57 return sizeof(SQLDOUBLE
);
59 return sizeof(SQLCHAR
);
62 return sizeof(SQLSCHAR
);
64 return sizeof(SQLCHAR
);
66 return sizeof(SQLBIGINT
);
68 return sizeof(SQLUBIGINT
);
69 /* UnixODBC gives this the same value as SQL_C_UBIGINT
71 return sizeof(BOOKMARK); */
74 return sizeof(SQL_DATE_STRUCT
);
77 return sizeof(SQL_TIME_STRUCT
);
78 case SQL_C_TYPE_TIMESTAMP
:
80 return sizeof(SQL_TIMESTAMP_STRUCT
);
82 return sizeof(SQL_NUMERIC_STRUCT
);
84 return sizeof(SQLGUID
);
85 case SQL_C_INTERVAL_YEAR
:
86 case SQL_C_INTERVAL_MONTH
:
87 case SQL_C_INTERVAL_DAY
:
88 case SQL_C_INTERVAL_HOUR
:
89 case SQL_C_INTERVAL_MINUTE
:
90 case SQL_C_INTERVAL_SECOND
:
91 case SQL_C_INTERVAL_YEAR_TO_MONTH
:
92 case SQL_C_INTERVAL_DAY_TO_HOUR
:
93 case SQL_C_INTERVAL_DAY_TO_MINUTE
:
94 case SQL_C_INTERVAL_DAY_TO_SECOND
:
95 case SQL_C_INTERVAL_HOUR_TO_MINUTE
:
96 case SQL_C_INTERVAL_HOUR_TO_SECOND
:
97 case SQL_C_INTERVAL_MINUTE_TO_SECOND
:
98 return sizeof(SQL_INTERVAL_STRUCT
);
99 // ** Variable-sized datatypes -> cannot predict length
103 // UnixODBC gives this the same value as SQL_C_BINARY
104 //case SQL_C_VARBOOKMARK:
105 // Unknown datatype -> cannot predict length
107 return static_cast<size_t>(-1);
111 void appendSQLWCHARs(OUStringBuffer
& s
, SQLWCHAR
const * d
, sal_Int32 n
)
114 sizeof (SQLWCHAR
) == sizeof (sal_Unicode
) || sizeof (SQLWCHAR
) == 4,
116 if (sizeof (SQLWCHAR
) == sizeof (sal_Unicode
)) {
117 s
.append(reinterpret_cast<sal_Unicode
const *>(d
), n
);
119 for (sal_Int32 i
= 0; i
!= n
; ++i
) {
127 void OTools::getValue( OConnection
const * _pConnection
,
128 SQLHANDLE _aStatementHandle
,
129 sal_Int32 columnIndex
,
132 const css::uno::Reference
< css::uno::XInterface
>& _xInterface
,
136 const size_t properSize
= sqlTypeLen(_nType
);
137 if ( properSize
== static_cast<size_t>(-1) )
138 SAL_WARN( "connectivity.drivers", "connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size");
141 OSL_ENSURE(static_cast<size_t>(_nSize
) == properSize
, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to");
142 if ( static_cast<size_t>(_nSize
) > properSize
)
144 SAL_WARN( "connectivity.drivers", "memory region is too big - trying to fudge it");
145 memset(_pValue
, 0, _nSize
);
147 // This is skewed in favour of integer types
148 _pValue
+= _nSize
- properSize
;
152 OSL_ENSURE(static_cast<size_t>(_nSize
) >= properSize
, "memory region is too small");
153 SQLLEN pcbValue
= SQL_NULL_DATA
;
154 OTools::ThrowException(_pConnection
,
155 (*reinterpret_cast<T3SQLGetData
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetData
)))(_aStatementHandle
,
156 static_cast<SQLUSMALLINT
>(columnIndex
),
161 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
,false);
162 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
165 void OTools::bindValue( OConnection
const * _pConnection
,
166 SQLHANDLE _aStatementHandle
,
167 sal_Int32 columnIndex
,
169 SQLSMALLINT _nMaxLen
,
173 const css::uno::Reference
< css::uno::XInterface
>& _xInterface
,
174 rtl_TextEncoding _nTextEncoding
,
175 bool _bUseOldTimeDate
)
178 SQLSMALLINT fSqlType
;
181 OTools::getBindTypes( false,
187 if (columnIndex
!= 0 && !_pValue
)
189 *pLen
= SQL_NULL_DATA
;
190 nRetcode
= (*reinterpret_cast<T3SQLBindCol
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::BindCol
)))(_aStatementHandle
,
191 static_cast<SQLUSMALLINT
>(columnIndex
),
207 OString
aString(OUStringToOString(*static_cast<OUString
const *>(_pValue
),_nTextEncoding
));
209 *static_cast<OString
*>(_pData
) = aString
;
212 _pData
= const_cast<char *>(aString
.getStr());
215 *static_cast<sal_Int64
*>(_pData
) = *static_cast<sal_Int64
const *>(_pValue
);
216 *pLen
= sizeof(sal_Int64
);
221 OString aString
= OString::number(*static_cast<double const *>(_pValue
));
222 *pLen
= static_cast<SQLSMALLINT
>(aString
.getLength());
223 *static_cast<OString
*>(_pData
) = aString
;
225 _pData
= const_cast<char *>(static_cast<OString
*>(_pData
)->getStr());
229 *static_cast<sal_Int8
*>(_pData
) = *static_cast<sal_Int8
const *>(_pValue
);
230 *pLen
= sizeof(sal_Int8
);
234 *static_cast<sal_Int16
*>(_pData
) = *static_cast<sal_Int16
const *>(_pValue
);
235 *pLen
= sizeof(sal_Int16
);
238 *static_cast<sal_Int32
*>(_pData
) = *static_cast<sal_Int32
const *>(_pValue
);
239 *pLen
= sizeof(sal_Int32
);
242 *static_cast<float*>(_pData
) = *static_cast<float const *>(_pValue
);
243 *pLen
= sizeof(float);
247 *static_cast<double*>(_pData
) = *static_cast<double const *>(_pValue
);
248 *pLen
= sizeof(double);
253 _pData
= const_cast<sal_Int8
*>(static_cast<const css::uno::Sequence
< sal_Int8
> *>(_pValue
)->getConstArray());
254 *pLen
= static_cast<const css::uno::Sequence
< sal_Int8
> *>(_pValue
)->getLength();
256 case SQL_LONGVARBINARY
:
258 /* see https://msdn.microsoft.com/en-us/library/ms716238%28v=vs.85%29.aspx
259 * for an explanation of that apparently weird cast */
260 _pData
= reinterpret_cast<void*>(static_cast<uintptr_t>(columnIndex
));
261 sal_Int32 nLen
= static_cast<const css::uno::Sequence
< sal_Int8
> *>(_pValue
)->getLength();
262 *pLen
= static_cast<SQLLEN
>(SQL_LEN_DATA_AT_EXEC(nLen
));
265 case SQL_LONGVARCHAR
:
267 /* see https://msdn.microsoft.com/en-us/library/ms716238%28v=vs.85%29.aspx
268 * for an explanation of that apparently weird cast */
269 _pData
= reinterpret_cast<void*>(static_cast<uintptr_t>(columnIndex
));
270 sal_Int32 nLen
= static_cast<OUString
const *>(_pValue
)->getLength();
271 *pLen
= static_cast<SQLLEN
>(SQL_LEN_DATA_AT_EXEC(nLen
));
274 *pLen
= sizeof(DATE_STRUCT
);
275 *static_cast<DATE_STRUCT
*>(_pData
) = *static_cast<DATE_STRUCT
const *>(_pValue
);
278 *pLen
= sizeof(TIME_STRUCT
);
279 *static_cast<TIME_STRUCT
*>(_pData
) = *static_cast<TIME_STRUCT
const *>(_pValue
);
282 *pLen
= sizeof(TIMESTAMP_STRUCT
);
283 *static_cast<TIMESTAMP_STRUCT
*>(_pData
) = *static_cast<TIMESTAMP_STRUCT
const *>(_pValue
);
291 nRetcode
= (*reinterpret_cast<T3SQLBindCol
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::BindCol
)))(_aStatementHandle
,
292 static_cast<SQLUSMALLINT
>(columnIndex
),
300 OTools::ThrowException(_pConnection
,nRetcode
,_aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
303 void OTools::ThrowException(const OConnection
* _pConnection
,
304 const SQLRETURN _rRetCode
,
305 const SQLHANDLE _pContext
,
306 const SQLSMALLINT _nHandleType
,
307 const Reference
< XInterface
>& _xInterface
,
308 const bool _bNoFound
)
313 case SQL_STILL_EXECUTING
:
316 case SQL_SUCCESS_WITH_INFO
:
318 case SQL_NO_DATA_FOUND
:
320 return; // no need to throw an exception
322 case SQL_ERROR
: break;
325 case SQL_INVALID_HANDLE
: SAL_WARN( "connectivity.drivers", "SdbODBC3_SetStatus: SQL_INVALID_HANDLE");
326 throw SQLException();
329 // Additional Information on the latest ODBC-functioncall available
330 // SQLError provides this Information.
332 SDB_ODBC_CHAR szSqlState
[5];
333 SQLINTEGER pfNativeError
;
334 SDB_ODBC_CHAR szErrorMessage
[SQL_MAX_MESSAGE_LENGTH
];
335 szErrorMessage
[0] = '\0';
336 SQLSMALLINT pcbErrorMsg
= 0;
338 // Information for latest operation:
339 // when hstmt != SQL_NULL_HSTMT is (Used from SetStatus in SdbCursor, SdbTable, ...),
340 // then the status of the latest statements will be fetched, without the Status of the last
341 // statements of this connection [what in this case will probably be the same, but the Reference
342 // Manual isn't totally clear in this...].
343 // corresponding for hdbc.
344 SQLRETURN n
= (*reinterpret_cast<T3SQLGetDiagRec
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetDiagRec
)))(_nHandleType
,_pContext
,1,
347 szErrorMessage
,sizeof szErrorMessage
- 1,&pcbErrorMsg
);
348 OSL_ENSURE(n
!= SQL_INVALID_HANDLE
,"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE");
349 OSL_ENSURE(n
== SQL_SUCCESS
|| n
== SQL_SUCCESS_WITH_INFO
|| n
== SQL_NO_DATA_FOUND
|| n
== SQL_ERROR
,"SdbODBC3_SetStatus: SQLError failed");
351 rtl_TextEncoding _nTextEncoding
= osl_getThreadTextEncoding();
352 // For the Return Code of SQLError see ODBC 2.0 Programmer's Reference Page 287ff
353 throw SQLException( OUString(reinterpret_cast<char *>(szErrorMessage
), pcbErrorMsg
, _nTextEncoding
),
355 OUString(reinterpret_cast<char *>(szSqlState
), 5, _nTextEncoding
),
362 Sequence
<sal_Int8
> OTools::getBytesValue(const OConnection
* _pConnection
,
363 const SQLHANDLE _aStatementHandle
,
364 const sal_Int32 columnIndex
,
365 const SQLSMALLINT _fSqlType
,
367 const Reference
< XInterface
>& _xInterface
)
369 sal_Int8 aCharArray
[2048];
370 // First try to fetch the data with the little Buffer:
371 const SQLLEN nMaxLen
= sizeof aCharArray
;
372 SQLLEN pcbValue
= SQL_NO_TOTAL
;
373 Sequence
<sal_Int8
> aData
;
375 OSL_ENSURE( _fSqlType
!= SQL_CHAR
&& _fSqlType
!= SQL_VARCHAR
&& _fSqlType
!= SQL_LONGVARCHAR
&&
376 _fSqlType
!= SQL_WCHAR
&& _fSqlType
!= SQL_WVARCHAR
&& _fSqlType
!= SQL_WLONGVARCHAR
,
377 "connectivity::odbc::OTools::getBytesValue called with character _fSqlType");
379 while (pcbValue
== SQL_NO_TOTAL
|| pcbValue
> nMaxLen
)
381 OTools::ThrowException(_pConnection
,
382 (*reinterpret_cast<T3SQLGetData
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetData
)))(
384 static_cast<SQLUSMALLINT
>(columnIndex
),
386 static_cast<SQLPOINTER
>(aCharArray
),
389 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
391 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
393 return Sequence
<sal_Int8
>();
396 // After the SQLGetData that wrote out to aCharArray the last byte of the data,
397 // pcbValue will not be SQL_NO_TOTAL -> we have a reliable count
398 if ( (pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxLen
) )
400 // we filled the buffer
401 nReadBytes
= nMaxLen
;
405 nReadBytes
= pcbValue
;
407 const sal_Int32 nLen
= aData
.getLength();
408 aData
.realloc(nLen
+ nReadBytes
);
409 memcpy(aData
.getArray() + nLen
, aCharArray
, nReadBytes
);
414 OUString
OTools::getStringValue(OConnection
const * _pConnection
,
415 SQLHANDLE _aStatementHandle
,
416 sal_Int32 columnIndex
,
417 SQLSMALLINT _fSqlType
,
419 const Reference
< XInterface
>& _xInterface
,
420 const rtl_TextEncoding _nTextEncoding
)
422 OUStringBuffer aData
;
427 case SQL_WLONGVARCHAR
:
429 SQLWCHAR waCharArray
[2048];
430 static_assert(sizeof(waCharArray
) % sizeof(SQLWCHAR
) == 0, "must fit in evenly");
431 static_assert(sizeof(SQLWCHAR
) == 2 || sizeof(SQLWCHAR
) == 4, "must be 2 or 4");
432 // Size == number of bytes, Len == number of UTF-16 or UCS4 code units
433 const SQLLEN nMaxSize
= sizeof(waCharArray
);
434 const SQLLEN nMaxLen
= sizeof(waCharArray
) / sizeof(SQLWCHAR
);
435 static_assert(nMaxLen
* sizeof(SQLWCHAR
) == nMaxSize
, "sizes must match");
437 // read the unicode data
438 SQLLEN pcbValue
= SQL_NO_TOTAL
;
439 while ((pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxSize
) )
441 OTools::ThrowException(_pConnection
,
442 (*reinterpret_cast<T3SQLGetData
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetData
)))(
444 static_cast<SQLUSMALLINT
>(columnIndex
),
447 SQLLEN(nMaxLen
)*sizeof(sal_Unicode
),
449 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
450 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
455 OSL_ENSURE( (pcbValue
< 0) || (pcbValue
% 2 == 0),
456 "ODBC: SQLGetData of SQL_C_WCHAR returned odd number of bytes");
457 if ( (pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxSize
) )
459 // we filled the buffer; remove the terminating null character
460 nReadChars
= nMaxLen
-1;
461 if ( waCharArray
[nReadChars
] != 0)
463 SAL_WARN( "connectivity.drivers", "Buggy ODBC driver? Did not null-terminate (variable length) data!");
469 nReadChars
= pcbValue
/sizeof(SQLWCHAR
);
472 appendSQLWCHARs(aData
, waCharArray
, nReadChars
);
478 char aCharArray
[2048];
479 // read the unicode data
480 const SQLLEN nMaxLen
= sizeof(aCharArray
);
481 SQLLEN pcbValue
= SQL_NO_TOTAL
;
483 while ((pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxLen
) )
485 OTools::ThrowException(_pConnection
,
486 (*reinterpret_cast<T3SQLGetData
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetData
)))(
488 static_cast<SQLUSMALLINT
>(columnIndex
),
493 _aStatementHandle
,SQL_HANDLE_STMT
,_xInterface
);
494 _bWasNull
= pcbValue
== SQL_NULL_DATA
;
499 if ( (pcbValue
== SQL_NO_TOTAL
) || (pcbValue
>= nMaxLen
) )
501 // we filled the buffer; remove the terminating null character
502 nReadChars
= nMaxLen
-1;
503 if ( aCharArray
[nReadChars
] != 0)
505 SAL_WARN( "connectivity.drivers", "Buggy ODBC driver? Did not null-terminate (variable length) data!");
511 nReadChars
= pcbValue
;
514 aData
.append(OUString(aCharArray
, nReadChars
, _nTextEncoding
));
521 return aData
.makeStringAndClear();
524 void OTools::GetInfo(OConnection
const * _pConnection
,
525 SQLHANDLE _aConnectionHandle
,
528 const Reference
< XInterface
>& _xInterface
,
529 rtl_TextEncoding _nTextEncoding
)
532 SQLSMALLINT nValueLen
=0;
533 OTools::ThrowException(_pConnection
,
534 (*reinterpret_cast<T3SQLGetInfo
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetInfo
)))(_aConnectionHandle
,_nInfo
,aValue
,(sizeof aValue
)-1,&nValueLen
),
535 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
537 _rValue
= OUString(aValue
,nValueLen
,_nTextEncoding
);
540 void OTools::GetInfo(OConnection
const * _pConnection
,
541 SQLHANDLE _aConnectionHandle
,
544 const Reference
< XInterface
>& _xInterface
)
546 SQLSMALLINT nValueLen
;
547 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
548 OTools::ThrowException(_pConnection
,
549 (*reinterpret_cast<T3SQLGetInfo
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetInfo
)))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
550 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
553 void OTools::GetInfo(OConnection
const * _pConnection
,
554 SQLHANDLE _aConnectionHandle
,
556 SQLUINTEGER
&_rValue
,
557 const Reference
< XInterface
>& _xInterface
)
559 SQLSMALLINT nValueLen
;
560 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
561 OTools::ThrowException(_pConnection
,
562 (*reinterpret_cast<T3SQLGetInfo
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetInfo
)))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
563 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
566 void OTools::GetInfo(OConnection
const * _pConnection
,
567 SQLHANDLE _aConnectionHandle
,
569 SQLUSMALLINT
&_rValue
,
570 const Reference
< XInterface
>& _xInterface
)
572 SQLSMALLINT nValueLen
;
573 _rValue
= 0; // in case the driver uses only 16 of the 32 bits (as it does, for example, for SQL_CATALOG_LOCATION)
574 OTools::ThrowException(_pConnection
,
575 (*reinterpret_cast<T3SQLGetInfo
>(_pConnection
->getOdbcFunction(ODBC3SQLFunctionId::GetInfo
)))(_aConnectionHandle
,_nInfo
,&_rValue
,sizeof _rValue
,&nValueLen
),
576 _aConnectionHandle
,SQL_HANDLE_DBC
,_xInterface
);
579 sal_Int32
OTools::MapOdbcType2Jdbc(SQLSMALLINT _nType
)
581 sal_Int32 nValue
= DataType::VARCHAR
;
585 nValue
= DataType::BIT
;
588 nValue
= DataType::TINYINT
;
591 nValue
= DataType::SMALLINT
;
594 nValue
= DataType::INTEGER
;
597 nValue
= DataType::BIGINT
;
600 nValue
= DataType::FLOAT
;
603 nValue
= DataType::REAL
;
606 nValue
= DataType::DOUBLE
;
609 nValue
= DataType::NUMERIC
;
612 nValue
= DataType::DECIMAL
;
616 nValue
= DataType::CHAR
;
620 nValue
= DataType::VARCHAR
;
622 case SQL_WLONGVARCHAR
:
623 case SQL_LONGVARCHAR
:
624 nValue
= DataType::LONGVARCHAR
;
628 nValue
= DataType::DATE
;
632 nValue
= DataType::TIME
;
634 case SQL_TYPE_TIMESTAMP
:
636 nValue
= DataType::TIMESTAMP
;
639 nValue
= DataType::BINARY
;
643 nValue
= DataType::VARBINARY
;
645 case SQL_LONGVARBINARY
:
646 nValue
= DataType::LONGVARBINARY
;
649 OSL_FAIL("Invalid type");
655 // Convert the JDBC SQL type to the correct ODBC type
657 SQLSMALLINT
OTools::jdbcTypeToOdbc(sal_Int32 jdbcType
)
659 // For the most part, JDBC types match ODBC types. We'll
660 // just convert the ones that we know are different
662 sal_Int32 odbcType
= jdbcType
;
672 case DataType::TIMESTAMP
:
673 odbcType
= SQL_TIMESTAMP
;
675 // ODBC doesn't have any notion of CLOB or BLOB
677 odbcType
= SQL_LONGVARCHAR
;
680 odbcType
= SQL_LONGVARBINARY
;
687 void OTools::getBindTypes(bool _bUseWChar
,
688 bool _bUseOldTimeDate
,
689 SQLSMALLINT _nOdbcType
,
691 SQLSMALLINT
& fSqlType
696 case SQL_CHAR
: if(_bUseWChar
)
698 fCType
= SQL_C_WCHAR
;
699 fSqlType
= SQL_WCHAR
;
707 case SQL_VARCHAR
: if(_bUseWChar
)
709 fCType
= SQL_C_WCHAR
;
710 fSqlType
= SQL_WVARCHAR
;
715 fSqlType
= SQL_VARCHAR
;
718 case SQL_LONGVARCHAR
: if(_bUseWChar
)
720 fCType
= SQL_C_WCHAR
;
721 fSqlType
= SQL_WLONGVARCHAR
;
726 fSqlType
= SQL_LONGVARCHAR
;
729 case SQL_DECIMAL
: fCType
= _bUseWChar
? SQL_C_WCHAR
: SQL_C_CHAR
;
730 fSqlType
= SQL_DECIMAL
; break;
731 case SQL_NUMERIC
: fCType
= _bUseWChar
? SQL_C_WCHAR
: SQL_C_CHAR
;
732 fSqlType
= SQL_NUMERIC
; break;
733 case SQL_BIT
: fCType
= SQL_C_TINYINT
;
734 fSqlType
= SQL_INTEGER
; break;
735 case SQL_TINYINT
: fCType
= SQL_C_TINYINT
;
736 fSqlType
= SQL_TINYINT
; break;
737 case SQL_SMALLINT
: fCType
= SQL_C_SHORT
;
738 fSqlType
= SQL_SMALLINT
; break;
739 case SQL_INTEGER
: fCType
= SQL_C_LONG
;
740 fSqlType
= SQL_INTEGER
; break;
741 case SQL_BIGINT
: fCType
= SQL_C_SBIGINT
;
742 fSqlType
= SQL_BIGINT
; break;
743 case SQL_FLOAT
: fCType
= SQL_C_FLOAT
;
744 fSqlType
= SQL_FLOAT
; break;
745 case SQL_REAL
: fCType
= SQL_C_DOUBLE
;
746 fSqlType
= SQL_REAL
; break;
747 case SQL_DOUBLE
: fCType
= SQL_C_DOUBLE
;
748 fSqlType
= SQL_DOUBLE
; break;
749 case SQL_BINARY
: fCType
= SQL_C_BINARY
;
750 fSqlType
= SQL_BINARY
; break;
752 fCType
= SQL_C_BINARY
;
753 fSqlType
= SQL_VARBINARY
; break;
754 case SQL_LONGVARBINARY
: fCType
= SQL_C_BINARY
;
755 fSqlType
= SQL_LONGVARBINARY
; break;
764 fCType
= SQL_C_TYPE_DATE
;
765 fSqlType
= SQL_TYPE_DATE
;
776 fCType
= SQL_C_TYPE_TIME
;
777 fSqlType
= SQL_TYPE_TIME
;
783 fCType
= SQL_C_TIMESTAMP
;
784 fSqlType
= SQL_TIMESTAMP
;
788 fCType
= SQL_C_TYPE_TIMESTAMP
;
789 fSqlType
= SQL_TYPE_TIMESTAMP
;
792 default: fCType
= SQL_C_BINARY
;
793 fSqlType
= SQL_LONGVARBINARY
; break;
798 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */