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
59using namespace
Qt::StringLiterals;
61#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
67#ifdef OCI_ATTR_CHARSET_FORM
72static const ub1 qOraCharsetForm = SQLCS_NCHAR;
75#if defined (OCI_UTF16ID)
115 OCIDescriptorAlloc (env,
reinterpret_cast<dvoid **
>(&
id),
116 OCI_DTYPE_ROWID, 0, 0);
122 OCIDescriptorFree(
id, OCI_DTYPE_ROWID);
137 OCIDescriptorAlloc(env,
reinterpret_cast<void**
>(&
dateTime), OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
142 const QString timeZone = dt.toString(
"ttt"_L1);
143 const OraText *
tz =
reinterpret_cast<const OraText *
>(timeZone.
utf16());
146 const_cast<OraText *
>(
tz), timeZone.
length() *
sizeof(
QChar));
153 OCIDescriptorFree(
dateTime, OCI_DTYPE_TIMESTAMP_TZ);
159 ub1 month, day, hour, minute, second;
161 sb1 tzHour, tzMinute;
163 OCIDateTimeGetDate(env, err,
dateTime, &year, &month, &day);
164 OCIDateTimeGetTime(env, err,
dateTime, &hour, &minute, &second, &nsec);
165 OCIDateTimeGetTimeZoneOffset(env, err,
dateTime, &tzHour, &tzMinute);
166 int secondsOffset = (
qAbs(tzHour) * 60 + tzMinute) * 60;
168 secondsOffset = -secondsOffset;
243#ifdef OCI_ATTR_CHARSET_FORM
248 const_cast<void *
>(
static_cast<const void *
>(&qOraCharsetForm)),
250 OCI_ATTR_CHARSET_FORM,
256 qCWarning(lcOci,
"QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_FORM.");
264 const_cast<void *
>(
static_cast<const void *
>(&
qOraCharset)),
269 qOraWarning(
"QOCIResultPrivate::setCharsetI Couldn't set OCI_ATTR_CHARSET_ID: ",
err);
285 OCI_ATTR_PREFETCH_ROWS,
288 qOraWarning(
"QOCIResultPrivate::setStatementAttributes:"
289 " Couldn't set OCI_ATTR_PREFETCH_ROWS: ",
err);
296 OCI_ATTR_PREFETCH_MEMORY,
299 qOraWarning(
"QOCIResultPrivate::setStatementAttributes:"
300 " Couldn't set OCI_ATTR_PREFETCH_MEMORY: ",
err);
308 void *
data =
const_cast<void *
>(val.constData());
310 switch (val.typeId()) {
311 case QMetaType::QByteArray:
312 r = OCIBindByPos(
sql, hbnd,
err,
315 ?
const_cast<char *
>(
reinterpret_cast<QByteArray *
>(
data)->constData())
318 SQLT_BIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
320 case QMetaType::QTime:
321 case QMetaType::QDate:
322 case QMetaType::QDateTime: {
324 r = OCIBindByPos(
sql, hbnd,
err,
327 sizeof(OCIDateTime *),
328 SQLT_TIMESTAMP_TZ, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
329 tmpStorage.dateTimes.append(
ptr);
333 r = OCIBindByPos(
sql, hbnd,
err,
337 const_cast<void *
>(
data),
339 SQLT_INT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
341 case QMetaType::UInt:
342 r = OCIBindByPos(
sql, hbnd,
err,
346 const_cast<void *
>(
data),
348 SQLT_UIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
350 case QMetaType::LongLong:
353 r = OCIBindByPos(
sql, hbnd,
err,
357 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
358 tmpStorage.rawData.append(
ba);
361 case QMetaType::ULongLong:
364 r = OCIBindByPos(
sql, hbnd,
err,
368 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
369 tmpStorage.rawData.append(
ba);
372 case QMetaType::Double:
373 r = OCIBindByPos(
sql, hbnd,
err,
377 const_cast<void *
>(
data),
379 SQLT_FLT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
381 case QMetaType::QString: {
384 r = OCIBindByPos(
sql, hbnd,
err,
386 const_cast<ushort *
>(
s.utf16()),
387 s.length() *
sizeof(
QChar),
388 SQLT_LNG, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
392 r = OCIBindByPos(
sql, hbnd,
err,
395 const_cast<ushort *
>(
s.utf16()),
396 (
s.length() + 1) *
sizeof(
QChar),
397 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
398 if (
r == OCI_SUCCESS)
409 r = OCIBindByPos(
sql, hbnd,
err,
412 const_cast<OCIRowid **
>(&rptr->id),
414 SQLT_RDD, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
418 if (
res->internal_prepare()) {
419 r = OCIBindByPos(
sql, hbnd,
err,
421 const_cast<OCIStmt **
>(&
res->d->sql),
423 SQLT_RSET, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
425 res->isCursor =
true;
428 qCWarning(lcOci,
"Unknown bind variable");
434 QByteArray ba(
reinterpret_cast<const char *
>(
s.utf16()), (
s.length() + 1) *
sizeof(
QChar));
438 r = OCIBindByPos(
sql, hbnd,
err,
442 SQLT_STR, indPtr, tmpSize, 0, 0, 0, OCI_DEFAULT);
444 r = OCIBindByPos(
sql, hbnd,
err,
448 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
450 if (
r == OCI_SUCCESS)
452 tmpStorage.rawData.append(
ba);
457 if (
r != OCI_SUCCESS)
466 for (
int i = 0;
i <
values.count(); ++
i) {
471 OCIBind * hbnd =
nullptr;
472 sb2 *indPtr = &indicators[
i];
483 switch (
value.typeId()) {
484 case QMetaType::QTime:
486 tmpStorage.dateTimes.takeFirst()->dateTime).time();
488 case QMetaType::QDate:
490 tmpStorage.dateTimes.takeFirst()->dateTime).date();
492 case QMetaType::QDateTime:
494 tmpStorage.dateTimes.takeFirst()->dateTime);
496 case QMetaType::LongLong:
499 case QMetaType::ULongLong:
502 case QMetaType::QString:
504 reinterpret_cast<const QChar *
>(tmpStorage.rawData.takeFirst().constData()));
514 for (
int i = 0;
i <
values.count(); ++
i) {
521 auto typ =
values.at(
i).metaType();
522 if (indicators[
i] == -1)
539 int r = OCIHandleAlloc(
env,
540 reinterpret_cast<void **
>(&
err),
543 if (
r != OCI_SUCCESS)
544 qCWarning(lcOci,
"QOCIDriver: unable to allocate error handle");
574 *errorCode = errcode;
575 return QString(
reinterpret_cast<const QChar *
>(errbuf));
607 if (ocitype ==
"VARCHAR2"_L1 || ocitype ==
"VARCHAR"_L1
608 || ocitype.startsWith(
"INTERVAL"_L1)
609 || ocitype ==
"CHAR"_L1 || ocitype ==
"NVARCHAR2"_L1
610 || ocitype ==
"NCHAR"_L1)
611 type = QMetaType::QString;
612 else if (ocitype ==
"NUMBER"_L1
613 || ocitype ==
"FLOAT"_L1
614 || ocitype ==
"BINARY_FLOAT"_L1
615 || ocitype ==
"BINARY_DOUBLE"_L1) {
616 switch(precisionPolicy) {
618 type = QMetaType::Int;
621 type = QMetaType::LongLong;
624 type = QMetaType::Double;
628 type = QMetaType::QString;
632 else if (ocitype ==
"LONG"_L1 || ocitype ==
"NCLOB"_L1 || ocitype ==
"CLOB"_L1)
633 type = QMetaType::QByteArray;
634 else if (ocitype ==
"RAW"_L1 || ocitype ==
"LONG RAW"_L1
635 || ocitype ==
"ROWID"_L1 || ocitype ==
"BLOB"_L1
636 || ocitype ==
"CFILE"_L1 || ocitype ==
"BFILE"_L1)
637 type = QMetaType::QByteArray;
638 else if (ocitype ==
"DATE"_L1 || ocitype.startsWith(
"TIME"_L1))
639 type = QMetaType::QDateTime;
640 else if (ocitype ==
"UNDEFINED"_L1)
659#ifdef SQLT_INTERVAL_YM
660 case SQLT_INTERVAL_YM:
662#ifdef SQLT_INTERVAL_DS
663 case SQLT_INTERVAL_DS:
665 type = QMetaType::QString;
668 type = QMetaType::Int;
674 switch(precisionPolicy) {
676 type = QMetaType::Int;
679 type = QMetaType::LongLong;
682 type = QMetaType::Double;
686 type = QMetaType::QString;
701 type = QMetaType::QByteArray;
706 case SQLT_TIMESTAMP_TZ:
707 case SQLT_TIMESTAMP_LTZ:
708 type = QMetaType::QDateTime;
711 qCWarning(lcOci,
"qDecodeOCIType: unknown OCI datatype: %d", ocitype);
720 f.setRequired(ofi.oraIsNull == 0);
722 if (ofi.type.id() == QMetaType::QString && ofi.oraType != SQLT_NUM && ofi.oraType != SQLT_VNU)
723 f.setLength(ofi.oraFieldLength);
725 f.setLength(ofi.oraPrecision == 0 ? 38 : int(ofi.oraPrecision));
727 f.setPrecision(ofi.oraScale);
740 OCINumberFromInt(err,
744 reinterpret_cast<OCINumber*
>(
ba.
data()));
757 OCINumberFromInt(err,
761 reinterpret_cast<OCINumber*
>(
ba.
data()));
768 OCINumberToInt(err,
reinterpret_cast<const OCINumber *
>(ociNumber),
sizeof(
qlonglong),
769 OCI_NUMBER_SIGNED, &qll);
776 OCINumberToInt(err,
reinterpret_cast<const OCINumber *
>(ociNumber),
sizeof(
qulonglong),
777 OCI_NUMBER_UNSIGNED, &qull);
803 OraFieldInf() :
data(0),
len(0), ind(0), oraType(0), def(0), lob(0), dataPtr(
nullptr)
816 QList<OraFieldInf> fieldInf;
820QOCICols::OraFieldInf::~OraFieldInf()
824 int r = OCIDescriptorFree(lob, OCI_DTYPE_LOB);
826 qCWarning(lcOci,
"QOCICols: Cannot free LOB descriptor");
830 case QMetaType::QDate:
831 case QMetaType::QTime:
832 case QMetaType::QDateTime: {
833 int r = OCIDescriptorFree(dataPtr, OCI_DTYPE_TIMESTAMP_TZ);
834 if (
r != OCI_SUCCESS)
835 qCWarning(lcOci,
"QOCICols: Cannot free OCIDateTime descriptor");
845 : fieldInf(
size), d(dp)
848 OCIDefine *dfn =
nullptr;
851 OCIParam *
param =
nullptr;
855 parmStatus = OCIParamGet(d->
sql,
858 reinterpret_cast<void **
>(&
param),
861 while (parmStatus == OCI_SUCCESS) {
863 if (ofi.oraType == SQLT_RDD)
865#ifdef SQLT_INTERVAL_YM
866#ifdef SQLT_INTERVAL_DS
867 else if (ofi.oraType == SQLT_INTERVAL_YM || ofi.oraType == SQLT_INTERVAL_DS)
873 else if (ofi.oraType == SQLT_NUM || ofi.oraType == SQLT_VNU){
874 if (ofi.oraPrecision > 0)
875 dataSize = (ofi.oraPrecision + 1) *
sizeof(utext);
877 dataSize = (38 + 1) *
sizeof(utext);
882 fieldInf[idx].typ = ofi.type;
883 fieldInf[idx].oraType = ofi.oraType;
886 switch (ofi.type.id()) {
887 case QMetaType::QDateTime:
888 r = OCIDescriptorAlloc(d->
env, (
void **)&fieldInf[idx].dataPtr, OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
889 if (
r != OCI_SUCCESS) {
890 qCWarning(lcOci,
"QOCICols: Unable to allocate the OCIDateTime descriptor");
893 r = OCIDefineByPos(d->
sql,
897 &fieldInf[idx].dataPtr,
898 sizeof(OCIDateTime *),
900 &(fieldInf[idx].ind),
903 case QMetaType::Double:
904 r = OCIDefineByPos(d->
sql,
908 create(idx,
sizeof(
double) - 1),
911 &(fieldInf[idx].ind),
915 r = OCIDefineByPos(d->
sql,
922 &(fieldInf[idx].ind),
925 case QMetaType::LongLong:
926 r = OCIDefineByPos(d->
sql,
930 create(idx,
sizeof(OCINumber)),
933 &(fieldInf[idx].ind),
936 case QMetaType::QByteArray:
938 if (ofi.oraType == SQLT_BIN) {
940 r = OCIDefineByPos(d->
sql,
947 &(fieldInf[idx].ind),
948 0, 0, OCI_DYNAMIC_FETCH);
949 }
else if (ofi.oraType == SQLT_LBI) {
951 r = OCIDefineByPos(d->
sql,
958 &(fieldInf[idx].ind),
959 0, 0, OCI_DYNAMIC_FETCH);
960 }
else if (ofi.oraType == SQLT_CLOB) {
961 r = OCIDefineByPos(d->
sql,
965 createLobLocator(idx, d->
env),
968 &(fieldInf[idx].ind),
972 r = OCIDefineByPos(d->
sql,
976 createLobLocator(idx, d->
env),
979 &(fieldInf[idx].ind),
983 case QMetaType::QString:
984 if (ofi.oraType == SQLT_LNG) {
985 r = OCIDefineByPos(d->
sql,
992 &(fieldInf[idx].ind),
993 0, 0, OCI_DYNAMIC_FETCH);
997 r = OCIDefineByPos(d->
sql,
1004 &(fieldInf[idx].ind),
1014 r = OCIDefineByPos(d->
sql,
1021 &(fieldInf[idx].ind),
1027 fieldInf[idx].def = dfn;
1030 parmStatus = OCIParamGet(d->
sql,
1033 reinterpret_cast<void **
>(&
param),
1044 char*
c =
new char[
size+1];
1046 memset(
c, 0,
size+1);
1052OCILobLocator **QOCICols::createLobLocator(
int position,
OCIEnv* env)
1054 OCILobLocator *& lob = fieldInf[
position].lob;
1055 int r = OCIDescriptorAlloc(env,
1056 reinterpret_cast<void **
>(&lob),
1061 qCWarning(lcOci,
"QOCICols: Cannot create LOB locator");
1082 r = OCIStmtGetPieceInfo(d->
sql, d->
err,
reinterpret_cast<void **
>(&dfn), &typep,
1083 &in_outp, &iterp, &idxp, &piecep);
1084 if (
r != OCI_SUCCESS)
1085 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to get piece info:", d->
err);
1087 bool isStringField = fieldInf.
at(fieldNum).oraType == SQLT_LNG;
1090 r = OCIStmtSetPieceInfo(dfn, OCI_HTYPE_DEFINE,
1092 &chunkSize, piecep, NULL, NULL);
1093 if (
r != OCI_SUCCESS)
1094 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to set piece info:", d->
err);
1095 status = OCIStmtFetch (d->
sql, d->
err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1098 OCIErrorGet(d->
err, 1, 0, &errcode, 0, 0,OCI_HTYPE_ERROR);
1104 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to fetch next:", d->
err);
1108 if (status == OCI_NO_DATA)
1110 if (nullField || !chunkSize) {
1111 fieldInf[fieldNum].ind = -1;
1113 if (isStringField) {
1117 fieldInf[fieldNum].ind = 0;
1122 memcpy(
ba.
data() + sz,
reinterpret_cast<char *
>(col), chunkSize);
1124 fieldInf[fieldNum].ind = 0;
1127 }
while (status == OCI_SUCCESS_WITH_INFO || status == OCI_NEED_DATA);
1135 text *colName =
nullptr;
1139 ub2 colFieldLength(0);
1140 sb2 colPrecision(0);
1171#ifdef OCI_ATTR_CHAR_SIZE
1182 colFieldLength = colLength;
1221 if (
type.id() == QMetaType::Int) {
1222 if ((colLength == 22 && colPrecision == 0 && colScale == 0) || colScale > 0)
1227 if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
1233 if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
1234 || (colType == SQLT_INT)) {
1241 if (colType == SQLT_BLOB)
1245 ofi.name =
QString(
reinterpret_cast<const QChar*
>(colName), colNameLen / 2);
1247 ofi.oraType = colType;
1248 ofi.oraFieldLength = colFieldLength;
1249 ofi.oraLength = colLength;
1250 ofi.oraScale = colScale;
1251 ofi.oraPrecision = colPrecision;
1252 ofi.oraIsNull = colIsNull;
1283 delete[]
col[
j].lengths;
1284 delete[]
col[
j].indicators;
1294 int columnCount = boundValues.
count();
1295 if (boundValues.
isEmpty() || columnCount == 0)
1299 qCDebug(lcOci) <<
"columnCount:" << columnCount << boundValues;
1305 QVarLengthArray<QMetaType> fieldTypes;
1306 for (
i = 0;
i < columnCount; ++
i) {
1311 QList<QOCIBatchColumn> columns(columnCount);
1316 for (
i = 0;
i < columnCount; ++
i) {
1318 if (boundValues.
at(
i).
typeId() != QMetaType::QVariantList) {
1322 singleCol.indicators =
new sb2[1];
1325 r =
d->bindValue(
d->sql, &singleCol.bindh,
d->err,
i,
1326 boundValues.
at(
i), singleCol.indicators, &tmpSizes[
i], tmpStorage);
1328 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1329 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:",
d->err);
1331 "Unable to bind column for batch execute"),
1346 switch (fieldTypes[
i].
id()) {
1347 case QMetaType::QTime:
1348 case QMetaType::QDate:
1349 case QMetaType::QDateTime:
1350 col.
bindAs = SQLT_TIMESTAMP_TZ;
1351 col.
maxLen =
sizeof(OCIDateTime *);
1354 case QMetaType::Int:
1356 col.
maxLen =
sizeof(int);
1359 case QMetaType::UInt:
1364 case QMetaType::LongLong:
1366 col.
maxLen =
sizeof(OCINumber);
1369 case QMetaType::ULongLong:
1371 col.
maxLen =
sizeof(OCINumber);
1374 case QMetaType::Double:
1376 col.
maxLen =
sizeof(double);
1379 case QMetaType::QString: {
1383 if (
d->isOutValue(
i))
1393 case QMetaType::QByteArray:
1397 col.
maxLen =
sizeof(OCIRowid*);
1401 if (
d->isOutValue(
i))
1421 columns[
i].indicators[
row] = -1;
1422 columns[
i].lengths[
row] = 0;
1424 columns[
i].indicators[
row] = 0;
1425 char *dataPtr = columns[
i].data + (columns[
i].maxLen *
row);
1426 switch (fieldTypes[
i].
id()) {
1427 case QMetaType::QTime:
1428 case QMetaType::QDate:
1429 case QMetaType::QDateTime:{
1430 columns[
i].lengths[
row] = columns[
i].maxLen;
1432 *
reinterpret_cast<OCIDateTime**
>(dataPtr) =
date->dateTime;
1433 tmpStorage.dateTimes.append(
date);
1436 case QMetaType::Int:
1437 columns[
i].lengths[
row] = columns[
i].maxLen;
1438 *
reinterpret_cast<int*
>(dataPtr) = val.toInt();
1441 case QMetaType::UInt:
1442 columns[
i].lengths[
row] = columns[
i].maxLen;
1443 *
reinterpret_cast<uint*
>(dataPtr) = val.toUInt();
1446 case QMetaType::LongLong:
1448 columns[
i].lengths[
row] = columns[
i].maxLen;
1454 case QMetaType::ULongLong:
1456 columns[
i].lengths[
row] = columns[
i].maxLen;
1462 case QMetaType::Double:
1463 columns[
i].lengths[
row] = columns[
i].maxLen;
1464 *
reinterpret_cast<double*
>(dataPtr) = val.toDouble();
1467 case QMetaType::QString: {
1469 columns[
i].lengths[
row] = (
s.length() + 1) *
sizeof(
QChar);
1470 memcpy(dataPtr,
s.utf16(), columns[
i].lengths[
row]);
1473 case QMetaType::QByteArray:
1478 *
reinterpret_cast<OCIRowid**
>(dataPtr) = rptr->id;
1479 columns[
i].lengths[
row] = 0;
1496 qCDebug(lcOci,
"OCIBindByPos(%p, %p, %p, %d, %p, %d, %d, %p, %p, 0, %d, %p, OCI_DEFAULT)",
1497 d->sql, &bindColumn.bindh,
d->err,
i + 1, bindColumn.data,
1498 bindColumn.maxLen, bindColumn.bindAs, bindColumn.indicators, bindColumn.lengths,
1499 arrayBind ? bindColumn.maxarr_len : 0, arrayBind ? &bindColumn.curelep : 0);
1501 for (
int ii = 0; ii < (int)bindColumn.recordCount; ++ii) {
1502 qCDebug(lcOci,
" record %d: indicator %d, length %d", ii, bindColumn.indicators[ii],
1503 bindColumn.lengths[ii]);
1510 d->sql, &bindColumn.bindh,
d->err,
i + 1,
1514 bindColumn.indicators,
1517 arrayBind ? bindColumn.maxarr_len : 0,
1518 arrayBind ? &bindColumn.curelep : 0,
1522 qCDebug(lcOci,
"After OCIBindByPos: r = %d, bindh = %p",
r, bindColumn.bindh);
1525 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1526 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:",
d->err);
1528 "Unable to bind column for batch execute"),
1533 r = OCIBindArrayOfStruct (
1534 columns[
i].bindh,
d->err,
1536 sizeof(columns[
i].indicators[0]),
1537 sizeof(columns[
i].lengths[0]),
1540 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1541 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:",
d->err);
1543 "Unable to bind column for batch execute"),
1550 r = OCIStmtExecute(
d->svc,
d->sql,
d->err,
1551 arrayBind ? 1 : columns[0].recordCount,
1553 d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS);
1555 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1556 qOraWarning(
"QOCIPrivate::execBatch: unable to execute batch statement:",
d->err);
1558 "Unable to execute batch statement"),
1564 for (
i = 0;
i < columnCount; ++
i) {
1566 if (!
d->isOutValue(
i))
1569 if (
auto tp = boundValues.
at(
i).
metaType(); tp.id() != QMetaType::QVariantList) {
1571 if (*columns[
i].indicators == -1)
1578 char*
data = columns[
i].data;
1579 for (
uint r = 0;
r < columns[
i].recordCount; ++
r){
1581 if (columns[
i].indicators[
r] == -1) {
1586 switch(columns[
i].bindAs) {
1588 case SQLT_TIMESTAMP_TZ:
1590 *
reinterpret_cast<OCIDateTime **
>(
data +
r * columns[
i].maxLen));
1593 (*list)[
r] = *
reinterpret_cast<int*
>(
data +
r * columns[
i].maxLen);
1597 (*list)[
r] = *
reinterpret_cast<uint*
>(
data +
r * columns[
i].maxLen);
1603 case QMetaType::LongLong:
1606 case QMetaType::ULongLong:
1616 (*list)[
r] = *
reinterpret_cast<double*
>(
data +
r * columns[
i].maxLen);
1621 +
r * columns[
i].maxLen));
1631 d->q_func()->setSelect(
false);
1633 d->q_func()->setActive(
true);
1639template<
class T,
int sz>
1647 r = OCILobCharSetForm(
d->env,
d->err, lob, &csfrm);
1648 if (
r != OCI_SUCCESS) {
1649 qOraWarning(
"OCIResultPrivate::readLobs: Couldn't get LOB char set form: ",
d->err);
1654 r = OCILobGetLength(
d->svc,
d->err, lob, &amount);
1655 if (
r == OCI_SUCCESS) {
1662 qOraWarning(
"OCIResultPrivate::readLobs: Couldn't get LOB length: ",
d->err);
1670 r = OCILobRead(
d->svc,
1683 if (
r != OCI_SUCCESS)
1684 qOraWarning(
"OCIResultPrivate::readLOBs: Cannot read LOB: ",
d->err);
1692 int r = OCI_SUCCESS;
1694 for (
int i = 0;
i <
size(); ++
i) {
1695 const OraFieldInf &fi = fieldInf.
at(
i);
1696 if (fi.ind == -1 || !(lob = fi.lob))
1699 bool isClob = fi.oraType == SQLT_CLOB;
1704 r = qReadLob<QString, sizeof(QChar)>(
str, d, lob);
1708 r = qReadLob<QByteArray, sizeof(char)>(
buf, d, lob);
1711 if (
r == OCI_SUCCESS)
1721 for (
int i = 0;
i < fieldInf.
count(); ++
i) {
1722 if (fieldInf.
at(
i).def ==
d)
1730 for (
int i = 0;
i < fieldInf.
size(); ++
i) {
1731 const OraFieldInf &fld = fieldInf.
at(
i);
1733 if (fld.ind == -1) {
1739 if (fld.oraType == SQLT_BIN || fld.oraType == SQLT_LBI || fld.oraType == SQLT_LNG)
1742 switch (fld.typ.id()) {
1743 case QMetaType::QDateTime:
1745 reinterpret_cast<OCIDateTime *
>(fld.dataPtr)));
1747 case QMetaType::Double:
1748 case QMetaType::Int:
1749 case QMetaType::LongLong:
1752 && (fld.typ.id() == QMetaType::Double)) {
1753 v[
index +
i] = *
reinterpret_cast<double *
>(fld.data);
1756 && (fld.typ.id() == QMetaType::LongLong)) {
1758 int r = OCINumberToInt(d->
err,
reinterpret_cast<OCINumber *
>(fld.data),
sizeof(
qint64),
1759 OCI_NUMBER_SIGNED, &qll);
1760 if (
r == OCI_SUCCESS)
1766 && (fld.typ.id() == QMetaType::Int)) {
1767 v[
index +
i] = *
reinterpret_cast<int *
>(fld.data);
1772 case QMetaType::QString:
1775 case QMetaType::QByteArray:
1782 qCWarning(lcOci,
"QOCICols::value: unknown data type");
1790 env(drv_d_func()->env),
1791 svc(const_cast<
OCISvcCtx*&>(drv_d_func()->svc)),
1792 transaction(drv_d_func()->transaction),
1793 serverVersion(drv_d_func()->serverVersion),
1794 prefetchRows(drv_d_func()->prefetchRows),
1795 prefetchMem(drv_d_func()->prefetchMem)
1798 int r = OCIHandleAlloc(
env,
1799 reinterpret_cast<void **
>(&
err),
1802 if (
r != OCI_SUCCESS)
1803 qCWarning(lcOci,
"QOCIResult: unable to alloc error handle");
1810 if (
sql && OCIHandleFree(
sql, OCI_HTYPE_STMT) != OCI_SUCCESS)
1811 qCWarning(lcOci,
"~QOCIResult: unable to free statement handle");
1813 if (OCIHandleFree(
err, OCI_HTYPE_ERROR) != OCI_SUCCESS)
1814 qCWarning(lcOci,
"~QOCIResult: unable to free error report handle");
1849 bool piecewise =
false;
1850 int r = OCI_SUCCESS;
1851 r = OCIStmtFetch(d->
sql, d->
err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1854 return r == OCI_SUCCESS ||
r == OCI_SUCCESS_WITH_INFO;
1859 case OCI_SUCCESS_WITH_INFO:
1880 "Unable to goto next"),
1886 if (
r == OCI_SUCCESS && piecewise)
1889 if (
r == OCI_SUCCESS)
1891 if (
r == OCI_SUCCESS)
1893 if (
r != OCI_SUCCESS)
1895 return r == OCI_SUCCESS ||
r == OCI_SUCCESS_WITH_INFO;
1928 r = OCIHandleFree(d->
sql, OCI_HTYPE_STMT);
1929 if (
r == OCI_SUCCESS)
1932 qOraWarning(
"QOCIResult::prepare: unable to free statement handle:", d->
err);
1935 r = OCIHandleAlloc(d->
env,
1936 reinterpret_cast<void **
>(&d->
sql),
1939 if (
r != OCI_SUCCESS) {
1940 qOraWarning(
"QOCIResult::prepare: unable to alloc statement:", d->
err);
1952 if (
query.isEmpty())
1959 const OraText *
txt =
reinterpret_cast<const OraText *
>(
query.utf16());
1961 r = OCIStmtPrepare(d->
sql,
1967 if (
r != OCI_SUCCESS) {
1968 qOraWarning(
"QOCIResult::prepare: unable to prepare statement:", d->
err);
1987 r = OCIAttrGet(d->
sql,
1994 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
1995 qOraWarning(
"QOCIResult::exec: Unable to get statement type:", d->
err);
2004 iters = stmtType == OCI_STMT_SELECT ? 0 : 1;
2021 r = OCIStmtExecute(d->
svc,
2029 if (
r != OCI_SUCCESS &&
r != OCI_SUCCESS_WITH_INFO) {
2030 qOraWarning(
"QOCIResult::exec: unable to execute statement:", d->
err);
2040 if (stmtType == OCI_STMT_SELECT) {
2042 int r = OCIAttrGet(d->
sql, OCI_HTYPE_STMT,
reinterpret_cast<void **
>(&parmCount),
2043 0, OCI_ATTR_PARAM_COUNT, d->
err);
2044 if (
r == 0 && !d->
cols)
2075 int r = OCIAttrGet(d->
sql, OCI_HTYPE_STMT,
ptr.constData()->id,
2076 0, OCI_ATTR_ROWID, d->
err);
2077 if (
r == OCI_SUCCESS)
2114 const ub4
mode = OCI_UTF16 | OCI_OBJECT | OCI_THREADED;
2116 const ub4
mode = OCI_UTF16 | OCI_OBJECT;
2118 int r = OCIEnvCreate(&
d->env,
2127 qCWarning(lcOci,
"QOCIDriver: unable to create environment");
2133 d->allocErrorHandle();
2143 d->allocErrorHandle();
2156 int r = OCIHandleFree(
d->err, OCI_HTYPE_ERROR);
2157 if (
r != OCI_SUCCESS)
2158 qCWarning(lcOci,
"Unable to free Error handle: %d",
r);
2159 r = OCIHandleFree(
d->env, OCI_HTYPE_ENV);
2160 if (
r != OCI_SUCCESS)
2161 qCWarning(lcOci,
"Unable to free Environment handle: %d",
r);
2185 return d->serverVersion >= 9;
2193 for (
const auto tmp : opts) {
2195 if ((idx = tmp.indexOf(u
'=')) == -1) {
2196 qCWarning(lcOci,
"QOCIDriver::parseArgs: Invalid parameter: '%ls'",
2203 if (
opt ==
"OCI_ATTR_PREFETCH_ROWS"_L1) {
2204 d->prefetchRows =
val.toInt(&
ok);
2206 d->prefetchRows = -1;
2207 }
else if (
opt ==
"OCI_ATTR_PREFETCH_MEMORY"_L1) {
2208 d->prefetchMem =
val.toInt(&
ok);
2210 d->prefetchMem = -1;
2211 }
else if (
opt ==
"OCI_AUTH_MODE"_L1) {
2212 if (
val ==
"OCI_SYSDBA"_L1) {
2213 d->authMode = OCI_SYSDBA;
2214 }
else if (
val ==
"OCI_SYSOPER"_L1) {
2215 d->authMode = OCI_SYSOPER;
2216 }
else if (
val !=
"OCI_DEFAULT"_L1) {
2217 qCWarning(lcOci,
"QOCIDriver::parseArgs: Unsupported value for OCI_AUTH_MODE: '%ls'",
2221 qCWarning(lcOci,
"QOCIDriver::parseArgs: Invalid parameter: '%ls'",
2247 "(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((
port > -1 ?
port : 1521)).arg(
db);
2250 r = OCIHandleAlloc(
d->env,
reinterpret_cast<void **
>(&
d->srvhp), OCI_HTYPE_SERVER, 0,
nullptr);
2251 if (
r == OCI_SUCCESS) {
2252 r = OCIServerAttach(
d->srvhp,
d->err,
2253 reinterpret_cast<const OraText *
>(connectionString.utf16()),
2254 connectionString.length() *
sizeof(
QChar), OCI_DEFAULT);
2257 if (
r == OCI_SUCCESS ||
r == OCI_SUCCESS_WITH_INFO) {
2258 r = OCIHandleAlloc(
d->env,
reinterpret_cast<void **
>(&
d->svc), OCI_HTYPE_SVCCTX,
2261 if (
r == OCI_SUCCESS)
2262 r = OCIAttrSet(
d->svc, OCI_HTYPE_SVCCTX,
d->srvhp, 0, OCI_ATTR_SERVER,
d->err);
2264 if (
r == OCI_SUCCESS) {
2265 r = OCIHandleAlloc(
d->env,
reinterpret_cast<void **
>(&
d->authp), OCI_HTYPE_SESSION,
2268 if (
r == OCI_SUCCESS) {
2269 r = OCIAttrSet(
d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *
>(user.
utf16()),
2270 user.
length() *
sizeof(
QChar), OCI_ATTR_USERNAME,
d->err);
2272 if (
r == OCI_SUCCESS) {
2273 r = OCIAttrSet(
d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *
>(password.
utf16()),
2274 password.
length() *
sizeof(
QChar), OCI_ATTR_PASSWORD,
d->err);
2277 if (
r == OCI_SUCCESS) {
2278 r = OCIHandleAlloc(
d->env,
reinterpret_cast<void **
>(&
d->trans), OCI_HTYPE_TRANS,
2281 if (
r == OCI_SUCCESS)
2282 r = OCIAttrSet(
d->svc, OCI_HTYPE_SVCCTX,
d->trans, 0, OCI_ATTR_TRANS,
d->err);
2284 if (
r == OCI_SUCCESS) {
2286 r = OCISessionBegin(
d->svc,
d->err,
d->authp, OCI_CRED_EXT,
d->authMode);
2288 r = OCISessionBegin(
d->svc,
d->err,
d->authp, OCI_CRED_RDBMS,
d->authMode);
2290 if (
r == OCI_SUCCESS ||
r == OCI_SUCCESS_WITH_INFO)
2291 r = OCIAttrSet(
d->svc, OCI_HTYPE_SVCCTX,
d->authp, 0, OCI_ATTR_SESSION,
d->err);
2293 if (
r != OCI_SUCCESS) {
2297 OCIHandleFree(
d->trans, OCI_HTYPE_TRANS);
2300 OCIHandleFree(
d->authp, OCI_HTYPE_SESSION);
2303 OCIHandleFree(
d->svc, OCI_HTYPE_SVCCTX);
2306 OCIHandleFree(
d->srvhp, OCI_HTYPE_SERVER);
2313 r = OCIServerVersion(
d->svc,
2315 reinterpret_cast<OraText *
>(vertxt),
2319 qCWarning(lcOci,
"QOCIDriver::open: could not get Oracle server version.");
2322 versionStr =
QString(
reinterpret_cast<const QChar *
>(vertxt));
2323#if QT_CONFIG(regularexpression)
2325 if (
match.hasMatch())
2326 d->serverVersion =
match.captured(1).toInt();
2328 if (
d->serverVersion == 0)
2329 d->serverVersion = -1;
2345 OCISessionEnd(
d->svc,
d->err,
d->authp, OCI_DEFAULT);
2346 OCIServerDetach(
d->srvhp,
d->err, OCI_DEFAULT);
2347 OCIHandleFree(
d->trans, OCI_HTYPE_TRANS);
2349 OCIHandleFree(
d->authp, OCI_HTYPE_SESSION);
2351 OCIHandleFree(
d->svc, OCI_HTYPE_SVCCTX);
2353 OCIHandleFree(
d->srvhp, OCI_HTYPE_SERVER);
2368 qCWarning(lcOci,
"QOCIDriver::beginTransaction: Database not open");
2371 int r = OCITransStart(
d->svc,
2374 OCI_TRANS_READWRITE);
2375 if (
r == OCI_ERROR) {
2381 d->transaction =
true;
2389 qCWarning(lcOci,
"QOCIDriver::commitTransaction: Database not open");
2392 int r = OCITransCommit(
d->svc,
2395 if (
r == OCI_ERROR) {
2401 d->transaction =
false;
2409 qCWarning(lcOci,
"QOCIDriver::rollbackTransaction: Database not open");
2412 int r = OCITransRollback(
d->svc,
2415 if (
r == OCI_ERROR) {
2416 qOraWarning(
"QOCIDriver::rollbackTransaction:",
d->err);
2421 d->transaction =
false;
2432 static const char sysUsers[][8] = {
2441 static const char joinC[][4] = {
"or" ,
"and" };
2442 static constexpr char16_t bang[] = { u
' ', u
'!' };
2447 result.reserve(
sizeof sysUsers /
sizeof *sysUsers *
2449 (9 +
sizeof *sysUsers + 5));
2450 for (
const auto &sysUser : sysUsers) {
2453 result +=
"owner "_L1 + bang[e] +
"= '"_L1 + l1 +
"' "_L1 + join + u
' ';
2476 t.setForwardOnly(
true);
2478 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2480 t.exec(tableQuery + where);
2482 if (
t.value(0).toString().toUpper() != user.
toUpper())
2483 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2485 tl.append(
t.value(1).toString());
2489 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2490 t.exec(synonymQuery + where);
2492 if (
t.value(0).toString() !=
d->user)
2493 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2495 tl.append(
t.value(1).toString());
2499 const auto query =
"select owner, view_name from all_views where "_L1;
2503 if (
t.value(0).toString().toUpper() !=
d->user.toUpper())
2504 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2506 tl.append(
t.value(1).toString());
2510 t.exec(
"select table_name from dictionary"_L1);
2512 tl.append(
t.value(0).toString());
2514 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2516 t.exec(tableQuery + where);
2518 if (
t.value(0).toString().toUpper() != user.
toUpper())
2519 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2521 tl.append(
t.value(1).toString());
2525 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2526 t.exec(synonymQuery + where);
2528 if (
t.value(0).toString() !=
d->user)
2529 tl.append(
t.value(0).toString() + u
'.' +
t.value(1).toString());
2531 tl.append(
t.value(1).toString());
2542 *tbl = tname.right(tname.length() -
i - 1);
2543 *owner = tname.
left(
i);
2559 QString stmt(
"select column_name, data_type, data_length, "
2560 "data_precision, data_scale, nullable, data_default%1"
2561 "from all_tab_columns a "_L1);
2562 if (
d->serverVersion >= 9)
2563 stmt = stmt.
arg(
", char_length "_L1);
2565 stmt = stmt.
arg(
" "_L1);
2566 bool buildRecordInfo =
false;
2575 tmpStmt = stmt +
"where a.table_name='"_L1 +
table + u
'\'';
2585 tmpStmt +=
" and a.owner='"_L1 + owner + u
'\'';
2586 t.setForwardOnly(
true);
2589 stmt = stmt +
" join all_synonyms b on a.owner=b.table_owner and a.table_name=b.table_name "
2590 "where b.owner='"_L1 + owner +
"' and b.synonym_name='"_L1 +
table + u
'\'';
2591 t.setForwardOnly(
true);
2594 buildRecordInfo =
true;
2596 buildRecordInfo =
true;
2599 <<
"BINARY_DOUBLE"_L1;
2600 if (buildRecordInfo) {
2604 f.setRequired(
t.value(5).toString() ==
"N"_L1);
2605 f.setPrecision(
t.value(4).toInt());
2606 if (
d->serverVersion >= 9 && (
ty.id() == QMetaType::QString) && !
t.isNull(3) && !
keywords.contains(
t.value(1).toString())) {
2608 f.setLength(
t.value(7).toInt());
2610 f.setLength(
t.value(
t.isNull(3) ? 2 : 3).
toInt());
2612 f.setDefaultValue(
t.value(6));
2626 QString stmt(
"select b.column_name, b.index_name, a.table_name, a.owner "
2627 "from all_constraints a, all_ind_columns b "
2628 "where a.constraint_type='P' "
2629 "and b.index_name = a.index_name "
2630 "and b.index_owner = a.owner"_L1);
2632 bool buildIndex =
false;
2641 tmpStmt = stmt +
" and a.table_name='"_L1 +
table + u
'\'';
2651 tmpStmt +=
" and a.owner='"_L1 + owner + u
'\'';
2652 t.setForwardOnly(
true);
2656 stmt +=
" and a.table_name=(select tname from sys.synonyms where sname='"_L1
2657 +
table +
"' and creator=a.owner)"_L1;
2658 t.setForwardOnly(
true);
2661 owner =
t.value(3).toString();
2669 tt.setForwardOnly(
true);
2670 idx.
setName(
t.value(1).toString());
2672 tt.exec(
"select data_type from all_tab_columns where table_name='"_L1 +
2673 t.value(2).toString() +
"' and column_name='"_L1 +
2674 t.value(0).toString() +
"' and owner='"_L1 +
2690 case QMetaType::QDateTime: {
2701 +
"','YYYY-MM-DD HH24:MI:SS')"_L1;
2703 datestring =
"NULL"_L1;
2707 case QMetaType::QTime: {
2711 datestring =
"TO_DATE('"_L1
2715 +
"','HH24:MI:SS')"_L1;
2717 datestring =
"NULL"_L1;
2721 case QMetaType::QDate: {
2730 datestring =
"NULL"_L1;
2761 return d->serverVersion > 12 ? 128 : 30;
2766#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)
QVariant lastInsertId() const
Returns the object ID of the most recent inserted row if the database supports it.
bool reset(const QString &query)
Sets the result to use the SQL statement query for subsequent data retrieval.
bool exec()
Executes the query, returning true if successful; otherwise returns false.
int numRowsAffected()
Returns the number of rows affected by the last query executed, or -1 if it cannot be determined or i...
int size()
Returns the size of the SELECT result, or -1 if it cannot be determined or if the query is not a SELE...
QSqlRecord record() const
Returns the current record if the query is active; otherwise returns an empty QSqlRecord.
void virtual_hook(int id, void *data)
QVariant handle() const
Returns the low-level database handle for this result set wrapped in a QVariant or an invalid QVarian...
bool prepare(const QString &query)
Prepares the given query for execution; the query will normally use placeholders so that it can be ex...
bool execBatch(bool arrayBind=false)
QOCIResult(const QOCIDriver *db, const QOCIDriverPrivate *p)
bool gotoNext(ValueCache &values, int index)
\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...
QSqlCachedResult::ValueCache cache
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.
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)
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 qCWarning(category,...)
#define qCDebug(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
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