76 #else |
76 #else |
77 # define QSQLLEN SQLLEN |
77 # define QSQLLEN SQLLEN |
78 # define QSQLULEN SQLULEN |
78 # define QSQLULEN SQLULEN |
79 #endif |
79 #endif |
80 |
80 |
81 |
|
82 static const int COLNAMESIZE = 256; |
81 static const int COLNAMESIZE = 256; |
83 //Map Qt parameter types to ODBC types |
82 //Map Qt parameter types to ODBC types |
84 static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT }; |
83 static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT }; |
85 |
84 |
|
85 inline static QString fromSQLTCHAR(const QVarLengthArray<SQLTCHAR>& input, int size=-1) |
|
86 { |
|
87 QString result; |
|
88 |
|
89 int realsize = qMin(size, input.size()); |
|
90 if(realsize > 0 && input[realsize-1] == 0) |
|
91 realsize--; |
|
92 switch(sizeof(SQLTCHAR)) { |
|
93 case 1: |
|
94 result=QString::fromUtf8((const char *)input.constData(), realsize); |
|
95 break; |
|
96 case 2: |
|
97 result=QString::fromUtf16((const ushort *)input.constData(), realsize); |
|
98 break; |
|
99 case 4: |
|
100 result=QString::fromUcs4((const uint *)input.constData(), realsize); |
|
101 break; |
|
102 default: |
|
103 qCritical() << "sizeof(SQLTCHAR) is " << sizeof(SQLTCHAR) << "Don't know how to handle this"; |
|
104 } |
|
105 return result; |
|
106 } |
|
107 |
|
108 inline static QVarLengthArray<SQLTCHAR> toSQLTCHAR(const QString &input) |
|
109 { |
|
110 QVarLengthArray<SQLTCHAR> result; |
|
111 result.resize(input.size()); |
|
112 switch(sizeof(SQLTCHAR)) { |
|
113 case 1: |
|
114 memcpy(result.data(), input.toUtf8().data(), input.size()); |
|
115 break; |
|
116 case 2: |
|
117 memcpy(result.data(), input.unicode(), input.size() * 2); |
|
118 break; |
|
119 case 4: |
|
120 memcpy(result.data(), input.toUcs4().data(), input.size() * 4); |
|
121 break; |
|
122 default: |
|
123 qCritical() << "sizeof(SQLTCHAR) is " << sizeof(SQLTCHAR) << "Don't know how to handle this"; |
|
124 } |
|
125 result.append(0); // make sure it's null terminated, doesn't matter if it already is, it does if it isn't. |
|
126 return result; |
|
127 } |
|
128 |
86 class QODBCDriverPrivate |
129 class QODBCDriverPrivate |
87 { |
130 { |
88 public: |
131 public: |
89 enum DefaultCase{Lower, Mixed, Upper, Sensitive}; |
132 enum DefaultCase{Lower, Mixed, Upper, Sensitive}; |
90 QODBCDriverPrivate() |
133 QODBCDriverPrivate() |
91 : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false), |
134 : hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), isMySqlServer(false), |
92 isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false), |
135 isMSSqlServer(false), isFreeTDSDriver(false), hasSQLFetchScroll(true), |
93 isQuoteInitialized(false), quote(QLatin1Char('"')) |
136 hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"')) |
94 { |
137 { |
95 unicode = false; |
|
96 } |
138 } |
97 |
139 |
98 SQLHANDLE hEnv; |
140 SQLHANDLE hEnv; |
99 SQLHANDLE hDbc; |
141 SQLHANDLE hDbc; |
100 |
142 |
101 uint unicode :1; |
143 bool unicode; |
102 uint useSchema :1; |
144 bool useSchema; |
103 int disconnectCount; |
145 int disconnectCount; |
104 bool isMySqlServer; |
146 bool isMySqlServer; |
105 bool isMSSqlServer; |
147 bool isMSSqlServer; |
|
148 bool isFreeTDSDriver; |
106 bool hasSQLFetchScroll; |
149 bool hasSQLFetchScroll; |
107 bool hasMultiResultSets; |
150 bool hasMultiResultSets; |
108 |
151 |
109 bool checkDriver() const; |
152 bool checkDriver() const; |
110 void checkUnicode(); |
153 void checkUnicode(); |
127 { |
170 { |
128 public: |
171 public: |
129 QODBCPrivate(QODBCDriverPrivate *dpp) |
172 QODBCPrivate(QODBCDriverPrivate *dpp) |
130 : hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false) |
173 : hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false) |
131 { |
174 { |
132 unicode = false; |
175 unicode = dpp->unicode; |
|
176 useSchema = dpp->useSchema; |
|
177 disconnectCount = dpp->disconnectCount; |
|
178 hasSQLFetchScroll = dpp->hasSQLFetchScroll; |
133 } |
179 } |
134 |
180 |
135 inline void clearValues() |
181 inline void clearValues() |
136 { fieldCache.fill(QVariant()); fieldCacheIdx = 0; } |
182 { fieldCache.fill(QVariant()); fieldCacheIdx = 0; } |
137 |
183 |
138 SQLHANDLE dpEnv() const { return driverPrivate ? driverPrivate->hEnv : 0;} |
184 SQLHANDLE dpEnv() const { return driverPrivate ? driverPrivate->hEnv : 0;} |
139 SQLHANDLE dpDbc() const { return driverPrivate ? driverPrivate->hDbc : 0;} |
185 SQLHANDLE dpDbc() const { return driverPrivate ? driverPrivate->hDbc : 0;} |
140 SQLHANDLE hStmt; |
186 SQLHANDLE hStmt; |
141 |
187 |
142 uint unicode :1; |
188 bool unicode; |
143 uint useSchema :1; |
189 bool useSchema; |
144 |
190 |
145 QSqlRecord rInf; |
191 QSqlRecord rInf; |
146 QVector<QVariant> fieldCache; |
192 QVector<QVariant> fieldCache; |
147 int fieldCacheIdx; |
193 int fieldCacheIdx; |
148 int disconnectCount; |
194 int disconnectCount; |
221 |
266 |
222 static QString qODBCWarn(const QODBCPrivate* odbc, int *nativeCode = 0) |
267 static QString qODBCWarn(const QODBCPrivate* odbc, int *nativeCode = 0) |
223 { |
268 { |
224 return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->dpEnv()) + QLatin1Char(' ') |
269 return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->dpEnv()) + QLatin1Char(' ') |
225 + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->dpDbc()) + QLatin1Char(' ') |
270 + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->dpDbc()) + QLatin1Char(' ') |
226 + qWarnODBCHandle(SQL_HANDLE_STMT, odbc->hStmt, nativeCode)); |
271 + qWarnODBCHandle(SQL_HANDLE_STMT, odbc->hStmt, nativeCode)).simplified(); |
227 } |
272 } |
228 |
273 |
229 static QString qODBCWarn(const QODBCDriverPrivate* odbc, int *nativeCode = 0) |
274 static QString qODBCWarn(const QODBCDriverPrivate* odbc, int *nativeCode = 0) |
230 { |
275 { |
231 return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1Char(' ') |
276 return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1Char(' ') |
232 + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->hDbc, nativeCode)); |
277 + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->hDbc, nativeCode)).simplified(); |
233 } |
278 } |
234 |
279 |
235 static void qSqlWarning(const QString& message, const QODBCPrivate* odbc) |
280 static void qSqlWarning(const QString& message, const QODBCPrivate* odbc) |
236 { |
281 { |
237 qWarning() << message << "\tError:" << qODBCWarn(odbc); |
282 qWarning() << message << "\tError:" << qODBCWarn(odbc); |
329 colSize = 256; |
376 colSize = 256; |
330 } else if (colSize > 65536) { // limit buffer size to 64 KB |
377 } else if (colSize > 65536) { // limit buffer size to 64 KB |
331 colSize = 65536; |
378 colSize = 65536; |
332 } else { |
379 } else { |
333 colSize++; // make sure there is room for more than the 0 termination |
380 colSize++; // make sure there is room for more than the 0 termination |
334 if (unicode) { |
381 } |
335 colSize *= 2; // a tiny bit faster, since it saves a SQLGetData() call |
382 if(unicode) { |
336 } |
|
337 } |
|
338 QVarLengthArray<char> buf(colSize); |
|
339 while (true) { |
|
340 r = SQLGetData(hStmt, |
383 r = SQLGetData(hStmt, |
341 column+1, |
384 column+1, |
342 unicode ? SQL_C_WCHAR : SQL_C_CHAR, |
385 SQL_C_TCHAR, |
343 (SQLPOINTER)buf.data(), |
386 NULL, |
344 colSize, |
387 0, |
345 &lengthIndicator); |
388 &lengthIndicator); |
346 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { |
389 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0) |
347 if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) { |
390 colSize = lengthIndicator/sizeof(SQLTCHAR) + 1; |
|
391 QVarLengthArray<SQLTCHAR> buf(colSize); |
|
392 memset(buf.data(), 0, colSize*sizeof(SQLTCHAR)); |
|
393 while (true) { |
|
394 r = SQLGetData(hStmt, |
|
395 column+1, |
|
396 SQL_C_TCHAR, |
|
397 (SQLPOINTER)buf.data(), |
|
398 colSize*sizeof(SQLTCHAR), |
|
399 &lengthIndicator); |
|
400 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { |
|
401 if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) { |
|
402 fieldVal.clear(); |
|
403 break; |
|
404 } |
|
405 // if SQL_SUCCESS_WITH_INFO is returned, indicating that |
|
406 // more data can be fetched, the length indicator does NOT |
|
407 // contain the number of bytes returned - it contains the |
|
408 // total number of bytes that CAN be fetched |
|
409 // colSize-1: remove 0 termination when there is more data to fetch |
|
410 int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR); |
|
411 fieldVal += fromSQLTCHAR(buf, rSize); |
|
412 if (lengthIndicator < (unsigned int)colSize*sizeof(SQLTCHAR)) { |
|
413 // workaround for Drivermanagers that don't return SQL_NO_DATA |
|
414 break; |
|
415 } |
|
416 } else if (r == SQL_NO_DATA) { |
|
417 break; |
|
418 } else { |
|
419 qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')'; |
348 fieldVal.clear(); |
420 fieldVal.clear(); |
349 break; |
421 break; |
350 } |
422 } |
351 // if SQL_SUCCESS_WITH_INFO is returned, indicating that |
423 } |
352 // more data can be fetched, the length indicator does NOT |
424 } else { |
353 // contain the number of bytes returned - it contains the |
425 r = SQLGetData(hStmt, |
354 // total number of bytes that CAN be fetched |
426 column+1, |
355 // colSize-1: remove 0 termination when there is more data to fetch |
427 SQL_C_CHAR, |
356 int rSize = (r == SQL_SUCCESS_WITH_INFO) ? (unicode ? colSize-2 : colSize-1) : lengthIndicator; |
428 NULL, |
357 if (unicode) { |
429 0, |
358 fieldVal += QString((const QChar*) buf.constData(), rSize / 2); |
430 &lengthIndicator); |
|
431 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0) |
|
432 colSize = lengthIndicator + 1; |
|
433 QVarLengthArray<SQLCHAR> buf(colSize); |
|
434 while (true) { |
|
435 r = SQLGetData(hStmt, |
|
436 column+1, |
|
437 SQL_C_CHAR, |
|
438 (SQLPOINTER)buf.data(), |
|
439 colSize, |
|
440 &lengthIndicator); |
|
441 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { |
|
442 if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) { |
|
443 fieldVal.clear(); |
|
444 break; |
|
445 } |
|
446 // if SQL_SUCCESS_WITH_INFO is returned, indicating that |
|
447 // more data can be fetched, the length indicator does NOT |
|
448 // contain the number of bytes returned - it contains the |
|
449 // total number of bytes that CAN be fetched |
|
450 // colSize-1: remove 0 termination when there is more data to fetch |
|
451 int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator; |
|
452 fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize); |
|
453 if (lengthIndicator < (unsigned int)colSize) { |
|
454 // workaround for Drivermanagers that don't return SQL_NO_DATA |
|
455 break; |
|
456 } |
|
457 } else if (r == SQL_NO_DATA) { |
|
458 break; |
359 } else { |
459 } else { |
360 fieldVal += QString::fromAscii(buf.constData(), rSize); |
460 qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')'; |
361 } |
461 fieldVal.clear(); |
362 memset(buf.data(), 0, colSize); |
|
363 if (lengthIndicator < colSize) { |
|
364 // workaround for Drivermanagers that don't return SQL_NO_DATA |
|
365 break; |
462 break; |
366 } |
463 } |
367 } else if (r == SQL_NO_DATA) { |
|
368 break; |
|
369 } else { |
|
370 qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')'; |
|
371 fieldVal.clear(); |
|
372 break; |
|
373 } |
464 } |
374 } |
465 } |
375 return fieldVal; |
466 return fieldVal; |
376 } |
467 } |
377 |
468 |
579 { |
671 { |
580 #ifndef Q_ODBC_VERSION_2 |
672 #ifndef Q_ODBC_VERSION_2 |
581 if (connOpts.contains(QLatin1String("SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC3"), Qt::CaseInsensitive)) |
673 if (connOpts.contains(QLatin1String("SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC3"), Qt::CaseInsensitive)) |
582 return SQL_OV_ODBC3; |
674 return SQL_OV_ODBC3; |
583 #endif |
675 #endif |
|
676 if (connOpts.contains(QLatin1String("SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC2"), Qt::CaseInsensitive)) |
|
677 return SQL_OV_ODBC2; |
|
678 #ifdef _IODBCUNIX_H |
|
679 return SQL_OV_ODBC3; |
|
680 #else |
584 return SQL_OV_ODBC2; |
681 return SQL_OV_ODBC2; |
|
682 #endif |
585 } |
683 } |
586 |
684 |
587 QChar QODBCDriverPrivate::quoteChar() |
685 QChar QODBCDriverPrivate::quoteChar() |
588 { |
686 { |
589 if (!isQuoteInitialized) { |
687 if (!isQuoteInitialized) { |
590 char driverResponse[4]; |
688 SQLTCHAR driverResponse[4]; |
591 SQLSMALLINT length; |
689 SQLSMALLINT length; |
592 int r = SQLGetInfo(hDbc, |
690 int r = SQLGetInfo(hDbc, |
593 SQL_IDENTIFIER_QUOTE_CHAR, |
691 SQL_IDENTIFIER_QUOTE_CHAR, |
594 &driverResponse, |
692 &driverResponse, |
595 sizeof(driverResponse), |
693 sizeof(driverResponse), |
596 &length); |
694 &length); |
597 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { |
695 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) |
|
696 #ifdef UNICODE |
|
697 quote = QChar(driverResponse[0]); |
|
698 #else |
598 quote = QLatin1Char(driverResponse[0]); |
699 quote = QLatin1Char(driverResponse[0]); |
599 } else { |
700 #endif |
|
701 else |
600 quote = QLatin1Char('"'); |
702 quote = QLatin1Char('"'); |
601 } |
|
602 isQuoteInitialized = true; |
703 isQuoteInitialized = true; |
603 } |
704 } |
604 return quote; |
705 return quote; |
605 } |
706 } |
606 |
707 |
640 r = SQLSetConnectAttr(hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0); |
741 r = SQLSetConnectAttr(hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0); |
641 } else if (opt.toUpper() == QLatin1String("SQL_ATTR_CURRENT_CATALOG")) { |
742 } else if (opt.toUpper() == QLatin1String("SQL_ATTR_CURRENT_CATALOG")) { |
642 val.utf16(); // 0 terminate |
743 val.utf16(); // 0 terminate |
643 r = SQLSetConnectAttr(hDbc, SQL_ATTR_CURRENT_CATALOG, |
744 r = SQLSetConnectAttr(hDbc, SQL_ATTR_CURRENT_CATALOG, |
644 #ifdef UNICODE |
745 #ifdef UNICODE |
645 (SQLWCHAR*) val.unicode(), |
746 toSQLTCHAR(val).data(), |
646 #else |
747 #else |
647 (SQLCHAR*) val.toLatin1().constData(), |
748 (SQLCHAR*) val.toUtf8().data(), |
648 #endif |
749 #endif |
649 SQL_NTS); |
750 val.length()*sizeof(SQLTCHAR)); |
650 } else if (opt.toUpper() == QLatin1String("SQL_ATTR_METADATA_ID")) { |
751 } else if (opt.toUpper() == QLatin1String("SQL_ATTR_METADATA_ID")) { |
651 if (val.toUpper() == QLatin1String("SQL_TRUE")) { |
752 if (val.toUpper() == QLatin1String("SQL_TRUE")) { |
652 v = SQL_TRUE; |
753 v = SQL_TRUE; |
653 } else if (val.toUpper() == QLatin1String("SQL_FALSE")) { |
754 } else if (val.toUpper() == QLatin1String("SQL_FALSE")) { |
654 v = SQL_FALSE; |
755 v = SQL_FALSE; |
662 r = SQLSetConnectAttr(hDbc, SQL_ATTR_PACKET_SIZE, (SQLPOINTER) v, 0); |
763 r = SQLSetConnectAttr(hDbc, SQL_ATTR_PACKET_SIZE, (SQLPOINTER) v, 0); |
663 } else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACEFILE")) { |
764 } else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACEFILE")) { |
664 val.utf16(); // 0 terminate |
765 val.utf16(); // 0 terminate |
665 r = SQLSetConnectAttr(hDbc, SQL_ATTR_TRACEFILE, |
766 r = SQLSetConnectAttr(hDbc, SQL_ATTR_TRACEFILE, |
666 #ifdef UNICODE |
767 #ifdef UNICODE |
667 (SQLWCHAR*) val.unicode(), |
768 toSQLTCHAR(val).data(), |
668 #else |
769 #else |
669 (SQLCHAR*) val.toLatin1().constData(), |
770 (SQLCHAR*) val.toUtf8().data(), |
670 #endif |
771 #endif |
671 SQL_NTS); |
772 val.length()*sizeof(SQLTCHAR)); |
672 } else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACE")) { |
773 } else if (opt.toUpper() == QLatin1String("SQL_ATTR_TRACE")) { |
673 if (val.toUpper() == QLatin1String("SQL_OPT_TRACE_OFF")) { |
774 if (val.toUpper() == QLatin1String("SQL_OPT_TRACE_OFF")) { |
674 v = SQL_OPT_TRACE_OFF; |
775 v = SQL_OPT_TRACE_OFF; |
675 } else if (val.toUpper() == QLatin1String("SQL_OPT_TRACE_ON")) { |
776 } else if (val.toUpper() == QLatin1String("SQL_OPT_TRACE_ON")) { |
676 v = SQL_OPT_TRACE_ON; |
777 v = SQL_OPT_TRACE_ON; |
878 return false; |
975 return false; |
879 } |
976 } |
880 |
977 |
881 #ifdef UNICODE |
978 #ifdef UNICODE |
882 r = SQLExecDirect(d->hStmt, |
979 r = SQLExecDirect(d->hStmt, |
883 (SQLWCHAR*) query.unicode(), |
980 toSQLTCHAR(query).data(), |
884 (SQLINTEGER) query.length()); |
981 (SQLINTEGER) query.length()); |
885 #else |
982 #else |
886 QByteArray query8 = query.toLocal8Bit(); |
983 QByteArray query8 = query.toUtf8(); |
887 r = SQLExecDirect(d->hStmt, |
984 r = SQLExecDirect(d->hStmt, |
888 (SQLCHAR*) query8.constData(), |
985 (SQLCHAR*) query8.data(), |
889 (SQLINTEGER) query8.length()); |
986 (SQLINTEGER) query8.length()); |
890 #endif |
987 #endif |
891 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { |
988 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r!= SQL_NO_DATA) { |
892 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", |
989 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", |
893 "Unable to execute statement"), QSqlError::StatementError, d)); |
990 "Unable to execute statement"), QSqlError::StatementError, d)); |
894 return false; |
991 return false; |
|
992 } |
|
993 |
|
994 if(r == SQL_NO_DATA) { |
|
995 setSelect(false); |
|
996 return true; |
895 } |
997 } |
896 |
998 |
897 SQLINTEGER isScrollable, bufferLength; |
999 SQLINTEGER isScrollable, bufferLength; |
898 r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, &bufferLength); |
1000 r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, &bufferLength); |
899 if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) |
1001 if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) |
1224 return false; |
1326 return false; |
1225 } |
1327 } |
1226 |
1328 |
1227 #ifdef UNICODE |
1329 #ifdef UNICODE |
1228 r = SQLPrepare(d->hStmt, |
1330 r = SQLPrepare(d->hStmt, |
1229 (SQLWCHAR*) query.unicode(), |
1331 toSQLTCHAR(query).data(), |
1230 (SQLINTEGER) query.length()); |
1332 (SQLINTEGER) query.length()); |
1231 #else |
1333 #else |
1232 QByteArray query8 = query.toLocal8Bit(); |
1334 QByteArray query8 = query.toUtf8(); |
1233 r = SQLPrepare(d->hStmt, |
1335 r = SQLPrepare(d->hStmt, |
1234 (SQLCHAR*) query8.constData(), |
1336 (SQLCHAR*) query8.data(), |
1235 (SQLINTEGER) query8.length()); |
1337 (SQLINTEGER) query8.length()); |
1236 #endif |
1338 #endif |
1237 |
1339 |
1238 if (r != SQL_SUCCESS) { |
1340 if (r != SQL_SUCCESS) { |
1239 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", |
1341 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", |
1428 break; |
1530 break; |
1429 case QVariant::String: |
1531 case QVariant::String: |
1430 #ifndef Q_ODBC_VERSION_2 |
1532 #ifndef Q_ODBC_VERSION_2 |
1431 if (d->unicode) { |
1533 if (d->unicode) { |
1432 QString str = val.toString(); |
1534 QString str = val.toString(); |
1433 str.utf16(); |
|
1434 if (*ind != SQL_NULL_DATA) |
1535 if (*ind != SQL_NULL_DATA) |
1435 *ind = str.length() * sizeof(QChar); |
1536 *ind = str.length() * sizeof(SQLTCHAR); |
1436 int strSize = str.length() * sizeof(QChar); |
1537 int strSize = str.length() * sizeof(SQLTCHAR); |
1437 |
1538 |
1438 if (bindValueType(i) & QSql::Out) { |
1539 if (bindValueType(i) & QSql::Out) { |
1439 QByteArray ba((char*)str.constData(), str.capacity() * sizeof(QChar)); |
1540 QVarLengthArray<SQLTCHAR> ba(toSQLTCHAR(str)); |
|
1541 ba.reserve(str.capacity()); |
1440 r = SQLBindParameter(d->hStmt, |
1542 r = SQLBindParameter(d->hStmt, |
1441 i + 1, |
1543 i + 1, |
1442 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], |
1544 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], |
1443 SQL_C_WCHAR, |
1545 SQL_C_TCHAR, |
1444 strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, |
1546 strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, |
1445 0, // god knows... don't change this! |
1547 0, // god knows... don't change this! |
1446 0, |
1548 0, |
1447 (void *)ba.constData(), |
1549 (void *)ba.constData(), |
1448 ba.size(), |
1550 ba.size(), |
1449 ind); |
1551 ind); |
1450 tmpStorage.append(ba); |
1552 tmpStorage.append(QByteArray((const char *)ba.constData(), ba.size()*sizeof(SQLTCHAR))); |
1451 break; |
1553 break; |
1452 } |
1554 } |
1453 |
1555 QByteArray strba((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR)); |
1454 r = SQLBindParameter(d->hStmt, |
1556 r = SQLBindParameter(d->hStmt, |
1455 i + 1, |
1557 i + 1, |
1456 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], |
1558 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], |
1457 SQL_C_WCHAR, |
1559 SQL_C_TCHAR, |
1458 strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, |
1560 strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, |
1459 strSize, |
1561 strSize, |
1460 0, |
1562 0, |
1461 (void *)str.constData(), |
1563 (SQLPOINTER)strba.constData(), |
1462 strSize, |
1564 strba.size(), |
1463 ind); |
1565 ind); |
|
1566 tmpStorage.append(strba); |
1464 break; |
1567 break; |
1465 } |
1568 } |
1466 else |
1569 else |
1467 #endif |
1570 #endif |
1468 { |
1571 { |
1469 QByteArray str = val.toString().toAscii(); |
1572 QByteArray str = val.toString().toUtf8(); |
1470 if (*ind != SQL_NULL_DATA) |
1573 if (*ind != SQL_NULL_DATA) |
1471 *ind = str.length(); |
1574 *ind = str.length(); |
1472 int strSize = str.length(); |
1575 int strSize = str.length(); |
1473 |
1576 |
1474 r = SQLBindParameter(d->hStmt, |
1577 r = SQLBindParameter(d->hStmt, |
1565 case QVariant::ULongLong: |
1668 case QVariant::ULongLong: |
1566 //nothing to do |
1669 //nothing to do |
1567 break; |
1670 break; |
1568 case QVariant::String: |
1671 case QVariant::String: |
1569 if (d->unicode) { |
1672 if (d->unicode) { |
1570 if (bindValueType(i) & QSql::Out) |
1673 if (bindValueType(i) & QSql::Out) { |
1571 values[i] = QString::fromUtf16((ushort*)tmpStorage.takeFirst().constData()); |
1674 QByteArray first = tmpStorage.takeFirst(); |
|
1675 QVarLengthArray<SQLTCHAR> array; |
|
1676 array.append((SQLTCHAR *)first.constData(), first.size()); |
|
1677 values[i] = fromSQLTCHAR(array, first.size()/sizeof(SQLTCHAR*)); |
|
1678 } |
1572 break; |
1679 break; |
1573 } |
1680 } |
1574 // fall through |
1681 // fall through |
1575 default: { |
1682 default: { |
1576 QByteArray ba = tmpStorage.takeFirst(); |
|
1577 if (bindValueType(i) & QSql::Out) |
1683 if (bindValueType(i) & QSql::Out) |
1578 values[i] = QString::fromAscii(ba.constData()); |
1684 values[i] = tmpStorage.takeFirst(); |
1579 break; } |
1685 break; } |
1580 } |
1686 } |
1581 if (indicators[i] == SQL_NULL_DATA) |
1687 if (indicators[i] == SQL_NULL_DATA) |
1582 values[i] = QVariant(values[i].type()); |
1688 values[i] = QVariant(values[i].type()); |
1583 } |
1689 } |
1782 connQStr += QLatin1String(";UID=") + user; |
1888 connQStr += QLatin1String(";UID=") + user; |
1783 if (!password.isEmpty()) |
1889 if (!password.isEmpty()) |
1784 connQStr += QLatin1String(";PWD=") + password; |
1890 connQStr += QLatin1String(";PWD=") + password; |
1785 |
1891 |
1786 SQLSMALLINT cb; |
1892 SQLSMALLINT cb; |
1787 SQLTCHAR connOut[1024]; |
1893 QVarLengthArray<SQLTCHAR> connOut(1024); |
|
1894 memset(connOut.data(), 0, connOut.size() * sizeof(SQLTCHAR)); |
1788 r = SQLDriverConnect(d->hDbc, |
1895 r = SQLDriverConnect(d->hDbc, |
1789 NULL, |
1896 NULL, |
1790 #ifdef UNICODE |
1897 #ifdef UNICODE |
1791 (SQLWCHAR*)connQStr.unicode(), |
1898 toSQLTCHAR(connQStr).data(), |
1792 #else |
1899 #else |
1793 (SQLCHAR*)connQStr.toLatin1().constData(), |
1900 (SQLCHAR*)connQStr.toUtf8().data(), |
1794 #endif |
1901 #endif |
1795 (SQLSMALLINT)connQStr.length(), |
1902 (SQLSMALLINT)connQStr.length(), |
1796 connOut, |
1903 connOut.data(), |
1797 1024, |
1904 1024, |
1798 &cb, |
1905 &cb, |
1799 SQL_DRIVER_NOPROMPT); |
1906 /*SQL_DRIVER_NOPROMPT*/0); |
|
1907 |
1800 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { |
1908 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { |
1801 setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d)); |
1909 setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d)); |
1802 setOpenError(true); |
1910 setOpenError(true); |
1803 return false; |
1911 return false; |
1804 } |
1912 } |
1879 (SQLPOINTER)&fFunc, |
1987 (SQLPOINTER)&fFunc, |
1880 sizeof(fFunc), |
1988 sizeof(fFunc), |
1881 NULL); |
1989 NULL); |
1882 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WCHAR)) { |
1990 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WCHAR)) { |
1883 unicode = true; |
1991 unicode = true; |
|
1992 return; |
1884 } |
1993 } |
1885 |
1994 |
1886 r = SQLGetInfo(hDbc, |
1995 r = SQLGetInfo(hDbc, |
1887 SQL_CONVERT_VARCHAR, |
1996 SQL_CONVERT_VARCHAR, |
1888 (SQLPOINTER)&fFunc, |
1997 (SQLPOINTER)&fFunc, |
1889 sizeof(fFunc), |
1998 sizeof(fFunc), |
1890 NULL); |
1999 NULL); |
1891 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WVARCHAR)) { |
2000 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WVARCHAR)) { |
1892 unicode = true; |
2001 unicode = true; |
|
2002 return; |
1893 } |
2003 } |
1894 |
2004 |
1895 r = SQLGetInfo(hDbc, |
2005 r = SQLGetInfo(hDbc, |
1896 SQL_CONVERT_LONGVARCHAR, |
2006 SQL_CONVERT_LONGVARCHAR, |
1897 (SQLPOINTER)&fFunc, |
2007 (SQLPOINTER)&fFunc, |
1898 sizeof(fFunc), |
2008 sizeof(fFunc), |
1899 NULL); |
2009 NULL); |
1900 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WLONGVARCHAR)) { |
2010 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WLONGVARCHAR)) { |
1901 unicode = true; |
2011 unicode = true; |
1902 } |
2012 return; |
|
2013 } |
|
2014 SQLHANDLE hStmt; |
|
2015 r = SQLAllocHandle(SQL_HANDLE_STMT, |
|
2016 hDbc, |
|
2017 &hStmt); |
|
2018 |
|
2019 r = SQLExecDirect(hStmt, toSQLTCHAR(QLatin1String("select 'test'")).data(), SQL_NTS); |
|
2020 if(r == SQL_SUCCESS) { |
|
2021 r = SQLFetch(hStmt); |
|
2022 if(r == SQL_SUCCESS) { |
|
2023 QVarLengthArray<SQLWCHAR> buffer(10); |
|
2024 r = SQLGetData(hStmt, 1, SQL_C_WCHAR, buffer.data(), buffer.size() * sizeof(SQLWCHAR), NULL); |
|
2025 if(r == SQL_SUCCESS && fromSQLTCHAR(buffer) == QLatin1String("test")) { |
|
2026 unicode = true; |
|
2027 } |
|
2028 } |
|
2029 } |
|
2030 r = SQLFreeHandle(SQL_HANDLE_STMT, hStmt); |
1903 } |
2031 } |
1904 |
2032 |
1905 bool QODBCDriverPrivate::checkDriver() const |
2033 bool QODBCDriverPrivate::checkDriver() const |
1906 { |
2034 { |
1907 #ifdef ODBC_CHECK_DRIVER |
2035 #ifdef ODBC_CHECK_DRIVER |
1970 } |
2098 } |
1971 |
2099 |
1972 void QODBCDriverPrivate::checkSqlServer() |
2100 void QODBCDriverPrivate::checkSqlServer() |
1973 { |
2101 { |
1974 SQLRETURN r; |
2102 SQLRETURN r; |
1975 char serverString[200]; |
2103 QVarLengthArray<SQLTCHAR> serverString(200); |
1976 SQLSMALLINT t; |
2104 SQLSMALLINT t; |
|
2105 memset(serverString.data(), 0, serverString.size() * sizeof(SQLTCHAR)); |
1977 |
2106 |
1978 r = SQLGetInfo(hDbc, |
2107 r = SQLGetInfo(hDbc, |
1979 SQL_DBMS_NAME, |
2108 SQL_DBMS_NAME, |
1980 serverString, |
2109 serverString.data(), |
1981 sizeof(serverString), |
2110 serverString.size() * sizeof(SQLTCHAR), |
1982 &t); |
2111 &t); |
1983 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { |
2112 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { |
1984 QString serverType; |
2113 QString serverType; |
1985 #ifdef UNICODE |
2114 #ifdef UNICODE |
1986 serverType = QString(reinterpret_cast<const QChar*>(serverString), t/sizeof(QChar)); |
2115 serverType = fromSQLTCHAR(serverString, t/sizeof(SQLTCHAR)); |
1987 #else |
2116 #else |
1988 serverType = QString::fromLocal8Bit(serverString, t); |
2117 serverType = QString::fromUtf8((const char *)serverString.constData(), t); |
1989 #endif |
2118 #endif |
1990 isMySqlServer = serverType.contains(QLatin1String("mysql"), Qt::CaseInsensitive); |
2119 isMySqlServer = serverType.contains(QLatin1String("mysql"), Qt::CaseInsensitive); |
1991 isMSSqlServer = serverType.contains(QLatin1String("Microsoft SQL Server"), Qt::CaseInsensitive); |
2120 isMSSqlServer = serverType.contains(QLatin1String("Microsoft SQL Server"), Qt::CaseInsensitive); |
|
2121 } |
|
2122 r = SQLGetInfo(hDbc, |
|
2123 SQL_DRIVER_NAME, |
|
2124 serverString.data(), |
|
2125 serverString.size() * sizeof(SQLTCHAR), |
|
2126 &t); |
|
2127 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { |
|
2128 QString serverType; |
|
2129 #ifdef UNICODE |
|
2130 serverType = fromSQLTCHAR(serverString, t/sizeof(SQLTCHAR)); |
|
2131 #else |
|
2132 serverType = QString::fromUtf8((const char *)serverString.constData(), t); |
|
2133 #endif |
|
2134 isFreeTDSDriver = serverType.contains(QLatin1String("tdsodbc"), Qt::CaseInsensitive); |
|
2135 unicode = isFreeTDSDriver == false; |
1992 } |
2136 } |
1993 } |
2137 } |
1994 |
2138 |
1995 void QODBCDriverPrivate::checkHasSQLFetchScroll() |
2139 void QODBCDriverPrivate::checkHasSQLFetchScroll() |
1996 { |
2140 { |
2002 } |
2146 } |
2003 } |
2147 } |
2004 |
2148 |
2005 void QODBCDriverPrivate::checkHasMultiResults() |
2149 void QODBCDriverPrivate::checkHasMultiResults() |
2006 { |
2150 { |
2007 char driverResponse[4]; |
2151 QVarLengthArray<SQLTCHAR> driverResponse(2); |
2008 SQLSMALLINT length; |
2152 SQLSMALLINT length; |
2009 SQLRETURN r = SQLGetInfo(hDbc, |
2153 SQLRETURN r = SQLGetInfo(hDbc, |
2010 SQL_MULT_RESULT_SETS, |
2154 SQL_MULT_RESULT_SETS, |
2011 driverResponse, |
2155 driverResponse.data(), |
2012 sizeof(driverResponse), |
2156 driverResponse.size() * sizeof(SQLTCHAR), |
2013 &length); |
2157 &length); |
2014 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) |
2158 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) |
2015 #ifdef UNICODE |
2159 #ifdef UNICODE |
2016 hasMultiResultSets = QString(reinterpret_cast<const QChar*>(driverResponse), length/sizeof(QChar)).startsWith(QLatin1Char('Y')); |
2160 hasMultiResultSets = fromSQLTCHAR(driverResponse, length/sizeof(SQLTCHAR)).startsWith(QLatin1Char('Y')); |
2017 #else |
2161 #else |
2018 hasMultiResultSets = QString::fromLocal8Bit(driverResponse, length).startsWith(QLatin1Char('Y')); |
2162 hasMultiResultSets = QString::fromUtf8((const char *)driverResponse.constData(), length).startsWith(QLatin1Char('Y')); |
2019 #endif |
2163 #endif |
2020 } |
2164 } |
2021 |
2165 |
2022 QSqlResult *QODBCDriver::createResult() const |
2166 QSqlResult *QODBCDriver::createResult() const |
2023 { |
2167 { |
2142 r = SQLFetchScroll(hStmt, |
2286 r = SQLFetchScroll(hStmt, |
2143 SQL_FETCH_NEXT, |
2287 SQL_FETCH_NEXT, |
2144 0); |
2288 0); |
2145 else |
2289 else |
2146 r = SQLFetch(hStmt); |
2290 r = SQLFetch(hStmt); |
|
2291 |
|
2292 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r != SQL_NO_DATA) { |
|
2293 qWarning() << "QODBCDriver::tables failed to retrieve table/view list: (" << r << "," << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ")"; |
|
2294 return QStringList(); |
|
2295 } |
2147 |
2296 |
2148 while (r == SQL_SUCCESS) { |
2297 while (r == SQL_SUCCESS) { |
2149 QString fieldVal = qGetStringData(hStmt, 2, -1, false); |
2298 QString fieldVal = qGetStringData(hStmt, 2, -1, false); |
2150 tl.append(fieldVal); |
2299 tl.append(fieldVal); |
2151 |
2300 |
2201 SQL_ATTR_CURSOR_TYPE, |
2350 SQL_ATTR_CURSOR_TYPE, |
2202 (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, |
2351 (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, |
2203 SQL_IS_UINTEGER); |
2352 SQL_IS_UINTEGER); |
2204 r = SQLPrimaryKeys(hStmt, |
2353 r = SQLPrimaryKeys(hStmt, |
2205 #ifdef UNICODE |
2354 #ifdef UNICODE |
2206 catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(), |
2355 catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(), |
2207 #else |
2356 #else |
2208 catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toLatin1().constData(), |
2357 catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toUtf8().data(), |
2209 #endif |
2358 #endif |
2210 catalog.length(), |
2359 catalog.length(), |
2211 #ifdef UNICODE |
2360 #ifdef UNICODE |
2212 schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(), |
2361 schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(), |
2213 #else |
2362 #else |
2214 schema.length() == 0 ? NULL : (SQLCHAR*)schema.toLatin1().constData(), |
2363 schema.length() == 0 ? NULL : (SQLCHAR*)schema.toUtf8().data(), |
2215 #endif |
2364 #endif |
2216 schema.length(), |
2365 schema.length(), |
2217 #ifdef UNICODE |
2366 #ifdef UNICODE |
2218 (SQLWCHAR*)table.unicode(), |
2367 toSQLTCHAR(table).data(), |
2219 #else |
2368 #else |
2220 (SQLCHAR*)table.toLatin1().constData(), |
2369 (SQLCHAR*)table.toUtf8().data(), |
2221 #endif |
2370 #endif |
2222 table.length() /* in characters, not in bytes */); |
2371 table.length() /* in characters, not in bytes */); |
2223 |
2372 |
2224 // if the SQLPrimaryKeys() call does not succeed (e.g the driver |
2373 // if the SQLPrimaryKeys() call does not succeed (e.g the driver |
2225 // does not support it) - try an alternative method to get hold of |
2374 // does not support it) - try an alternative method to get hold of |
2226 // the primary index (e.g MS Access and FoxPro) |
2375 // the primary index (e.g MS Access and FoxPro) |
2227 if (r != SQL_SUCCESS) { |
2376 if (r != SQL_SUCCESS) { |
2228 r = SQLSpecialColumns(hStmt, |
2377 r = SQLSpecialColumns(hStmt, |
2229 SQL_BEST_ROWID, |
2378 SQL_BEST_ROWID, |
2230 #ifdef UNICODE |
2379 #ifdef UNICODE |
2231 catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(), |
2380 catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(), |
2232 #else |
2381 #else |
2233 catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toLatin1().constData(), |
2382 catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toUtf8().data(), |
2234 #endif |
2383 #endif |
2235 catalog.length(), |
2384 catalog.length(), |
2236 #ifdef UNICODE |
2385 #ifdef UNICODE |
2237 schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(), |
2386 schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(), |
2238 #else |
2387 #else |
2239 schema.length() == 0 ? NULL : (SQLCHAR*)schema.toLatin1().constData(), |
2388 schema.length() == 0 ? NULL : (SQLCHAR*)schema.toUtf8().data(), |
2240 #endif |
2389 #endif |
2241 schema.length(), |
2390 schema.length(), |
2242 #ifdef UNICODE |
2391 #ifdef UNICODE |
2243 (SQLWCHAR*)table.unicode(), |
2392 toSQLTCHAR(table).data(), |
2244 #else |
2393 #else |
2245 (SQLCHAR*)table.toLatin1().constData(), |
2394 (SQLCHAR*)table.toUtf8().data(), |
2246 #endif |
2395 #endif |
2247 table.length(), |
2396 table.length(), |
2248 SQL_SCOPE_CURROW, |
2397 SQL_SCOPE_CURROW, |
2249 SQL_NULLABLE); |
2398 SQL_NULLABLE); |
2250 |
2399 |
2326 SQL_ATTR_CURSOR_TYPE, |
2475 SQL_ATTR_CURSOR_TYPE, |
2327 (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, |
2476 (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, |
2328 SQL_IS_UINTEGER); |
2477 SQL_IS_UINTEGER); |
2329 r = SQLColumns(hStmt, |
2478 r = SQLColumns(hStmt, |
2330 #ifdef UNICODE |
2479 #ifdef UNICODE |
2331 catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(), |
2480 catalog.length() == 0 ? NULL : toSQLTCHAR(catalog).data(), |
2332 #else |
2481 #else |
2333 catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toLatin1().constData(), |
2482 catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.toUtf8().data(), |
2334 #endif |
2483 #endif |
2335 catalog.length(), |
2484 catalog.length(), |
2336 #ifdef UNICODE |
2485 #ifdef UNICODE |
2337 schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(), |
2486 schema.length() == 0 ? NULL : toSQLTCHAR(schema).data(), |
2338 #else |
2487 #else |
2339 schema.length() == 0 ? NULL : (SQLCHAR*)schema.toLatin1().constData(), |
2488 schema.length() == 0 ? NULL : (SQLCHAR*)schema.toUtf8().data(), |
2340 #endif |
2489 #endif |
2341 schema.length(), |
2490 schema.length(), |
2342 #ifdef UNICODE |
2491 #ifdef UNICODE |
2343 (SQLWCHAR*)table.unicode(), |
2492 toSQLTCHAR(table).data(), |
2344 #else |
2493 #else |
2345 (SQLCHAR*)table.toLatin1().constData(), |
2494 (SQLCHAR*)table.toUtf8().data(), |
2346 #endif |
2495 #endif |
2347 table.length(), |
2496 table.length(), |
2348 NULL, |
2497 NULL, |
2349 0); |
2498 0); |
2350 if (r != SQL_SUCCESS) |
2499 if (r != SQL_SUCCESS) |