22#include <com/sun/star/sdbc/DataType.hpp>
24#include <osl/diagnose.h>
25#include <osl/endian.h>
27#include <rtl/ustrbuf.hxx>
38size_t sqlTypeLen ( SQLSMALLINT _nType )
44 return sizeof(SQLSMALLINT);
46 return sizeof(SQLUSMALLINT);
49 return sizeof(SQLINTEGER);
51 return sizeof(SQLUINTEGER);
53 return sizeof(SQLREAL);
55 static_assert(
sizeof(SQLDOUBLE) ==
sizeof(SQLFLOAT),
"SQLDOUBLE/SQLFLOAT confusion");
56 return sizeof(SQLDOUBLE);
58 return sizeof(SQLCHAR);
61 return sizeof(SQLSCHAR);
63 return sizeof(SQLCHAR);
65 return sizeof(SQLBIGINT);
67 return sizeof(SQLUBIGINT);
73 return sizeof(SQL_DATE_STRUCT);
76 return sizeof(SQL_TIME_STRUCT);
77 case SQL_C_TYPE_TIMESTAMP:
79 return sizeof(SQL_TIMESTAMP_STRUCT);
81 return sizeof(SQL_NUMERIC_STRUCT);
83 return sizeof(SQLGUID);
84 case SQL_C_INTERVAL_YEAR:
85 case SQL_C_INTERVAL_MONTH:
86 case SQL_C_INTERVAL_DAY:
87 case SQL_C_INTERVAL_HOUR:
88 case SQL_C_INTERVAL_MINUTE:
89 case SQL_C_INTERVAL_SECOND:
90 case SQL_C_INTERVAL_YEAR_TO_MONTH:
91 case SQL_C_INTERVAL_DAY_TO_HOUR:
92 case SQL_C_INTERVAL_DAY_TO_MINUTE:
93 case SQL_C_INTERVAL_DAY_TO_SECOND:
94 case SQL_C_INTERVAL_HOUR_TO_MINUTE:
95 case SQL_C_INTERVAL_HOUR_TO_SECOND:
96 case SQL_C_INTERVAL_MINUTE_TO_SECOND:
97 return sizeof(SQL_INTERVAL_STRUCT);
106 return static_cast<size_t>(-1);
110void appendSQLWCHARs(OUStringBuffer & s, SQLWCHAR
const * d, sal_Int32 n)
113 sizeof (SQLWCHAR) ==
sizeof (
sal_Unicode) ||
sizeof (SQLWCHAR) == 4,
118 for (sal_Int32 i = 0;
i !=
n; ++
i) {
127 SQLHANDLE _aStatementHandle,
128 sal_Int32 columnIndex,
131 const css::uno::Reference< css::uno::XInterface >& _xInterface,
135 const size_t properSize = sqlTypeLen(_nType);
136 if ( properSize ==
static_cast<size_t>(-1) )
137 SAL_WARN(
"connectivity.drivers",
"connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size");
140 OSL_ENSURE(
static_cast<size_t>(_nSize) == properSize,
"connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to");
143 SAL_WARN(
"connectivity.drivers",
"memory region is too big - trying to fudge it");
144 memset(_pValue, 0, _nSize);
147 _pValue =
static_cast<char*
>(_pValue) + _nSize - properSize;
152 SQLLEN pcbValue = SQL_NULL_DATA;
155 static_cast<SQLUSMALLINT
>(columnIndex),
160 _aStatementHandle,SQL_HANDLE_STMT,_xInterface,
false);
161 _bWasNull = pcbValue == SQL_NULL_DATA;
165 SQLHANDLE _aStatementHandle,
166 sal_Int32 columnIndex,
168 SQLSMALLINT _nMaxLen,
172 const css::uno::Reference< css::uno::XInterface >& _xInterface,
173 rtl_TextEncoding _nTextEncoding,
174 bool _bUseOldTimeDate)
177 SQLSMALLINT fSqlType;
186 if (columnIndex != 0 && !_pValue)
188 *pLen = SQL_NULL_DATA;
190 static_cast<SQLUSMALLINT
>(columnIndex),
206 OString aString(
OUStringToOString(*
static_cast<OUString
const *
>(_pValue),_nTextEncoding));
208 *
static_cast<OString*
>(_pData) = aString;
211 _pData =
const_cast<char *
>(aString.getStr());
214 *
static_cast<sal_Int64*
>(_pData) = *
static_cast<sal_Int64
const *
>(_pValue);
215 *pLen =
sizeof(sal_Int64);
220 OString aString = OString::number(*
static_cast<double const *
>(_pValue));
221 *pLen =
static_cast<SQLSMALLINT
>(aString.getLength());
222 *
static_cast<OString*
>(_pData) = aString;
224 _pData =
const_cast<char *
>(
static_cast<OString*
>(_pData)->getStr());
233 *
static_cast<sal_Int16*
>(_pData) = *
static_cast<sal_Int16
const *
>(_pValue);
234 *pLen =
sizeof(sal_Int16);
237 *
static_cast<sal_Int32*
>(_pData) = *
static_cast<sal_Int32
const *
>(_pValue);
238 *pLen =
sizeof(sal_Int32);
241 *
static_cast<float*
>(_pData) = *
static_cast<float const *
>(_pValue);
242 *pLen =
sizeof(float);
246 *
static_cast<double*
>(_pData) = *
static_cast<double const *
>(_pValue);
247 *pLen =
sizeof(double);
252 _pData =
const_cast<sal_Int8 *
>(
static_cast<const css::uno::Sequence< sal_Int8 > *
>(_pValue)->getConstArray());
253 *pLen =
static_cast<const css::uno::Sequence< sal_Int8 > *
>(_pValue)->
getLength();
255 case SQL_LONGVARBINARY:
259 _pData =
reinterpret_cast<void*
>(
static_cast<uintptr_t
>(columnIndex));
260 sal_Int32 nLen =
static_cast<const css::uno::Sequence< sal_Int8 > *
>(_pValue)->
getLength();
261 *pLen =
static_cast<SQLLEN
>(SQL_LEN_DATA_AT_EXEC(nLen));
264 case SQL_LONGVARCHAR:
268 _pData =
reinterpret_cast<void*
>(
static_cast<uintptr_t
>(columnIndex));
269 sal_Int32 nLen =
static_cast<OUString
const *
>(_pValue)->
getLength();
270 *pLen =
static_cast<SQLLEN
>(SQL_LEN_DATA_AT_EXEC(nLen));
273 *pLen =
sizeof(DATE_STRUCT);
274 *
static_cast<DATE_STRUCT*
>(_pData) = *
static_cast<DATE_STRUCT
const *
>(_pValue);
277 *pLen =
sizeof(TIME_STRUCT);
278 *
static_cast<TIME_STRUCT*
>(_pData) = *
static_cast<TIME_STRUCT
const *
>(_pValue);
281 *pLen =
sizeof(TIMESTAMP_STRUCT);
282 *
static_cast<TIMESTAMP_STRUCT*
>(_pData) = *
static_cast<TIMESTAMP_STRUCT
const *
>(_pValue);
291 static_cast<SQLUSMALLINT
>(columnIndex),
303 const SQLRETURN _rRetCode,
304 const SQLHANDLE _pContext,
305 const SQLSMALLINT _nHandleType,
307 const bool _bNoFound)
312 case SQL_STILL_EXECUTING:
315 case SQL_SUCCESS_WITH_INFO:
317 case SQL_NO_DATA_FOUND:
321 case SQL_ERROR:
break;
324 case SQL_INVALID_HANDLE:
SAL_WARN(
"connectivity.drivers",
"SdbODBC3_SetStatus: SQL_INVALID_HANDLE");
325 throw SQLException();
332 SQLINTEGER pfNativeError;
334 szErrorMessage[0] =
'\0';
335 SQLSMALLINT pcbErrorMsg = 0;
346 szErrorMessage,
sizeof szErrorMessage - 1,&pcbErrorMsg);
347 OSL_ENSURE(
n != SQL_INVALID_HANDLE,
"SdbODBC3_SetStatus: SQLError returned SQL_INVALID_HANDLE");
348 OSL_ENSURE(
n == SQL_SUCCESS ||
n == SQL_SUCCESS_WITH_INFO ||
n == SQL_NO_DATA_FOUND ||
n == SQL_ERROR,
"SdbODBC3_SetStatus: SQLError failed");
350 rtl_TextEncoding _nTextEncoding = osl_getThreadTextEncoding();
352 throw SQLException( OUString(
reinterpret_cast<char *
>(szErrorMessage), pcbErrorMsg, _nTextEncoding),
354 OUString(
reinterpret_cast<char *
>(szSqlState), 5, _nTextEncoding),
362 const SQLHANDLE _aStatementHandle,
363 const sal_Int32 columnIndex,
364 const SQLSMALLINT _fSqlType,
370 const SQLLEN nMaxLen =
sizeof aCharArray;
371 SQLLEN pcbValue = SQL_NO_TOTAL;
374 OSL_ENSURE( _fSqlType != SQL_CHAR && _fSqlType != SQL_VARCHAR && _fSqlType != SQL_LONGVARCHAR &&
376 "connectivity::odbc::OTools::getBytesValue called with character _fSqlType");
378 while (pcbValue == SQL_NO_TOTAL || pcbValue > nMaxLen)
383 static_cast<SQLUSMALLINT
>(columnIndex),
385 static_cast<SQLPOINTER
>(aCharArray),
388 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
390 _bWasNull = pcbValue == SQL_NULL_DATA;
397 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxLen) )
400 nReadBytes = nMaxLen;
404 nReadBytes = pcbValue;
406 const sal_Int32 nLen =
aData.getLength();
407 aData.realloc(nLen + nReadBytes);
408 memcpy(
aData.getArray() + nLen, aCharArray, nReadBytes);
414 SQLHANDLE _aStatementHandle,
415 sal_Int32 columnIndex,
416 SQLSMALLINT _fSqlType,
419 const rtl_TextEncoding _nTextEncoding)
421 OUStringBuffer
aData;
428 SQLWCHAR waCharArray[2048];
429 static_assert(
sizeof(waCharArray) %
sizeof(SQLWCHAR) == 0,
"must fit in evenly");
430 static_assert(
sizeof(SQLWCHAR) == 2 ||
sizeof(SQLWCHAR) == 4,
"must be 2 or 4");
432 const SQLLEN nMaxSize =
sizeof(waCharArray);
433 const SQLLEN nMaxLen =
sizeof(waCharArray) /
sizeof(SQLWCHAR);
434 static_assert(nMaxLen *
sizeof(SQLWCHAR) == nMaxSize,
"sizes must match");
437 SQLLEN pcbValue = SQL_NO_TOTAL;
438 while ((pcbValue == SQL_NO_TOTAL ) || (pcbValue >= nMaxSize) )
443 static_cast<SQLUSMALLINT
>(columnIndex),
448 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
449 _bWasNull = pcbValue == SQL_NULL_DATA;
454 OSL_ENSURE( (pcbValue < 0) || (pcbValue % 2 == 0),
455 "ODBC: SQLGetData of SQL_C_WCHAR returned odd number of bytes");
456 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxSize) )
459 nReadChars = nMaxLen-1;
460 if ( waCharArray[nReadChars] != 0)
462 SAL_WARN(
"connectivity.drivers",
"Buggy ODBC driver? Did not null-terminate (variable length) data!");
468 nReadChars = pcbValue/
sizeof(SQLWCHAR);
471 appendSQLWCHARs(
aData, waCharArray, nReadChars);
477 char aCharArray[2048];
479 const SQLLEN nMaxLen =
sizeof(aCharArray);
480 SQLLEN pcbValue = SQL_NO_TOTAL;
482 while ((pcbValue == SQL_NO_TOTAL ) || (pcbValue >= nMaxLen) )
487 static_cast<SQLUSMALLINT
>(columnIndex),
492 _aStatementHandle,SQL_HANDLE_STMT,_xInterface);
493 _bWasNull = pcbValue == SQL_NULL_DATA;
498 if ( (pcbValue == SQL_NO_TOTAL) || (pcbValue >= nMaxLen) )
501 nReadChars = nMaxLen-1;
502 if ( aCharArray[nReadChars] != 0)
504 SAL_WARN(
"connectivity.drivers",
"Buggy ODBC driver? Did not null-terminate (variable length) data!");
510 nReadChars = pcbValue;
513 aData.append(OUString(aCharArray, nReadChars, _nTextEncoding));
520 return aData.makeStringAndClear();
524 SQLHANDLE _aConnectionHandle,
528 rtl_TextEncoding _nTextEncoding)
531 SQLSMALLINT nValueLen=0;
534 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
536 _rValue = OUString(aValue,nValueLen,_nTextEncoding);
540 SQLHANDLE _aConnectionHandle,
545 SQLSMALLINT nValueLen;
549 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
553 SQLHANDLE _aConnectionHandle,
555 SQLUINTEGER &_rValue,
558 SQLSMALLINT nValueLen;
562 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
566 SQLHANDLE _aConnectionHandle,
568 SQLUSMALLINT &_rValue,
571 SQLSMALLINT nValueLen;
575 _aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
580 sal_Int32
nValue = DataType::VARCHAR;
587 nValue = DataType::TINYINT;
590 nValue = DataType::SMALLINT;
593 nValue = DataType::INTEGER;
596 nValue = DataType::BIGINT;
605 nValue = DataType::DOUBLE;
608 nValue = DataType::NUMERIC;
611 nValue = DataType::DECIMAL;
619 nValue = DataType::VARCHAR;
622 case SQL_LONGVARCHAR:
623 nValue = DataType::LONGVARCHAR;
633 case SQL_TYPE_TIMESTAMP:
635 nValue = DataType::TIMESTAMP;
638 nValue = DataType::BINARY;
642 nValue = DataType::VARBINARY;
644 case SQL_LONGVARBINARY:
645 nValue = DataType::LONGVARBINARY;
648 OSL_FAIL(
"Invalid type");
661 sal_Int32 odbcType = jdbcType;
671 case DataType::TIMESTAMP:
672 odbcType = SQL_TIMESTAMP;
676 odbcType = SQL_LONGVARCHAR;
679 odbcType = SQL_LONGVARBINARY;
687 bool _bUseOldTimeDate,
688 SQLSMALLINT _nOdbcType,
690 SQLSMALLINT& fSqlType
695 case SQL_CHAR:
if(_bUseWChar)
706 case SQL_VARCHAR:
if(_bUseWChar)
714 fSqlType = SQL_VARCHAR;
717 case SQL_LONGVARCHAR:
if(_bUseWChar)
725 fSqlType = SQL_LONGVARCHAR;
728 case SQL_DECIMAL: fCType = _bUseWChar ?
SQL_C_WCHAR : SQL_C_CHAR;
729 fSqlType = SQL_DECIMAL;
break;
730 case SQL_NUMERIC: fCType = _bUseWChar ?
SQL_C_WCHAR : SQL_C_CHAR;
731 fSqlType = SQL_NUMERIC;
break;
732 case SQL_BIT: fCType = SQL_C_TINYINT;
733 fSqlType = SQL_INTEGER;
break;
734 case SQL_TINYINT: fCType = SQL_C_TINYINT;
735 fSqlType = SQL_TINYINT;
break;
736 case SQL_SMALLINT: fCType = SQL_C_SHORT;
737 fSqlType = SQL_SMALLINT;
break;
738 case SQL_INTEGER: fCType = SQL_C_LONG;
739 fSqlType = SQL_INTEGER;
break;
740 case SQL_BIGINT: fCType = SQL_C_SBIGINT;
741 fSqlType = SQL_BIGINT;
break;
742 case SQL_FLOAT: fCType = SQL_C_FLOAT;
743 fSqlType = SQL_FLOAT;
break;
744 case SQL_REAL: fCType = SQL_C_DOUBLE;
745 fSqlType = SQL_REAL;
break;
746 case SQL_DOUBLE: fCType = SQL_C_DOUBLE;
747 fSqlType = SQL_DOUBLE;
break;
748 case SQL_BINARY: fCType = SQL_C_BINARY;
749 fSqlType = SQL_BINARY;
break;
751 fCType = SQL_C_BINARY;
752 fSqlType = SQL_VARBINARY;
break;
753 case SQL_LONGVARBINARY: fCType = SQL_C_BINARY;
754 fSqlType = SQL_LONGVARBINARY;
break;
763 fCType = SQL_C_TYPE_DATE;
764 fSqlType = SQL_TYPE_DATE;
775 fCType = SQL_C_TYPE_TIME;
776 fSqlType = SQL_TYPE_TIME;
782 fCType = SQL_C_TIMESTAMP;
783 fSqlType = SQL_TIMESTAMP;
787 fCType = SQL_C_TYPE_TIMESTAMP;
788 fSqlType = SQL_TYPE_TIMESTAMP;
791 default: fCType = SQL_C_BINARY;
792 fSqlType = SQL_LONGVARBINARY;
break;
oslGenericFunction getOdbcFunction(ODBC3SQLFunctionId _nIndex) const
#define SAL_WARN(area, stream)
constexpr OUStringLiteral aData
double getLength(const B2DPolygon &rCandidate)
static bool getValue(EContact *pContact, sal_Int32 nColumnNum, GType nType, GValue *pStackValue, bool &_out_rWasNull)
SQLRETURN(SQL_API * T3SQLGetDiagRec)(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, SQLINTEGER *NativeErrorPtr, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLengthPtr)
SQLRETURN(SQL_API * T3SQLGetData)(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_IndPtr)
SQLRETURN(SQL_API * T3SQLBindCol)(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_IndPtr)
SQLRETURN(SQL_API * T3SQLGetInfo)(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValuePtr, SQLSMALLINT BufferLength, SQLSMALLINT *StringLengthPtr)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)