60 #if defined(__MINGW64_VERSION_MAJOR) && defined(_WIN64) 61 #define _int64 __int64 75 #define QOCI_DYNAMIC_CHUNK_SIZE 65535 76 #define QOCI_PREFETCH_MEM 10240 90 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN 96 #ifdef OCI_ATTR_CHARSET_FORM 101 static const ub1 qOraCharsetForm = SQLCS_NCHAR;
104 #if defined (OCI_UTF16ID) 147 OCIDescriptorAlloc (env, reinterpret_cast<dvoid **>(&
id),
148 OCI_DTYPE_ROWID, 0, 0);
154 OCIDescriptorFree(
id, OCI_DTYPE_ROWID);
179 void setStatementAttributes();
180 int bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err,
int pos,
196 #ifdef OCI_ATTR_CHARSET_FORM 197 r = OCIAttrSet(handle,
201 const_cast<void *>(static_cast<const void *>(&qOraCharsetForm)),
203 OCI_ATTR_CHARSET_FORM,
209 qWarning(
"QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_FORM.");
213 r = OCIAttrSet(handle,
217 const_cast<void *>(static_cast<const void *>(&
qOraCharset)),
222 qOraWarning(
"QOCIResultPrivate::setCharsetI Couldn't set OCI_ATTR_CHARSET_ID: ", err);
233 if (prefetchRows >= 0) {
238 OCI_ATTR_PREFETCH_ROWS,
241 qOraWarning(
"QOCIResultPrivate::setStatementAttributes:" 242 " Couldn't set OCI_ATTR_PREFETCH_ROWS: ", err);
244 if (prefetchMem >= 0) {
249 OCI_ATTR_PREFETCH_MEMORY,
252 qOraWarning(
"QOCIResultPrivate::setStatementAttributes:" 253 " Couldn't set OCI_ATTR_PREFETCH_MEMORY: ", err);
263 switch (val.
type()) {
265 r = OCIBindByPos(sql, hbnd, err,
268 ? const_cast<char *>(reinterpret_cast<QByteArray *>(data)->constData())
269 : reinterpret_cast<QByteArray *>(data)->
data(),
270 reinterpret_cast<QByteArray *>(data)->size(),
271 SQLT_BIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
277 r = OCIBindByPos(sql, hbnd, err,
281 SQLT_DAT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
285 r = OCIBindByPos(sql, hbnd, err,
289 const_cast<void *>(data),
291 SQLT_INT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
294 r = OCIBindByPos(sql, hbnd, err,
298 const_cast<void *>(data),
300 SQLT_UIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
305 r = OCIBindByPos(sql, hbnd, err,
309 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
316 r = OCIBindByPos(sql, hbnd, err,
320 SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
325 r = OCIBindByPos(sql, hbnd, err,
329 const_cast<void *>(data),
331 SQLT_FLT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
337 r = OCIBindByPos(sql, hbnd, err,
340 const_cast<OCIRowid **>(&rptr->id),
342 SQLT_RDD, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
350 if (isBinaryValue(pos)) {
351 r = OCIBindByPos(sql, hbnd, err,
353 const_cast<ushort *>(s.
utf16()),
355 SQLT_LNG, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
357 }
else if (!isOutValue(pos)) {
359 r = OCIBindByPos(sql, hbnd, err,
362 const_cast<ushort *>(s.
utf16()),
364 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
365 if (r == OCI_SUCCESS)
366 setCharset(*hbnd, OCI_HTYPE_BIND);
374 if (isOutValue(pos)) {
376 *tmpSize = ba.size();
377 r = OCIBindByPos(sql, hbnd, err,
381 SQLT_STR, indPtr, tmpSize, 0, 0, 0, OCI_DEFAULT);
383 r = OCIBindByPos(sql, hbnd, err,
387 SQLT_STR, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
389 if (r == OCI_SUCCESS)
390 setCharset(*hbnd, OCI_HTYPE_BIND);
395 if (r != OCI_SUCCESS)
404 for (
int i = 0; i < values.
count(); ++i) {
410 sb2 *indPtr = &indicators[i];
411 *indPtr = val.
isNull() ? -1 : 0;
413 bindValue(sql, &hbnd, err, i, val, indPtr, &tmpSizes[i], tmpStorage);
421 switch (value.
type()) {
449 for (
int i = 0; i < values.
count(); ++i) {
457 if (indicators[i] == -1)
480 void allocErrorHandle();
484 : env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false), serverVersion(-1),
491 int r = OCIHandleAlloc(
env,
492 reinterpret_cast<void **>(&
err),
497 qWarning(
"QOCIDriver: unable to allocate error handle");
527 *errorCode = errcode;
528 return QString(reinterpret_cast<const QChar *>(errbuf));
558 return QSqlError(errString, oraErrorString, type, errorCode);
573 switch(precisionPolicy) {
617 #ifdef SQLT_INTERVAL_YM 618 case SQLT_INTERVAL_YM:
620 #ifdef SQLT_INTERVAL_DS 621 case SQLT_INTERVAL_DS:
632 switch(precisionPolicy) {
663 #ifdef SQLT_TIMESTAMP 665 case SQLT_TIMESTAMP_TZ:
666 case SQLT_TIMESTAMP_LTZ:
672 qWarning(
"qDecodeOCIType: unknown OCI datatype: %d", ocitype);
707 ba[0]= (year / 100) + 100;
708 ba[1]= (year % 100) + 100;
729 OCINumberFromInt(err,
733 reinterpret_cast<OCINumber*>(ba.
data()));
749 OCINumberFromInt(err,
753 reinterpret_cast<OCINumber*>(ba.
data()));
760 OCINumberToInt(err, reinterpret_cast<const OCINumber *>(ociNumber),
sizeof(
qlonglong),
761 OCI_NUMBER_SIGNED, &qll);
768 OCINumberToInt(err, reinterpret_cast<const OCINumber *>(ociNumber),
sizeof(
qulonglong),
769 OCI_NUMBER_UNSIGNED, &qull);
775 int century =
uchar(oraDate[0]);
777 int year =
uchar(oraDate[1]);
778 year = ((century-100)*100) + (year-100);
779 int month = oraDate[2];
780 int day = oraDate[3];
781 int hour = oraDate[4] - 1;
782 int min = oraDate[5] - 1;
783 int sec = oraDate[6] - 1;
796 int fieldFromDefine(OCIDefine*
d);
798 inline int size() {
return fieldInf.size(); }
831 int r = OCIDescriptorFree(lob, OCI_DTYPE_LOB);
833 qWarning(
"QOCICols: Cannot free LOB descriptor");
838 : fieldInf(size),
d(dp)
848 parmStatus = OCIParamGet(
d->
sql,
851 reinterpret_cast<void **>(¶m),
854 while (parmStatus == OCI_SUCCESS) {
858 #ifdef SQLT_INTERVAL_YM 859 #ifdef SQLT_INTERVAL_DS 860 else if (ofi.
oraType == SQLT_INTERVAL_YM || ofi.
oraType == SQLT_INTERVAL_DS)
864 #endif //SQLT_INTERVAL_DS 865 #endif //SQLT_INTERVAL_YM 870 dataSize = (38 + 1) *
sizeof(utext);
881 r = OCIDefineByPos(
d->
sql,
892 r = OCIDefineByPos(
d->
sql,
896 create(idx,
sizeof(
double) - 1),
903 r = OCIDefineByPos(
d->
sql,
914 r = OCIDefineByPos(
d->
sql,
918 create(idx,
sizeof(OCINumber)),
928 r = OCIDefineByPos(
d->
sql,
936 0, 0, OCI_DYNAMIC_FETCH);
937 }
else if (ofi.
oraType == SQLT_LBI) {
939 r = OCIDefineByPos(
d->
sql,
947 0, 0, OCI_DYNAMIC_FETCH);
948 }
else if (ofi.
oraType == SQLT_CLOB) {
949 r = OCIDefineByPos(
d->
sql,
960 r = OCIDefineByPos(
d->
sql,
973 r = OCIDefineByPos(
d->
sql,
981 0, 0, OCI_DYNAMIC_FETCH);
983 dataSize += dataSize +
sizeof(
QChar);
985 r = OCIDefineByPos(
d->
sql,
1000 dataSize = (dataSize + 1) *
sizeof(utext) ;
1002 r = OCIDefineByPos(
d->
sql,
1018 parmStatus = OCIParamGet(
d->
sql,
1021 reinterpret_cast<void **>(¶m),
1032 char*
c =
new char[size+1];
1034 memset(c, 0, size+1);
1043 int r = OCIDescriptorAlloc(env,
1044 reinterpret_cast<void **>(&lob),
1049 qWarning(
"QOCICols: Cannot create LOB locator");
1070 r = OCIStmtGetPieceInfo(
d->
sql,
d->
err, reinterpret_cast<void **>(&dfn), &typep,
1071 &in_outp, &iterp, &idxp, &piecep);
1072 if (r != OCI_SUCCESS)
1073 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to get piece info:",
d->
err);
1075 bool isStringField =
fieldInf.at(fieldNum).oraType == SQLT_LNG;
1078 r = OCIStmtSetPieceInfo(dfn, OCI_HTYPE_DEFINE,
1080 &chunkSize, piecep, NULL, NULL);
1081 if (r != OCI_SUCCESS)
1082 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to set piece info:",
d->
err);
1083 status = OCIStmtFetch (
d->
sql,
d->
err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1086 OCIErrorGet(
d->
err, 1, 0, &errcode, 0, 0,OCI_HTYPE_ERROR);
1092 qOraWarning(
"OCIResultPrivate::readPiecewise: unable to fetch next:",
d->
err);
1096 if (status == OCI_NO_DATA)
1098 if (nullField || !chunkSize) {
1101 if (isStringField) {
1103 str +=
QString(reinterpret_cast<const QChar *>(col), chunkSize / 2);
1104 values[fieldNum +
index] = str;
1109 ba.
resize(sz + chunkSize);
1110 memcpy(ba.
data() + sz,
reinterpret_cast<char *
>(col), chunkSize);
1111 values[fieldNum +
index] = ba;
1115 }
while (status == OCI_SUCCESS_WITH_INFO || status == OCI_NEED_DATA);
1127 ub2 colFieldLength(0);
1128 sb2 colPrecision(0);
1133 r = OCIAttrGet(param,
1142 r = OCIAttrGet(param,
1151 r = OCIAttrGet(param,
1160 #ifdef OCI_ATTR_CHAR_SIZE 1161 r = OCIAttrGet(param,
1171 colFieldLength = colLength;
1174 r = OCIAttrGet(param,
1183 r = OCIAttrGet(param,
1191 r = OCIAttrGet(param,
1199 r = OCIAttrGet(param,
1211 if (colLength == 22 && colPrecision == 0 && colScale == 0)
1218 if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
1224 if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
1225 || (colType == SQLT_INT)) {
1232 if (colType == SQLT_BLOB)
1236 ofi.
name =
QString(reinterpret_cast<const QChar*>(colName), colNameLen / 2);
1251 : bindh(0), bindAs(0), maxLen(0), recordCount(0),
1252 data(0), lengths(0), indicators(0), maxarr_len(0), curelep(0) {}
1273 for (
int j = 0; j < col.count(); ++j){
1274 delete[] col[j].lengths;
1275 delete[] col[j].indicators;
1276 delete[] col[j].data;
1285 int columnCount = boundValues.
count();
1286 if (boundValues.
isEmpty() || columnCount == 0)
1290 qDebug() <<
"columnCount:" << columnCount << boundValues;
1297 for (i = 0; i < columnCount; ++i) {
1309 for (i = 0; i < columnCount; ++i) {
1316 *singleCol.
indicators = boundValues.at(i).isNull() ? -1 : 0;
1319 boundValues.at(i), singleCol.
indicators, &tmpSizes[i], tmpStorage);
1321 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1322 qOraWarning(
"QOCIPrivate::execBatch: unable to bind column:", d->
err);
1324 "Unable to bind column for batch execute"),
1332 col.
recordCount = boundValues.at(i).toList().count();
1339 switch (fieldTypes[i]) {
1349 col.
maxLen =
sizeof(int);
1359 col.
maxLen =
sizeof(OCINumber);
1364 col.
maxLen =
sizeof(OCINumber);
1369 col.
maxLen =
sizeof(double);
1374 col.
maxLen =
sizeof(OCIRowid*);
1382 len = boundValues.at(i).toList().at(j).toString().capacity() + 1;
1384 len = boundValues.at(i).toList().at(j).toString().length() + 1;
1396 col.
lengths[j] = boundValues.at(i).toList().at(j).toByteArray().capacity();
1398 col.
lengths[j] = boundValues.at(i).toList().at(j).toByteArray().size();
1413 columns[i].indicators[row] = -1;
1414 columns[i].lengths[row] = 0;
1416 columns[i].indicators[row] = 0;
1417 char *dataPtr = columns[i].
data + (columns[i].maxLen * row);
1418 switch (fieldTypes[i]) {
1422 columns[i].lengths[row] = columns[i].maxLen;
1425 memcpy(dataPtr, ba.
constData(), columns[i].maxLen);
1429 columns[i].lengths[row] = columns[i].maxLen;
1430 *
reinterpret_cast<int*
>(dataPtr) = val.
toInt();
1434 columns[i].lengths[row] = columns[i].maxLen;
1435 *
reinterpret_cast<uint*
>(dataPtr) = val.
toUInt();
1440 columns[i].lengths[row] = columns[i].maxLen;
1443 memcpy(dataPtr, ba.
constData(), columns[i].maxLen);
1448 columns[i].lengths[row] = columns[i].maxLen;
1451 memcpy(dataPtr, ba.
constData(), columns[i].maxLen);
1455 columns[i].lengths[row] = columns[i].maxLen;
1456 *
reinterpret_cast<double*
>(dataPtr) = val.
toDouble();
1461 columns[i].lengths[row] = (s.
length() + 1) *
sizeof(
QChar);
1462 memcpy(dataPtr, s.
utf16(), columns[i].lengths[row]);
1468 *
reinterpret_cast<OCIRowid**
>(dataPtr) = rptr->id;
1469 columns[i].lengths[row] = 0;
1475 columns[i].lengths[row] = ba.
size();
1486 qDebug(
"OCIBindByPos(%p, %p, %p, %d, %p, %d, %d, %p, %p, 0, %d, %p, OCI_DEFAULT)",
1491 for (
int ii = 0; ii < (int)bindColumn.
recordCount; ++ii) {
1492 qDebug(
" record %d: indicator %d, length %d", ii, bindColumn.
indicators[ii],
1508 arrayBind ? &bindColumn.
curelep : 0,
1512 qDebug(
"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);
1518 "Unable to bind column for batch execute"),
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);
1533 "Unable to bind column for batch execute"),
1540 r = OCIStmtExecute(d->
svc, d->
sql, 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);
1548 "Unable to execute batch statement"),
1554 for (i = 0; i < columnCount; ++i) {
1562 if (*columns[i].indicators == -1)
1569 char*
data = columns[i].data;
1570 for (
uint r = 0; r < columns[i].recordCount; ++r){
1572 if (columns[i].indicators[r] == -1) {
1577 switch(columns[i].bindAs) {
1580 (*list)[r] =
qMakeDate(data + r * columns[i].maxLen);
1584 (*list)[r] = *
reinterpret_cast<int*
>(data + r * columns[i].maxLen);
1588 (*list)[r] = *
reinterpret_cast<uint*
>(data + r * columns[i].maxLen);
1593 switch (boundValues.at(i).type()) {
1607 (*list)[r] = *
reinterpret_cast<double*
>(data + r * columns[i].maxLen);
1611 (*list)[r] =
QString(reinterpret_cast<const QChar *>(data
1612 + r * columns[i].maxLen));
1616 (*list)[r] =
QByteArray(data + r * columns[i].maxLen, columns[i].maxLen);
1629 template<
class T,
int sz>
1637 r = OCILobCharSetForm(d->
env, d->
err, lob, &csfrm);
1638 if (r != OCI_SUCCESS) {
1639 qOraWarning(
"OCIResultPrivate::readLobs: Couldn't get LOB char set form: ", d->
err);
1644 r = OCILobGetLength(d->
svc, d->
err, lob, &amount);
1645 if (r == OCI_SUCCESS) {
1652 qOraWarning(
"OCIResultPrivate::readLobs: Couldn't get LOB length: ", d->
err);
1660 r = OCILobRead(d->
svc,
1673 if (r != OCI_SUCCESS)
1674 qOraWarning(
"OCIResultPrivate::readLOBs: Cannot read LOB: ", d->
err);
1682 int r = OCI_SUCCESS;
1684 for (
int i = 0; i <
size(); ++i) {
1686 if (fi.
ind == -1 || !(lob = fi.
lob))
1689 bool isClob = fi.
oraType == SQLT_CLOB;
1694 r = qReadLob<QString, sizeof(QChar)>(str,
d, lob);
1698 r = qReadLob<QByteArray, sizeof(char)>(buf,
d, lob);
1701 if (r == OCI_SUCCESS)
1702 values[index + i] = var;
1711 for (
int i = 0; i <
fieldInf.count(); ++i) {
1720 for (
int i = 0; i <
fieldInf.size(); ++i) {
1723 if (fld.
ind == -1) {
1742 v[index + i] = *
reinterpret_cast<double *
>(fld.
data);
1747 int r = OCINumberToInt(
d->
err, reinterpret_cast<OCINumber *>(fld.
data),
sizeof(
qint64),
1748 OCI_NUMBER_SIGNED, &qll);
1749 if(r == OCI_SUCCESS)
1756 v[index + i] = *
reinterpret_cast<int *
>(fld.
data);
1762 v[index + i] =
QString(reinterpret_cast<const QChar *>(fld.
data));
1771 qWarning(
"QOCICols::value: unknown data type");
1778 : cols(0), q(result), env(driver->env), err(0), svc(const_cast<
OCISvcCtx*&>(driver->svc)),
1779 sql(0), transaction(driver->transaction), serverVersion(driver->serverVersion),
1780 prefetchRows(driver->prefetchRows), prefetchMem(driver->prefetchMem)
1782 int r = OCIHandleAlloc(
env,
1783 reinterpret_cast<void **>(&
err),
1788 qWarning(
"QOCIResult: unable to alloc error handle");
1795 int r = OCIHandleFree(
err, OCI_HTYPE_ERROR);
1797 qWarning(
"~QOCIResult: unable to free statement handle");
1812 int r = OCIHandleFree(
d->
sql, OCI_HTYPE_STMT);
1814 qWarning(
"~QOCIResult: unable to free statement handle");
1836 bool piecewise =
false;
1837 int r = OCI_SUCCESS;
1838 r = OCIStmtFetch(
d->
sql,
d->
err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
1841 return r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO;
1846 case OCI_SUCCESS_WITH_INFO:
1859 qWarning(
"QOCI Warning: data truncated for %s",
lastQuery().toLocal8Bit().constData());
1867 "Unable to goto next"),
1873 if (r == OCI_SUCCESS && piecewise)
1876 if (r == OCI_SUCCESS)
1878 if (r == OCI_SUCCESS)
1880 if (r != OCI_SUCCESS)
1882 return r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO;
1912 r = OCIHandleFree(
d->
sql, OCI_HTYPE_STMT);
1913 if (r != OCI_SUCCESS)
1914 qOraWarning(
"QOCIResult::prepare: unable to free statement handle:",
d->
err);
1918 r = OCIHandleAlloc(
d->
env,
1919 reinterpret_cast<void **>(&
d->
sql),
1923 if (r != OCI_SUCCESS) {
1924 qOraWarning(
"QOCIResult::prepare: unable to alloc statement:",
d->
err);
1930 const OraText *txt =
reinterpret_cast<const OraText *
>(query.
utf16());
1932 r = OCIStmtPrepare(
d->
sql,
1938 if (r != OCI_SUCCESS) {
1939 qOraWarning(
"QOCIResult::prepare: unable to prepare statement:",
d->
err);
1957 r = OCIAttrGet(
d->
sql,
1964 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
1965 qOraWarning(
"QOCIResult::exec: Unable to get statement type:",
d->
err);
1974 if (stmtType == OCI_STMT_SELECT) {
1979 mode =
d->
transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS;
1995 r = OCIStmtExecute(
d->
svc,
2003 if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
2004 qOraWarning(
"QOCIResult::exec: unable to execute statement:",
d->
err);
2013 if (stmtType == OCI_STMT_SELECT) {
2015 int r = OCIAttrGet(
d->
sql, OCI_HTYPE_STMT, reinterpret_cast<void **>(&parmCount),
2016 0, OCI_ATTR_PARAM_COUNT,
d->
err);
2017 if (r == 0 && !
d->
cols)
2046 int r = OCIAttrGet(
d->
sql, OCI_HTYPE_STMT, ptr.
constData()->id,
2047 0, OCI_ATTR_ROWID,
d->
err);
2048 if (r == OCI_SUCCESS)
2075 #ifdef QOCI_THREADED 2076 const ub4 mode = OCI_UTF16 | OCI_OBJECT | OCI_THREADED;
2078 const ub4 mode = OCI_UTF16 | OCI_OBJECT;
2080 int r = OCIEnvCreate(&
d->
env,
2089 qWarning(
"QOCIDriver: unable to create environment");
2117 int r = OCIHandleFree(
d->
err, OCI_HTYPE_ERROR);
2118 if (r != OCI_SUCCESS)
2119 qWarning(
"Unable to free Error handle: %d", r);
2120 r = OCIHandleFree(
d->
env, OCI_HTYPE_ENV);
2121 if (r != OCI_SUCCESS)
2122 qWarning(
"Unable to free Environment handle: %d", r);
2154 for (
int i = 0; i < opts.count(); ++i) {
2155 const QString tmp(opts.at(i));
2157 if ((idx = tmp.indexOf(
QLatin1Char(
'='))) == -1) {
2158 qWarning(
"QOCIDriver::parseArgs: Invalid parameter: '%s'",
2159 tmp.toLocal8Bit().constData());
2169 }
else if (opt ==
QLatin1String(
"OCI_ATTR_PREFETCH_MEMORY")) {
2174 qWarning (
"QOCIDriver::parseArgs: Invalid parameter: '%s'",
2195 QString connectionString = db;
2199 "(CONNECT_DATA=(SID=%3)))").
arg(hostname).
arg((port > -1 ? port : 1521)).
arg(db);
2201 r = OCIHandleAlloc(
d->
env, reinterpret_cast<void **>(&
d->
srvhp), OCI_HTYPE_SERVER, 0, 0);
2202 if (r == OCI_SUCCESS)
2203 r = OCIServerAttach(
d->
srvhp,
d->
err, reinterpret_cast<const OraText *>(connectionString.
utf16()),
2204 connectionString.
length() *
sizeof(
QChar), OCI_DEFAULT);
2205 if (r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO)
2206 r = OCIHandleAlloc(
d->
env, reinterpret_cast<void **>(&
d->
svc), OCI_HTYPE_SVCCTX, 0, 0);
2207 if (r == OCI_SUCCESS)
2208 r = OCIAttrSet(
d->
svc, OCI_HTYPE_SVCCTX,
d->
srvhp, 0, OCI_ATTR_SERVER,
d->
err);
2209 if (r == OCI_SUCCESS)
2210 r = OCIHandleAlloc(
d->
env, reinterpret_cast<void **>(&
d->
authp), OCI_HTYPE_SESSION, 0, 0);
2211 if (r == OCI_SUCCESS)
2212 r = OCIAttrSet(
d->
authp, OCI_HTYPE_SESSION, const_cast<ushort *>(user.
utf16()),
2214 if (r == OCI_SUCCESS)
2215 r = OCIAttrSet(
d->
authp, OCI_HTYPE_SESSION, const_cast<ushort *>(password.
utf16()),
2219 if (r == OCI_SUCCESS)
2220 r = OCIHandleAlloc(
d->
env, reinterpret_cast<void **>(&trans), OCI_HTYPE_TRANS, 0, 0);
2221 if (r == OCI_SUCCESS)
2222 r = OCIAttrSet(
d->
svc, OCI_HTYPE_SVCCTX, trans, 0, OCI_ATTR_TRANS,
d->
err);
2224 if (r == OCI_SUCCESS) {
2226 r = OCISessionBegin(
d->
svc,
d->
err,
d->
authp, OCI_CRED_EXT, OCI_DEFAULT);
2228 r = OCISessionBegin(
d->
svc,
d->
err,
d->
authp, OCI_CRED_RDBMS, OCI_DEFAULT);
2230 if (r == OCI_SUCCESS || r == OCI_SUCCESS_WITH_INFO)
2231 r = OCIAttrSet(
d->
svc, OCI_HTYPE_SVCCTX,
d->
authp, 0, OCI_ATTR_SESSION,
d->
err);
2233 if (r != OCI_SUCCESS) {
2237 OCIHandleFree(
d->
authp, OCI_HTYPE_SESSION);
2240 OCIHandleFree(
d->
srvhp, OCI_HTYPE_SERVER);
2247 r = OCIServerVersion(
d->
svc,
2249 reinterpret_cast<OraText *>(vertxt),
2253 qWarning(
"QOCIDriver::open: could not get Oracle server version.");
2256 versionStr =
QString(reinterpret_cast<const QChar *>(vertxt));
2258 if (vers.
indexIn(versionStr) >= 0)
2277 OCIServerDetach(
d->
srvhp,
d->
err, OCI_DEFAULT);
2278 OCIHandleFree(
d->
authp, OCI_HTYPE_SESSION);
2280 OCIHandleFree(
d->
srvhp, OCI_HTYPE_SERVER);
2282 OCIHandleFree(
d->
svc, OCI_HTYPE_SVCCTX);
2296 qWarning(
"QOCIDriver::beginTransaction: Database not open");
2299 int r = OCITransStart(
d->
svc,
2302 OCI_TRANS_READWRITE);
2303 if (r == OCI_ERROR) {
2316 qWarning(
"QOCIDriver::commitTransaction: Database not open");
2319 int r = OCITransCommit(
d->
svc,
2322 if (r == OCI_ERROR) {
2335 qWarning(
"QOCIDriver::rollbackTransaction: Database not open");
2338 int r = OCITransRollback(
d->
svc,
2341 if (r == OCI_ERROR) {
2379 foreach(
const QString &sysUserName, sysUsers)
2381 t.
exec(query + whereList.
join(QLatin1String(
" and ")));
2391 query =
QLatin1String(
"select owner, synonym_name from all_synonyms where ");
2392 t.
exec(query + whereList.
join(QLatin1String(
" and ")));
2403 foreach(
const QString &sysUserName, sysUsers)
2405 t.
exec(query + whereList.
join(QLatin1String(
" and ")));
2420 foreach(
const QString &sysUserName, sysUsers)
2422 t.
exec(query + whereList.
join(QLatin1String(
" or ")));
2432 query =
QLatin1String(
"select owner, synonym_name from all_synonyms where ");
2433 t.
exec(query + whereList.
join(QLatin1String(
" or ")));
2450 *owner = tname.
left(i);
2466 "data_precision, data_scale, nullable, data_default%1" 2467 "from all_tab_columns a " 2468 "where a.table_name=%2"));
2473 bool buildRecordInfo =
false;
2497 "on a.owner=b.table_owner and a.table_name=b.table_name " 2498 "where b.owner='") + owner +
2504 buildRecordInfo =
true;
2506 buildRecordInfo =
true;
2510 if (buildRecordInfo) {
2522 f.setDefaultValue(t.
value(6));
2536 "from all_constraints a, all_ind_columns b " 2537 "where a.constraint_type='P' " 2538 "and b.index_name = a.constraint_name " 2539 "and b.index_owner = a.owner"));
2541 bool buildIndex =
false;
2560 tmpStmt +=
QLatin1String(
" and a.owner='") + owner + QLatin1Char(
'\'');
2565 stmt +=
QLatin1String(
" and a.table_name=(select tname from sys.synonyms " 2566 "where sname='") + table +
QLatin1String(
"' and creator=a.owner)");
2581 tt.
exec(
QLatin1String(
"select data_type from all_tab_columns where table_name='") +
2584 owner + QLatin1Char(
'\''));
2598 switch (field.
type()) {
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
The QVariant class acts like a union for the most common Qt data types.
The QSqlError class provides SQL database error information.
The QSqlIndex class provides functions to manipulate and describe database indexes.
QOCIDriver(QObject *parent=0)
QVariant data(int i)
Returns the data for field index in the current row as a QVariant.
bool isOutValue(int i) const
QOCIResult(const QOCIDriver *db, const QOCIDriverPrivate *p)
QVariant::Type qDecodeOCIType(const QString &ocitype, QSql::NumericalPrecisionPolicy precisionPolicy)
static QDateTime qMakeDate(const char *oraDate)
bool isActive() const
Returns true if the result has records to be retrieved; otherwise returns false.
QVariant handle() const
Returns the low-level database handle for this result set wrapped in a QVariant or an invalid QVarian...
QString cap(int nth=0) const
Returns the text captured by the nth subexpression.
#define QT_END_NAMESPACE
This macro expands to.
virtual void setOpen(bool o)
This function sets the open state of the database to open.
int size()
Returns the size of the SELECT result, or -1 if it cannot be determined or if the query is not a SELE...
char * data()
Returns a pointer to the data stored in the byte array.
QVector< QOCIBatchColumn > & col
~QOCIBatchCleanupHandler()
void virtual_hook(int id, void *data)
The QRegExp class provides pattern matching using regular expressions.
DriverFeature
This enum contains a list of features a driver might support.
bool isValid() const
Returns true if this date is valid; otherwise returns false.
QString escapeIdentifier(const QString &identifier, IdentifierType) const
Returns the identifier escaped according to the database rules.
int toInt(bool *ok=0, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
bool isNull() const
Returns true if this is a NULL variant, false otherwise.
static QSqlField qFromOraInf(const OraFieldInfo &ofi)
virtual void setOpenError(bool e)
This function sets the open error state of the database to error.
int count(const T &t) const
Returns the number of occurrences of value in the vector.
void append(const QSqlField &field)
Appends the field field to the list of indexed fields.
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const
Returns the current precision policy.
QVariant lastInsertId() const
Returns the object ID of the most recent inserted row if the database supports it.
#define QOCI_PREFETCH_MEM
QOCICols(int size, QOCIResultPrivate *dp)
QVariant value() const
Returns the value of the field as a QVariant.
int bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos, const QVariant &val, dvoid *indPtr, ub2 *tmpSize, QList< QByteArray > &tmpStorage)
QString & replace(int i, int len, QChar after)
The QByteArray class provides an array of bytes.
static Expression::Ptr create(Expression *const expr, const YYLTYPE &sourceLocator, const ParserContext *const parseInfo)
int length() const
Returns the number of characters in this string.
QString & prepend(QChar c)
QString toUpper() const Q_REQUIRED_RESULT
Returns an uppercase copy of the string.
int month() const
Returns the number corresponding to the month of this date, using the following convention: ...
The QSqlQuery class provides a means of executing and manipulating SQL statements.
static QByteArray qMakeOraDate(const QDateTime &dt)
Convert QDateTime to the internal Oracle DATE format NB! It does not handle BCE dates.
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
int qReadLob(T &buf, const QOCIResultPrivate *d, OCILobLocator *lob)
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has type() DateTime , Date , or String ; otherwise ...
static void qParseOpts(const QString &options, QOCIDriverPrivate *d)
void setPrecision(int precision)
Sets the field's precision.
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
static const ub2 qOraCharset
QString formatValue(const QSqlField &field, bool trimStrings) const
Returns a string representation of the field value for the database.
int day() const
Returns the day of the month (1 to 31) of this date.
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has type() List or StringList ; otherwise return...
static LibLoadStatus status
bool isValid() const
Returns true if both the date and the time are valid; otherwise returns false.
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
The QDate class provides date functions.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
virtual bool isOpen() const
Returns true if the database connection is open; otherwise returns false.
The QSqlRecord class encapsulates a database record.
void close()
Derived classes must reimplement this pure virtual function in order to close the database connection...
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const
The QSqlDriver class is an abstract base class for accessing specific SQL databases.
The QString class provides a Unicode character string.
int at() const
Returns the current (zero-based) row position of the result.
The QObject class is the base class of all Qt objects.
QString lastQuery() const
Returns the current SQL query text, or an empty string if there isn't one.
The QChar class provides a 16-bit Unicode character.
QOCIBatchCleanupHandler(QVector< QOCIBatchColumn > &columns)
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
QSharedDataPointer< QOCIRowId > QOCIRowIdPointer
static void qOraOutValue(QVariant &value, QList< QByteArray > &storage, OCIError *err)
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
int numRowsAffected()
Returns the number of rows affected by the last query executed, or -1 if it cannot be determined or i...
bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const
Returns whether identifier is escaped according to the database rules.
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
ErrorType
This enum type describes the context in which the error occurred, e.
Q_CORE_EXPORT void qDebug(const char *,...)
void append(const T &t)
Inserts value at the end of the list.
friend struct QOCIResultPrivate
QVariant handle() const
Returns the low-level database handle wrapped in a QVariant or an invalid variant if there is no hand...
The QTime class provides clock time functions.
#define QT_BEGIN_NAMESPACE
This macro expands to.
qlonglong toLongLong(bool *ok=0) const
Returns the variant as a long long int if the variant has type() LongLong , Bool , ByteArray , Char , Double , Int , String , UInt , or ULongLong ; otherwise returns 0.
virtual void setSelect(bool s)
This function is provided for derived classes to indicate whether or not the current statement is a S...
bool canConvert(Type t) const
Returns true if the variant's type can be cast to the requested type, t.
int indexIn(const QString &str, int offset=0, CaretMode caretMode=CaretAtZero) const
Attempts to find a match in str from position offset (0 by default).
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
int readLOBs(QVector< QVariant > &values, int index=0)
T takeFirst()
Removes the first item in the list and returns it.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
const T & at(int i) const
Returns the item at index position i in the list.
The QStringList class provides a list of strings.
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...
void setLength(int fieldLength)
Sets the field's length to fieldLength.
QSql::ParamType bindValueType(const QString &placeholder) const
Returns the parameter type for the value bound with the given placeholder name.
static int toInt(const QByteArray &str)
qulonglong toULongLong(bool *ok=0) const
Returns the variant as as an unsigned long long int if the variant has type() ULongLong ...
Q_CORE_EXPORT void qWarning(const char *,...)
int second() const
Returns the second part (0 to 59) of the time.
const T * constData() const
Returns a const pointer to the shared data object.
static const char * data(const QByteArray &arr)
void setName(const QString &name)
Sets the name of the index to name.
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
char * create(int position, int size)
int readPiecewise(QVector< QVariant > &values, int index=0)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Type
This enum type defines the types of variable that a QVariant can contain.
int boundValueCount() const
Returns the number of bound values in the result.
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
QString right(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n rightmost characters of the string.
const T * ptr(const T &t)
int minute() const
Returns the minute part (0 to 59) of the time.
const T & at(int idx) const
QSqlRecord record() const
Returns the current record if the query is active; otherwise returns an empty QSqlRecord.
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 isBinaryValue(int i) const
QVariant::Type type() const
Returns the field's type as stored in the database.
static QVariant fromValue(const T &value)
Returns a QVariant containing a copy of value.
QVector< OraFieldInf > fieldInf
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
void setForwardOnly(bool forward)
Sets forward only mode to forward.
const T & at(int i) const
Returns the item at index position i in the vector.
bool prepare(const QString &query)
Prepares the given query for execution; the query will normally use placeholders so that it can be ex...
bool reset(const QString &query)
Sets the result to use the SQL statement query for subsequent data retrieval.
bool rollbackTransaction()
This function is called to rollback a transaction.
const char * constData() const
Returns a pointer to the data stored in the byte array.
QDate date() const
Returns the date part of the datetime.
static qlonglong qMakeLongLong(const char *ociNumber, OCIError *err)
QString join(const QString &sep) const
Joins all the string list's strings into a single string with each element separated by the given sep...
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
static bool execBatch(QOCIResultPrivate *d, QVector< QVariant > &boundValues, bool arrayBind)
QDate toDate() const
Returns the variant as a QDate if the variant has type() Date , DateTime , or String ; otherwise retu...
void setRequired(bool required)
Sets the required status of this field to Required if required is true; otherwise sets it to Optional...
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
bool gotoNext(ValueCache &values, int index)
#define QOCI_DYNAMIC_CHUNK_SIZE
void outValues(QVector< QVariant > &values, IndicatorArray &indicators, QList< QByteArray > &tmpStorage)
QString & append(QChar c)
The QDateTime class provides date and time functions.
The QSharedData class is a base class for shared data objects.
static int qOraErrorNumber(OCIError *err)
const QOCIResultPrivate *const d
int capacity() const
Returns the maximum number of characters that can be stored in the string without forcing a reallocat...
bool beginTransaction()
This function is called to begin a transaction.
QStringList tables(QSql::TableType) const
Returns a list of the names of the tables in the database.
void qSplitTableAndOwner(const QString &tname, QString *tbl, QString *owner)
QString simplified() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end, and that has each sequence o...
QOCIResultPrivate(QOCIResult *result, const QOCIDriverPrivate *driver)
bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port, const QString &connOpts)
Derived classes must reimplement this pure virtual function to open a database connection on database...
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
static const char *const keywords[MAX_KEYWORD]
Type type() const
Returns the storage type of the value stored in the variant.
QObject * parent() const
Returns a pointer to the parent object.
const void * constData() const
virtual QString formatValue(const QSqlField &field, bool trimStrings=false) const
Returns a string representation of the field value for the database.
void getValues(QVector< QVariant > &v, int index)
void resize(int size)
Sets the size of the byte array to size bytes.
uint toUInt(bool *ok=0) const
Returns the variant as an unsigned int if the variant has type() UInt , Bool , ByteArray ...
static QByteArray qMakeOCINumber(const qlonglong &ll, OCIError *err)
Convert qlonglong to the internal Oracle OCINumber format.
void append(const QSqlField &field)
Append a copy of field field to the end of the record.
int bindValues(QVector< QVariant > &values, IndicatorArray &indicators, SizeArray &tmpSizes, QList< QByteArray > &tmpStorage)
T qvariant_cast(const QVariant &)
bool hasFeature(DriverFeature f) const
Returns true if the driver supports feature feature; otherwise returns false.
bool isSelect() const
Returns true if the current result is from a SELECT statement; otherwise returns false.
int size() const
Returns the number of bytes in this byte array.
double toDouble(bool *ok=0) const
Returns the variant as a double if the variant has type() Double , QMetaType::Float ...
virtual void setActive(bool a)
This function is provided for derived classes to set the internal active state to active...
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
bool commitTransaction()
This function is called to commit a transaction.
void setStatementAttributes()
int year() const
Returns the year of this date.
T * data()
Returns a pointer to the data stored in the vector.
OraFieldInfo qMakeOraField(const QOCIResultPrivate *p, OCIParam *param) const
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
QSqlIndex primaryIndex(const QString &tablename) const
Returns the primary index for table tableName.
QTime time() const
Returns the time part of the datetime.
The QSqlField class manipulates the fields in SQL database tables and views.
static QHash< QString, QVariant > getValues(const QString &prefix)
void setCharset(dvoid *handle, ub4 type) const
bool exec(const QString &query)
Executes the SQL in query.
virtual void setLastError(const QSqlError &e)
This function is used to set the value of the last error, error, that occurred on the database...
OCILobLocator ** createLobLocator(int position, OCIEnv *env)
QOCIRowId(const QOCIRowId &other)
QString stripDelimiters(const QString &identifier, IdentifierType type) const
Returns the identifier with the leading and trailing delimiters removed, identifier can either be a t...
QVector< QVariant > & boundValues() const
Returns a vector of the result's bound values for the current record (row).
bool exec()
Executes the query, returning true if successful; otherwise returns false.
int fieldFromDefine(OCIDefine *d)
void reserve(int size)
Attempts to allocate memory for at least size bytes.
static QSqlError qMakeError(const QString &errString, QSqlError::ErrorType type, OCIError *err)
bool isNull(int field) const
Returns true if the query is active and positioned on a valid record and the field is NULL; otherwise...
static void qOraWarning(const char *msg, OCIError *err)
QSqlResult * createResult() const
Creates an empty SQL result on the database.
struct OCISvcCtx OCISvcCtx
#define qPrintable(string)
QVariant value(int i) const
Returns the value of field index in the current record.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
bool next()
Retrieves the next record in the result, if available, and positions the query on the retrieved recor...
The QSqlResult class provides an abstract interface for accessing data from specific SQL databases...
QVarLengthArray< ub2, 32 > SizeArray
The QSharedDataPointer class represents a pointer to an implicitly shared object. ...
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
void virtual_hook(int id, void *data)
IdentifierType
This enum contains a list of SQL identifier types.
QVarLengthArray< sb2, 32 > IndicatorArray
static QString qOraWarn(OCIError *err, int *errorCode=0)
int hour() const
Returns the hour part (0 to 23) of the time.
void setSqlType(int type)
QSqlRecord record(const QString &tablename) const
Returns a QSqlRecord populated with the names of the fields in table tableName.
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
static qulonglong qMakeULongLong(const char *ociNumber, OCIError *err)
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.