12#if QT_CONFIG(regularexpression)
20#include <QtSql/private/qsqlcachedresult_p.h>
21#include <QtSql/private/qsqldriver_p.h>
23#if QT_CONFIG(timezone)
30#if defined(__MINGW64_VERSION_MAJOR) && defined(_WIN64)
38#define QOCI_DYNAMIC_CHUNK_SIZE 65535
39#define QOCI_PREFETCH_MEM 10240
57using namespace
Qt::StringLiterals;
59#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
65#ifdef OCI_ATTR_CHARSET_FORM
70static const ub1 qOraCharsetForm = SQLCS_NCHAR;
73#if defined (OCI_UTF16ID)
113 OCIDescriptorAlloc (env,
reinterpret_cast<dvoid **
>(&
id),
114 OCI_DTYPE_ROWID, 0, 0);
120 OCIDescriptorFree(
id, OCI_DTYPE_ROWID);
135 OCIDescriptorAlloc(env,
reinterpret_cast<void**
>(&
dateTime), OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
140 const QString timeZone = dt.toString(
"ttt"_L1);
141 const OraText *
tz =
reinterpret_cast<const OraText *
>(timeZone.
utf16());
144 const_cast<OraText *
>(
tz), timeZone.
length() *
sizeof(
QChar));
151 OCIDescriptorFree(
dateTime, OCI_DTYPE_TIMESTAMP_TZ);
157 ub1 month, day, hour, minute, second;
159 sb1 tzHour, tzMinute;
161 OCIDateTimeGetDate(env, err,
dateTime, &year, &month, &day);
162 OCIDateTimeGetTime(env, err,
dateTime, &hour, &minute, &second, &nsec);
163 OCIDateTimeGetTimeZoneOffset(env, err,
dateTime, &tzHour, &tzMinute);
164 int secondsOffset = (
qAbs(tzHour) * 60 + tzMinute) * 60;
166 secondsOffset = -secondsOffset;
217 bool exec() override;
242 OCIError *err =
nullptr;
244 OCIStmt *sql =
nullptr;
249 void setStatementAttributes();
250 int bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err,
int pos,
266#ifdef OCI_ATTR_CHARSET_FORM
271 const_cast<void *
>(
static_cast<const void *
>(&qOraCharsetForm)),
273 OCI_ATTR_CHARSET_FORM,
279 qCWarning(lcOci,
"QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_FORM.");
287 const_cast<void *
>(
static_cast<const void *
>(&
qOraCharset)),
292 qOraWarning(
"QOCIResultPrivate::setCharsetI Couldn't set OCI_ATTR_CHARSET_ID: ", err);
303 if (prefetchRows >= 0) {
308 OCI_ATTR_PREFETCH_ROWS,
311 qOraWarning(
"QOCIResultPrivate::setStatementAttributes:"
312 " Couldn't set OCI_ATTR_PREFETCH_ROWS: ", err);
314 if (prefetchMem >= 0) {
319 OCI_ATTR_PREFETCH_MEMORY,
322 qOraWarning(
"QOCIResultPrivate::setStatementAttributes:"
323 " Couldn't set OCI_ATTR_PREFETCH_MEMORY: ", err);
331 void *
data =
const_cast<void *
>(
val.constData());
333 switch (
val.typeId()) {
334 case QMetaType::QByteArray:
335 r = OCIBindByPos(sql, hbnd, err,
338 ?
const_cast<char *
>(
reinterpret_cast<QByteArray *
>(
data)->constData())
341 SQLT_BIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
343 case QMetaType::QTime:
344 case QMetaType::QDate:
345 case QMetaType::QDateTime: {
347 r = OCIBindByPos(sql, hbnd, err,
350 sizeof(OCIDateTime *),
351 SQLT_TIMESTAMP_TZ, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
352 tmpStorage.dateTimes.append(
ptr);
356 r = OCIBindByPos(sql, hbnd, err,
360 const_cast<void *
>(
data),
362 SQLT_INT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
364 case QMetaType::UInt:
365 r = OCIBindByPos(sql, hbnd, err,
369 const_cast<void *
>(
data),
371 SQLT_UIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
373 case QMetaType::LongLong:
376 r = OCIBindByPos(sql, hbnd, err,
380 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
381 tmpStorage.rawData.append(
ba);
384 case QMetaType::ULongLong:
387 r = OCIBindByPos(sql, hbnd, err,
391 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
392 tmpStorage.rawData.append(
ba);
395 case QMetaType::Double:
396 r = OCIBindByPos(sql, hbnd, err,
400 const_cast<void *
>(
data),
402 SQLT_FLT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
404 case QMetaType::QString: {
406 if (isBinaryValue(
pos)) {
407 r = OCIBindByPos(sql, hbnd, err,
409 const_cast<ushort *
>(
s.utf16()),
410 s.length() *
sizeof(
QChar),
411 SQLT_LNG, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
413 }
else if (!isOutValue(
pos)) {
415 r = OCIBindByPos(sql, hbnd, err,
418 const_cast<ushort *
>(
s.utf16()),
419 (
s.length() + 1) *
sizeof(
QChar),
420 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
421 if (
r == OCI_SUCCESS)
422 setCharset(*hbnd, OCI_HTYPE_BIND);
432 r = OCIBindByPos(sql, hbnd, err,
435 const_cast<OCIRowid **
>(&rptr->id),
437 SQLT_RDD, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
439 qCWarning(lcOci,
"Unknown bind variable");
445 QByteArray ba(
reinterpret_cast<const char *
>(
s.utf16()), (
s.length() + 1) *
sizeof(
QChar));
446 if (isOutValue(
pos)) {
449 r = OCIBindByPos(sql, hbnd, err,
453 SQLT_STR, indPtr, tmpSize, 0, 0, 0, OCI_DEFAULT);
455 r = OCIBindByPos(sql, hbnd, err,
459 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
461 if (
r == OCI_SUCCESS)
462 setCharset(*hbnd, OCI_HTYPE_BIND);
463 tmpStorage.rawData.append(
ba);
468 if (
r != OCI_SUCCESS)
477 for (
int i = 0;
i <
values.count(); ++
i) {
482 OCIBind * hbnd =
nullptr;
483 sb2 *indPtr = &indicators[
i];
486 bindValue(sql, &hbnd, err,
i,
val, indPtr, &tmpSizes[
i], tmpStorage);
494 switch (
value.typeId()) {
495 case QMetaType::QTime:
497 tmpStorage.dateTimes.takeFirst()->dateTime).time();
499 case QMetaType::QDate:
501 tmpStorage.dateTimes.takeFirst()->dateTime).date();
503 case QMetaType::QDateTime:
505 tmpStorage.dateTimes.takeFirst()->dateTime);
507 case QMetaType::LongLong:
510 case QMetaType::ULongLong:
513 case QMetaType::QString:
515 reinterpret_cast<const QChar *
>(tmpStorage.rawData.takeFirst().constData()));
525 for (
int i = 0;
i <
values.count(); ++
i) {
532 auto typ =
values.at(
i).metaType();
533 if (indicators[
i] == -1)
550 int r = OCIHandleAlloc(
env,
551 reinterpret_cast<void **
>(&
err),
554 if (
r != OCI_SUCCESS)
555 qCWarning(lcOci,
"QOCIDriver: unable to allocate error handle");
585 *errorCode = errcode;
586 return QString(
reinterpret_cast<const QChar *
>(errbuf));
618 if (ocitype ==
"VARCHAR2"_L1 || ocitype ==
"VARCHAR"_L1
619 || ocitype.startsWith(
"INTERVAL"_L1)
620 || ocitype ==
"CHAR"_L1 || ocitype ==
"NVARCHAR2"_L1
621 || ocitype ==
"NCHAR"_L1)
622 type = QMetaType::QString;
623 else if (ocitype ==
"NUMBER"_L1
624 || ocitype ==
"FLOAT"_L1
625 || ocitype ==
"BINARY_FLOAT"_L1
626 || ocitype ==
"BINARY_DOUBLE"_L1) {
627 switch(precisionPolicy) {
629 type = QMetaType::Int;
632 type = QMetaType::LongLong;
635 type = QMetaType::Double;
639 type = QMetaType::QString;
643 else if (ocitype ==
"LONG"_L1 || ocitype ==
"NCLOB"_L1 || ocitype ==
"CLOB"_L1)
644 type = QMetaType::QByteArray;
645 else if (ocitype ==
"RAW"_L1 || ocitype ==
"LONG RAW"_L1
646 || ocitype ==
"ROWID"_L1 || ocitype ==
"BLOB"_L1
647 || ocitype ==
"CFILE"_L1 || ocitype ==
"BFILE"_L1)
648 type = QMetaType::QByteArray;
649 else if (ocitype ==
"DATE"_L1 || ocitype.startsWith(
"TIME"_L1))
650 type = QMetaType::QDateTime;
651 else if (ocitype ==
"UNDEFINED"_L1)
670#ifdef SQLT_INTERVAL_YM
671 case SQLT_INTERVAL_YM:
673#ifdef SQLT_INTERVAL_DS
674 case SQLT_INTERVAL_DS:
676 type = QMetaType::QString;
679 type = QMetaType::Int;
685 switch(precisionPolicy) {
687 type = QMetaType::Int;
690 type = QMetaType::LongLong;
693 type = QMetaType::Double;
697 type = QMetaType::QString;
712 type = QMetaType::QByteArray;
717 case SQLT_TIMESTAMP_TZ:
718 case SQLT_TIMESTAMP_LTZ:
719 type = QMetaType::QDateTime;
722 qCWarning(lcOci,
"qDecodeOCIType: unknown OCI datatype: %d", ocitype);
731 f.setRequired(ofi.oraIsNull == 0);
733 if (ofi.type.id() == QMetaType::QString && ofi.oraType != SQLT_NUM && ofi.oraType != SQLT_VNU)
734 f.setLength(ofi.oraFieldLength);
736 f.setLength(ofi.oraPrecision == 0 ? 38 : int(ofi.oraPrecision));
738 f.setPrecision(ofi.oraScale);
751 OCINumberFromInt(err,
755 reinterpret_cast<OCINumber*
>(
ba.
data()));
768 OCINumberFromInt(err,
772 reinterpret_cast<OCINumber*
>(
ba.
data()));
779 OCINumberToInt(err,
reinterpret_cast<const OCINumber *
>(ociNumber),
sizeof(
qlonglong),
780 OCI_NUMBER_SIGNED, &qll);
787 OCINumberToInt(err,
reinterpret_cast<const OCINumber *
>(ociNumber),
sizeof(
qulonglong),
788 OCI_NUMBER_UNSIGNED, &qull);
814 OraFieldInf() :
data(0),
len(0), ind(0), oraType(0), def(0), lob(0), dataPtr(
nullptr)
827 QList<OraFieldInf> fieldInf;
831QOCICols::OraFieldInf::~OraFieldInf()
835 int r = OCIDescriptorFree(lob, OCI_DTYPE_LOB);
837 qCWarning(lcOci,
"QOCICols: Cannot free LOB descriptor");
841 case QMetaType::QDate:
842 case QMetaType::QTime:
843 case QMetaType::QDateTime: {
844 int r = OCIDescriptorFree(dataPtr, OCI_DTYPE_TIMESTAMP_TZ);
845 if (
r != OCI_SUCCESS)
846 qCWarning(lcOci,
"QOCICols: Cannot free OCIDateTime descriptor");
856 : fieldInf(
size), d(dp)
859 OCIDefine *dfn =
nullptr;
862 OCIParam *
param =
nullptr;
866 parmStatus = OCIParamGet(d->
sql,
869 reinterpret_cast<void **
>(&
param),
872 while (parmStatus == OCI_SUCCESS) {
874 if (ofi.oraType == SQLT_RDD)
876#ifdef SQLT_INTERVAL_YM
877#ifdef SQLT_INTERVAL_DS
878 else if (ofi.oraType == SQLT_INTERVAL_YM || ofi.oraType == SQLT_INTERVAL_DS)
884 else if (ofi.oraType == SQLT_NUM || ofi.oraType == SQLT_VNU){
885 if (ofi.oraPrecision > 0)
886 dataSize = (ofi.oraPrecision + 1) *
sizeof(utext);
888 dataSize = (38 + 1) *
sizeof(utext);
893 fieldInf[idx].typ = ofi.type;
894 fieldInf[idx].oraType = ofi.oraType;
897 switch (ofi.type.id()) {
898 case QMetaType::QDateTime:
899 r = OCIDescriptorAlloc(d->
env, (
void **)&fieldInf[idx].dataPtr, OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
900 if (
r != OCI_SUCCESS) {
901 qCWarning(lcOci,
"QOCICols: Unable to allocate the OCIDateTime descriptor");
904 r = OCIDefineByPos(d->
sql,
908 &fieldInf[idx].dataPtr,
909 sizeof(OCIDateTime *),
911 &(fieldInf[idx].ind),
914 case QMetaType::Double:
915 r = OCIDefineByPos(d->
sql,
919 create(idx,
sizeof(
double) - 1),
922 &(fieldInf[idx].ind),
926 r = OCIDefineByPos(d->
sql,
933 &(fieldInf[idx].ind),
936 case QMetaType::LongLong:
937 r = OCIDefineByPos(d->
sql,
941 create(idx,
sizeof(OCINumber)),
944 &(fieldInf[idx].ind),
947 case QMetaType::QByteArray:
949 if (ofi.oraType == SQLT_BIN) {
951 r = OCIDefineByPos(d->
sql,
958 &(fieldInf[idx].ind),
959 0, 0, OCI_DYNAMIC_FETCH);
960 }
else if (ofi.oraType == SQLT_LBI) {
962 r = OCIDefineByPos(d->
sql,
969 &(fieldInf[idx].ind),
970 0, 0, OCI_DYNAMIC_FETCH);
971 }
else if (ofi.oraType == SQLT_CLOB) {
972 r = OCIDefineByPos(d->
sql,
976 createLobLocator(idx, d->
env),
979 &(fieldInf[idx].ind),
983 r = OCIDefineByPos(d->
sql,
987 createLobLocator(idx, d->
env),
990 &(fieldInf[idx].ind),
994 case QMetaType::QString:
995 if (ofi.oraType == SQLT_LNG) {
996 r = OCIDefineByPos(d->
sql,
1003 &(fieldInf[idx].ind),
1004 0, 0, OCI_DYNAMIC_FETCH);
1008 r = OCIDefineByPos(d->
sql,
1015 &(fieldInf[idx].ind),
1025 r = OCIDefineByPos(d->
sql,
1032 &(fieldInf[idx].ind),
1038 fieldInf[idx].def = dfn;
1041 parmStatus = OCIParamGet(d->
sql,
1044 reinterpret_cast<void **
>(&
param),
1055 char*
c =
new char[
size+1];
1057 memset(
c, 0,
size+1);
1063OCILobLocator **QOCICols::createLobLocator(
int position,
OCIEnv* env)
1065 OCILobLocator *& lob = fieldInf[
position].lob;
1066 int r = OCIDescriptorAlloc(env,
1067 reinterpret_cast<void **
>(&lob),
1072 qCWarning(lcOci,
"QOCICols: Cannot create LOB locator");
1093 r = OCIStmtGetPieceInfo(d->
sql, d->
err,
reinterpret_cast<void **
>(&dfn), &typep,
1094 &in_outp, &iterp, &idxp, &piecep);
1095 if (
r != OCI_SUCCESS)
1096 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to get piece info:", d->
err);
1098 bool isStringField = fieldInf.
at(fieldNum).oraType == SQLT_LNG;
1101 r = OCIStmtSetPieceInfo(dfn, OCI_HTYPE_DEFINE,
1103 &chunkSize, piecep, NULL, NULL);
1104 if (
r != OCI_SUCCESS)
1105 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to set piece info:", d->
err);
1106 status = OCIStmtFetch (d->
sql, d->
err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1109 OCIErrorGet(d->
err, 1, 0, &errcode, 0, 0,OCI_HTYPE_ERROR);
1115 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to fetch next:", d->
err);
1119 if (status == OCI_NO_DATA)
1121 if (nullField || !chunkSize) {
1122 fieldInf[fieldNum].ind = -1;
1124 if (isStringField) {
1128 fieldInf[fieldNum].ind = 0;
1133 memcpy(
ba.
data() + sz,
reinterpret_cast<char *
>(col), chunkSize);
1135 fieldInf[fieldNum].ind = 0;
1138 }
while (status == OCI_SUCCESS_WITH_INFO || status == OCI_NEED_DATA);
1146 text *colName =
nullptr;
1150 ub2 colFieldLength(0);
1151 sb2 colPrecision(0);
1182#ifdef OCI_ATTR_CHAR_SIZE
1193 colFieldLength = colLength;
1232 if (
type.id() == QMetaType::Int) {
1233 if ((colLength == 22 && colPrecision == 0 && colScale == 0) || colScale > 0)
1238 if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
1244 if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
1245 || (colType == SQLT_INT)) {
1252 if (colType == SQLT_BLOB)
1256 ofi.name =
QString(
reinterpret_cast<const QChar*
>(colName), colNameLen / 2);
1258 ofi.oraType = colType;
1259 ofi.oraFieldLength = colFieldLength;
1260 ofi.oraLength = colLength;
1261 ofi.oraScale = colScale;
1262 ofi.oraPrecision = colPrecision;
1263 ofi.oraIsNull = colIsNull;
1294 delete[]
col[
j].lengths;
1295 delete[]
col[
j].indicators;
1305 int columnCount = boundValues.
count();
1306 if (boundValues.
isEmpty() || columnCount == 0)
1310 qCDebug(lcOci) <<
"columnCount:" << columnCount << boundValues;
1316 QVarLengthArray<QMetaType> fieldTypes;
1317 for (
i = 0;
i < columnCount; ++
i) {
1322 QList<QOCIBatchColumn> columns(columnCount);
1327 for (
i = 0;
i < columnCount; ++
i) {
1329 if (boundValues.
at(
i).
typeId() != QMetaType::QVariantList) {
1333 singleCol.indicators =
new sb2[1];
1336 r =
d->bindValue(
d->sql, &singleCol.bindh,
d->err,
i,
1337 boundValues.
at(
i), singleCol.indicators, &tmpSizes[
i], tmpStorage);
1339 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1340 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:",
d->err);
1342 "Unable to bind column for batch execute"),
1357 switch (fieldTypes[
i].
id()) {
1358 case QMetaType::QTime:
1359 case QMetaType::QDate:
1360 case QMetaType::QDateTime:
1361 col.
bindAs = SQLT_TIMESTAMP_TZ;
1362 col.
maxLen =
sizeof(OCIDateTime *);
1365 case QMetaType::Int:
1367 col.
maxLen =
sizeof(int);
1370 case QMetaType::UInt:
1375 case QMetaType::LongLong:
1377 col.
maxLen =
sizeof(OCINumber);
1380 case QMetaType::ULongLong:
1382 col.
maxLen =
sizeof(OCINumber);
1385 case QMetaType::Double:
1387 col.
maxLen =
sizeof(double);
1390 case QMetaType::QString: {
1394 if (
d->isOutValue(
i))
1404 case QMetaType::QByteArray:
1408 col.
maxLen =
sizeof(OCIRowid*);
1412 if (
d->isOutValue(
i))
1432 columns[
i].indicators[
row] = -1;
1433 columns[
i].lengths[
row] = 0;
1435 columns[
i].indicators[
row] = 0;
1436 char *dataPtr = columns[
i].data + (columns[
i].maxLen *
row);
1437 switch (fieldTypes[
i].
id()) {
1438 case QMetaType::QTime:
1439 case QMetaType::QDate:
1440 case QMetaType::QDateTime:{
1441 columns[
i].lengths[
row] = columns[
i].maxLen;
1443 *
reinterpret_cast<OCIDateTime**
>(dataPtr) =
date->dateTime;
1444 tmpStorage.dateTimes.append(
date);
1447 case QMetaType::Int:
1448 columns[
i].lengths[
row] = columns[
i].maxLen;
1449 *
reinterpret_cast<int*
>(dataPtr) =
val.toInt();
1452 case QMetaType::UInt:
1453 columns[
i].lengths[
row] = columns[
i].maxLen;
1454 *
reinterpret_cast<uint*
>(dataPtr) =
val.toUInt();
1457 case QMetaType::LongLong:
1459 columns[
i].lengths[
row] = columns[
i].maxLen;
1465 case QMetaType::ULongLong:
1467 columns[
i].lengths[
row] = columns[
i].maxLen;
1473 case QMetaType::Double:
1474 columns[
i].lengths[
row] = columns[
i].maxLen;
1475 *
reinterpret_cast<double*
>(dataPtr) =
val.toDouble();
1478 case QMetaType::QString: {
1480 columns[
i].lengths[
row] = (
s.length() + 1) *
sizeof(
QChar);
1481 memcpy(dataPtr,
s.utf16(), columns[
i].lengths[
row]);
1484 case QMetaType::QByteArray:
1489 *
reinterpret_cast<OCIRowid**
>(dataPtr) = rptr->id;
1490 columns[
i].lengths[
row] = 0;
1507 qCDebug(lcOci,
"OCIBindByPos(%p, %p, %p, %d, %p, %d, %d, %p, %p, 0, %d, %p, OCI_DEFAULT)",
1508 d->sql, &bindColumn.bindh,
d->err,
i + 1, bindColumn.data,
1509 bindColumn.maxLen, bindColumn.bindAs, bindColumn.indicators, bindColumn.lengths,
1510 arrayBind ? bindColumn.maxarr_len : 0, arrayBind ? &bindColumn.curelep : 0);
1512 for (
int ii = 0; ii < (int)bindColumn.recordCount; ++ii) {
1513 qCDebug(lcOci,
" record %d: indicator %d, length %d", ii, bindColumn.indicators[ii],
1514 bindColumn.lengths[ii]);
1521 d->sql, &bindColumn.bindh,
d->err,
i + 1,
1525 bindColumn.indicators,
1528 arrayBind ? bindColumn.maxarr_len : 0,
1529 arrayBind ? &bindColumn.curelep : 0,
1533 qCDebug(lcOci,
"After OCIBindByPos: r = %d, bindh = %p",
r, bindColumn.bindh);
1536 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1537 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:",
d->err);
1539 "Unable to bind column for batch execute"),
1544 r = OCIBindArrayOfStruct (
1545 columns[
i].bindh,
d->err,
1547 sizeof(columns[
i].indicators[0]),
1548 sizeof(columns[
i].lengths[0]),
1551 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1552 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:",
d->err);
1554 "Unable to bind column for batch execute"),
1561 r = OCIStmtExecute(
d->svc,
d->sql,
d->err,
1562 arrayBind ? 1 : columns[0].recordCount,
1564 d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS);
1566 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1567 qOraWarning(
"QOCIPrivate::execBatch: unable to execute batch statement:",
d->err);
1569 "Unable to execute batch statement"),
1575 for (
i = 0;
i < columnCount; ++
i) {
1577 if (!
d->isOutValue(
i))
1580 if (
auto tp = boundValues.
at(
i).
metaType(); tp.id() != QMetaType::QVariantList) {
1582 if (*columns[
i].indicators == -1)
1589 char*
data = columns[
i].data;
1590 for (
uint r = 0;
r < columns[
i].recordCount; ++
r){
1592 if (columns[
i].indicators[
r] == -1) {
1597 switch(columns[
i].bindAs) {
1599 case SQLT_TIMESTAMP_TZ:
1601 *
reinterpret_cast<OCIDateTime **
>(
data +
r * columns[
i].maxLen));
1604 (*list)[
r] = *
reinterpret_cast<int*
>(
data +
r * columns[
i].maxLen);
1608 (*list)[
r] = *
reinterpret_cast<uint*
>(
data +
r * columns[
i].maxLen);
1614 case QMetaType::LongLong:
1617 case QMetaType::ULongLong:
1627 (*list)[
r] = *
reinterpret_cast<double*
>(
data +
r * columns[
i].maxLen);
1632 +
r * columns[
i].maxLen));
1642 d->q_func()->setSelect(
false);
1644 d->q_func()->setActive(
true);
1650template<
class T,
int sz>
1658 r = OCILobCharSetForm(
d->env,
d->err, lob, &csfrm);
1659 if (
r != OCI_SUCCESS) {
1660 qOraWarning(
"OCIResultPrivate::readLobs: Couldn't get LOB char set form: ",
d->err);
1665 r = OCILobGetLength(
d->svc,
d->err, lob, &amount);
1666 if (
r == OCI_SUCCESS) {
1673 qOraWarning(
"OCIResultPrivate::readLobs: Couldn't get LOB length: ",
d->err);
1681 r = OCILobRead(
d->svc,
1694 if (
r != OCI_SUCCESS)
1695 qOraWarning(
"OCIResultPrivate::readLOBs: Cannot read LOB: ",
d->err);
1703 int r = OCI_SUCCESS;
1705 for (
int i = 0;
i <
size(); ++
i) {
1706 const OraFieldInf &fi = fieldInf.
at(
i);
1707 if (fi.ind == -1 || !(lob = fi.lob))
1710 bool isClob = fi.oraType == SQLT_CLOB;
1715 r = qReadLob<QString, sizeof(QChar)>(
str, d, lob);
1719 r = qReadLob<QByteArray, sizeof(char)>(
buf, d, lob);
1722 if (
r == OCI_SUCCESS)
1732 for (
int i = 0;
i < fieldInf.
count(); ++
i) {
1733 if (fieldInf.
at(
i).def ==
d)
1741 for (
int i = 0;
i < fieldInf.
size(); ++
i) {
1742 const OraFieldInf &fld = fieldInf.
at(
i);
1744 if (fld.ind == -1) {
1750 if (fld.oraType == SQLT_BIN || fld.oraType == SQLT_LBI || fld.oraType == SQLT_LNG)
1753 switch (fld.typ.id()) {
1754 case QMetaType::QDateTime:
1756 reinterpret_cast<OCIDateTime *
>(fld.dataPtr)));
1758 case QMetaType::Double:
1759 case QMetaType::Int:
1760 case QMetaType::LongLong:
1763 && (fld.typ.id() == QMetaType::Double)) {
1764 v[
index +
i] = *
reinterpret_cast<double *
>(fld.data);
1767 && (fld.typ.id() == QMetaType::LongLong)) {
1769 int r = OCINumberToInt(d->
err,
reinterpret_cast<OCINumber *
>(fld.data),
sizeof(
qint64),
1770 OCI_NUMBER_SIGNED, &qll);
1771 if (
r == OCI_SUCCESS)
1777 && (fld.typ.id() == QMetaType::Int)) {
1778 v[
index +
i] = *
reinterpret_cast<int *
>(fld.data);
1783 case QMetaType::QString:
1786 case QMetaType::QByteArray:
1793 qCWarning(lcOci,
"QOCICols::value: unknown data type");
1801 env(drv_d_func()->env),
1802 svc(const_cast<
OCISvcCtx*&>(drv_d_func()->svc)),
1803 transaction(drv_d_func()->transaction),
1804 serverVersion(drv_d_func()->serverVersion),
1805 prefetchRows(drv_d_func()->prefetchRows),
1806 prefetchMem(drv_d_func()->prefetchMem)
1809 int r = OCIHandleAlloc(
env,
1810 reinterpret_cast<void **
>(&
err),
1813 if (
r != OCI_SUCCESS)
1814 qCWarning(lcOci,
"QOCIResult: unable to alloc error handle");
1821 if (
sql && OCIHandleFree(
sql, OCI_HTYPE_STMT) != OCI_SUCCESS)
1822 qCWarning(lcOci,
"~QOCIResult: unable to free statement handle");
1824 if (OCIHandleFree(
err, OCI_HTYPE_ERROR) != OCI_SUCCESS)
1825 qCWarning(lcOci,
"~QOCIResult: unable to free error report handle");
1859 bool piecewise =
false;
1860 int r = OCI_SUCCESS;
1861 r = OCIStmtFetch(
d->sql,
d->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1864 return r == OCI_SUCCESS ||
r == OCI_SUCCESS_WITH_INFO;
1869 case OCI_SUCCESS_WITH_INFO:
1870 qOraWarning(
"QOCIResult::gotoNext: SuccessWithInfo: ",
d->err);
1890 "Unable to goto next"),
1896 if (
r == OCI_SUCCESS && piecewise)
1899 if (
r == OCI_SUCCESS)
1901 if (
r == OCI_SUCCESS)
1903 if (
r != OCI_SUCCESS)
1905 return r == OCI_SUCCESS ||
r == OCI_SUCCESS_WITH_INFO;
1937 r = OCIHandleFree(
d->sql, OCI_HTYPE_STMT);
1938 if (
r == OCI_SUCCESS)
1941 qOraWarning(
"QOCIResult::prepare: unable to free statement handle:",
d->err);
1943 if (
query.isEmpty())
1945 r = OCIHandleAlloc(
d->env,
1946 reinterpret_cast<void **
>(&
d->sql),
1949 if (
r != OCI_SUCCESS) {
1950 qOraWarning(
"QOCIResult::prepare: unable to alloc statement:",
d->err);
1955 d->setStatementAttributes();
1956 const OraText *
txt =
reinterpret_cast<const OraText *
>(
query.utf16());
1958 r = OCIStmtPrepare(
d->sql,
1964 if (
r != OCI_SUCCESS) {
1965 qOraWarning(
"QOCIResult::prepare: unable to prepare statement:",
d->err);
1984 r = OCIAttrGet(
d->sql,
1991 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1992 qOraWarning(
"QOCIResult::exec: Unable to get statement type:",
d->err);
2001 iters = stmtType == OCI_STMT_SELECT ? 0 : 1;
2002 mode =
d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS;
2006 &&
d->bindValues(
boundValues(), indicators, tmpSizes, tmpStorage) != OCI_SUCCESS) {
2007 qOraWarning(
"QOCIResult::exec: unable to bind value: ",
d->err);
2017 r = OCIStmtExecute(
d->svc,
2025 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
2026 qOraWarning(
"QOCIResult::exec: unable to execute statement:",
d->err);
2035 if (stmtType == OCI_STMT_SELECT) {
2037 int r = OCIAttrGet(
d->sql, OCI_HTYPE_STMT,
reinterpret_cast<void **
>(&parmCount),
2038 0, OCI_ATTR_PARAM_COUNT,
d->err);
2039 if (
r == 0 && !
d->cols)
2061 return d->cols->rec;
2070 int r = OCIAttrGet(
d->sql, OCI_HTYPE_STMT,
ptr.constData()->id,
2071 0, OCI_ATTR_ROWID,
d->err);
2072 if (
r == OCI_SUCCESS)
2109 const ub4
mode = OCI_UTF16 | OCI_OBJECT | OCI_THREADED;
2111 const ub4
mode = OCI_UTF16 | OCI_OBJECT;
2113 int r = OCIEnvCreate(&
d->env,
2122 qCWarning(lcOci,
"QOCIDriver: unable to create environment");
2128 d->allocErrorHandle();
2138 d->allocErrorHandle();
2151 int r = OCIHandleFree(
d->err, OCI_HTYPE_ERROR);
2152 if (
r != OCI_SUCCESS)
2153 qCWarning(lcOci,
"Unable to free Error handle: %d",
r);
2154 r = OCIHandleFree(
d->env, OCI_HTYPE_ENV);
2155 if (
r != OCI_SUCCESS)
2156 qCWarning(lcOci,
"Unable to free Environment handle: %d",
r);
2180 return d->serverVersion >= 9;
2188 for (
const auto tmp : opts) {
2190 if ((idx = tmp.indexOf(u
'=')) == -1) {
2191 qCWarning(lcOci,
"QOCIDriver::parseArgs: Invalid parameter: '%ls'",
2198 if (
opt ==
"OCI_ATTR_PREFETCH_ROWS"_L1) {
2199 d->prefetchRows =
val.toInt(&
ok);
2201 d->prefetchRows = -1;
2202 }
else if (
opt ==
"OCI_ATTR_PREFETCH_MEMORY"_L1) {
2203 d->prefetchMem =
val.toInt(&
ok);
2205 d->prefetchMem = -1;
2206 }
else if (
opt ==
"OCI_AUTH_MODE"_L1) {
2207 if (
val ==
"OCI_SYSDBA"_L1) {
2208 d->authMode = OCI_SYSDBA;
2209 }
else if (
val ==
"OCI_SYSOPER"_L1) {
2210 d->authMode = OCI_SYSOPER;
2211 }
else if (
val !=
"OCI_DEFAULT"_L1) {
2212 qCWarning(lcOci,
"QOCIDriver::parseArgs: Unsupported value for OCI_AUTH_MODE: '%ls'",
2216 qCWarning(lcOci,
"QOCIDriver::parseArgs: Invalid parameter: '%ls'",
2242 "(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((
port > -1 ?
port : 1521)).arg(
db);
2245 r = OCIHandleAlloc(
d->env,
reinterpret_cast<void **
>(&
d->srvhp), OCI_HTYPE_SERVER, 0,
nullptr);
2246 if (
r == OCI_SUCCESS) {
2247 r = OCIServerAttach(
d->srvhp,
d->err,
2248 reinterpret_cast<const OraText *
>(connectionString.utf16()),
2249 connectionString.length() *
sizeof(
QChar), OCI_DEFAULT);
2252 if (
r == OCI_SUCCESS ||
r == OCI_SUCCESS_WITH_INFO) {
2253 r = OCIHandleAlloc(
d->env,
reinterpret_cast<void **
>(&
d->svc), OCI_HTYPE_SVCCTX,
2256 if (
r == OCI_SUCCESS)
2257 r = OCIAttrSet(
d->svc, OCI_HTYPE_SVCCTX,
d->srvhp, 0, OCI_ATTR_SERVER,
d->err);
2259 if (
r == OCI_SUCCESS) {
2260 r = OCIHandleAlloc(
d->env,
reinterpret_cast<void **
>(&
d->authp), OCI_HTYPE_SESSION,
2263 if (
r == OCI_SUCCESS) {
2264 r = OCIAttrSet(
d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *
>(user.
utf16()),
2265 user.
length() *
sizeof(
QChar), OCI_ATTR_USERNAME,
d->err);
2267 if (
r == OCI_SUCCESS) {
2268 r = OCIAttrSet(
d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *
>(password.
utf16()),
2269 password.
length() *
sizeof(
QChar), OCI_ATTR_PASSWORD,
d->err);
2272 if (
r == OCI_SUCCESS) {
2273 r = OCIHandleAlloc(
d->env,
reinterpret_cast<void **
>(&
d->trans), OCI_HTYPE_TRANS,
2276 if (
r == OCI_SUCCESS)
2277 r = OCIAttrSet(
d->svc, OCI_HTYPE_SVCCTX,
d->trans, 0, OCI_ATTR_TRANS,
d->err);
2279 if (
r == OCI_SUCCESS) {
2281 r = OCISessionBegin(
d->svc,
d->err,
d->authp, OCI_CRED_EXT,
d->authMode);
2283 r = OCISessionBegin(
d->svc,
d->err,
d->authp, OCI_CRED_RDBMS,
d->authMode);
2285 if (
r == OCI_SUCCESS ||
r == OCI_SUCCESS_WITH_INFO)
2286 r = OCIAttrSet(
d->svc, OCI_HTYPE_SVCCTX,
d->authp, 0, OCI_ATTR_SESSION,
d->err);
2288 if (
r != OCI_SUCCESS) {
2292 OCIHandleFree(
d->trans, OCI_HTYPE_TRANS);
2295 OCIHandleFree(
d->authp, OCI_HTYPE_SESSION);
2298 OCIHandleFree(
d->svc, OCI_HTYPE_SVCCTX);
2301 OCIHandleFree(
d->srvhp, OCI_HTYPE_SERVER);
2308 r = OCIServerVersion(
d->svc,
2310 reinterpret_cast<OraText *
>(vertxt),
2314 qCWarning(lcOci,
"QOCIDriver::open: could not get Oracle server version.");
2317 versionStr =
QString(
reinterpret_cast<const QChar *
>(vertxt));
2318#if QT_CONFIG(regularexpression)
2320 if (
match.hasMatch())
2321 d->serverVersion =
match.captured(1).toInt();
2323 if (
d->serverVersion == 0)
2324 d->serverVersion = -1;
2340 OCISessionEnd(
d->svc,
d->err,
d->authp, OCI_DEFAULT);
2341 OCIServerDetach(
d->srvhp,
d->err, OCI_DEFAULT);
2342 OCIHandleFree(
d->trans, OCI_HTYPE_TRANS);
2344 OCIHandleFree(
d->authp, OCI_HTYPE_SESSION);
2346 OCIHandleFree(
d->svc, OCI_HTYPE_SVCCTX);
2348 OCIHandleFree(
d->srvhp, OCI_HTYPE_SERVER);
2363 qCWarning(lcOci,
"QOCIDriver::beginTransaction: Database not open");
2366 int r = OCITransStart(
d->svc,
2369 OCI_TRANS_READWRITE);
2370 if (
r == OCI_ERROR) {
2376 d->transaction =
true;
2384 qCWarning(lcOci,
"QOCIDriver::commitTransaction: Database not open");
2387 int r = OCITransCommit(
d->svc,
2390 if (
r == OCI_ERROR) {
2396 d->transaction =
false;
2404 qCWarning(lcOci,
"QOCIDriver::rollbackTransaction: Database not open");
2407 int r = OCITransRollback(
d->svc,
2410 if (
r == OCI_ERROR) {
2411 qOraWarning(
"QOCIDriver::rollbackTransaction:",
d->err);
2416 d->transaction =
false;
2427 static const char sysUsers[][8] = {
2436 static const char joinC[][4] = {
"or" ,
"and" };
2437 static constexpr char16_t bang[] = { u
' ', u
'!' };
2444 (9 +
sizeof *sysUsers + 5));
2445 for (
const auto &sysUser : sysUsers) {
2448 result +=
"owner "_L1 + bang[e] +
"= '"_L1 + l1 +
"' "_L1 + join + u
' ';
2471 t.setForwardOnly(
true);
2473 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2475 t.exec(tableQuery + where);
2477 if (
t.value(0).toString().toUpper() != user.
toUpper())
2478 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2480 tl.append(
t.value(1).toString());
2484 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2485 t.exec(synonymQuery + where);
2487 if (
t.value(0).toString() !=
d->user)
2488 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2490 tl.append(
t.value(1).toString());
2494 const auto query =
"select owner, view_name from all_views where "_L1;
2498 if (
t.value(0).toString().toUpper() !=
d->user.toUpper())
2499 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2501 tl.append(
t.value(1).toString());
2505 t.exec(
"select table_name from dictionary"_L1);
2507 tl.append(
t.value(0).toString());
2509 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2511 t.exec(tableQuery + where);
2513 if (
t.value(0).toString().toUpper() != user.
toUpper())
2514 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2516 tl.append(
t.value(1).toString());
2520 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2521 t.exec(synonymQuery + where);
2523 if (
t.value(0).toString() !=
d->user)
2524 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2526 tl.append(
t.value(1).toString());
2537 *tbl = tname.right(tname.length() -
i - 1);
2538 *owner = tname.
left(
i);
2554 QString stmt(
"select column_name, data_type, data_length, "
2555 "data_precision, data_scale, nullable, data_default%1"
2556 "from all_tab_columns a "_L1);
2557 if (
d->serverVersion >= 9)
2558 stmt = stmt.
arg(
", char_length "_L1);
2560 stmt = stmt.
arg(
" "_L1);
2561 bool buildRecordInfo =
false;
2570 tmpStmt = stmt +
"where a.table_name='"_L1 +
table + u
'\'';
2580 tmpStmt +=
" and a.owner='"_L1 + owner + u
'\'';
2581 t.setForwardOnly(
true);
2584 stmt = stmt +
" join all_synonyms b on a.owner=b.table_owner and a.table_name=b.table_name "
2585 "where b.owner='"_L1 + owner +
"' and b.synonym_name='"_L1 +
table + u
'\'';
2586 t.setForwardOnly(
true);
2589 buildRecordInfo =
true;
2591 buildRecordInfo =
true;
2594 <<
"BINARY_DOUBLE"_L1;
2595 if (buildRecordInfo) {
2599 f.setRequired(
t.value(5).toString() ==
"N"_L1);
2600 f.setPrecision(
t.value(4).toInt());
2601 if (
d->serverVersion >= 9 && (
ty.id() == QMetaType::QString) && !
t.isNull(3) && !
keywords.contains(
t.value(1).toString())) {
2603 f.setLength(
t.value(7).toInt());
2605 f.setLength(
t.value(
t.isNull(3) ? 2 : 3).
toInt());
2607 f.setDefaultValue(
t.value(6));
2621 QString stmt(
"select b.column_name, b.index_name, a.table_name, a.owner "
2622 "from all_constraints a, all_ind_columns b "
2623 "where a.constraint_type='P' "
2624 "and b.index_name = a.index_name "
2625 "and b.index_owner = a.owner"_L1);
2627 bool buildIndex =
false;
2636 tmpStmt = stmt +
" and a.table_name='"_L1 +
table + u
'\'';
2646 tmpStmt +=
" and a.owner='"_L1 + owner + u
'\'';
2647 t.setForwardOnly(
true);
2651 stmt +=
" and a.table_name=(select tname from sys.synonyms where sname='"_L1
2652 +
table +
"' and creator=a.owner)"_L1;
2653 t.setForwardOnly(
true);
2656 owner =
t.value(3).toString();
2664 tt.setForwardOnly(
true);
2665 idx.
setName(
t.value(1).toString());
2667 tt.exec(
"select data_type from all_tab_columns where table_name='"_L1 +
2668 t.value(2).toString() +
"' and column_name='"_L1 +
2669 t.value(0).toString() +
"' and owner='"_L1 +
2685 case QMetaType::QDateTime: {
2696 +
"','YYYY-MM-DD HH24:MI:SS')"_L1;
2698 datestring =
"NULL"_L1;
2702 case QMetaType::QTime: {
2706 datestring =
"TO_DATE('"_L1
2710 +
"','HH24:MI:SS')"_L1;
2712 datestring =
"NULL"_L1;
2716 case QMetaType::QDate: {
2725 datestring =
"NULL"_L1;
2756 return d->serverVersion > 12 ? 128 : 30;
2761#include "moc_qsql_oci_p.cpp"
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
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.
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
qsizetype capacity() const
Returns the maximum number of bytes that can be stored in the byte array without forcing a reallocati...
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
\inmodule QtCore\reentrant
QTime time() const
Returns the time part of the datetime.
bool isValid() const
Returns true if this datetime represents a definite moment, otherwise false.
QDate date() const
Returns the date part of the datetime.
\inmodule QtCore \reentrant
constexpr bool isValid() const
Returns true if this date is valid; otherwise returns false.
int month() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int day() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int year() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr void chop(qsizetype n)
constexpr qsizetype size() const noexcept
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
T value(qsizetype i) const
qsizetype count() const noexcept
int readPiecewise(QVariantList &values, int index=0)
int fieldFromDefine(OCIDefine *d)
void getValues(QVariantList &v, int index)
int readLOBs(QVariantList &values, int index=0)
static bool execBatch(QOCIResultPrivate *d, QVariantList &boundValues, bool arrayBind)
QOCICols(int size, QOCIResultPrivate *dp)
static QDateTime fromOCIDateTime(OCIEnv *env, OCIError *err, OCIDateTime *dt)
QOCIDateTime(OCIEnv *env, OCIError *err, const QDateTime &dt=QDateTime())
QString formatValue(const QSqlField &field, bool trimStrings) const override
Returns a string representation of the field value for the database.
bool rollbackTransaction() override
This function is called to rollback a transaction.
int maximumIdentifierLength(IdentifierType type) const override
QStringList tables(QSql::TableType) const override
Returns a list of the names of the tables in the database.
QSqlIndex primaryIndex(const QString &tablename) const override
Returns the primary index for table tableName.
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.
bool commitTransaction() override
This function is called to commit a transaction.
bool beginTransaction() override
This function is called to begin a transaction.
QSqlRecord record(const QString &tablename) const override
Returns a QSqlRecord populated with the names of the fields in table tableName.
QSqlResult * createResult() const override
Creates an empty SQL result on the database.
QVariant handle() const override
Returns the low-level database handle wrapped in a QVariant or an invalid variant if there is no hand...
void close() override
Derived classes must reimplement this pure virtual function in order to close the database connection...
QOCIDriver(QObject *parent=nullptr)
QString escapeIdentifier(const QString &identifier, IdentifierType) const override
Returns the identifier escaped according to the database rules.
void setCharset(dvoid *handle, ub4 type) const
void setStatementAttributes()
QOCIResultPrivate(QOCIResult *q, const QOCIDriver *drv)
bool isOutValue(int i) const
int bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos, const QVariant &val, dvoid *indPtr, ub2 *tmpSize, TempStorage &tmpStorage)
int bindValues(QVariantList &values, IndicatorArray &indicators, SizeArray &tmpSizes, TempStorage &tmpStorage)
bool isBinaryValue(int i) const
void outValues(QVariantList &values, IndicatorArray &indicators, TempStorage &tmpStorage)
bool execBatch(bool arrayBind=false) override
QOCIResult(const QOCIDriver *db)
int numRowsAffected() override
Returns the number of rows affected by the last query executed, or -1 if it cannot be determined or i...
QSqlRecord record() const override
Returns the current record if the query is active; otherwise returns an empty QSqlRecord.
bool exec() override
Executes the query, returning true if successful; otherwise returns false.
bool reset(const QString &query) override
Sets the result to use the SQL statement query for subsequent data retrieval.
bool prepare(const QString &query) override
Prepares the given query for execution; the query will normally use placeholders so that it can be ex...
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 gotoNext(ValueCache &values, int index) override
void virtual_hook(int id, void *data) override
bool fetchNext() override
Positions the result to the next available record (row) in the result.
QVariant lastInsertId() const override
Returns the object ID of the most recent inserted row if the database supports it.
\inmodule QtCore \reentrant
QRegularExpressionMatch match(const QString &subject, qsizetype offset=0, MatchType matchType=NormalMatch, MatchOptions matchOptions=NoMatchOption) const
Attempts to match the regular expression against the given subject string, starting at the position o...
void virtual_hook(int id, void *data) override
bool fetchNext() override
Positions the result to the next available record (row) in the result.
QSqlDriver::DbmsType dbmsType
The QSqlDriver class is an abstract base class for accessing specific SQL databases.
virtual QString formatValue(const QSqlField &field, bool trimStrings=false) const
Returns a string representation of the field value for the database.
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 type() const
Returns the error type, or -1 if the type cannot be determined.
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.
The QSqlIndex class provides functions to manipulate and describe database indexes.
void setName(const QString &name)
Sets \l name to name.
void append(const QSqlField &field)
Appends the field field to the list of indexed fields.
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.
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.
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...
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...
QString lastQuery() const
Returns the current SQL query text, or an empty string if there isn't one.
bool hasOutValues() const
Returns true if at least one of the query's bound values is a QSql::Out or a QSql::InOut; otherwise r...
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)
void resetBindCount()
Resets the number of bind parameters.
QSqlError lastError() const
Returns the last error associated with the result.
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
int boundValueCount() const
Returns the number of bound values in 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.
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString left(qsizetype n) const &
QString & replace(qsizetype i, qsizetype len, QChar after)
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
qsizetype capacity() const
Returns the maximum number of characters that can be stored in the string without forcing a reallocat...
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString toUpper() const &
qsizetype length() const noexcept
Returns the number of characters in this string.
static QTimeZone fromSecondsAheadOfUtc(int offset)
\inmodule QtCore \reentrant
int hour() const
Returns the hour part (0 to 23) of the time.
int minute() const
Returns the minute part (0 to 59) of the time.
int msec() const
Returns the millisecond part (0 to 999) of the time.
int second() const
Returns the second part (0 to 59) of the time.
void * data()
Returns a pointer to the contained object as a generic void* that can be written to.
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has userType() \l QMetaType::QDateTime,...
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has userType() \l QMetaType::QVariantList.
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
int typeId() const
Returns the storage type of the value stored in the variant.
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 >
QDate toDate() const
Returns the variant as a QDate if the variant has userType() \l QMetaType::QDate, \l QMetaType::QDate...
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
QMetaType metaType() const
qDeleteAll(list.begin(), list.end())
static const struct @480 keywords[]
Combined button and popup list for selecting options.
QList< QString > QStringList
Constructs a string list that contains the given string, str.
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
static ControlElement< T > * ptr(QWidget *widget)
constexpr T qAbs(const T &t)
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
GLuint64 GLenum void * handle
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei GLenum GLenum GLuint GLenum GLsizei * lengths
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum const GLint * param
GLdouble GLdouble GLdouble GLdouble q
GLenum GLenum GLsizei void * row
GLenum GLenum GLsizei void * table
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static void split(QT_FT_Vector *b)
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QDB2DriverPrivate *p)
static QString make_where_clause(const QString &user, Expression e)
int qReadLob(T &buf, const QOCIResultPrivate *d, OCILobLocator *lob)
QSharedDataPointer< QOCIRowId > QOCIRowIdPointer
#define QOCI_PREFETCH_MEM
static void qOraOutValue(QVariant &value, TempStorage &tmpStorage, OCIEnv *env, OCIError *err)
static qlonglong qMakeLongLong(const char *ociNumber, OCIError *err)
static QString qOraWarn(OCIError *err, int *errorCode=0)
static qulonglong qMakeULongLong(const char *ociNumber, OCIError *err)
static void qOraWarning(const char *msg, OCIError *err)
#define QOCI_DYNAMIC_CHUNK_SIZE
static void qParseOpts(const QString &options, QOCIDriverPrivate *d)
static QSqlField qFromOraInf(const OraFieldInfo &ofi)
static QSqlError qMakeError(const QString &errString, QSqlError::ErrorType type, OCIError *err)
static int qOraErrorNumber(OCIError *err)
static const ub2 qOraCharset
QVarLengthArray< ub2, 32 > SizeArray
QMetaType qDecodeOCIType(const QString &ocitype, QSql::NumericalPrecisionPolicy precisionPolicy)
static QByteArray qMakeOCINumber(const qlonglong &ll, OCIError *err)
void qSplitTableAndOwner(const QString &tname, QString *tbl, QString *owner)
QVarLengthArray< sb2, 32 > IndicatorArray
struct OCISvcCtx OCISvcCtx
#define Q_DECLARE_SQLDRIVER_PRIVATE(Class)
#define qUtf16Printable(string)
#define QT_BEGIN_INCLUDE_NAMESPACE
#define QT_END_INCLUDE_NAMESPACE
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
static int toInt(const QChar &qc, int R)
QOCIBatchCleanupHandler(QList< QOCIBatchColumn > &columns)
QList< QOCIBatchColumn > & col
~QOCIBatchCleanupHandler()
QList< QOCIDateTime * > dateTimes
QList< QByteArray > rawData