306 const QVariant &val, dvoid *indPtr, ub4 *tmpSize,
TempStorage &tmpStorage)
309 void *data =
const_cast<
void *>(val.constData());
311 switch (val.typeId()) {
312 case QMetaType::QByteArray:
313 r = OCIBindByPos2(stmtp, hbnd, err,
316 ?
const_cast<
char *>(
reinterpret_cast<QByteArray *>(data)->constData())
317 :
reinterpret_cast<QByteArray *>(data)->data(),
318 reinterpret_cast<QByteArray *>(data)->size(),
319 SQLT_BIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
321 case QMetaType::QTime:
322 case QMetaType::QDate:
323 case QMetaType::QDateTime: {
325 r = OCIBindByPos2(stmtp, hbnd, err,
328 sizeof(OCIDateTime *),
329 SQLT_TIMESTAMP_TZ, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
330 tmpStorage.dateTimes.append(ptr);
334 r = OCIBindByPos2(stmtp, hbnd, err,
338 const_cast<
void *>(data),
340 SQLT_INT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
342 case QMetaType::UInt:
343 r = OCIBindByPos2(stmtp, hbnd, err,
347 const_cast<
void *>(data),
349 SQLT_UIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
351 case QMetaType::LongLong:
353 QByteArray ba = qMakeOCINumber(val.toLongLong(), err);
354 r = OCIBindByPos2(stmtp, hbnd, err,
358 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
359 tmpStorage.rawData.append(ba);
362 case QMetaType::ULongLong:
364 QByteArray ba = qMakeOCINumber(val.toULongLong(), err);
365 r = OCIBindByPos2(stmtp, hbnd, err,
369 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
370 tmpStorage.rawData.append(ba);
373 case QMetaType::Double:
374 r = OCIBindByPos2(stmtp, hbnd, err,
378 const_cast<
void *>(data),
380 SQLT_FLT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
382 case QMetaType::QString: {
383 const QString s = val.toString();
385 r = OCIBindByPos2(stmtp, hbnd, err,
387 const_cast<ushort *>(s.utf16()),
388 s.length() *
sizeof(QChar),
389 SQLT_LNG, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
393 r = OCIBindByPos2(stmtp, hbnd, err,
396 const_cast<ushort *>(s.utf16()),
397 (s.length() + 1) *
sizeof(QChar),
398 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
399 if (r == OCI_SUCCESS)
400 setCharset(*hbnd, OCI_HTYPE_BIND);
406 if (val.typeId() >= QMetaType::User) {
410 r = OCIBindByPos2(stmtp, hbnd, err,
413 const_cast<OCIRowid **>(&rptr->id),
415 SQLT_RDD, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
416 }
else if (val.canConvert<QOCIResult *>() && isOutValue(pos)) {
417 QOCIResult *res = qvariant_cast<QOCIResult *>(val);
420 if (res->internal_prepare()) {
421 r = OCIBindByPos2(stmtp, hbnd, err,
425 SQLT_RSET, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
427 res->isCursor =
true;
430 qCWarning(lcOci,
"Unknown bind variable");
434 const QString s = val.toString();
436 QByteArray ba(
reinterpret_cast<
const char *>(s.utf16()), (s.length() + 1) *
sizeof(QChar));
438 ba.reserve((s.capacity() + 1) *
sizeof(QChar));
439 *tmpSize = ba.size();
440 r = OCIBindByPos2(stmtp, hbnd, err,
444 SQLT_STR, indPtr, tmpSize, 0, 0, 0, OCI_DEFAULT);
446 r = OCIBindByPos2(stmtp, hbnd, err,
450 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
452 if (r == OCI_SUCCESS)
453 setCharset(*hbnd, OCI_HTYPE_BIND);
454 tmpStorage.rawData.append(ba);
459 if (r != OCI_SUCCESS)
460 qOraWarning(
"QOCIResultPrivate::bindValue:", err);
848 OCIDefine *dfn =
nullptr;
851 OCIParam *param =
nullptr;
855 parmStatus = OCIParamGet(d->stmtp,
858 reinterpret_cast<
void **>(¶m),
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);
880 dataSize = ofi.oraLength;
882 fieldInf[idx].typ = ofi.type;
883 fieldInf[idx].oraType = ofi.oraType;
884 rec.append(qFromOraInf(ofi));
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->stmtp,
897 &fieldInf[idx].dataPtr,
898 sizeof(OCIDateTime *),
900 &(fieldInf[idx].ind),
903 case QMetaType::Double:
904 r = OCIDefineByPos(d->stmtp,
908 create(idx,
sizeof(
double) - 1),
911 &(fieldInf[idx].ind),
915 r = OCIDefineByPos(d->stmtp,
919 create(idx,
sizeof(qint32) - 1),
922 &(fieldInf[idx].ind),
925 case QMetaType::LongLong:
926 r = OCIDefineByPos(d->stmtp,
930 create(idx,
sizeof(OCINumber)),
933 &(fieldInf[idx].ind),
936 case QMetaType::QByteArray:
938 if (ofi.oraType == SQLT_BIN) {
940 r = OCIDefineByPos(d->stmtp,
944 create(idx, dataSize),
947 &(fieldInf[idx].ind),
948 0, 0, OCI_DYNAMIC_FETCH);
949 }
else if (ofi.oraType == SQLT_LBI) {
951 r = OCIDefineByPos(d->stmtp,
958 &(fieldInf[idx].ind),
959 0, 0, OCI_DYNAMIC_FETCH);
960 }
else if (ofi.oraType == SQLT_CLOB) {
961 r = OCIDefineByPos(d->stmtp,
965 createLobLocator(idx, d->env),
968 &(fieldInf[idx].ind),
972 r = OCIDefineByPos(d->stmtp,
976 createLobLocator(idx, d->env),
979 &(fieldInf[idx].ind),
983 case QMetaType::QString:
984 if (ofi.oraType == SQLT_LNG) {
985 r = OCIDefineByPos(d->stmtp,
992 &(fieldInf[idx].ind),
993 0, 0, OCI_DYNAMIC_FETCH);
995 dataSize += dataSize +
sizeof(QChar);
997 r = OCIDefineByPos(d->stmtp,
1001 create(idx, dataSize),
1004 &(fieldInf[idx].ind),
1007 d->setCharset(dfn, OCI_HTYPE_DEFINE);
1012 dataSize = (dataSize + 1) *
sizeof(utext) ;
1014 r = OCIDefineByPos(d->stmtp,
1018 create(idx, dataSize),
1021 &(fieldInf[idx].ind),
1026 qOraWarning(
"QOCICols::bind:", d->err);
1027 fieldInf[idx].def = dfn;
1030 parmStatus = OCIParamGet(d->stmtp,
1033 reinterpret_cast<
void **>(¶m),
1077 r = OCIStmtGetPieceInfo(d->stmtp, d->err,
reinterpret_cast<
void **>(&dfn), &typep,
1078 &in_outp, &iterp, &idxp, &piecep);
1079 if (r != OCI_SUCCESS)
1080 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to get piece info:", d->err);
1081 qsizetype fieldNum = fieldFromDefine(dfn);
1082 bool isStringField = fieldInf.at(fieldNum).oraType == SQLT_LNG;
1085 r = OCIStmtSetPieceInfo(dfn, OCI_HTYPE_DEFINE,
1087 &chunkSize, piecep, NULL, NULL);
1088 if (r != OCI_SUCCESS)
1089 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to set piece info:", d->err);
1090 status = OCIStmtFetch (d->stmtp, d->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1093 OCIErrorGet(d->err, 1, 0, &errcode, 0, 0,OCI_HTYPE_ERROR);
1099 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to fetch next:", d->err);
1103 if (status == OCI_NO_DATA)
1105 if (nullField || !chunkSize) {
1106 fieldInf[fieldNum].ind = -1;
1108 if (isStringField) {
1109 QString str = values.at(fieldNum + index).toString();
1110 str += QString(
reinterpret_cast<
const QChar *>(col), chunkSize / 2);
1111 values[fieldNum + index] = str;
1112 fieldInf[fieldNum].ind = 0;
1114 QByteArray ba = values.at(fieldNum + index).toByteArray();
1116 ba.resize(sz + chunkSize);
1117 memcpy(ba.data() + sz,
reinterpret_cast<
char *>(col), 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());