309 const QVariant &val, dvoid *indPtr, ub4 *tmpSize,
TempStorage &tmpStorage)
312 void *data =
const_cast<
void *>(val.constData());
314 switch (val.typeId()) {
315 case QMetaType::QByteArray:
316 r = OCIBindByPos2(stmtp, hbnd, err,
319 ?
const_cast<
char *>(
reinterpret_cast<
QByteArray *>(data)->constData())
320 :
reinterpret_cast<
QByteArray *>(data)->data(),
322 SQLT_BIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
324 case QMetaType::QTime:
325 case QMetaType::QDate:
326 case QMetaType::QDateTime: {
328 r = OCIBindByPos2(stmtp, hbnd, err,
331 sizeof(OCIDateTime *),
332 SQLT_TIMESTAMP_TZ, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
333 tmpStorage.dateTimes.append(ptr);
337 r = OCIBindByPos2(stmtp, hbnd, err,
341 const_cast<
void *>(data),
343 SQLT_INT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
345 case QMetaType::UInt:
346 r = OCIBindByPos2(stmtp, hbnd, err,
350 const_cast<
void *>(data),
352 SQLT_UIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
354 case QMetaType::LongLong:
356 QByteArray ba = qMakeOCINumber(val.toLongLong(), err);
357 r = OCIBindByPos2(stmtp, hbnd, err,
361 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
362 tmpStorage.rawData.append(ba);
365 case QMetaType::ULongLong:
367 QByteArray ba = qMakeOCINumber(val.toULongLong(), err);
368 r = OCIBindByPos2(stmtp, hbnd, err,
372 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
373 tmpStorage.rawData.append(ba);
376 case QMetaType::Double:
377 r = OCIBindByPos2(stmtp, hbnd, err,
381 const_cast<
void *>(data),
383 SQLT_FLT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
385 case QMetaType::QString: {
387 const QString s = val.toString().nullTerminated();
388 tmpStorage.stringData.append(s);
390 r = OCIBindByPos2(stmtp, hbnd, err,
392 const_cast<ushort *>(s.utf16()),
393 s.length() *
sizeof(QChar),
394 SQLT_LNG, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
398 r = OCIBindByPos2(stmtp, hbnd, err,
401 const_cast<ushort *>(s.utf16()),
402 (s.length() + 1) *
sizeof(QChar),
403 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
404 if (r == OCI_SUCCESS)
405 setCharset(*hbnd, OCI_HTYPE_BIND);
411 if (val.typeId() >= QMetaType::User) {
415 r = OCIBindByPos2(stmtp, hbnd, err,
418 const_cast<OCIRowid **>(&rptr->id),
420 SQLT_RDD, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
421 }
else if (val.canConvert<QOCIResult *>() && isOutValue(pos)) {
422 QOCIResult *res = qvariant_cast<QOCIResult *>(val);
425 if (res->internal_prepare()) {
426 r = OCIBindByPos2(stmtp, hbnd, err,
430 SQLT_RSET, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
432 res->isCursor =
true;
435 qCWarning(lcOci,
"Unknown bind variable");
439 const QString s = val.toString().nullTerminated();
442 QByteArray ba(
reinterpret_cast<
const char *>(s.utf16()),
443 (s.length() + 1) *
sizeof(QChar));
444 ba.reserve((s.capacity() + 1) *
sizeof(QChar));
445 *tmpSize = ba.size();
446 r = OCIBindByPos2(stmtp, hbnd, err,
450 SQLT_STR, indPtr, tmpSize, 0, 0, 0, OCI_DEFAULT);
451 tmpStorage.rawData.append(ba);
453 tmpStorage.stringData.append(s);
454 r = OCIBindByPos2(stmtp, hbnd, err,
456 const_cast<ushort *>(s.utf16()),
457 (s.length() + 1) *
sizeof(QChar),
458 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
460 if (r == OCI_SUCCESS)
461 setCharset(*hbnd, OCI_HTYPE_BIND);
466 if (r != OCI_SUCCESS)
467 qOraWarning(
"QOCIResultPrivate::bindValue:", err);
855 OCIDefine *dfn =
nullptr;
858 OCIParam *param =
nullptr;
862 parmStatus = OCIParamGet(d->stmtp,
865 reinterpret_cast<
void **>(¶m),
868 while (parmStatus == OCI_SUCCESS) {
870 if (ofi.oraType == SQLT_RDD)
872#ifdef SQLT_INTERVAL_YM
873#ifdef SQLT_INTERVAL_DS
874 else if (ofi.oraType == SQLT_INTERVAL_YM || ofi.oraType == SQLT_INTERVAL_DS)
880 else if (ofi.oraType == SQLT_NUM || ofi.oraType == SQLT_VNU){
881 if (ofi.oraPrecision > 0)
882 dataSize = (ofi.oraPrecision + 1) *
sizeof(utext);
884 dataSize = (38 + 1) *
sizeof(utext);
887 dataSize = ofi.oraLength;
889 fieldInf[idx].typ = ofi.type;
890 fieldInf[idx].oraType = ofi.oraType;
891 rec.append(qFromOraInf(ofi));
893 switch (ofi.type.id()) {
894 case QMetaType::QDateTime:
895 r = OCIDescriptorAlloc(d
->env, (
void **)&fieldInf[idx].dataPtr, OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
896 if (r != OCI_SUCCESS) {
897 qCWarning(lcOci,
"QOCICols: Unable to allocate the OCIDateTime descriptor");
900 r = OCIDefineByPos(d->stmtp,
904 &fieldInf[idx].dataPtr,
905 sizeof(OCIDateTime *),
907 &(fieldInf[idx].ind),
910 case QMetaType::Double:
911 r = OCIDefineByPos(d->stmtp,
915 create(idx,
sizeof(
double) - 1),
918 &(fieldInf[idx].ind),
922 r = OCIDefineByPos(d->stmtp,
926 create(idx,
sizeof(qint32) - 1),
929 &(fieldInf[idx].ind),
932 case QMetaType::LongLong:
933 r = OCIDefineByPos(d->stmtp,
937 create(idx,
sizeof(OCINumber)),
940 &(fieldInf[idx].ind),
943 case QMetaType::QByteArray:
945 if (ofi.oraType == SQLT_BIN) {
947 r = OCIDefineByPos(d->stmtp,
951 create(idx, dataSize),
954 &(fieldInf[idx].ind),
955 0, 0, OCI_DYNAMIC_FETCH);
956 }
else if (ofi.oraType == SQLT_LBI) {
958 r = OCIDefineByPos(d->stmtp,
965 &(fieldInf[idx].ind),
966 0, 0, OCI_DYNAMIC_FETCH);
967 }
else if (ofi.oraType == SQLT_CLOB) {
968 r = OCIDefineByPos(d->stmtp,
972 createLobLocator(idx, d->env),
975 &(fieldInf[idx].ind),
979 r = OCIDefineByPos(d->stmtp,
983 createLobLocator(idx, d->env),
986 &(fieldInf[idx].ind),
990 case QMetaType::QString:
991 if (ofi.oraType == SQLT_LNG) {
992 r = OCIDefineByPos(d->stmtp,
999 &(fieldInf[idx].ind),
1000 0, 0, OCI_DYNAMIC_FETCH);
1002 dataSize += dataSize +
sizeof(QChar);
1004 r = OCIDefineByPos(d->stmtp,
1008 create(idx, dataSize),
1011 &(fieldInf[idx].ind),
1014 d->setCharset(dfn, OCI_HTYPE_DEFINE);
1019 dataSize = (dataSize + 1) *
sizeof(utext) ;
1021 r = OCIDefineByPos(d->stmtp,
1025 create(idx, dataSize),
1028 &(fieldInf[idx].ind),
1033 qOraWarning(
"QOCICols::bind:", d->err);
1034 fieldInf[idx].def = dfn;
1037 parmStatus = OCIParamGet(d->stmtp,
1040 reinterpret_cast<
void **>(¶m),
1084 r = OCIStmtGetPieceInfo(d->stmtp, d->err,
reinterpret_cast<
void **>(&dfn), &typep,
1085 &in_outp, &iterp, &idxp, &piecep);
1086 if (r != OCI_SUCCESS)
1087 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to get piece info:", d->err);
1088 qsizetype fieldNum = fieldFromDefine(dfn);
1089 bool isStringField = fieldInf.at(fieldNum).oraType == SQLT_LNG;
1092 r = OCIStmtSetPieceInfo(dfn, OCI_HTYPE_DEFINE,
1094 &chunkSize, piecep, NULL, NULL);
1095 if (r != OCI_SUCCESS)
1096 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to set piece info:", d->err);
1097 status = OCIStmtFetch (d->stmtp, d->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1100 OCIErrorGet(d->err, 1, 0, &errcode, 0, 0,OCI_HTYPE_ERROR);
1106 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to fetch next:", d->err);
1110 if (status == OCI_NO_DATA)
1112 if (nullField || !chunkSize) {
1113 fieldInf[fieldNum].ind = -1;
1115 if (isStringField) {
1116 QString str = values.at(fieldNum + index).toString()
1117 + QStringView(
reinterpret_cast<
const QChar *>(col.get()), chunkSize / 2);
1118 values[fieldNum + index] = str;
1119 fieldInf[fieldNum].ind = 0;
1121 QByteArray ba = values.at(fieldNum + index).toByteArray()
1122 + QByteArrayView(col.get(), chunkSize);
1123 values[fieldNum + index] = ba;
1124 fieldInf[fieldNum].ind = 0;
1127 }
while (status == OCI_SUCCESS_WITH_INFO || status == OCI_NEED_DATA);
1290 qsizetype columnCount = boundValues.count();
1291 if (boundValues.isEmpty() || columnCount == 0)
1295 qCDebug(lcOci) <<
"columnCount:" << columnCount << boundValues;
1300 QVarLengthArray<QMetaType> fieldTypes;
1301 for (qsizetype i = 0; i < columnCount; ++i) {
1302 QMetaType tp = boundValues.at(i).metaType();
1303 fieldTypes.append(tp.id() == QMetaType::QVariantList ? boundValues.at(i).toList().value(0).metaType() : tp);
1311 for (qsizetype i = 0; i < columnCount; ++i) {
1313 if (boundValues.at(i).typeId() != QMetaType::QVariantList) {
1317 singleCol.indicators =
new sb2[1];
1318 *singleCol.indicators = QSqlResultPrivate::isVariantNull(boundValues.at(i)) ? -1 : 0;
1320 r = d->bindValue(d->stmtp, &singleCol.bindh, d->err, i,
1321 boundValues.at(i), singleCol.indicators, &tmpSizes[i], tmpStorage);
1323 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1324 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1325 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1326 "Unable to bind column for batch execute"),
1327 QSqlError::StatementError, d->err));
1334 col.recordCount = boundValues.at(i).toList().count();
1336 col.lengths =
new ub4[col.recordCount];
1337 col.indicators =
new sb2[col.recordCount];
1338 col.maxarr_len = col.recordCount;
1339 col.curelep = col.recordCount;
1341 switch (fieldTypes[i].id()) {
1342 case QMetaType::QTime:
1343 case QMetaType::QDate:
1344 case QMetaType::QDateTime:
1345 col.bindAs = SQLT_TIMESTAMP_TZ;
1346 col.maxLen =
sizeof(OCIDateTime *);
1349 case QMetaType::Int:
1350 col.bindAs = SQLT_INT;
1351 col.maxLen =
sizeof(
int);
1354 case QMetaType::UInt:
1355 col.bindAs = SQLT_UIN;
1356 col.maxLen =
sizeof(uint);
1359 case QMetaType::LongLong:
1360 col.bindAs = SQLT_VNU;
1361 col.maxLen =
sizeof(OCINumber);
1364 case QMetaType::ULongLong:
1365 col.bindAs = SQLT_VNU;
1366 col.maxLen =
sizeof(OCINumber);
1369 case QMetaType::Double:
1370 col.bindAs = SQLT_FLT;
1371 col.maxLen =
sizeof(
double);
1374 case QMetaType::QString: {
1375 col.bindAs = SQLT_STR;
1376 for (uint j = 0; j < col.recordCount; ++j) {
1379 len = boundValues.at(i).toList().at(j).toString().capacity() + 1;
1381 len = boundValues.at(i).toList().at(j).toString().length() + 1;
1382 if (len > col.maxLen)
1385 col.maxLen *=
sizeof(QChar);
1388 case QMetaType::QByteArray:
1390 if (fieldTypes[i].id() >= QMetaType::User) {
1391 col.bindAs = SQLT_RDD;
1392 col.maxLen =
sizeof(OCIRowid*);
1394 col.bindAs = SQLT_LBI;
1395 for (uint j = 0; j < col.recordCount; ++j) {
1397 col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().capacity();
1399 col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().size();
1400 if (col.lengths[j] > col.maxLen)
1401 col.maxLen = col.lengths[j];
1408 col
.data =
new char[size_t(col.maxLen) * col.recordCount];
1409 memset(col
.data, 0, size_t(col.maxLen) * col.recordCount);
1412 for (uint row = 0; row < col.recordCount; ++row) {
1413 const QVariant val = boundValues.at(i).toList().at(row);
1415 if (QSqlResultPrivate::isVariantNull(val) && !d->isOutValue(i)) {
1416 columns[i].indicators[row] = -1;
1417 columns[i].lengths[row] = 0;
1419 columns[i].indicators[row] = 0;
1420 char *
const dataPtr = columns[i].data + size_t(columns[i].maxLen) * row;
1421 switch (fieldTypes[i].id()) {
1422 case QMetaType::QTime:
1423 case QMetaType::QDate:
1424 case QMetaType::QDateTime:{
1425 columns[i].lengths[row] = columns[i].maxLen;
1427 *
reinterpret_cast<OCIDateTime**>(dataPtr) = date->dateTime;
1428 tmpStorage.dateTimes.append(date);
1431 case QMetaType::Int:
1432 columns[i].lengths[row] = columns[i].maxLen;
1433 *
reinterpret_cast<
int*>(dataPtr) = val.toInt();
1436 case QMetaType::UInt:
1437 columns[i].lengths[row] = columns[i].maxLen;
1438 *
reinterpret_cast<uint*>(dataPtr) = val.toUInt();
1441 case QMetaType::LongLong:
1443 columns[i].lengths[row] = columns[i].maxLen;
1444 const QByteArray ba = qMakeOCINumber(val.toLongLong(), d->err);
1445 Q_ASSERT(ba.size() == columns[i].maxLen);
1446 memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1449 case QMetaType::ULongLong:
1451 columns[i].lengths[row] = columns[i].maxLen;
1452 const QByteArray ba = qMakeOCINumber(val.toULongLong(), d->err);
1453 Q_ASSERT(ba.size() == columns[i].maxLen);
1454 memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1457 case QMetaType::Double:
1458 columns[i].lengths[row] = columns[i].maxLen;
1459 *
reinterpret_cast<
double*>(dataPtr) = val.toDouble();
1462 case QMetaType::QString: {
1463 const QString s = val.toString();
1464 columns[i].lengths[row] = ub2((s.length() + 1) *
sizeof(QChar));
1465 memcpy(dataPtr, s.utf16(), columns[i].lengths[row]);
1468 case QMetaType::QByteArray:
1470 if (fieldTypes[i].id() >= QMetaType::User) {
1473 *
reinterpret_cast<OCIRowid**>(dataPtr) = rptr->id;
1474 columns[i].lengths[row] = 0;
1479 columns[i].lengths[row] = ba.size();
1480 memcpy(dataPtr, ba.constData(), ba.size());
1491 qCDebug(lcOci,
"OCIBindByPos2(%p, %p, %p, %d, %p, %d, %d, %p, %p, 0, %d, %p, OCI_DEFAULT)",
1492 d->stmtp, &bindColumn.bindh, d->err, i + 1, bindColumn.data,
1493 bindColumn.maxLen, bindColumn.bindAs, bindColumn.indicators, bindColumn.lengths,
1494 arrayBind ? bindColumn.maxarr_len : 0, arrayBind ? &bindColumn.curelep : 0);
1496 for (
int ii = 0; ii < (
int)bindColumn.recordCount; ++ii) {
1497 qCDebug(lcOci,
" record %d: indicator %d, length %d", ii, bindColumn.indicators[ii],
1498 bindColumn.lengths[ii]);
1505 d->stmtp, &bindColumn.bindh, d->err, i + 1,
1509 bindColumn.indicators,
1512 arrayBind ? bindColumn.maxarr_len : 0,
1513 arrayBind ? &bindColumn.curelep : 0,
1517 qCDebug(lcOci,
"After OCIBindByPos: r = %d, bindh = %p", r, bindColumn.bindh);
1520 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1521 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1522 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1523 "Unable to bind column for batch execute"),
1524 QSqlError::StatementError, d->err));
1528 r = OCIBindArrayOfStruct (
1529 columns[i].bindh, d->err,
1531 sizeof(columns[i].indicators[0]),
1532 sizeof(columns[i].lengths[0]),
1535 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1536 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1537 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1538 "Unable to bind column for batch execute"),
1539 QSqlError::StatementError, d->err));
1545 r = OCIStmtExecute(d
->svc, d->stmtp, d->err,
1546 arrayBind ? 1 : columns[0].recordCount,
1548 d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS);
1550 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1551 qOraWarning(
"QOCIPrivate::execBatch: unable to execute batch statement:", d->err);
1552 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1553 "Unable to execute batch statement"),
1554 QSqlError::StatementError, d->err));
1559 for (qsizetype i = 0; i < columnCount; ++i) {
1564 if (
auto tp = boundValues.at(i).metaType(); tp.id() != QMetaType::QVariantList) {
1565 qOraOutValue(boundValues[i], tmpStorage, d
->env, d->err);
1566 if (*columns[i].indicators == -1)
1567 boundValues[i] = QVariant(tp);
1571 QVariantList *list =
static_cast<QVariantList *>(
const_cast<
void*>(boundValues.at(i).data()));
1573 char* data = columns[i].data;
1574 for (uint r = 0; r < columns[i].recordCount; ++r){
1576 if (columns[i].indicators[r] == -1) {
1577 (*list)[r] = QVariant(fieldTypes[i]);
1581 char *
const colData = data + r * size_t(columns[i].maxLen);
1582 switch(columns[i].bindAs) {
1584 case SQLT_TIMESTAMP_TZ:
1585 (*list)[r] = QOCIDateTime::fromOCIDateTime(d->env, d->err,
1586 *
reinterpret_cast<OCIDateTime **>(colData));
1589 (*list)[r] = *
reinterpret_cast<
int*>(colData);
1593 (*list)[r] = *
reinterpret_cast<uint*>(colData);
1598 switch (boundValues.at(i).typeId()) {
1599 case QMetaType::LongLong:
1600 (*list)[r] = qMakeLongLong(colData, d->err);
1602 case QMetaType::ULongLong:
1603 (*list)[r] = qMakeULongLong(colData, d->err);
1612 (*list)[r] = *
reinterpret_cast<
double*>(colData);
1616 (*list)[r] = QString(
reinterpret_cast<
const QChar *>(colData));
1620 (*list)[r] =
QByteArray(colData, columns[i].maxLen);
1626 d->q_func()->setSelect(
false);
1627 d->q_func()->setAt(QSql::BeforeFirstRow);
1628 d->q_func()->setActive(
true);
1630 qDeleteAll(tmpStorage.dateTimes);
1972bool QOCIResult::exec()
1979 TempStorage tmpStorage;
1980 IndicatorArray indicators(boundValueCount());
1981 SizeArray tmpSizes(boundValueCount());
1983 r = OCIAttrGet(d->stmtp,
1990 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1991 qOraWarning(
"QOCIResult::exec: Unable to get statement type:", d->err);
1992 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1993 "Unable to get statement type"), QSqlError::StatementError, d->err));
1995 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
2000 iters = stmtType == OCI_STMT_SELECT ? 0 : 1;
2001 mode = d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS;
2004 if (boundValueCount() > 0
2005 && d->bindValues(boundValues(), indicators, tmpSizes, tmpStorage) != OCI_SUCCESS) {
2006 qOraWarning(
"QOCIResult::exec: unable to bind value: ", d->err);
2007 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
"Unable to bind value"),
2008 QSqlError::StatementError, d->err));
2010 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
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);
2027 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
2028 "Unable to execute statement"), QSqlError::StatementError, d->err));
2030 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
2036 if (stmtType == OCI_STMT_SELECT) {
2038 int r = OCIAttrGet(d->stmtp, OCI_HTYPE_STMT,
reinterpret_cast<
void **>(&parmCount),
2039 0, OCI_ATTR_PARAM_COUNT, d->err);
2040 if (r == 0 && !d->cols)
2041 d->cols =
new QOCICols(parmCount, d);
2043 QSqlCachedResult::init(parmCount);
2047 setAt(QSql::BeforeFirstRow);
2051 d->outValues(boundValues(), indicators, tmpStorage);
2052 qDeleteAll(tmpStorage.dateTimes);
2223bool QOCIDriver::open(
const QString & db,
2224 const QString & user,
2225 const QString & password,
2226 const QString & hostname,
2228 const QString &opts)
2236 qParseOpts(opts, d);
2239 QString connectionString = db;
2240 if (!hostname.isEmpty())
2242 QString::fromLatin1(
"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
2243 "(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
2245 Q_ASSERT(!d->srvhp);
2246 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->srvhp), OCI_HTYPE_SERVER, 0,
nullptr);
2247 if (r == OCI_SUCCESS) {
2248 r = OCIServerAttach(d->srvhp, d->err,
2249 reinterpret_cast<
const OraText *>(connectionString.utf16()),
2250 sb4(connectionString.length() *
sizeof(QChar)), OCI_DEFAULT);
2253 if (r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO) {
2254 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->svc), OCI_HTYPE_SVCCTX,
2257 if (r == OCI_SUCCESS)
2258 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->srvhp, 0, OCI_ATTR_SERVER, d->err);
2259 Q_ASSERT(!d->authp);
2260 if (r == OCI_SUCCESS) {
2261 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->authp), OCI_HTYPE_SESSION,
2264 if (r == OCI_SUCCESS) {
2265 r = OCIAttrSet(d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *>(user.utf16()),
2266 ub4(user.length() *
sizeof(QChar)), OCI_ATTR_USERNAME, d->err);
2268 if (r == OCI_SUCCESS) {
2269 r = OCIAttrSet(d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *>(password.utf16()),
2270 ub4(password.length() *
sizeof(QChar)), OCI_ATTR_PASSWORD, d->err);
2272 Q_ASSERT(!d->trans);
2273 if (r == OCI_SUCCESS) {
2274 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->trans), OCI_HTYPE_TRANS,
2277 if (r == OCI_SUCCESS)
2278 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->trans, 0, OCI_ATTR_TRANS, d->err);
2280 if (r == OCI_SUCCESS) {
2281 if (user.isEmpty() && password.isEmpty())
2282 r = OCISessionBegin(d->svc, d->err, d->authp, OCI_CRED_EXT, d->authMode);
2284 r = OCISessionBegin(d->svc, d->err, d->authp, OCI_CRED_RDBMS, d->authMode);
2286 if (r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO)
2287 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->authp, 0, OCI_ATTR_SESSION, d->err);
2289 if (r != OCI_SUCCESS) {
2290 setLastError(qMakeError(tr(
"Unable to logon"), QSqlError::ConnectionError, d->err));
2293 OCIHandleFree(d->trans, OCI_HTYPE_TRANS);
2296 OCIHandleFree(d->authp, OCI_HTYPE_SESSION);
2299 OCIHandleFree(d->svc, OCI_HTYPE_SVCCTX);
2302 OCIHandleFree(d->srvhp, OCI_HTYPE_SERVER);
2309 r = OCIServerVersion(d->svc,
2311 reinterpret_cast<OraText *>(vertxt),
2315 qCWarning(lcOci,
"QOCIDriver::open: could not get Oracle server version.");
2318 versionStr = QString(
reinterpret_cast<
const QChar *>(vertxt));
2319#if QT_CONFIG(regularexpression)
2320 auto match = QRegularExpression(
"([0-9]+)\\.[0-9\\.]+[0-9]"_L1).match(versionStr);
2321 if (match.hasMatch())
2322 d->serverVersion = match.captured(1).toInt();
2324 if (d->serverVersion == 0)
2325 d->serverVersion = -1;
2329 setOpenError(
false);
2457QStringList QOCIDriver::tables(QSql::TableType type)
const
2459 Q_D(
const QOCIDriver);
2462 QString user = d->user;
2463 if ( isIdentifierEscaped(user, QSqlDriver::TableName))
2464 user = stripDelimiters(user, QSqlDriver::TableName);
2466 user = user.toUpper();
2471 QSqlQuery t(createResult());
2472 t.setForwardOnly(
true);
2473 if (type & QSql::Tables) {
2474 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2475 const QString where = make_where_clause(user, AndExpression);
2476 t.exec(tableQuery + where);
2478 if (t.value(0).toString().toUpper() != user.toUpper())
2479 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2481 tl.append(t.value(1).toString());
2485 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2486 t.exec(synonymQuery + where);
2488 if (t.value(0).toString() != d->user)
2489 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2491 tl.append(t.value(1).toString());
2494 if (type & QSql::Views) {
2495 const auto query =
"select owner, view_name from all_views where "_L1;
2496 const QString where = make_where_clause(user, AndExpression);
2497 t.exec(query + where);
2499 if (t.value(0).toString().toUpper() != d->user.toUpper())
2500 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2502 tl.append(t.value(1).toString());
2505 if (type & QSql::SystemTables) {
2506 t.exec(
"select table_name from dictionary"_L1);
2508 tl.append(t.value(0).toString());
2510 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2511 const QString where = make_where_clause(user, OrExpression);
2512 t.exec(tableQuery + where);
2514 if (t.value(0).toString().toUpper() != user.toUpper())
2515 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2517 tl.append(t.value(1).toString());
2521 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2522 t.exec(synonymQuery + where);
2524 if (t.value(0).toString() != d->user)
2525 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2527 tl.append(t.value(1).toString());