308 const QVariant &val, dvoid *indPtr, ub4 *tmpSize,
TempStorage &tmpStorage)
311 void *data =
const_cast<
void *>(val.constData());
313 switch (val.typeId()) {
314 case QMetaType::QByteArray:
315 r = OCIBindByPos2(stmtp, hbnd, err,
318 ?
const_cast<
char *>(
reinterpret_cast<
QByteArray *>(data)->constData())
319 :
reinterpret_cast<
QByteArray *>(data)->data(),
321 SQLT_BIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
323 case QMetaType::QTime:
324 case QMetaType::QDate:
325 case QMetaType::QDateTime: {
327 r = OCIBindByPos2(stmtp, hbnd, err,
330 sizeof(OCIDateTime *),
331 SQLT_TIMESTAMP_TZ, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
332 tmpStorage.dateTimes.append(ptr);
336 r = OCIBindByPos2(stmtp, hbnd, err,
340 const_cast<
void *>(data),
342 SQLT_INT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
344 case QMetaType::UInt:
345 r = OCIBindByPos2(stmtp, hbnd, err,
349 const_cast<
void *>(data),
351 SQLT_UIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
353 case QMetaType::LongLong:
355 QByteArray ba = qMakeOCINumber(val.toLongLong(), err);
356 r = OCIBindByPos2(stmtp, hbnd, err,
360 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
361 tmpStorage.rawData.append(ba);
364 case QMetaType::ULongLong:
366 QByteArray ba = qMakeOCINumber(val.toULongLong(), err);
367 r = OCIBindByPos2(stmtp, hbnd, err,
371 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
372 tmpStorage.rawData.append(ba);
375 case QMetaType::Double:
376 r = OCIBindByPos2(stmtp, hbnd, err,
380 const_cast<
void *>(data),
382 SQLT_FLT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
384 case QMetaType::QString: {
385 const QString s = val.toString();
387 r = OCIBindByPos2(stmtp, hbnd, err,
389 const_cast<ushort *>(s.utf16()),
390 s.length() *
sizeof(QChar),
391 SQLT_LNG, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
395 r = OCIBindByPos2(stmtp, hbnd, err,
398 const_cast<ushort *>(s.utf16()),
399 (s.length() + 1) *
sizeof(QChar),
400 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
401 if (r == OCI_SUCCESS)
402 setCharset(*hbnd, OCI_HTYPE_BIND);
408 if (val.typeId() >= QMetaType::User) {
412 r = OCIBindByPos2(stmtp, hbnd, err,
415 const_cast<OCIRowid **>(&rptr->id),
417 SQLT_RDD, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
418 }
else if (val.canConvert<QOCIResult *>() && isOutValue(pos)) {
419 QOCIResult *res = qvariant_cast<QOCIResult *>(val);
422 if (res->internal_prepare()) {
423 r = OCIBindByPos2(stmtp, hbnd, err,
427 SQLT_RSET, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
429 res->isCursor =
true;
432 qCWarning(lcOci,
"Unknown bind variable");
436 const QString s = val.toString();
438 QByteArray ba(
reinterpret_cast<
const char *>(s.utf16()), (s.length() + 1) *
sizeof(QChar));
440 ba.reserve((s.capacity() + 1) *
sizeof(QChar));
441 *tmpSize = ba.size();
442 r = OCIBindByPos2(stmtp, hbnd, err,
446 SQLT_STR, indPtr, tmpSize, 0, 0, 0, OCI_DEFAULT);
448 r = OCIBindByPos2(stmtp, hbnd, err,
452 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
454 if (r == OCI_SUCCESS)
455 setCharset(*hbnd, OCI_HTYPE_BIND);
456 tmpStorage.rawData.append(ba);
461 if (r != OCI_SUCCESS)
462 qOraWarning(
"QOCIResultPrivate::bindValue:", err);
850 OCIDefine *dfn =
nullptr;
853 OCIParam *param =
nullptr;
857 parmStatus = OCIParamGet(d->stmtp,
860 reinterpret_cast<
void **>(¶m),
863 while (parmStatus == OCI_SUCCESS) {
865 if (ofi.oraType == SQLT_RDD)
867#ifdef SQLT_INTERVAL_YM
868#ifdef SQLT_INTERVAL_DS
869 else if (ofi.oraType == SQLT_INTERVAL_YM || ofi.oraType == SQLT_INTERVAL_DS)
875 else if (ofi.oraType == SQLT_NUM || ofi.oraType == SQLT_VNU){
876 if (ofi.oraPrecision > 0)
877 dataSize = (ofi.oraPrecision + 1) *
sizeof(utext);
879 dataSize = (38 + 1) *
sizeof(utext);
882 dataSize = ofi.oraLength;
884 fieldInf[idx].typ = ofi.type;
885 fieldInf[idx].oraType = ofi.oraType;
886 rec.append(qFromOraInf(ofi));
888 switch (ofi.type.id()) {
889 case QMetaType::QDateTime:
890 r = OCIDescriptorAlloc(d
->env, (
void **)&fieldInf[idx].dataPtr, OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
891 if (r != OCI_SUCCESS) {
892 qCWarning(lcOci,
"QOCICols: Unable to allocate the OCIDateTime descriptor");
895 r = OCIDefineByPos(d->stmtp,
899 &fieldInf[idx].dataPtr,
900 sizeof(OCIDateTime *),
902 &(fieldInf[idx].ind),
905 case QMetaType::Double:
906 r = OCIDefineByPos(d->stmtp,
910 create(idx,
sizeof(
double) - 1),
913 &(fieldInf[idx].ind),
917 r = OCIDefineByPos(d->stmtp,
921 create(idx,
sizeof(qint32) - 1),
924 &(fieldInf[idx].ind),
927 case QMetaType::LongLong:
928 r = OCIDefineByPos(d->stmtp,
932 create(idx,
sizeof(OCINumber)),
935 &(fieldInf[idx].ind),
938 case QMetaType::QByteArray:
940 if (ofi.oraType == SQLT_BIN) {
942 r = OCIDefineByPos(d->stmtp,
946 create(idx, dataSize),
949 &(fieldInf[idx].ind),
950 0, 0, OCI_DYNAMIC_FETCH);
951 }
else if (ofi.oraType == SQLT_LBI) {
953 r = OCIDefineByPos(d->stmtp,
960 &(fieldInf[idx].ind),
961 0, 0, OCI_DYNAMIC_FETCH);
962 }
else if (ofi.oraType == SQLT_CLOB) {
963 r = OCIDefineByPos(d->stmtp,
967 createLobLocator(idx, d->env),
970 &(fieldInf[idx].ind),
974 r = OCIDefineByPos(d->stmtp,
978 createLobLocator(idx, d->env),
981 &(fieldInf[idx].ind),
985 case QMetaType::QString:
986 if (ofi.oraType == SQLT_LNG) {
987 r = OCIDefineByPos(d->stmtp,
994 &(fieldInf[idx].ind),
995 0, 0, OCI_DYNAMIC_FETCH);
997 dataSize += dataSize +
sizeof(QChar);
999 r = OCIDefineByPos(d->stmtp,
1003 create(idx, dataSize),
1006 &(fieldInf[idx].ind),
1009 d->setCharset(dfn, OCI_HTYPE_DEFINE);
1014 dataSize = (dataSize + 1) *
sizeof(utext) ;
1016 r = OCIDefineByPos(d->stmtp,
1020 create(idx, dataSize),
1023 &(fieldInf[idx].ind),
1028 qOraWarning(
"QOCICols::bind:", d->err);
1029 fieldInf[idx].def = dfn;
1032 parmStatus = OCIParamGet(d->stmtp,
1035 reinterpret_cast<
void **>(¶m),
1079 r = OCIStmtGetPieceInfo(d->stmtp, d->err,
reinterpret_cast<
void **>(&dfn), &typep,
1080 &in_outp, &iterp, &idxp, &piecep);
1081 if (r != OCI_SUCCESS)
1082 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to get piece info:", d->err);
1083 qsizetype fieldNum = fieldFromDefine(dfn);
1084 bool isStringField = fieldInf.at(fieldNum).oraType == SQLT_LNG;
1087 r = OCIStmtSetPieceInfo(dfn, OCI_HTYPE_DEFINE,
1089 &chunkSize, piecep, NULL, NULL);
1090 if (r != OCI_SUCCESS)
1091 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to set piece info:", d->err);
1092 status = OCIStmtFetch (d->stmtp, d->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1095 OCIErrorGet(d->err, 1, 0, &errcode, 0, 0,OCI_HTYPE_ERROR);
1101 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to fetch next:", d->err);
1105 if (status == OCI_NO_DATA)
1107 if (nullField || !chunkSize) {
1108 fieldInf[fieldNum].ind = -1;
1110 if (isStringField) {
1111 QString str = values.at(fieldNum + index).toString()
1112 + QStringView(
reinterpret_cast<
const QChar *>(col.get()), chunkSize / 2);
1113 values[fieldNum + index] = str;
1114 fieldInf[fieldNum].ind = 0;
1116 QByteArray ba = values.at(fieldNum + index).toByteArray()
1117 + QByteArrayView(col.get(), chunkSize);
1118 values[fieldNum + index] = ba;
1119 fieldInf[fieldNum].ind = 0;
1122 }
while (status == OCI_SUCCESS_WITH_INFO || status == OCI_NEED_DATA);
1285 qsizetype columnCount = boundValues.count();
1286 if (boundValues.isEmpty() || columnCount == 0)
1290 qCDebug(lcOci) <<
"columnCount:" << columnCount << boundValues;
1295 QVarLengthArray<QMetaType> fieldTypes;
1296 for (qsizetype i = 0; i < columnCount; ++i) {
1297 QMetaType tp = boundValues.at(i).metaType();
1298 fieldTypes.append(tp.id() == QMetaType::QVariantList ? boundValues.at(i).toList().value(0).metaType() : tp);
1306 for (qsizetype i = 0; i < columnCount; ++i) {
1308 if (boundValues.at(i).typeId() != QMetaType::QVariantList) {
1312 singleCol.indicators =
new sb2[1];
1313 *singleCol.indicators = QSqlResultPrivate::isVariantNull(boundValues.at(i)) ? -1 : 0;
1315 r = d->bindValue(d->stmtp, &singleCol.bindh, d->err, i,
1316 boundValues.at(i), singleCol.indicators, &tmpSizes[i], tmpStorage);
1318 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1319 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1320 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1321 "Unable to bind column for batch execute"),
1322 QSqlError::StatementError, d->err));
1329 col.recordCount = boundValues.at(i).toList().count();
1331 col.lengths =
new ub4[col.recordCount];
1332 col.indicators =
new sb2[col.recordCount];
1333 col.maxarr_len = col.recordCount;
1334 col.curelep = col.recordCount;
1336 switch (fieldTypes[i].id()) {
1337 case QMetaType::QTime:
1338 case QMetaType::QDate:
1339 case QMetaType::QDateTime:
1340 col.bindAs = SQLT_TIMESTAMP_TZ;
1341 col.maxLen =
sizeof(OCIDateTime *);
1344 case QMetaType::Int:
1345 col.bindAs = SQLT_INT;
1346 col.maxLen =
sizeof(
int);
1349 case QMetaType::UInt:
1350 col.bindAs = SQLT_UIN;
1351 col.maxLen =
sizeof(uint);
1354 case QMetaType::LongLong:
1355 col.bindAs = SQLT_VNU;
1356 col.maxLen =
sizeof(OCINumber);
1359 case QMetaType::ULongLong:
1360 col.bindAs = SQLT_VNU;
1361 col.maxLen =
sizeof(OCINumber);
1364 case QMetaType::Double:
1365 col.bindAs = SQLT_FLT;
1366 col.maxLen =
sizeof(
double);
1369 case QMetaType::QString: {
1370 col.bindAs = SQLT_STR;
1371 for (uint j = 0; j < col.recordCount; ++j) {
1374 len = boundValues.at(i).toList().at(j).toString().capacity() + 1;
1376 len = boundValues.at(i).toList().at(j).toString().length() + 1;
1377 if (len > col.maxLen)
1380 col.maxLen *=
sizeof(QChar);
1383 case QMetaType::QByteArray:
1385 if (fieldTypes[i].id() >= QMetaType::User) {
1386 col.bindAs = SQLT_RDD;
1387 col.maxLen =
sizeof(OCIRowid*);
1389 col.bindAs = SQLT_LBI;
1390 for (uint j = 0; j < col.recordCount; ++j) {
1392 col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().capacity();
1394 col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().size();
1395 if (col.lengths[j] > col.maxLen)
1396 col.maxLen = col.lengths[j];
1403 col
.data =
new char[col.maxLen * col.recordCount];
1404 memset(col
.data, 0, col.maxLen * col.recordCount);
1407 for (uint row = 0; row < col.recordCount; ++row) {
1408 const QVariant val = boundValues.at(i).toList().at(row);
1410 if (QSqlResultPrivate::isVariantNull(val) && !d->isOutValue(i)) {
1411 columns[i].indicators[row] = -1;
1412 columns[i].lengths[row] = 0;
1414 columns[i].indicators[row] = 0;
1415 char *dataPtr = columns[i].data + (columns[i].maxLen * row);
1416 switch (fieldTypes[i].id()) {
1417 case QMetaType::QTime:
1418 case QMetaType::QDate:
1419 case QMetaType::QDateTime:{
1420 columns[i].lengths[row] = columns[i].maxLen;
1422 *
reinterpret_cast<OCIDateTime**>(dataPtr) = date->dateTime;
1423 tmpStorage.dateTimes.append(date);
1426 case QMetaType::Int:
1427 columns[i].lengths[row] = columns[i].maxLen;
1428 *
reinterpret_cast<
int*>(dataPtr) = val.toInt();
1431 case QMetaType::UInt:
1432 columns[i].lengths[row] = columns[i].maxLen;
1433 *
reinterpret_cast<uint*>(dataPtr) = val.toUInt();
1436 case QMetaType::LongLong:
1438 columns[i].lengths[row] = columns[i].maxLen;
1439 const QByteArray ba = qMakeOCINumber(val.toLongLong(), d->err);
1440 Q_ASSERT(ba.size() == columns[i].maxLen);
1441 memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1444 case QMetaType::ULongLong:
1446 columns[i].lengths[row] = columns[i].maxLen;
1447 const QByteArray ba = qMakeOCINumber(val.toULongLong(), d->err);
1448 Q_ASSERT(ba.size() == columns[i].maxLen);
1449 memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1452 case QMetaType::Double:
1453 columns[i].lengths[row] = columns[i].maxLen;
1454 *
reinterpret_cast<
double*>(dataPtr) = val.toDouble();
1457 case QMetaType::QString: {
1458 const QString s = val.toString();
1459 columns[i].lengths[row] = ub2((s.length() + 1) *
sizeof(QChar));
1460 memcpy(dataPtr, s.utf16(), columns[i].lengths[row]);
1463 case QMetaType::QByteArray:
1465 if (fieldTypes[i].id() >= QMetaType::User) {
1468 *
reinterpret_cast<OCIRowid**>(dataPtr) = rptr->id;
1469 columns[i].lengths[row] = 0;
1474 columns[i].lengths[row] = ba.size();
1475 memcpy(dataPtr, ba.constData(), ba.size());
1486 qCDebug(lcOci,
"OCIBindByPos2(%p, %p, %p, %d, %p, %d, %d, %p, %p, 0, %d, %p, OCI_DEFAULT)",
1487 d->stmtp, &bindColumn.bindh, d->err, i + 1, bindColumn.data,
1488 bindColumn.maxLen, bindColumn.bindAs, bindColumn.indicators, bindColumn.lengths,
1489 arrayBind ? bindColumn.maxarr_len : 0, arrayBind ? &bindColumn.curelep : 0);
1491 for (
int ii = 0; ii < (
int)bindColumn.recordCount; ++ii) {
1492 qCDebug(lcOci,
" record %d: indicator %d, length %d", ii, bindColumn.indicators[ii],
1493 bindColumn.lengths[ii]);
1500 d->stmtp, &bindColumn.bindh, d->err, i + 1,
1504 bindColumn.indicators,
1507 arrayBind ? bindColumn.maxarr_len : 0,
1508 arrayBind ? &bindColumn.curelep : 0,
1512 qCDebug(lcOci,
"After OCIBindByPos: r = %d, bindh = %p", r, bindColumn.bindh);
1515 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1516 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1517 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1518 "Unable to bind column for batch execute"),
1519 QSqlError::StatementError, d->err));
1523 r = OCIBindArrayOfStruct (
1524 columns[i].bindh, d->err,
1526 sizeof(columns[i].indicators[0]),
1527 sizeof(columns[i].lengths[0]),
1530 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1531 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1532 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1533 "Unable to bind column for batch execute"),
1534 QSqlError::StatementError, d->err));
1540 r = OCIStmtExecute(d
->svc, d->stmtp, d->err,
1541 arrayBind ? 1 : columns[0].recordCount,
1543 d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS);
1545 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1546 qOraWarning(
"QOCIPrivate::execBatch: unable to execute batch statement:", d->err);
1547 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1548 "Unable to execute batch statement"),
1549 QSqlError::StatementError, d->err));
1554 for (qsizetype i = 0; i < columnCount; ++i) {
1559 if (
auto tp = boundValues.at(i).metaType(); tp.id() != QMetaType::QVariantList) {
1560 qOraOutValue(boundValues[i], tmpStorage, d
->env, d->err);
1561 if (*columns[i].indicators == -1)
1562 boundValues[i] = QVariant(tp);
1566 QVariantList *list =
static_cast<QVariantList *>(
const_cast<
void*>(boundValues.at(i).data()));
1568 char* data = columns[i].data;
1569 for (uint r = 0; r < columns[i].recordCount; ++r){
1571 if (columns[i].indicators[r] == -1) {
1572 (*list)[r] = QVariant(fieldTypes[i]);
1576 switch(columns[i].bindAs) {
1578 case SQLT_TIMESTAMP_TZ:
1579 (*list)[r] = QOCIDateTime::fromOCIDateTime(d->env, d->err,
1580 *
reinterpret_cast<OCIDateTime **>(data + r * columns[i].maxLen));
1583 (*list)[r] = *
reinterpret_cast<
int*>(data + r * columns[i].maxLen);
1587 (*list)[r] = *
reinterpret_cast<uint*>(data + r * columns[i].maxLen);
1592 switch (boundValues.at(i).typeId()) {
1593 case QMetaType::LongLong:
1594 (*list)[r] = qMakeLongLong(data + r * columns[i].maxLen, d->err);
1596 case QMetaType::ULongLong:
1597 (*list)[r] = qMakeULongLong(data + r * columns[i].maxLen, d->err);
1606 (*list)[r] = *
reinterpret_cast<
double*>(data + r * columns[i].maxLen);
1610 (*list)[r] = QString(
reinterpret_cast<
const QChar *>(data
1611 + r * columns[i].maxLen));
1615 (*list)[r] =
QByteArray(data + r * columns[i].maxLen, columns[i].maxLen);
1621 d->q_func()->setSelect(
false);
1622 d->q_func()->setAt(QSql::BeforeFirstRow);
1623 d->q_func()->setActive(
true);
1625 qDeleteAll(tmpStorage.dateTimes);
1967bool QOCIResult::exec()
1974 TempStorage tmpStorage;
1975 IndicatorArray indicators(boundValueCount());
1976 SizeArray tmpSizes(boundValueCount());
1978 r = OCIAttrGet(d->stmtp,
1985 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1986 qOraWarning(
"QOCIResult::exec: Unable to get statement type:", d->err);
1987 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1988 "Unable to get statement type"), QSqlError::StatementError, d->err));
1990 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
1995 iters = stmtType == OCI_STMT_SELECT ? 0 : 1;
1996 mode = d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS;
1999 if (boundValueCount() > 0
2000 && d->bindValues(boundValues(), indicators, tmpSizes, tmpStorage) != OCI_SUCCESS) {
2001 qOraWarning(
"QOCIResult::exec: unable to bind value: ", d->err);
2002 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
"Unable to bind value"),
2003 QSqlError::StatementError, d->err));
2005 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
2012 r = OCIStmtExecute(d->svc,
2020 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
2021 qOraWarning(
"QOCIResult::exec: unable to execute statement:", d->err);
2022 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
2023 "Unable to execute statement"), QSqlError::StatementError, d->err));
2025 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
2031 if (stmtType == OCI_STMT_SELECT) {
2033 int r = OCIAttrGet(d->stmtp, OCI_HTYPE_STMT,
reinterpret_cast<
void **>(&parmCount),
2034 0, OCI_ATTR_PARAM_COUNT, d->err);
2035 if (r == 0 && !d->cols)
2036 d->cols =
new QOCICols(parmCount, d);
2038 QSqlCachedResult::init(parmCount);
2042 setAt(QSql::BeforeFirstRow);
2046 d->outValues(boundValues(), indicators, tmpStorage);
2047 qDeleteAll(tmpStorage.dateTimes);
2218bool QOCIDriver::open(
const QString & db,
2219 const QString & user,
2220 const QString & password,
2221 const QString & hostname,
2223 const QString &opts)
2231 qParseOpts(opts, d);
2234 QString connectionString = db;
2235 if (!hostname.isEmpty())
2237 QString::fromLatin1(
"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
2238 "(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
2240 Q_ASSERT(!d->srvhp);
2241 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->srvhp), OCI_HTYPE_SERVER, 0,
nullptr);
2242 if (r == OCI_SUCCESS) {
2243 r = OCIServerAttach(d->srvhp, d->err,
2244 reinterpret_cast<
const OraText *>(connectionString.utf16()),
2245 sb4(connectionString.length() *
sizeof(QChar)), OCI_DEFAULT);
2248 if (r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO) {
2249 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->svc), OCI_HTYPE_SVCCTX,
2252 if (r == OCI_SUCCESS)
2253 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->srvhp, 0, OCI_ATTR_SERVER, d->err);
2254 Q_ASSERT(!d->authp);
2255 if (r == OCI_SUCCESS) {
2256 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->authp), OCI_HTYPE_SESSION,
2259 if (r == OCI_SUCCESS) {
2260 r = OCIAttrSet(d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *>(user.utf16()),
2261 ub4(user.length() *
sizeof(QChar)), OCI_ATTR_USERNAME, d->err);
2263 if (r == OCI_SUCCESS) {
2264 r = OCIAttrSet(d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *>(password.utf16()),
2265 ub4(password.length() *
sizeof(QChar)), OCI_ATTR_PASSWORD, d->err);
2267 Q_ASSERT(!d->trans);
2268 if (r == OCI_SUCCESS) {
2269 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->trans), OCI_HTYPE_TRANS,
2272 if (r == OCI_SUCCESS)
2273 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->trans, 0, OCI_ATTR_TRANS, d->err);
2275 if (r == OCI_SUCCESS) {
2276 if (user.isEmpty() && password.isEmpty())
2277 r = OCISessionBegin(d->svc, d->err, d->authp, OCI_CRED_EXT, d->authMode);
2279 r = OCISessionBegin(d->svc, d->err, d->authp, OCI_CRED_RDBMS, d->authMode);
2281 if (r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO)
2282 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->authp, 0, OCI_ATTR_SESSION, d->err);
2284 if (r != OCI_SUCCESS) {
2285 setLastError(qMakeError(tr(
"Unable to logon"), QSqlError::ConnectionError, d->err));
2288 OCIHandleFree(d->trans, OCI_HTYPE_TRANS);
2291 OCIHandleFree(d->authp, OCI_HTYPE_SESSION);
2294 OCIHandleFree(d->svc, OCI_HTYPE_SVCCTX);
2297 OCIHandleFree(d->srvhp, OCI_HTYPE_SERVER);
2304 r = OCIServerVersion(d->svc,
2306 reinterpret_cast<OraText *>(vertxt),
2310 qCWarning(lcOci,
"QOCIDriver::open: could not get Oracle server version.");
2313 versionStr = QString(
reinterpret_cast<
const QChar *>(vertxt));
2314#if QT_CONFIG(regularexpression)
2315 auto match = QRegularExpression(
"([0-9]+)\\.[0-9\\.]+[0-9]"_L1).match(versionStr);
2316 if (match.hasMatch())
2317 d->serverVersion = match.captured(1).toInt();
2319 if (d->serverVersion == 0)
2320 d->serverVersion = -1;
2324 setOpenError(
false);
2452QStringList QOCIDriver::tables(QSql::TableType type)
const
2454 Q_D(
const QOCIDriver);
2457 QString user = d->user;
2458 if ( isIdentifierEscaped(user, QSqlDriver::TableName))
2459 user = stripDelimiters(user, QSqlDriver::TableName);
2461 user = user.toUpper();
2466 QSqlQuery t(createResult());
2467 t.setForwardOnly(
true);
2468 if (type & QSql::Tables) {
2469 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2470 const QString where = make_where_clause(user, AndExpression);
2471 t.exec(tableQuery + where);
2473 if (t.value(0).toString().toUpper() != user.toUpper())
2474 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2476 tl.append(t.value(1).toString());
2480 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2481 t.exec(synonymQuery + where);
2483 if (t.value(0).toString() != d->user)
2484 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2486 tl.append(t.value(1).toString());
2489 if (type & QSql::Views) {
2490 const auto query =
"select owner, view_name from all_views where "_L1;
2491 const QString where = make_where_clause(user, AndExpression);
2492 t.exec(query + where);
2494 if (t.value(0).toString().toUpper() != d->user.toUpper())
2495 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2497 tl.append(t.value(1).toString());
2500 if (type & QSql::SystemTables) {
2501 t.exec(
"select table_name from dictionary"_L1);
2503 tl.append(t.value(0).toString());
2505 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2506 const QString where = make_where_clause(user, OrExpression);
2507 t.exec(tableQuery + where);
2509 if (t.value(0).toString().toUpper() != user.toUpper())
2510 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2512 tl.append(t.value(1).toString());
2516 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2517 t.exec(synonymQuery + where);
2519 if (t.value(0).toString() != d->user)
2520 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2522 tl.append(t.value(1).toString());