305 const QVariant &val, dvoid *indPtr, ub4 *tmpSize,
TempStorage &tmpStorage)
308 void *data =
const_cast<
void *>(val.constData());
310 switch (val.typeId()) {
311 case QMetaType::QByteArray:
312 r = OCIBindByPos2(sql, hbnd, err,
315 ?
const_cast<
char *>(
reinterpret_cast<QByteArray *>(data)->constData())
316 :
reinterpret_cast<QByteArray *>(data)->data(),
317 reinterpret_cast<QByteArray *>(data)->size(),
318 SQLT_BIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
320 case QMetaType::QTime:
321 case QMetaType::QDate:
322 case QMetaType::QDateTime: {
324 r = OCIBindByPos2(sql, hbnd, err,
327 sizeof(OCIDateTime *),
328 SQLT_TIMESTAMP_TZ, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
329 tmpStorage.dateTimes.append(ptr);
333 r = OCIBindByPos2(sql, hbnd, err,
337 const_cast<
void *>(data),
339 SQLT_INT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
341 case QMetaType::UInt:
342 r = OCIBindByPos2(sql, hbnd, err,
346 const_cast<
void *>(data),
348 SQLT_UIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
350 case QMetaType::LongLong:
352 QByteArray ba = qMakeOCINumber(val.toLongLong(), err);
353 r = OCIBindByPos2(sql, hbnd, err,
357 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
358 tmpStorage.rawData.append(ba);
361 case QMetaType::ULongLong:
363 QByteArray ba = qMakeOCINumber(val.toULongLong(), err);
364 r = OCIBindByPos2(sql, hbnd, err,
368 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
369 tmpStorage.rawData.append(ba);
372 case QMetaType::Double:
373 r = OCIBindByPos2(sql, hbnd, err,
377 const_cast<
void *>(data),
379 SQLT_FLT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
381 case QMetaType::QString: {
382 const QString s = val.toString();
384 r = OCIBindByPos2(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 = OCIBindByPos2(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)
399 setCharset(*hbnd, OCI_HTYPE_BIND);
405 if (val.typeId() >= QMetaType::User) {
409 r = OCIBindByPos2(sql, hbnd, err,
412 const_cast<OCIRowid **>(&rptr->id),
414 SQLT_RDD, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
415 }
else if (val.canConvert<QOCIResult *>() && isOutValue(pos)) {
416 QOCIResult *res = qvariant_cast<QOCIResult *>(val);
418 if (res->internal_prepare()) {
419 r = OCIBindByPos2(sql, hbnd, err,
421 const_cast<OCIStmt **>(&res->d_ptr->sql),
423 SQLT_RSET, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
425 res->isCursor =
true;
428 qCWarning(lcOci,
"Unknown bind variable");
432 const QString s = val.toString();
434 QByteArray ba(
reinterpret_cast<
const char *>(s.utf16()), (s.length() + 1) *
sizeof(QChar));
436 ba.reserve((s.capacity() + 1) *
sizeof(QChar));
437 *tmpSize = ba.size();
438 r = OCIBindByPos2(sql, hbnd, err,
442 SQLT_STR, indPtr, tmpSize, 0, 0, 0, OCI_DEFAULT);
444 r = OCIBindByPos2(sql, hbnd, err,
448 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
450 if (r == OCI_SUCCESS)
451 setCharset(*hbnd, OCI_HTYPE_BIND);
452 tmpStorage.rawData.append(ba);
457 if (r != OCI_SUCCESS)
458 qOraWarning(
"QOCIResultPrivate::bindValue:", err);
846 OCIDefine *dfn =
nullptr;
849 OCIParam *param =
nullptr;
853 parmStatus = OCIParamGet(d->sql,
856 reinterpret_cast<
void **>(¶m),
859 while (parmStatus == OCI_SUCCESS) {
861 if (ofi.oraType == SQLT_RDD)
863#ifdef SQLT_INTERVAL_YM
864#ifdef SQLT_INTERVAL_DS
865 else if (ofi.oraType == SQLT_INTERVAL_YM || ofi.oraType == SQLT_INTERVAL_DS)
871 else if (ofi.oraType == SQLT_NUM || ofi.oraType == SQLT_VNU){
872 if (ofi.oraPrecision > 0)
873 dataSize = (ofi.oraPrecision + 1) *
sizeof(utext);
875 dataSize = (38 + 1) *
sizeof(utext);
878 dataSize = ofi.oraLength;
880 fieldInf[idx].typ = ofi.type;
881 fieldInf[idx].oraType = ofi.oraType;
882 rec.append(qFromOraInf(ofi));
884 switch (ofi.type.id()) {
885 case QMetaType::QDateTime:
886 r = OCIDescriptorAlloc(d->env, (
void **)&fieldInf[idx].dataPtr, OCI_DTYPE_TIMESTAMP_TZ, 0, 0);
887 if (r != OCI_SUCCESS) {
888 qCWarning(lcOci,
"QOCICols: Unable to allocate the OCIDateTime descriptor");
891 r = OCIDefineByPos(d->sql,
895 &fieldInf[idx].dataPtr,
896 sizeof(OCIDateTime *),
898 &(fieldInf[idx].ind),
901 case QMetaType::Double:
902 r = OCIDefineByPos(d->sql,
906 create(idx,
sizeof(
double) - 1),
909 &(fieldInf[idx].ind),
913 r = OCIDefineByPos(d->sql,
917 create(idx,
sizeof(qint32) - 1),
920 &(fieldInf[idx].ind),
923 case QMetaType::LongLong:
924 r = OCIDefineByPos(d->sql,
928 create(idx,
sizeof(OCINumber)),
931 &(fieldInf[idx].ind),
934 case QMetaType::QByteArray:
936 if (ofi.oraType == SQLT_BIN) {
938 r = OCIDefineByPos(d->sql,
942 create(idx, dataSize),
945 &(fieldInf[idx].ind),
946 0, 0, OCI_DYNAMIC_FETCH);
947 }
else if (ofi.oraType == SQLT_LBI) {
949 r = OCIDefineByPos(d->sql,
956 &(fieldInf[idx].ind),
957 0, 0, OCI_DYNAMIC_FETCH);
958 }
else if (ofi.oraType == SQLT_CLOB) {
959 r = OCIDefineByPos(d->sql,
963 createLobLocator(idx, d->env),
966 &(fieldInf[idx].ind),
970 r = OCIDefineByPos(d->sql,
974 createLobLocator(idx, d->env),
977 &(fieldInf[idx].ind),
981 case QMetaType::QString:
982 if (ofi.oraType == SQLT_LNG) {
983 r = OCIDefineByPos(d->sql,
990 &(fieldInf[idx].ind),
991 0, 0, OCI_DYNAMIC_FETCH);
993 dataSize += dataSize +
sizeof(QChar);
995 r = OCIDefineByPos(d->sql,
999 create(idx, dataSize),
1002 &(fieldInf[idx].ind),
1005 d->setCharset(dfn, OCI_HTYPE_DEFINE);
1010 dataSize = (dataSize + 1) *
sizeof(utext) ;
1012 r = OCIDefineByPos(d->sql,
1016 create(idx, dataSize),
1019 &(fieldInf[idx].ind),
1024 qOraWarning(
"QOCICols::bind:", d->err);
1025 fieldInf[idx].def = dfn;
1028 parmStatus = OCIParamGet(d->sql,
1031 reinterpret_cast<
void **>(¶m),
1075 r = OCIStmtGetPieceInfo(d->sql, d->err,
reinterpret_cast<
void **>(&dfn), &typep,
1076 &in_outp, &iterp, &idxp, &piecep);
1077 if (r != OCI_SUCCESS)
1078 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to get piece info:", d->err);
1079 qsizetype fieldNum = fieldFromDefine(dfn);
1080 bool isStringField = fieldInf.at(fieldNum).oraType == SQLT_LNG;
1083 r = OCIStmtSetPieceInfo(dfn, OCI_HTYPE_DEFINE,
1085 &chunkSize, piecep, NULL, NULL);
1086 if (r != OCI_SUCCESS)
1087 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to set piece info:", d->err);
1088 status = OCIStmtFetch (d->sql, d->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1091 OCIErrorGet(d->err, 1, 0, &errcode, 0, 0,OCI_HTYPE_ERROR);
1097 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to fetch next:", d->err);
1101 if (status == OCI_NO_DATA)
1103 if (nullField || !chunkSize) {
1104 fieldInf[fieldNum].ind = -1;
1106 if (isStringField) {
1107 QString str = values.at(fieldNum + index).toString();
1108 str += QString(
reinterpret_cast<
const QChar *>(col), chunkSize / 2);
1109 values[fieldNum + index] = str;
1110 fieldInf[fieldNum].ind = 0;
1112 QByteArray ba = values.at(fieldNum + index).toByteArray();
1114 ba.resize(sz + chunkSize);
1115 memcpy(ba.data() + sz,
reinterpret_cast<
char *>(col), chunkSize);
1116 values[fieldNum + index] = ba;
1117 fieldInf[fieldNum].ind = 0;
1120 }
while (status == OCI_SUCCESS_WITH_INFO || status == OCI_NEED_DATA);
1283 qsizetype columnCount = boundValues.count();
1284 if (boundValues.isEmpty() || columnCount == 0)
1288 qCDebug(lcOci) <<
"columnCount:" << columnCount << boundValues;
1293 QVarLengthArray<QMetaType> fieldTypes;
1294 for (qsizetype i = 0; i < columnCount; ++i) {
1295 QMetaType tp = boundValues.at(i).metaType();
1296 fieldTypes.append(tp.id() == QMetaType::QVariantList ? boundValues.at(i).toList().value(0).metaType() : tp);
1304 for (qsizetype i = 0; i < columnCount; ++i) {
1306 if (boundValues.at(i).typeId() != QMetaType::QVariantList) {
1310 singleCol.indicators =
new sb2[1];
1311 *singleCol.indicators = QSqlResultPrivate::isVariantNull(boundValues.at(i)) ? -1 : 0;
1313 r = d->bindValue(d->sql, &singleCol.bindh, d->err, i,
1314 boundValues.at(i), singleCol.indicators, &tmpSizes[i], tmpStorage);
1316 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1317 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1318 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1319 "Unable to bind column for batch execute"),
1320 QSqlError::StatementError, d->err));
1327 col.recordCount = boundValues.at(i).toList().count();
1329 col.lengths =
new ub4[col.recordCount];
1330 col.indicators =
new sb2[col.recordCount];
1331 col.maxarr_len = col.recordCount;
1332 col.curelep = col.recordCount;
1334 switch (fieldTypes[i].id()) {
1335 case QMetaType::QTime:
1336 case QMetaType::QDate:
1337 case QMetaType::QDateTime:
1338 col.bindAs = SQLT_TIMESTAMP_TZ;
1339 col.maxLen =
sizeof(OCIDateTime *);
1342 case QMetaType::Int:
1343 col.bindAs = SQLT_INT;
1344 col.maxLen =
sizeof(
int);
1347 case QMetaType::UInt:
1348 col.bindAs = SQLT_UIN;
1349 col.maxLen =
sizeof(uint);
1352 case QMetaType::LongLong:
1353 col.bindAs = SQLT_VNU;
1354 col.maxLen =
sizeof(OCINumber);
1357 case QMetaType::ULongLong:
1358 col.bindAs = SQLT_VNU;
1359 col.maxLen =
sizeof(OCINumber);
1362 case QMetaType::Double:
1363 col.bindAs = SQLT_FLT;
1364 col.maxLen =
sizeof(
double);
1367 case QMetaType::QString: {
1368 col.bindAs = SQLT_STR;
1369 for (uint j = 0; j < col.recordCount; ++j) {
1372 len = boundValues.at(i).toList().at(j).toString().capacity() + 1;
1374 len = boundValues.at(i).toList().at(j).toString().length() + 1;
1375 if (len > col.maxLen)
1378 col.maxLen *=
sizeof(QChar);
1381 case QMetaType::QByteArray:
1383 if (fieldTypes[i].id() >= QMetaType::User) {
1384 col.bindAs = SQLT_RDD;
1385 col.maxLen =
sizeof(OCIRowid*);
1387 col.bindAs = SQLT_LBI;
1388 for (uint j = 0; j < col.recordCount; ++j) {
1390 col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().capacity();
1392 col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().size();
1393 if (col.lengths[j] > col.maxLen)
1394 col.maxLen = col.lengths[j];
1401 col
.data =
new char[col.maxLen * col.recordCount];
1402 memset(col
.data, 0, col.maxLen * col.recordCount);
1405 for (uint row = 0; row < col.recordCount; ++row) {
1406 const QVariant val = boundValues.at(i).toList().at(row);
1408 if (QSqlResultPrivate::isVariantNull(val) && !d->isOutValue(i)) {
1409 columns[i].indicators[row] = -1;
1410 columns[i].lengths[row] = 0;
1412 columns[i].indicators[row] = 0;
1413 char *dataPtr = columns[i].data + (columns[i].maxLen * row);
1414 switch (fieldTypes[i].id()) {
1415 case QMetaType::QTime:
1416 case QMetaType::QDate:
1417 case QMetaType::QDateTime:{
1418 columns[i].lengths[row] = columns[i].maxLen;
1420 *
reinterpret_cast<OCIDateTime**>(dataPtr) = date->dateTime;
1421 tmpStorage.dateTimes.append(date);
1424 case QMetaType::Int:
1425 columns[i].lengths[row] = columns[i].maxLen;
1426 *
reinterpret_cast<
int*>(dataPtr) = val.toInt();
1429 case QMetaType::UInt:
1430 columns[i].lengths[row] = columns[i].maxLen;
1431 *
reinterpret_cast<uint*>(dataPtr) = val.toUInt();
1434 case QMetaType::LongLong:
1436 columns[i].lengths[row] = columns[i].maxLen;
1437 const QByteArray ba = qMakeOCINumber(val.toLongLong(), d->err);
1438 Q_ASSERT(ba.size() == columns[i].maxLen);
1439 memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1442 case QMetaType::ULongLong:
1444 columns[i].lengths[row] = columns[i].maxLen;
1445 const QByteArray ba = qMakeOCINumber(val.toULongLong(), d->err);
1446 Q_ASSERT(ba.size() == columns[i].maxLen);
1447 memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1450 case QMetaType::Double:
1451 columns[i].lengths[row] = columns[i].maxLen;
1452 *
reinterpret_cast<
double*>(dataPtr) = val.toDouble();
1455 case QMetaType::QString: {
1456 const QString s = val.toString();
1457 columns[i].lengths[row] = ub2((s.length() + 1) *
sizeof(QChar));
1458 memcpy(dataPtr, s.utf16(), columns[i].lengths[row]);
1461 case QMetaType::QByteArray:
1463 if (fieldTypes[i].id() >= QMetaType::User) {
1466 *
reinterpret_cast<OCIRowid**>(dataPtr) = rptr->id;
1467 columns[i].lengths[row] = 0;
1472 columns[i].lengths[row] = ba.size();
1473 memcpy(dataPtr, ba.constData(), ba.size());
1484 qCDebug(lcOci,
"OCIBindByPos2(%p, %p, %p, %d, %p, %d, %d, %p, %p, 0, %d, %p, OCI_DEFAULT)",
1485 d->sql, &bindColumn.bindh, d->err, i + 1, bindColumn.data,
1486 bindColumn.maxLen, bindColumn.bindAs, bindColumn.indicators, bindColumn.lengths,
1487 arrayBind ? bindColumn.maxarr_len : 0, arrayBind ? &bindColumn.curelep : 0);
1489 for (
int ii = 0; ii < (
int)bindColumn.recordCount; ++ii) {
1490 qCDebug(lcOci,
" record %d: indicator %d, length %d", ii, bindColumn.indicators[ii],
1491 bindColumn.lengths[ii]);
1498 d->sql, &bindColumn.bindh, d->err, i + 1,
1502 bindColumn.indicators,
1505 arrayBind ? bindColumn.maxarr_len : 0,
1506 arrayBind ? &bindColumn.curelep : 0,
1510 qCDebug(lcOci,
"After OCIBindByPos: r = %d, bindh = %p", r, bindColumn.bindh);
1513 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1514 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1515 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1516 "Unable to bind column for batch execute"),
1517 QSqlError::StatementError, d->err));
1521 r = OCIBindArrayOfStruct (
1522 columns[i].bindh, d->err,
1524 sizeof(columns[i].indicators[0]),
1525 sizeof(columns[i].lengths[0]),
1528 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1529 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->err);
1530 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1531 "Unable to bind column for batch execute"),
1532 QSqlError::StatementError, d->err));
1538 r = OCIStmtExecute(d->svc, d->sql, d->err,
1539 arrayBind ? 1 : columns[0].recordCount,
1541 d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS);
1543 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1544 qOraWarning(
"QOCIPrivate::execBatch: unable to execute batch statement:", d->err);
1545 d->q_func()->setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1546 "Unable to execute batch statement"),
1547 QSqlError::StatementError, d->err));
1552 for (qsizetype i = 0; i < columnCount; ++i) {
1557 if (
auto tp = boundValues.at(i).metaType(); tp.id() != QMetaType::QVariantList) {
1558 qOraOutValue(boundValues[i], tmpStorage, d
->env, d->err);
1559 if (*columns[i].indicators == -1)
1560 boundValues[i] = QVariant(tp);
1564 QVariantList *list =
static_cast<QVariantList *>(
const_cast<
void*>(boundValues.at(i).data()));
1566 char* data = columns[i].data;
1567 for (uint r = 0; r < columns[i].recordCount; ++r){
1569 if (columns[i].indicators[r] == -1) {
1570 (*list)[r] = QVariant(fieldTypes[i]);
1574 switch(columns[i].bindAs) {
1576 case SQLT_TIMESTAMP_TZ:
1577 (*list)[r] = QOCIDateTime::fromOCIDateTime(d->env, d->err,
1578 *
reinterpret_cast<OCIDateTime **>(data + r * columns[i].maxLen));
1581 (*list)[r] = *
reinterpret_cast<
int*>(data + r * columns[i].maxLen);
1585 (*list)[r] = *
reinterpret_cast<uint*>(data + r * columns[i].maxLen);
1590 switch (boundValues.at(i).typeId()) {
1591 case QMetaType::LongLong:
1592 (*list)[r] = qMakeLongLong(data + r * columns[i].maxLen, d->err);
1594 case QMetaType::ULongLong:
1595 (*list)[r] = qMakeULongLong(data + r * columns[i].maxLen, d->err);
1604 (*list)[r] = *
reinterpret_cast<
double*>(data + r * columns[i].maxLen);
1608 (*list)[r] = QString(
reinterpret_cast<
const QChar *>(data
1609 + r * columns[i].maxLen));
1613 (*list)[r] =
QByteArray(data + r * columns[i].maxLen, columns[i].maxLen);
1619 d->q_func()->setSelect(
false);
1620 d->q_func()->setAt(QSql::BeforeFirstRow);
1621 d->q_func()->setActive(
true);
1623 qDeleteAll(tmpStorage.dateTimes);
1965bool QOCIResult::exec()
1972 TempStorage tmpStorage;
1973 IndicatorArray indicators(boundValueCount());
1974 SizeArray tmpSizes(boundValueCount());
1976 r = OCIAttrGet(d->sql,
1983 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1984 qOraWarning(
"QOCIResult::exec: Unable to get statement type:", d->err);
1985 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
1986 "Unable to get statement type"), QSqlError::StatementError, d->err));
1988 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
1993 iters = stmtType == OCI_STMT_SELECT ? 0 : 1;
1994 mode = d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS;
1997 if (boundValueCount() > 0
1998 && d->bindValues(boundValues(), indicators, tmpSizes, tmpStorage) != OCI_SUCCESS) {
1999 qOraWarning(
"QOCIResult::exec: unable to bind value: ", d->err);
2000 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
"Unable to bind value"),
2001 QSqlError::StatementError, d->err));
2003 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
2010 r = OCIStmtExecute(d->svc,
2018 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
2019 qOraWarning(
"QOCIResult::exec: unable to execute statement:", d->err);
2020 setLastError(qMakeError(QCoreApplication::translate(
"QOCIResult",
2021 "Unable to execute statement"), QSqlError::StatementError, d->err));
2023 qCDebug(lcOci) <<
"lastQuery()" << lastQuery();
2029 if (stmtType == OCI_STMT_SELECT) {
2031 int r = OCIAttrGet(d->sql, OCI_HTYPE_STMT,
reinterpret_cast<
void **>(&parmCount),
2032 0, OCI_ATTR_PARAM_COUNT, d->err);
2033 if (r == 0 && !d->cols)
2034 d->cols =
new QOCICols(parmCount, d);
2036 QSqlCachedResult::init(parmCount);
2040 setAt(QSql::BeforeFirstRow);
2044 d->outValues(boundValues(), indicators, tmpStorage);
2045 qDeleteAll(tmpStorage.dateTimes);
2216bool QOCIDriver::open(
const QString & db,
2217 const QString & user,
2218 const QString & password,
2219 const QString & hostname,
2221 const QString &opts)
2229 qParseOpts(opts, d);
2232 QString connectionString = db;
2233 if (!hostname.isEmpty())
2235 QString::fromLatin1(
"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
2236 "(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
2238 Q_ASSERT(!d->srvhp);
2239 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->srvhp), OCI_HTYPE_SERVER, 0,
nullptr);
2240 if (r == OCI_SUCCESS) {
2241 r = OCIServerAttach(d->srvhp, d->err,
2242 reinterpret_cast<
const OraText *>(connectionString.utf16()),
2243 sb4(connectionString.length() *
sizeof(QChar)), OCI_DEFAULT);
2246 if (r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO) {
2247 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->svc), OCI_HTYPE_SVCCTX,
2250 if (r == OCI_SUCCESS)
2251 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->srvhp, 0, OCI_ATTR_SERVER, d->err);
2252 Q_ASSERT(!d->authp);
2253 if (r == OCI_SUCCESS) {
2254 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->authp), OCI_HTYPE_SESSION,
2257 if (r == OCI_SUCCESS) {
2258 r = OCIAttrSet(d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *>(user.utf16()),
2259 ub4(user.length() *
sizeof(QChar)), OCI_ATTR_USERNAME, d->err);
2261 if (r == OCI_SUCCESS) {
2262 r = OCIAttrSet(d->authp, OCI_HTYPE_SESSION,
const_cast<ushort *>(password.utf16()),
2263 ub4(password.length() *
sizeof(QChar)), OCI_ATTR_PASSWORD, d->err);
2265 Q_ASSERT(!d->trans);
2266 if (r == OCI_SUCCESS) {
2267 r = OCIHandleAlloc(d->env,
reinterpret_cast<
void **>(&d->trans), OCI_HTYPE_TRANS,
2270 if (r == OCI_SUCCESS)
2271 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->trans, 0, OCI_ATTR_TRANS, d->err);
2273 if (r == OCI_SUCCESS) {
2274 if (user.isEmpty() && password.isEmpty())
2275 r = OCISessionBegin(d->svc, d->err, d->authp, OCI_CRED_EXT, d->authMode);
2277 r = OCISessionBegin(d->svc, d->err, d->authp, OCI_CRED_RDBMS, d->authMode);
2279 if (r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO)
2280 r = OCIAttrSet(d->svc, OCI_HTYPE_SVCCTX, d->authp, 0, OCI_ATTR_SESSION, d->err);
2282 if (r != OCI_SUCCESS) {
2283 setLastError(qMakeError(tr(
"Unable to logon"), QSqlError::ConnectionError, d->err));
2286 OCIHandleFree(d->trans, OCI_HTYPE_TRANS);
2289 OCIHandleFree(d->authp, OCI_HTYPE_SESSION);
2292 OCIHandleFree(d->svc, OCI_HTYPE_SVCCTX);
2295 OCIHandleFree(d->srvhp, OCI_HTYPE_SERVER);
2302 r = OCIServerVersion(d->svc,
2304 reinterpret_cast<OraText *>(vertxt),
2308 qCWarning(lcOci,
"QOCIDriver::open: could not get Oracle server version.");
2311 versionStr = QString(
reinterpret_cast<
const QChar *>(vertxt));
2312#if QT_CONFIG(regularexpression)
2313 auto match = QRegularExpression(
"([0-9]+)\\.[0-9\\.]+[0-9]"_L1).match(versionStr);
2314 if (match.hasMatch())
2315 d->serverVersion = match.captured(1).toInt();
2317 if (d->serverVersion == 0)
2318 d->serverVersion = -1;
2322 setOpenError(
false);
2450QStringList QOCIDriver::tables(QSql::TableType type)
const
2452 Q_D(
const QOCIDriver);
2455 QString user = d->user;
2456 if ( isIdentifierEscaped(user, QSqlDriver::TableName))
2457 user = stripDelimiters(user, QSqlDriver::TableName);
2459 user = user.toUpper();
2464 QSqlQuery t(createResult());
2465 t.setForwardOnly(
true);
2466 if (type & QSql::Tables) {
2467 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2468 const QString where = make_where_clause(user, AndExpression);
2469 t.exec(tableQuery + where);
2471 if (t.value(0).toString().toUpper() != user.toUpper())
2472 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2474 tl.append(t.value(1).toString());
2478 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2479 t.exec(synonymQuery + where);
2481 if (t.value(0).toString() != d->user)
2482 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2484 tl.append(t.value(1).toString());
2487 if (type & QSql::Views) {
2488 const auto query =
"select owner, view_name from all_views where "_L1;
2489 const QString where = make_where_clause(user, AndExpression);
2490 t.exec(query + where);
2492 if (t.value(0).toString().toUpper() != d->user.toUpper())
2493 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2495 tl.append(t.value(1).toString());
2498 if (type & QSql::SystemTables) {
2499 t.exec(
"select table_name from dictionary"_L1);
2501 tl.append(t.value(0).toString());
2503 const auto tableQuery =
"select owner, table_name from all_tables where "_L1;
2504 const QString where = make_where_clause(user, OrExpression);
2505 t.exec(tableQuery + where);
2507 if (t.value(0).toString().toUpper() != user.toUpper())
2508 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2510 tl.append(t.value(1).toString());
2514 const auto synonymQuery =
"select owner, synonym_name from all_synonyms where "_L1;
2515 t.exec(synonymQuery + where);
2517 if (t.value(0).toString() != d->user)
2518 tl.append(t.value(0).toString() + u'.' + t.value(1).toString());
2520 tl.append(t.value(1).toString());