17#if defined(Q_OS_WIN32)
18# include <QtCore/qt_windows.h>
20#include <QtSql/private/qsqlresult_p.h>
21#include <QtSql/private/qsqldriver_p.h>
24#define MIMER_DEFAULT_DATATYPE 1000
36enum class MimerColumnTypes {
75 bool fetch(
int i)
override;
86 bool execBatch(
bool arrayBind =
false)
override;
144 str_len = (rc = MimerGetError(
p->sessionhandle, &e_code, NULL, 0)) + 1;
145 if (!MIMER_SUCCEEDED(rc)) {
149 QVarLengthArray<wchar_t> tmp_buff((
qsizetype)str_len);
150 if (!MIMER_SUCCEEDED(
151 rc = MimerGetError(
p->sessionhandle, &e_code, tmp_buff.data(), str_len)))
187 d->sessionhandle = *conn;
211 case MIMER_BINARY_VARYING:
212 return MimerColumnTypes::Binary;
214 case MIMER_NATIVE_BLOB:
215 return MimerColumnTypes::Blob;
218 case MIMER_NATIVE_CLOB:
219 case MIMER_NATIVE_NCLOB:
220 return MimerColumnTypes::Clob;
222 return MimerColumnTypes::Date;
224 return MimerColumnTypes::Time;
225 case MIMER_TIMESTAMP:
226 return MimerColumnTypes::Timestamp;
227 case MIMER_INTERVAL_DAY:
228 case MIMER_INTERVAL_DAY_TO_HOUR:
229 case MIMER_INTERVAL_DAY_TO_MINUTE:
230 case MIMER_INTERVAL_DAY_TO_SECOND:
231 case MIMER_INTERVAL_HOUR:
232 case MIMER_INTERVAL_HOUR_TO_MINUTE:
233 case MIMER_INTERVAL_HOUR_TO_SECOND:
234 case MIMER_INTERVAL_MINUTE:
235 case MIMER_INTERVAL_MINUTE_TO_SECOND:
236 case MIMER_INTERVAL_MONTH:
237 case MIMER_INTERVAL_SECOND:
238 case MIMER_INTERVAL_YEAR:
239 case MIMER_INTERVAL_YEAR_TO_MONTH:
241 case MIMER_CHARACTER:
242 case MIMER_CHARACTER_VARYING:
243 case MIMER_NCHAR_VARYING:
246 return MimerColumnTypes::String;
250 return MimerColumnTypes::Numeric;
252 return MimerColumnTypes::Boolean;
254 case MIMER_T_UNSIGNED_BIGINT:
255 case MIMER_NATIVE_BIGINT_NULLABLE:
256 case MIMER_NATIVE_BIGINT:
257 return MimerColumnTypes::Long;
258 case MIMER_NATIVE_REAL_NULLABLE:
259 case MIMER_NATIVE_REAL:
261 return MimerColumnTypes::Float;
263 case MIMER_NATIVE_DOUBLE_NULLABLE:
264 case MIMER_NATIVE_DOUBLE:
266 return MimerColumnTypes::Double;
267 case MIMER_NATIVE_INTEGER:
268 case MIMER_NATIVE_INTEGER_NULLABLE:
269 case MIMER_NATIVE_SMALLINT_NULLABLE:
270 case MIMER_NATIVE_SMALLINT:
271 case MIMER_T_INTEGER:
272 case MIMER_T_SMALLINT:
273 return MimerColumnTypes::Int;
275 return MimerColumnTypes::Uuid;
277 qCWarning(lcMimer) <<
"QMimerSQLDriver::mimerMapColumnTypes: Unknown data type:" <<
t;
279 return MimerColumnTypes::Unknown;
286 case MIMER_BINARY_VARYING:
288 case MIMER_NATIVE_BLOB:
289 return QMetaType::QByteArray;
292 case MIMER_NATIVE_CLOB:
293 case MIMER_NATIVE_NCLOB:
294 case MIMER_INTERVAL_DAY:
296 case MIMER_INTERVAL_DAY_TO_HOUR:
297 case MIMER_INTERVAL_DAY_TO_MINUTE:
298 case MIMER_INTERVAL_DAY_TO_SECOND:
299 case MIMER_INTERVAL_HOUR:
300 case MIMER_INTERVAL_HOUR_TO_MINUTE:
301 case MIMER_INTERVAL_HOUR_TO_SECOND:
302 case MIMER_INTERVAL_MINUTE:
303 case MIMER_INTERVAL_MINUTE_TO_SECOND:
304 case MIMER_INTERVAL_MONTH:
305 case MIMER_INTERVAL_SECOND:
306 case MIMER_INTERVAL_YEAR:
307 case MIMER_INTERVAL_YEAR_TO_MONTH:
309 case MIMER_CHARACTER:
310 case MIMER_CHARACTER_VARYING:
311 case MIMER_NCHAR_VARYING:
316 return QMetaType::QString;
318 return QMetaType::Bool;
320 case MIMER_T_UNSIGNED_BIGINT:
321 case MIMER_NATIVE_BIGINT_NULLABLE:
322 case MIMER_NATIVE_BIGINT:
323 return QMetaType::LongLong;
324 case MIMER_NATIVE_REAL_NULLABLE:
325 case MIMER_NATIVE_REAL:
327 return QMetaType::Float;
329 case MIMER_NATIVE_DOUBLE_NULLABLE:
330 case MIMER_NATIVE_DOUBLE:
332 return QMetaType::Double;
333 case MIMER_NATIVE_INTEGER_NULLABLE:
334 case MIMER_T_INTEGER:
335 case MIMER_NATIVE_INTEGER:
336 return QMetaType::Int;
337 case MIMER_NATIVE_SMALLINT_NULLABLE:
338 case MIMER_T_SMALLINT:
339 return QMetaType::Int;
341 return QMetaType::QDate;
343 return QMetaType::QTime;
345 case MIMER_TIMESTAMP:
346 return QMetaType::QDateTime;
348 return QMetaType::QUuid;
350 qCWarning(lcMimer) <<
"QMimerSQLDriver::qDecodeMSQLType: Unknown data type:" <<
t;
359 if (
s == u
"BINARY VARYING")
360 return MIMER_BINARY_VARYING;
361 if (
s == u
"BINARY LARGE OBJECT")
363 if (
s == u
"CHARACTER LARGE OBJECT")
365 if (
s == u
"NATIONAL CHAR LARGE OBJECT")
367 if (
s == u
"INTERVAL DAY")
368 return MIMER_INTERVAL_DAY;
370 return MIMER_DECIMAL;
371 if (
s == u
"INTERVAL DAY TO HOUR")
372 return MIMER_INTERVAL_DAY_TO_HOUR;
373 if (
s == u
"INTERVAL DAY TO MINUTE")
374 return MIMER_INTERVAL_DAY_TO_MINUTE;
375 if (
s == u
"INTERVAL DAY TO SECOND")
376 return MIMER_INTERVAL_DAY_TO_SECOND;
377 if (
s == u
"INTERVAL HOUR")
378 return MIMER_INTERVAL_HOUR;
379 if (
s == u
"INTERVAL HOUR TO MINUTE")
380 return MIMER_INTERVAL_HOUR_TO_MINUTE;
381 if (
s == u
"INTERVAL HOUR TO SECOND")
382 return MIMER_INTERVAL_HOUR_TO_SECOND;
383 if (
s == u
"INTERVAL MINUTE")
384 return MIMER_INTERVAL_MINUTE;
385 if (
s == u
"INTERVAL MINUTE TO SECOND")
386 return MIMER_INTERVAL_MINUTE_TO_SECOND;
387 if (
s == u
"INTERVAL MONTH")
388 return MIMER_INTERVAL_MONTH;
389 if (
s == u
"INTERVAL SECOND")
390 return MIMER_INTERVAL_SECOND;
391 if (
s == u
"INTERVAL YEAR")
392 return MIMER_INTERVAL_YEAR;
393 if (
s == u
"INTERVAL YEAR TO MONTH")
394 return MIMER_INTERVAL_YEAR_TO_MONTH;
395 if (
s == u
"NATIONAL CHARACTER")
397 if (
s == u
"CHARACTER")
398 return MIMER_CHARACTER;
399 if (
s == u
"CHARACTER VARYING")
400 return MIMER_CHARACTER_VARYING;
401 if (
s == u
"NATIONAL CHARACTER VARYING")
402 return MIMER_NCHAR_VARYING;
406 return MIMER_BOOLEAN;
408 return MIMER_T_BIGINT;
412 return MIMER_T_FLOAT;
413 if (
s == u
"DOUBLE PRECISION")
414 return MIMER_T_DOUBLE;
416 return MIMER_T_INTEGER;
417 if (
s == u
"SMALLINT")
418 return MIMER_T_SMALLINT;
423 if (
s == u
"TIMESTAMP")
424 return MIMER_TIMESTAMP;
425 if (
s == u
"BUILTIN.UUID")
427 if (
s == u
"USER-DEFINED")
429 qCWarning(lcMimer) <<
"QMimerSQLDriver::qLookupMimDataType: Unhandled data type:" <<
s;
439void QMimerSQLResult::cleanup()
443 d->openCursor =
false;
444 d->openStatement =
false;
448 const int32_t err = MimerCloseCursor(
d->statementhandle);
449 if (!MIMER_SUCCEEDED(err))
453 d->openCursor =
false;
455 if (
d->openStatement) {
456 const int32_t err = MimerEndStatement(&
d->statementhandle);
457 if (!MIMER_SUCCEEDED(err))
461 d->openStatement =
false;
466qint64 QMimerSQLResult::currentRow()
469 return d->currentRow;
490 }
while (rc && currentRow() <
i);
493 err = MimerFetchScroll(
d->statementhandle, MIMER_ABSOLUTE,
i + 1);
494 if (err == MIMER_NO_DATA)
497 if (!MIMER_SUCCEEDED(err)) {
503 setAt(MimerCurrentRow(
d->statementhandle) - 1);
514 if (currentRow() < 0)
516 else if (currentRow() == 0)
521 err = MimerFetchScroll(
d->statementhandle, MIMER_FIRST, 0);
522 if (MIMER_SUCCEEDED(err) && err != MIMER_NO_DATA)
525 if (!MIMER_SUCCEEDED(err)) {
531 if (err == MIMER_NO_DATA)
549 return currentRow() >= 0;
551 err = MimerFetchScroll(
d->statementhandle,
static_cast<std::int32_t
>(MIMER_LAST), 0);
552 if (err == MIMER_NO_DATA)
554 if (MIMER_SUCCEEDED(err)) {
555 row = MimerCurrentRow(
d->statementhandle) - 1;
580 err = MimerFetch(
d->statementhandle);
582 err = MimerFetchScroll(
d->statementhandle, MIMER_NEXT, 0);
583 if (!MIMER_SUCCEEDED(err)) {
591 if (err == MIMER_NO_DATA)
596 setAt(MimerCurrentRow(
d->statementhandle) - 1);
605 if (
d->callWithOut) {
606 if (
i >= MimerParameterCount(
d->statementhandle)) {
613 mType = MimerParameterType(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1));
615 if (
i >= MimerColumnCount(
d->statementhandle)) {
622 mType = MimerColumnType(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1));
626 err = MimerIsNull(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1));
630 switch (mimDataType) {
631 case MimerColumnTypes::Date: {
633 err = MimerGetString(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), dateString_w,
634 sizeof(dateString_w) /
sizeof(dateString_w[0]));
635 if (!MIMER_SUCCEEDED(err)) {
642 case MimerColumnTypes::Time: {
644 err = MimerGetString(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), timeString_w,
645 sizeof(timeString_w) /
sizeof(timeString_w[0]));
646 if (!MIMER_SUCCEEDED(err)) {
652 QString timeFormatString =
"HH:mm:ss"_L1;
653 if (timeString.size() > 8) {
654 timeFormatString.
append(
".zzz"_L1);
655 timeString = timeString.
left(12);
657 return QTime::fromString(timeString, timeFormatString);
659 case MimerColumnTypes::Timestamp: {
661 err = MimerGetString(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1),
663 sizeof(dateTimeString_w) /
sizeof(dateTimeString_w[0]));
664 if (!MIMER_SUCCEEDED(err)) {
671 QString dateTimeFormatString =
"yyyy-MM-dd HH:mm:ss"_L1;
672 if (dateTimeString.size() > 19) {
673 dateTimeFormatString.
append(
".zzz"_L1);
674 dateTimeString = dateTimeString.
left(23);
676 return QDateTime::fromString(dateTimeString, dateTimeFormatString);
678 case MimerColumnTypes::Int: {
680 err = MimerGetInt32(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), &resInt);
681 if (!MIMER_SUCCEEDED(err)) {
688 case MimerColumnTypes::Long: {
690 err = MimerGetInt64(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), &resLongLong);
691 if (!MIMER_SUCCEEDED(err)) {
698 case MimerColumnTypes::Boolean: {
699 err = MimerGetBoolean(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1));
700 if (!MIMER_SUCCEEDED(err)) {
708 case MimerColumnTypes::Float: {
710 err = MimerGetFloat(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), &resFloat);
711 if (!MIMER_SUCCEEDED(err)) {
718 case MimerColumnTypes::Double: {
720 err = MimerGetDouble(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), &resDouble);
721 if (!MIMER_SUCCEEDED(err)) {
729 return static_cast<std::int32_t
>(resDouble);
731 return static_cast<qint64>(resDouble);
733 return static_cast<qreal>(resDouble);
739 case MimerColumnTypes::Binary: {
742 err = MimerGetBinary(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), NULL, 0);
743 if (MIMER_SUCCEEDED(err)) {
745 err = MimerGetBinary(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1),
746 byteArray.
data(), err);
748 if (!MIMER_SUCCEEDED(err)) {
756 case MimerColumnTypes::Blob: {
759 err = MimerGetLob(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), &
size,
761 if (MIMER_SUCCEEDED(err)) {
765 size_t left_to_return =
size;
766 while (left_to_return > 0) {
767 const size_t bytesToReceive =
768 left_to_return <= maxSize ? left_to_return : maxSize;
769 err = MimerGetBlobData(&
d->lobhandle, blobchar.data(), bytesToReceive);
771 left_to_return -= bytesToReceive;
772 if (!MIMER_SUCCEEDED(err)) {
785 case MimerColumnTypes::Numeric:
786 case MimerColumnTypes::String: {
789 err = MimerGetString(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), resString_w,
791 if (MIMER_SUCCEEDED(err)) {
795 err = MimerGetString(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1),
797 if (MIMER_SUCCEEDED(err))
800 QVarLengthArray<wchar_t> largeResString_w(
size + 1);
801 err = MimerGetString(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1),
802 largeResString_w.data(),
size + 1);
803 if (MIMER_SUCCEEDED(err))
808 mimDataType == MimerColumnTypes::Numeric ?
"numeric" :
"string",
i),
812 case MimerColumnTypes::Clob: {
814 err = MimerGetLob(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), &
size,
816 if (MIMER_SUCCEEDED(err)) {
820 size_t left_to_return =
size;
822 while (left_to_return > 0) {
823 const size_t bytesToReceive =
824 left_to_return <= maxSize ? left_to_return : maxSize;
825 err = MimerGetNclobData(&
d->lobhandle, clobstring_w.data(), bytesToReceive + 1);
827 left_to_return -= bytesToReceive;
828 if (!MIMER_SUCCEEDED(err)) {
840 case MimerColumnTypes::Uuid: {
841 unsigned char uuidChar[16];
842 err = MimerGetUUID(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), uuidChar);
843 if (!MIMER_SUCCEEDED(err)) {
851 case MimerColumnTypes::Unknown:
864 const int32_t rc = MimerIsNull(
d->statementhandle,
static_cast<std::int16_t
>(
index + 1));
865 if (!MIMER_SUCCEEDED(rc)) {
888 if (
d->currentSize != -1)
889 return d->currentSize;
891 const int currentRow = MimerCurrentRow(
d->statementhandle);
892 MimerFetchScroll(
d->statementhandle,
static_cast<std::int32_t
>(MIMER_LAST), 0);
893 int size = MimerCurrentRow(
d->statementhandle);
894 if (!MIMER_SUCCEEDED(
size))
896 MimerFetchScroll(
d->statementhandle, MIMER_ABSOLUTE, currentRow);
897 d->currentSize =
size;
904 return d->rowsAffected;
914 const int colSize = MimerColumnCount(
d->statementhandle);
915 for (
int i = 0;
i < colSize;
i++) {
916 wchar_t colName_w[100];
917 MimerColumnName(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1), colName_w,
918 sizeof(colName_w) /
sizeof(colName_w[0]));
920 const int32_t mType = MimerColumnType(
d->statementhandle,
static_cast<std::int16_t
>(
i + 1));
939 if (!
d->preparedQuery)
945 err = MimerBeginStatement8(
d->drv_d_func()->sessionhandle,
query.toUtf8().constData(),
option,
946 &
d->statementhandle);
947 if (err == MIMER_STATEMENT_CANNOT_BE_PREPARED) {
948 err = MimerExecuteStatement8(
d->drv_d_func()->sessionhandle,
query.toUtf8().constData());
949 if (MIMER_SUCCEEDED(err)) {
950 d->executedStatement =
true;
951 d->openCursor =
false;
952 d->openStatement =
false;
956 if (!MIMER_SUCCEEDED(err)) {
958 "Could not prepare/execute statement"),
962 d->openStatement =
true;
972 if (!
d->preparedQuery)
974 if (
d->executedStatement) {
975 d->executedStatement =
false;
980 err = MimerCloseCursor(
d->statementhandle);
981 d->openCursor =
false;
987 int mimParamCount = MimerParameterCount(
d->statementhandle);
988 if (!MIMER_SUCCEEDED(mimParamCount))
990 if (mimParamCount !=
values.size()) {
996 for (
int i = 0;
i < mimParamCount;
i++) {
998 d->callWithOut =
true;
1003 err = MimerSetNull(
d->statementhandle,
i + 1);
1004 if (!MIMER_SUCCEEDED(err)) {
1013 const int mimParamType = MimerParameterType(
d->statementhandle,
i + 1);
1015 switch (mimDataType) {
1016 case MimerColumnTypes::Int: {
1018 err = MimerSetInt32(
d->statementhandle,
i + 1, val.toInt(&convertOk));
1019 if (!convertOk || !MIMER_SUCCEEDED(err)) {
1023 convertOk ?
d->drv_d_func() :
nullptr));
1028 case MimerColumnTypes::Long: {
1030 err = MimerSetInt64(
d->statementhandle,
i + 1, val.toLongLong(&convertOk));
1031 if (!convertOk || !MIMER_SUCCEEDED(err)) {
1035 convertOk ?
d->drv_d_func() :
nullptr));
1040 case MimerColumnTypes::Float: {
1042 err = MimerSetFloat(
d->statementhandle,
i + 1, val.toFloat(&convertOk));
1043 if (!convertOk || !MIMER_SUCCEEDED(err)) {
1047 convertOk ?
d->drv_d_func() :
nullptr));
1052 case MimerColumnTypes::Double: {
1054 err = MimerSetDouble(
d->statementhandle,
i + 1, val.toDouble(&convertOk));
1055 if (!convertOk || !MIMER_SUCCEEDED(err)) {
1059 convertOk ?
d->drv_d_func() :
nullptr));
1064 case MimerColumnTypes::Binary: {
1066 size_t size =
static_cast<std::size_t
>(binArr.size());
1067 err = MimerSetBinary(
d->statementhandle,
i + 1, binArr.data(),
size);
1068 if (!MIMER_SUCCEEDED(err)) {
1076 case MimerColumnTypes::Boolean: {
1077 err = MimerSetBoolean(
d->statementhandle,
i + 1, val.toBool() ==
true ? 1 : 0);
1078 if (!MIMER_SUCCEEDED(err)) {
1086 case MimerColumnTypes::Uuid: {
1089 const unsigned char *uuid =
1090 reinterpret_cast<const unsigned char *
>(uuidArray.constData());
1091 err = MimerSetUUID(
d->statementhandle,
i + 1, uuid);
1092 if (!MIMER_SUCCEEDED(err)) {
1100 case MimerColumnTypes::Numeric:
1101 case MimerColumnTypes::String: {
1103 const char *string_u = string_b.
constData();
1104 err = MimerSetString8(
d->statementhandle,
i + 1, string_u);
1105 if (!MIMER_SUCCEEDED(err)) {
1108 mimDataType == MimerColumnTypes::Numeric ?
"numeric" :
"string",
i),
1114 case MimerColumnTypes::Date: {
1115 err = MimerSetString8(
d->statementhandle,
i + 1, val.toString().toUtf8().constData());
1116 if (!MIMER_SUCCEEDED(err)) {
1124 case MimerColumnTypes::Time: {
1125 QString timeFormatString =
"hh:mm:ss"_L1;
1126 const QTime timeVal = val.toTime();
1127 if (timeVal.msec() > 0)
1128 timeFormatString.append(
".zzz"_L1);
1129 err = MimerSetString8(
d->statementhandle,
i + 1,
1130 timeVal.toString(timeFormatString).toUtf8().constData());
1131 if (!MIMER_SUCCEEDED(err)) {
1139 case MimerColumnTypes::Timestamp: {
1140 QString dateTimeFormatString =
"yyyy-MM-dd hh:mm:ss"_L1;
1141 const QDateTime dateTimeVal = val.toDateTime();
1142 if (dateTimeVal.time().msec() > 0)
1143 dateTimeFormatString.append(
".zzz"_L1);
1144 err = MimerSetString8(
1145 d->statementhandle,
i + 1,
1146 val.toDateTime().toString(dateTimeFormatString).toUtf8().constData());
1147 if (!MIMER_SUCCEEDED(err)) {
1154 case MimerColumnTypes::Blob: {
1156 const char *blobData = blobArr.
constData();
1158 err = MimerSetLob(
d->statementhandle,
i + 1,
size, &
d->lobhandle);
1159 if (MIMER_SUCCEEDED(err)) {
1161 if (
size > maxSize) {
1163 for (
qsizetype k = 0; left_to_send > 0; k++) {
1164 if (left_to_send <= maxSize) {
1165 err = MimerSetBlobData(&
d->lobhandle, &blobData[k * maxSize],
1169 err = MimerSetBlobData(&
d->lobhandle, &blobData[k * maxSize], maxSize);
1170 left_to_send = left_to_send - maxSize;
1173 if (!MIMER_SUCCEEDED(err)) {
1180 err = MimerSetBlobData(&
d->lobhandle, blobArr,
size);
1183 if (!MIMER_SUCCEEDED(err)) {
1190 case MimerColumnTypes::Clob: {
1192 const char *string_u = string_b.
constData();
1195 while (string_u[
size++])
1196 if ((string_u[
size] & 0xc0) != 0x80)
1198 err = MimerSetLob(
d->statementhandle,
i + 1, size_c, &
d->lobhandle);
1199 if (MIMER_SUCCEEDED(err)) {
1201 if (
size > maxSize) {
1202 size_t left_to_send =
size;
1205 while (left_to_send > 0 && step_back < maxSize) {
1207 if (left_to_send <= maxSize) {
1208 err = MimerSetNclobData8(&
d->lobhandle, &string_u[
pos], left_to_send);
1212 while (
pos + maxSize - step_back > 0
1213 && (string_u[
pos + maxSize - step_back] & 0xc0) == 0x80)
1215 err = MimerSetNclobData8(&
d->lobhandle, &string_u[
pos],
1216 maxSize - step_back);
1217 left_to_send = left_to_send - maxSize + step_back;
1218 pos += maxSize - step_back;
1220 if (!MIMER_SUCCEEDED(err)) {
1227 err = MimerSetNclobData8(&
d->lobhandle, string_u,
size);
1230 if (!MIMER_SUCCEEDED(err)) {
1238 case MimerColumnTypes::Unknown:
1249 err = MimerExecute(
d->statementhandle);
1250 if (MIMER_SUCCEEDED(err)) {
1251 d->rowsAffected = err;
1259 d->callWithOut =
false;
1262 if (MIMER_SEQUENCE_ERROR == err) {
1263 err = MimerOpenCursor(
d->statementhandle);
1264 d->rowsAffected = err;
1265 d->openCursor =
true;
1269 if (!MIMER_SUCCEEDED(err)) {
1272 "Could not execute statement/open cursor"),
1293 "Only input parameters can be used in batch operations"),
1295 d->execBatch =
false;
1298 d->execBatch =
true;
1301 d->batch_vector.append(
values.at(
j).toList().at(
i));
1303 if (
i != (
values.at(0).toList().size() - 1)) {
1304 err = MimerAddBatch(
d->statementhandle);
1305 if (!MIMER_SUCCEEDED(err)) {
1311 d->execBatch =
false;
1315 d->batch_vector.clear();
1317 d->execBatch =
false;
1318 err = MimerExecute(
d->statementhandle);
1319 if (!MIMER_SUCCEEDED(err)) {
1331 int64_t lastSequence;
1332 const int32_t err = MimerGetSequenceInt64(
d->statementhandle, &lastSequence);
1333 if (!MIMER_SUCCEEDED(err))
1371 const int32_t err = MimerBeginSession8(
db.toUtf8().constData(), user.
toUtf8().
constData(),
1373 if (!MIMER_SUCCEEDED(err)) {
1392 const int end_err = MimerEndSession(&
d->sessionhandle);
1393 if (MIMER_SUCCEEDED(end_err)) {
1414 sql =
"select table_name from information_schema.tables where "
1415 "table_type=\'BASE TABLE\' AND table_schema = CURRENT_USER"_L1;
1419 sql =
"select table_name from information_schema.tables where "
1420 "table_type=\'BASE TABLE\' AND table_schema = \'SYSTEM\'"_L1;
1424 sql =
"select table_name from information_schema.tables where "
1425 "table_type=\'VIEW\' AND table_schema = CURRENT_USER"_L1;
1429 sql =
"select table_name from information_schema.tables where "
1430 "(table_type=\'VIEW\' or table_type=\'BASE TABLE\')"
1431 " AND (table_schema = CURRENT_USER OR table_schema =\'SYSTEM\')"_L1;
1440 tl.append(
t.value(0).toString());
1457 d->splitTableQualifier(qualifiedName, &schema, &
table);
1459 "select information_schema.ext_access_paths.column_name,"
1460 "case when data_type = 'INTERVAL' then 'INTERVAL '|| interval_type "
1461 "when data_type = 'INTEGER' and numeric_precision > 10 then 'BIGINT' "
1462 "when data_type = 'INTEGER' and numeric_precision <= 10 AND NUMERIC_PRECISION > 5 "
1463 "then 'INTEGER' when data_type = 'INTEGER' and numeric_precision <= 5 then 'SMALLINT' "
1464 "else upper(data_type) end as data_type "
1465 "from information_schema.ext_access_paths full outer join "
1466 "information_schema.columns on information_schema.ext_access_paths.column_name = "
1467 "information_schema.columns.column_name and "
1468 "information_schema.ext_access_paths.table_name = "
1469 "information_schema.columns.table_name where "
1470 "information_schema.ext_access_paths.table_name = \'"_L1;
1472 .
append(
"\' and index_type = \'PRIMARY KEY\'"_L1);
1473 if (schema.length() == 0)
1474 sql.
append(
" and table_schema = CURRENT_USER"_L1);
1486 index.setName(
t.value(0).toString());
1499 QString qualifiedName = tablename;
1503 d->splitTableQualifier(qualifiedName, &schema, &
table);
1506 "select column_name, case when data_type = 'INTERVAL' then 'INTERVAL '|| interval_type "
1507 "when data_type = 'INTEGER' and numeric_precision > 10 then 'BIGINT' "
1508 "when data_type = 'INTEGER' and numeric_precision <= 10 AND numeric_precision > 5 "
1509 "then 'INTEGER' when data_type = 'INTEGER' and numeric_precision <= 5 then 'SMALLINT' "
1510 "else UPPER(data_type) end as data_type, case when is_nullable = 'YES' then false else "
1511 "true end as required, "
1512 "coalesce(numeric_precision, coalesce(datetime_precision,coalesce(interval_precision, "
1513 "-1))) as prec from information_schema.columns where table_name = \'"_L1;
1514 if (schema.length() == 0)
1518 sql.
append(
" order by ordinal_position"_L1);
1527 if (
t.value(3).toInt() != -1)
1556 const int32_t err = MimerBeginTransaction(
d->sessionhandle, MIMER_TRANS_READWRITE);
1557 if (!MIMER_SUCCEEDED(err)) {
1569 const int32_t err = MimerEndTransaction(
d->sessionhandle, MIMER_COMMIT);
1570 if (!MIMER_SUCCEEDED(err)) {
1582 const int32_t err = MimerEndTransaction(
d->sessionhandle, MIMER_ROLLBACK);
1583 if (!MIMER_SUCCEEDED(err)) {
1599 }
else if (
n == 1) {
1601 *
table = l.at(0).toString();
1603 *schema = l.at(0).toString();
1604 *
table = l.at(1).toString();
1610#include "moc_qsql_mimer.cpp"
QByteArray trimmed() const &
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
static QByteArray fromHex(const QByteArray &hexEncoded)
Returns a decoded copy of the hex encoded array hexEncoded.
void reserve(qsizetype size)
Attempts to allocate memory for at least size bytes.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
\inmodule QtCore\reentrant
MimerSession sessionhandle
void splitTableQualifier(const QString &qualifier, QString *schema, QString *table) const
~QMimerSQLDriver() override
QSqlIndex primaryIndex(const QString &tablename) const override
Returns the primary index for table tableName.
bool rollbackTransaction() override
This function is called to rollback a transaction.
bool commitTransaction() override
This function is called to commit a transaction.
bool beginTransaction() override
This function is called to begin a transaction.
QStringList tables(QSql::TableType type) const override
Returns a list of the names of the tables in the database.
void close() override
Derived classes must reimplement this pure virtual function in order to close the database connection...
QString escapeIdentifier(const QString &identifier, IdentifierType type) const override
Returns the identifier escaped according to the database rules.
QMimerSQLDriver(QObject *parent=nullptr)
bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port, const QString &connOpts) override
Derived classes must reimplement this pure virtual function to open a database connection on database...
bool hasFeature(DriverFeature f) const override
Returns true if the driver supports feature feature; otherwise returns false.
QSqlResult * createResult() const override
Creates an empty SQL result on the database.
QSqlRecord record(const QString &tablename) const override
Returns a QSqlRecord populated with the names of the fields in table tableName.
QVariant handle() const override
Returns the low-level database handle wrapped in a QVariant or an invalid variant if there is no hand...
MimerStatement statementhandle
QVector< QVariant > batch_vector
static constexpr int maxTimestampStringSize
static constexpr int lobChunkMaxSizeSet
bool fetchNext() override
Positions the result to the next available record (row) in the result.
bool reset(const QString &query) override
Sets the result to use the SQL statement query for subsequent data retrieval.
static constexpr int maxDateStringSize
bool prepare(const QString &query) override
Prepares the given query for execution; the query will normally use placeholders so that it can be ex...
QVariant data(int i) override
Returns the data for field index in the current row as a QVariant.
QSqlRecord record() const override
Returns the current record if the query is active; otherwise returns an empty QSqlRecord.
int size() override
Returns the size of the SELECT result, or -1 if it cannot be determined or if the query is not a SELE...
QVariant handle() const override
Returns the low-level database handle for this result set wrapped in a QVariant or an invalid QVarian...
bool fetchLast() override
Positions the result to the last record (last row) in the result.
bool fetch(int i) override
Positions the result to an arbitrary (zero-based) row index.
bool execBatch(bool arrayBind=false) override
bool isNull(int index) override
Returns true if the field at position index in the current row is null; otherwise returns false.
bool fetchFirst() override
Positions the result to the first record (row 0) in the result.
int numRowsAffected() override
Returns the number of rows affected by the last query executed, or -1 if it cannot be determined or i...
static constexpr int maxTimeStringSize
static constexpr int genericError
static constexpr int lobChunkMaxSizeFetch
QMimerSQLResult(const QMimerSQLDriver *db)
virtual ~QMimerSQLResult() override
bool exec() override
Executes the query, returning true if successful; otherwise returns false.
static constexpr int maxStackStringSize
QVariant lastInsertId() const override
Returns the object ID of the most recent inserted row if the database supports it.
The QSqlDriver class is an abstract base class for accessing specific SQL databases.
IdentifierType
This enum contains a list of SQL identifier types.
virtual QString stripDelimiters(const QString &identifier, IdentifierType type) const
Returns the identifier with the leading and trailing delimiters removed, identifier can either be a t...
DriverFeature
This enum contains a list of features a driver might support.
virtual void setLastError(const QSqlError &e)
This function is used to set the value of the last error, error, that occurred on the database.
virtual bool isOpen() const
Returns true if the database connection is open; otherwise returns false.
virtual void setOpenError(bool e)
This function sets the open error state of the database to error.
virtual bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const
Returns whether identifier is escaped according to the database rules.
virtual void setOpen(bool o)
This function sets the open state of the database to open.
The QSqlError class provides SQL database error information.
ErrorType
This enum type describes the context in which the error occurred, e.g., a connection error,...
The QSqlField class manipulates the fields in SQL database tables and views.
void setValue(const QVariant &value)
Sets \l value to value.
void setName(const QString &name)
Sets \l name to name.
void setMetaType(QMetaType type)
Sets \l metaType to type.
void setRequired(bool required)
Sets the required status of this field to \l Required if required is true; otherwise sets it to \l Op...
void setPrecision(int precision)
Sets \l precision to precision.
The QSqlIndex class provides functions to manipulate and describe database indexes.
The QSqlQuery class provides a means of executing and manipulating SQL statements.
The QSqlRecord class encapsulates a database record.
void append(const QSqlField &field)
Append a copy of field field to the end of the record.
void insert(int pos, const QSqlField &field)
Inserts the field field at position pos in the record.
static bool isVariantNull(const QVariant &variant)
The QSqlResult class provides an abstract interface for accessing data from specific SQL databases.
bool isForwardOnly() const
Returns true if you can only scroll forward through the result set; otherwise returns false.
QSql::ParamType bindValueType(const QString &placeholder) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int at() const
Returns the current (zero-based) row position of the result.
virtual bool prepare(const QString &query)
Prepares the given query for execution; the query will normally use placeholders so that it can be ex...
virtual bool exec()
Executes the query, returning true if successful; otherwise returns false.
bool isSelect() const
Returns true if the current result is from a SELECT statement; otherwise returns false.
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index.
virtual void setSelect(bool s)
This function is provided for derived classes to indicate whether or not the current statement is a S...
virtual void setActive(bool a)
This function is provided for derived classes to set the internal active state to active.
QVariantList & boundValues(QT6_DECL_NEW_OVERLOAD)
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
const QSqlDriver * driver() const
Returns the driver associated with the result.
virtual void bindValue(int pos, const QVariant &val, QSql::ParamType type)
Binds the value val of parameter type paramType to position index in the current record (row).
bool isActive() const
Returns true if the result has records to be retrieved; otherwise returns false.
Q_CORE_EXPORT QList< QStringView > split(QStringView sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the view into substring views wherever sep occurs, and returns the list of those string views.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString left(qsizetype n) const &
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
QString & replace(qsizetype i, qsizetype len, QChar after)
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString & append(QChar c)
QByteArray toUtf8() const &
qsizetype length() const noexcept
Returns the number of characters in this string.
\inmodule QtCore \reentrant
static QUuid fromRfc4122(QByteArrayView) noexcept
Creates a QUuid object from the binary representation of the UUID, as specified by RFC 4122 section 4...
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Combined button and popup list for selecting options.
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
GLenum GLsizei GLsizei GLint * values
[15]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei void GLsizei void * column
GLdouble GLdouble GLdouble GLdouble q
GLenum GLenum GLsizei void * row
GLenum GLenum GLsizei void * table
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QDB2DriverPrivate *p)
static QList< QVariant > toList(char **buf, int count)
static QSqlError qMakeError(const QString &err, const int errCode, QSqlError::ErrorType type, const QMimerSQLDriverPrivate *p)
static MimerColumnTypes mimerMapColumnTypes(int32_t t)
static QString msgCouldNotGet(const char *type, int column)
static QMetaType::Type qDecodeMSQLType(int32_t t)
static QString msgCouldNotSet(const char *type, int column)
static int32_t qLookupMimDataType(QStringView s)
#define MIMER_DEFAULT_DATATYPE
#define Q_DECLARE_SQLDRIVER_PRIVATE(Class)