Qt 4.8
Classes | Public Functions | Static Public Functions | Public Variables | Private Functions | Properties | List of all members
QOCICols Class Reference

Classes

class  OraFieldInf
 

Public Functions

int fieldFromDefine (OCIDefine *d)
 
void getValues (QVector< QVariant > &v, int index)
 
 QOCICols (int size, QOCIResultPrivate *dp)
 
int readLOBs (QVector< QVariant > &values, int index=0)
 
int readPiecewise (QVector< QVariant > &values, int index=0)
 
int size ()
 
 ~QOCICols ()
 

Static Public Functions

static bool execBatch (QOCIResultPrivate *d, QVector< QVariant > &boundValues, bool arrayBind)
 

Public Variables

QSqlRecord rec
 

Private Functions

char * create (int position, int size)
 
OCILobLocator ** createLobLocator (int position, OCIEnv *env)
 
OraFieldInfo qMakeOraField (const QOCIResultPrivate *p, OCIParam *param) const
 

Properties

const QOCIResultPrivate *const d
 
QVector< OraFieldInffieldInf
 

Detailed Description

Definition at line 789 of file qsql_oci.cpp.

Constructors and Destructors

◆ QOCICols()

QOCICols::QOCICols ( int  size,
QOCIResultPrivate dp 
)

Definition at line 837 of file qsql_oci.cpp.

838  : fieldInf(size), d(dp)
839 {
840  ub4 dataSize = 0;
841  OCIDefine* dfn = 0;
842  int r;
843 
844  OCIParam* param = 0;
845  sb4 parmStatus = 0;
846  ub4 count = 1;
847  int idx = 0;
848  parmStatus = OCIParamGet(d->sql,
849  OCI_HTYPE_STMT,
850  d->err,
851  reinterpret_cast<void **>(&param),
852  count);
853 
854  while (parmStatus == OCI_SUCCESS) {
855  OraFieldInfo ofi = qMakeOraField(d, param);
856  if (ofi.oraType == SQLT_RDD)
857  dataSize = 50;
858 #ifdef SQLT_INTERVAL_YM
859 #ifdef SQLT_INTERVAL_DS
860  else if (ofi.oraType == SQLT_INTERVAL_YM || ofi.oraType == SQLT_INTERVAL_DS)
861  // since we are binding interval datatype as string,
862  // we are not interested in the number of bytes but characters.
863  dataSize = 50; // magic number
864 #endif //SQLT_INTERVAL_DS
865 #endif //SQLT_INTERVAL_YM
866  else if (ofi.oraType == SQLT_NUM || ofi.oraType == SQLT_VNU){
867  if (ofi.oraPrecision > 0)
868  dataSize = (ofi.oraPrecision + 1) * sizeof(utext);
869  else
870  dataSize = (38 + 1) * sizeof(utext);
871  }
872  else
873  dataSize = ofi.oraLength;
874 
875  fieldInf[idx].typ = ofi.type;
876  fieldInf[idx].oraType = ofi.oraType;
877  rec.append(qFromOraInf(ofi));
878 
879  switch (ofi.type) {
880  case QVariant::DateTime:
881  r = OCIDefineByPos(d->sql,
882  &dfn,
883  d->err,
884  count,
885  create(idx, dataSize+1),
886  dataSize+1,
887  SQLT_DAT,
888  &(fieldInf[idx].ind),
889  0, 0, OCI_DEFAULT);
890  break;
891  case QVariant::Double:
892  r = OCIDefineByPos(d->sql,
893  &dfn,
894  d->err,
895  count,
896  create(idx, sizeof(double) - 1),
897  sizeof(double),
898  SQLT_FLT,
899  &(fieldInf[idx].ind),
900  0, 0, OCI_DEFAULT);
901  break;
902  case QVariant::Int:
903  r = OCIDefineByPos(d->sql,
904  &dfn,
905  d->err,
906  count,
907  create(idx, sizeof(qint32) - 1),
908  sizeof(qint32),
909  SQLT_INT,
910  &(fieldInf[idx].ind),
911  0, 0, OCI_DEFAULT);
912  break;
913  case QVariant::LongLong:
914  r = OCIDefineByPos(d->sql,
915  &dfn,
916  d->err,
917  count,
918  create(idx, sizeof(OCINumber)),
919  sizeof(OCINumber),
920  SQLT_VNU,
921  &(fieldInf[idx].ind),
922  0, 0, OCI_DEFAULT);
923  break;
924  case QVariant::ByteArray:
925  // RAW and LONG RAW fields can't be bound to LOB locators
926  if (ofi.oraType == SQLT_BIN) {
927 // qDebug("binding SQLT_BIN");
928  r = OCIDefineByPos(d->sql,
929  &dfn,
930  d->err,
931  count,
932  create(idx, dataSize),
933  dataSize,
934  SQLT_BIN,
935  &(fieldInf[idx].ind),
936  0, 0, OCI_DYNAMIC_FETCH);
937  } else if (ofi.oraType == SQLT_LBI) {
938 // qDebug("binding SQLT_LBI");
939  r = OCIDefineByPos(d->sql,
940  &dfn,
941  d->err,
942  count,
943  0,
944  SB4MAXVAL,
945  SQLT_LBI,
946  &(fieldInf[idx].ind),
947  0, 0, OCI_DYNAMIC_FETCH);
948  } else if (ofi.oraType == SQLT_CLOB) {
949  r = OCIDefineByPos(d->sql,
950  &dfn,
951  d->err,
952  count,
953  createLobLocator(idx, d->env),
954  -1,
955  SQLT_CLOB,
956  &(fieldInf[idx].ind),
957  0, 0, OCI_DEFAULT);
958  } else {
959 // qDebug("binding SQLT_BLOB");
960  r = OCIDefineByPos(d->sql,
961  &dfn,
962  d->err,
963  count,
964  createLobLocator(idx, d->env),
965  -1,
966  SQLT_BLOB,
967  &(fieldInf[idx].ind),
968  0, 0, OCI_DEFAULT);
969  }
970  break;
971  case QVariant::String:
972  if (ofi.oraType == SQLT_LNG) {
973  r = OCIDefineByPos(d->sql,
974  &dfn,
975  d->err,
976  count,
977  0,
978  SB4MAXVAL,
979  SQLT_LNG,
980  &(fieldInf[idx].ind),
981  0, 0, OCI_DYNAMIC_FETCH);
982  } else {
983  dataSize += dataSize + sizeof(QChar);
984  //qDebug("OCIDefineByPosStr(%d): %d", count, dataSize);
985  r = OCIDefineByPos(d->sql,
986  &dfn,
987  d->err,
988  count,
989  create(idx, dataSize),
990  dataSize,
991  SQLT_STR,
992  &(fieldInf[idx].ind),
993  0, 0, OCI_DEFAULT);
994  if (r == 0)
995  d->setCharset(dfn, OCI_HTYPE_DEFINE);
996  }
997  break;
998  default:
999  // this should make enough space even with character encoding
1000  dataSize = (dataSize + 1) * sizeof(utext) ;
1001  //qDebug("OCIDefineByPosDef(%d): %d", count, dataSize);
1002  r = OCIDefineByPos(d->sql,
1003  &dfn,
1004  d->err,
1005  count,
1006  create(idx, dataSize),
1007  dataSize+1,
1008  SQLT_STR,
1009  &(fieldInf[idx].ind),
1010  0, 0, OCI_DEFAULT);
1011  break;
1012  }
1013  if (r != 0)
1014  qOraWarning("QOCICols::bind:", d->err);
1015  fieldInf[idx].def = dfn;
1016  ++count;
1017  ++idx;
1018  parmStatus = OCIParamGet(d->sql,
1019  OCI_HTYPE_STMT,
1020  d->err,
1021  reinterpret_cast<void **>(&param),
1022  count);
1023  }
1024 }
int qint32
Definition: qglobal.h:937
static QSqlField qFromOraInf(const OraFieldInfo &ofi)
Definition: qsql_oci.cpp:678
int size()
Definition: qsql_oci.cpp:798
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
char * create(int position, int size)
Definition: qsql_oci.cpp:1030
QSqlRecord rec
Definition: qsql_oci.cpp:801
QVector< OraFieldInf > fieldInf
Definition: qsql_oci.cpp:823
OCIError * err
Definition: qsql_oci.cpp:172
const QOCIResultPrivate *const d
Definition: qsql_oci.cpp:824
void append(const QSqlField &field)
Append a copy of field field to the end of the record.
Definition: qsqlrecord.cpp:312
OraFieldInfo qMakeOraField(const QOCIResultPrivate *p, OCIParam *param) const
Definition: qsql_oci.cpp:1119
void setCharset(dvoid *handle, ub4 type) const
Definition: qsql_oci.cpp:191
OCILobLocator ** createLobLocator(int position, OCIEnv *env)
Definition: qsql_oci.cpp:1040
sb2 oraPrecision
Definition: qsql_oci.cpp:509
static void qOraWarning(const char *msg, OCIError *err)
Definition: qsql_oci.cpp:531
QVariant::Type type
Definition: qsql_oci.cpp:503

◆ ~QOCICols()

QOCICols::~QOCICols ( )

Definition at line 1026 of file qsql_oci.cpp.

1027 {
1028 }

Functions

◆ create()

char * QOCICols::create ( int  position,
int  size 
)
private

Definition at line 1030 of file qsql_oci.cpp.

Referenced by QOCICols().

1031 {
1032  char* c = new char[size+1];
1033  // Oracle may not fill fixed width fields
1034  memset(c, 0, size+1);
1035  fieldInf[position].data = c;
1036  fieldInf[position].len = size;
1037  return c;
1038 }
unsigned char c[8]
Definition: qnumeric_p.h:62
int size()
Definition: qsql_oci.cpp:798
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
QVector< OraFieldInf > fieldInf
Definition: qsql_oci.cpp:823

◆ createLobLocator()

OCILobLocator ** QOCICols::createLobLocator ( int  position,
OCIEnv env 
)
private

Definition at line 1040 of file qsql_oci.cpp.

Referenced by QOCICols().

1041 {
1042  OCILobLocator *& lob = fieldInf[position].lob;
1043  int r = OCIDescriptorAlloc(env,
1044  reinterpret_cast<void **>(&lob),
1045  OCI_DTYPE_LOB,
1046  0,
1047  0);
1048  if (r != 0) {
1049  qWarning("QOCICols: Cannot create LOB locator");
1050  lob = 0;
1051  }
1052  return &lob;
1053 }
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
Q_CORE_EXPORT void qWarning(const char *,...)
QVector< OraFieldInf > fieldInf
Definition: qsql_oci.cpp:823

◆ execBatch()

bool QOCICols::execBatch ( QOCIResultPrivate d,
QVector< QVariant > &  boundValues,
bool  arrayBind 
)
static

Definition at line 1283 of file qsql_oci.cpp.

Referenced by QOCIResult::virtual_hook().

1284 {
1285  int columnCount = boundValues.count();
1286  if (boundValues.isEmpty() || columnCount == 0)
1287  return false;
1288 
1289 #ifdef QOCI_DEBUG
1290  qDebug() << "columnCount:" << columnCount << boundValues;
1291 #endif
1292 
1293  int i;
1294  sword r;
1295 
1297  for (i = 0; i < columnCount; ++i) {
1298  QVariant::Type tp = boundValues.at(i).type();
1299  fieldTypes.append(tp == QVariant::List ? boundValues.at(i).toList().value(0).type()
1300  : tp);
1301  }
1302 
1303  QList<QByteArray> tmpStorage;
1304  SizeArray tmpSizes(columnCount);
1305  QVector<QOCIBatchColumn> columns(columnCount);
1306  QOCIBatchCleanupHandler cleaner(columns);
1307 
1308  // figuring out buffer sizes
1309  for (i = 0; i < columnCount; ++i) {
1310 
1311  if (boundValues.at(i).type() != QVariant::List) {
1312 
1313  // not a list - create a deep-copy of the single value
1314  QOCIBatchColumn &singleCol = columns[i];
1315  singleCol.indicators = new sb2[1];
1316  *singleCol.indicators = boundValues.at(i).isNull() ? -1 : 0;
1317 
1318  r = d->bindValue(d->sql, &singleCol.bindh, d->err, i,
1319  boundValues.at(i), singleCol.indicators, &tmpSizes[i], tmpStorage);
1320 
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"),
1326  return false;
1327  }
1328  continue;
1329  }
1330 
1331  QOCIBatchColumn &col = columns[i];
1332  col.recordCount = boundValues.at(i).toList().count();
1333 
1334  col.lengths = new ub2[col.recordCount];
1335  col.indicators = new sb2[col.recordCount];
1336  col.maxarr_len = col.recordCount;
1337  col.curelep = col.recordCount;
1338 
1339  switch (fieldTypes[i]) {
1340  case QVariant::Time:
1341  case QVariant::Date:
1342  case QVariant::DateTime:
1343  col.bindAs = SQLT_DAT;
1344  col.maxLen = 7;
1345  break;
1346 
1347  case QVariant::Int:
1348  col.bindAs = SQLT_INT;
1349  col.maxLen = sizeof(int);
1350  break;
1351 
1352  case QVariant::UInt:
1353  col.bindAs = SQLT_UIN;
1354  col.maxLen = sizeof(uint);
1355  break;
1356 
1357  case QVariant::LongLong:
1358  col.bindAs = SQLT_VNU;
1359  col.maxLen = sizeof(OCINumber);
1360  break;
1361 
1362  case QVariant::ULongLong:
1363  col.bindAs = SQLT_VNU;
1364  col.maxLen = sizeof(OCINumber);
1365  break;
1366 
1367  case QVariant::Double:
1368  col.bindAs = SQLT_FLT;
1369  col.maxLen = sizeof(double);
1370  break;
1371 
1372  case QVariant::UserType:
1373  col.bindAs = SQLT_RDD;
1374  col.maxLen = sizeof(OCIRowid*);
1375  break;
1376 
1377  case QVariant::String: {
1378  col.bindAs = SQLT_STR;
1379  for (uint j = 0; j < col.recordCount; ++j) {
1380  uint len;
1381  if(d->isOutValue(i))
1382  len = boundValues.at(i).toList().at(j).toString().capacity() + 1;
1383  else
1384  len = boundValues.at(i).toList().at(j).toString().length() + 1;
1385  if (len > col.maxLen)
1386  col.maxLen = len;
1387  }
1388  col.maxLen *= sizeof(QChar);
1389  break; }
1390 
1391  case QVariant::ByteArray:
1392  default: {
1393  col.bindAs = SQLT_LBI;
1394  for (uint j = 0; j < col.recordCount; ++j) {
1395  if(d->isOutValue(i))
1396  col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().capacity();
1397  else
1398  col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().size();
1399  if (col.lengths[j] > col.maxLen)
1400  col.maxLen = col.lengths[j];
1401  }
1402  break; }
1403  }
1404 
1405  col.data = new char[col.maxLen * col.recordCount];
1406  memset(col.data, 0, col.maxLen * col.recordCount);
1407 
1408  // we may now populate column with data
1409  for (uint row = 0; row < col.recordCount; ++row) {
1410  const QVariant &val = boundValues.at(i).toList().at(row);
1411 
1412  if (val.isNull()){
1413  columns[i].indicators[row] = -1;
1414  columns[i].lengths[row] = 0;
1415  } else {
1416  columns[i].indicators[row] = 0;
1417  char *dataPtr = columns[i].data + (columns[i].maxLen * row);
1418  switch (fieldTypes[i]) {
1419  case QVariant::Time:
1420  case QVariant::Date:
1421  case QVariant::DateTime:{
1422  columns[i].lengths[row] = columns[i].maxLen;
1423  const QByteArray ba = qMakeOraDate(val.toDateTime());
1424  Q_ASSERT(ba.size() == int(columns[i].maxLen));
1425  memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1426  break;
1427  }
1428  case QVariant::Int:
1429  columns[i].lengths[row] = columns[i].maxLen;
1430  *reinterpret_cast<int*>(dataPtr) = val.toInt();
1431  break;
1432 
1433  case QVariant::UInt:
1434  columns[i].lengths[row] = columns[i].maxLen;
1435  *reinterpret_cast<uint*>(dataPtr) = val.toUInt();
1436  break;
1437 
1438  case QVariant::LongLong:
1439  {
1440  columns[i].lengths[row] = columns[i].maxLen;
1441  const QByteArray ba = qMakeOCINumber(val.toLongLong(), d->err);
1442  Q_ASSERT(ba.size() == int(columns[i].maxLen));
1443  memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1444  break;
1445  }
1446  case QVariant::ULongLong:
1447  {
1448  columns[i].lengths[row] = columns[i].maxLen;
1449  const QByteArray ba = qMakeOCINumber(val.toULongLong(), d->err);
1450  Q_ASSERT(ba.size() == int(columns[i].maxLen));
1451  memcpy(dataPtr, ba.constData(), columns[i].maxLen);
1452  break;
1453  }
1454  case QVariant::Double:
1455  columns[i].lengths[row] = columns[i].maxLen;
1456  *reinterpret_cast<double*>(dataPtr) = val.toDouble();
1457  break;
1458 
1459  case QVariant::String: {
1460  const QString s = val.toString();
1461  columns[i].lengths[row] = (s.length() + 1) * sizeof(QChar);
1462  memcpy(dataPtr, s.utf16(), columns[i].lengths[row]);
1463  break;
1464  }
1465  case QVariant::UserType:
1466  if (val.canConvert<QOCIRowIdPointer>()) {
1467  const QOCIRowIdPointer rptr = qvariant_cast<QOCIRowIdPointer>(val);
1468  *reinterpret_cast<OCIRowid**>(dataPtr) = rptr->id;
1469  columns[i].lengths[row] = 0;
1470  break;
1471  }
1472  case QVariant::ByteArray:
1473  default: {
1474  const QByteArray ba = val.toByteArray();
1475  columns[i].lengths[row] = ba.size();
1476  memcpy(dataPtr, ba.constData(), ba.size());
1477  break;
1478  }
1479  }
1480  }
1481  }
1482 
1483  QOCIBatchColumn &bindColumn = columns[i];
1484 
1485 #ifdef QOCI_DEBUG
1486  qDebug("OCIBindByPos(%p, %p, %p, %d, %p, %d, %d, %p, %p, 0, %d, %p, OCI_DEFAULT)",
1487  d->sql, &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);
1490 
1491  for (int ii = 0; ii < (int)bindColumn.recordCount; ++ii) {
1492  qDebug(" record %d: indicator %d, length %d", ii, bindColumn.indicators[ii],
1493  bindColumn.lengths[ii]);
1494  }
1495 #endif
1496 
1497 
1498  // binding the column
1499  r = OCIBindByPos(
1500  d->sql, &bindColumn.bindh, d->err, i + 1,
1501  bindColumn.data,
1502  bindColumn.maxLen,
1503  bindColumn.bindAs,
1504  bindColumn.indicators,
1505  bindColumn.lengths,
1506  0,
1507  arrayBind ? bindColumn.maxarr_len : 0,
1508  arrayBind ? &bindColumn.curelep : 0,
1509  OCI_DEFAULT);
1510 
1511 #ifdef QOCI_DEBUG
1512  qDebug("After OCIBindByPos: r = %d, bindh = %p", r, bindColumn.bindh);
1513 #endif
1514 
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"),
1520  return false;
1521  }
1522 
1523  r = OCIBindArrayOfStruct (
1524  columns[i].bindh, d->err,
1525  columns[i].maxLen,
1526  sizeof(columns[i].indicators[0]),
1527  sizeof(columns[i].lengths[0]),
1528  0);
1529 
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"),
1535  return false;
1536  }
1537  }
1538 
1539  //finaly we can execute
1540  r = OCIStmtExecute(d->svc, d->sql, d->err,
1541  arrayBind ? 1 : columns[0].recordCount,
1542  0, NULL, NULL,
1543  d->transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS);
1544 
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"),
1550  return false;
1551  }
1552 
1553  // for out parameters we copy data back to value vector
1554  for (i = 0; i < columnCount; ++i) {
1555 
1556  if (!d->isOutValue(i))
1557  continue;
1558 
1559  QVariant::Type tp = boundValues.at(i).type();
1560  if (tp != QVariant::List) {
1561  qOraOutValue(boundValues[i], tmpStorage, d->err);
1562  if (*columns[i].indicators == -1)
1563  boundValues[i] = QVariant(tp);
1564  continue;
1565  }
1566 
1567  QVariantList *list = static_cast<QVariantList *>(const_cast<void*>(boundValues.at(i).data()));
1568 
1569  char* data = columns[i].data;
1570  for (uint r = 0; r < columns[i].recordCount; ++r){
1571 
1572  if (columns[i].indicators[r] == -1) {
1573  (*list)[r] = QVariant();
1574  continue;
1575  }
1576 
1577  switch(columns[i].bindAs) {
1578 
1579  case SQLT_DAT:
1580  (*list)[r] = qMakeDate(data + r * columns[i].maxLen);
1581  break;
1582 
1583  case SQLT_INT:
1584  (*list)[r] = *reinterpret_cast<int*>(data + r * columns[i].maxLen);
1585  break;
1586 
1587  case SQLT_UIN:
1588  (*list)[r] = *reinterpret_cast<uint*>(data + r * columns[i].maxLen);
1589  break;
1590 
1591  case SQLT_VNU:
1592  {
1593  switch (boundValues.at(i).type()) {
1594  case QVariant::LongLong:
1595  (*list)[r] = qMakeLongLong(data + r * columns[i].maxLen, d->err);
1596  break;
1597  case QVariant::ULongLong:
1598  (*list)[r] = qMakeULongLong(data + r * columns[i].maxLen, d->err);
1599  break;
1600  default:
1601  break;
1602  }
1603  break;
1604  }
1605 
1606  case SQLT_FLT:
1607  (*list)[r] = *reinterpret_cast<double*>(data + r * columns[i].maxLen);
1608  break;
1609 
1610  case SQLT_STR:
1611  (*list)[r] = QString(reinterpret_cast<const QChar *>(data
1612  + r * columns[i].maxLen));
1613  break;
1614 
1615  default:
1616  (*list)[r] = QByteArray(data + r * columns[i].maxLen, columns[i].maxLen);
1617  break;
1618  }
1619  }
1620  }
1621 
1622  d->q->setSelect(false);
1624  d->q->setActive(true);
1625 
1626  return true;
1627 }
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
bool isOutValue(int i) const
Definition: qsql_oci.cpp:186
static QDateTime qMakeDate(const char *oraDate)
Definition: qsql_oci.cpp:773
bool isNull() const
Returns true if this is a NULL variant, false otherwise.
Definition: qvariant.cpp:3102
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
int bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos, const QVariant &val, dvoid *indPtr, ub2 *tmpSize, QList< QByteArray > &tmpStorage)
Definition: qsql_oci.cpp:257
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
static QByteArray qMakeOraDate(const QDateTime &dt)
Convert QDateTime to the internal Oracle DATE format NB! It does not handle BCE dates.
Definition: qsql_oci.cpp:702
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has type() DateTime , Date , or String ; otherwise ...
Definition: qvariant.cpp:2349
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has type() List or StringList ; otherwise return...
Definition: qvariant.cpp:2751
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void append(const T &t)
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Definition: qvariant.cpp:2383
QOCIResult * q
Definition: qsql_oci.cpp:170
static void qOraOutValue(QVariant &value, QList< QByteArray > &storage, OCIError *err)
Definition: qsql_oci.cpp:419
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
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.
Definition: qsqlresult.cpp:417
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
Q_CORE_EXPORT void qDebug(const char *,...)
void * data()
Definition: qvariant.cpp:3077
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.
Definition: qvariant.cpp:2659
virtual void setSelect(bool s)
This function is provided for derived classes to indicate whether or not the current statement is a S...
Definition: qsqlresult.cpp:367
bool canConvert(Type t) const
Returns true if the variant&#39;s type can be cast to the requested type, t.
Definition: qvariant.cpp:2886
OCISvcCtx *& svc
Definition: qsql_oci.cpp:173
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
qulonglong toULongLong(bool *ok=0) const
Returns the variant as as an unsigned long long int if the variant has type() ULongLong ...
Definition: qvariant.cpp:2675
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
Type
This enum type defines the types of variable that a QVariant can contain.
Definition: qvariant.h:95
const T & at(int idx) const
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
static qlonglong qMakeLongLong(const char *ociNumber, OCIError *err)
Definition: qsql_oci.cpp:757
OCIError * err
Definition: qsql_oci.cpp:172
uint toUInt(bool *ok=0) const
Returns the variant as an unsigned int if the variant has type() UInt , Bool , ByteArray ...
Definition: qvariant.cpp:2644
OCIBind * bindh
Definition: qsql_oci.cpp:1254
static QByteArray qMakeOCINumber(const qlonglong &ll, OCIError *err)
Convert qlonglong to the internal Oracle OCINumber format.
Definition: qsql_oci.cpp:725
T qvariant_cast(const QVariant &)
Definition: qvariant.h:571
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
double toDouble(bool *ok=0) const
Returns the variant as a double if the variant has type() Double , QMetaType::Float ...
Definition: qvariant.cpp:2710
virtual void setActive(bool a)
This function is provided for derived classes to set the internal active state to active...
Definition: qsqlresult.cpp:402
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
static QSqlError qMakeError(const QString &errString, QSqlError::ErrorType type, OCIError *err)
Definition: qsql_oci.cpp:554
static void qOraWarning(const char *msg, OCIError *err)
Definition: qsql_oci.cpp:531
The QSharedDataPointer class represents a pointer to an implicitly shared object. ...
Definition: qshareddata.h:54
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
static qulonglong qMakeULongLong(const char *ociNumber, OCIError *err)
Definition: qsql_oci.cpp:765

◆ fieldFromDefine()

int QOCICols::fieldFromDefine ( OCIDefine *  d)

Definition at line 1709 of file qsql_oci.cpp.

Referenced by readPiecewise().

1710 {
1711  for (int i = 0; i < fieldInf.count(); ++i) {
1712  if (fieldInf.at(i).def == d)
1713  return i;
1714  }
1715  return -1;
1716 }
QVector< OraFieldInf > fieldInf
Definition: qsql_oci.cpp:823
const QOCIResultPrivate *const d
Definition: qsql_oci.cpp:824

◆ getValues()

void QOCICols::getValues ( QVector< QVariant > &  v,
int  index 
)

Definition at line 1718 of file qsql_oci.cpp.

Referenced by QOCIResult::gotoNext().

1719 {
1720  for (int i = 0; i < fieldInf.size(); ++i) {
1721  const OraFieldInf &fld = fieldInf.at(i);
1722 
1723  if (fld.ind == -1) {
1724  // got a NULL value
1725  v[index + i] = QVariant(fld.typ);
1726  continue;
1727  }
1728 
1729  if (fld.oraType == SQLT_BIN || fld.oraType == SQLT_LBI || fld.oraType == SQLT_LNG)
1730  continue; // already fetched piecewise
1731 
1732  switch (fld.typ) {
1733  case QVariant::DateTime:
1734  v[index + i] = QVariant(qMakeDate(fld.data));
1735  break;
1736  case QVariant::Double:
1737  case QVariant::Int:
1738  case QVariant::LongLong:
1741  && (fld.typ == QVariant::Double)) {
1742  v[index + i] = *reinterpret_cast<double *>(fld.data);
1743  break;
1745  && (fld.typ == QVariant::LongLong)) {
1746  qint64 qll = 0;
1747  int r = OCINumberToInt(d->err, reinterpret_cast<OCINumber *>(fld.data), sizeof(qint64),
1748  OCI_NUMBER_SIGNED, &qll);
1749  if(r == OCI_SUCCESS)
1750  v[index + i] = qll;
1751  else
1752  v[index + i] = QVariant();
1753  break;
1755  && (fld.typ == QVariant::Int)) {
1756  v[index + i] = *reinterpret_cast<int *>(fld.data);
1757  break;
1758  }
1759  }
1760  // else fall through
1761  case QVariant::String:
1762  v[index + i] = QString(reinterpret_cast<const QChar *>(fld.data));
1763  break;
1764  case QVariant::ByteArray:
1765  if (fld.len > 0)
1766  v[index + i] = QByteArray(fld.data, fld.len);
1767  else
1769  break;
1770  default:
1771  qWarning("QOCICols::value: unknown data type");
1772  break;
1773  }
1774  }
1775 }
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QDateTime qMakeDate(const char *oraDate)
Definition: qsql_oci.cpp:773
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const
The QString class provides a Unicode character string.
Definition: qstring.h:83
QOCIResult * q
Definition: qsql_oci.cpp:170
Q_CORE_EXPORT void qWarning(const char *,...)
__int64 qint64
Definition: qglobal.h:942
QVector< OraFieldInf > fieldInf
Definition: qsql_oci.cpp:823
OCIError * err
Definition: qsql_oci.cpp:172
const QOCIResultPrivate *const d
Definition: qsql_oci.cpp:824
quint16 index

◆ qMakeOraField()

OraFieldInfo QOCICols::qMakeOraField ( const QOCIResultPrivate p,
OCIParam *  param 
) const
private

Definition at line 1119 of file qsql_oci.cpp.

Referenced by QOCICols().

1120 {
1121  OraFieldInfo ofi;
1122  ub2 colType(0);
1123  text *colName = 0;
1124  ub4 colNameLen(0);
1125  sb1 colScale(0);
1126  ub2 colLength(0);
1127  ub2 colFieldLength(0);
1128  sb2 colPrecision(0);
1129  ub1 colIsNull(0);
1130  int r(0);
1132 
1133  r = OCIAttrGet(param,
1134  OCI_DTYPE_PARAM,
1135  &colType,
1136  0,
1137  OCI_ATTR_DATA_TYPE,
1138  p->err);
1139  if (r != 0)
1140  qOraWarning("qMakeOraField:", p->err);
1141 
1142  r = OCIAttrGet(param,
1143  OCI_DTYPE_PARAM,
1144  &colName,
1145  &colNameLen,
1146  OCI_ATTR_NAME,
1147  p->err);
1148  if (r != 0)
1149  qOraWarning("qMakeOraField:", p->err);
1150 
1151  r = OCIAttrGet(param,
1152  OCI_DTYPE_PARAM,
1153  &colLength,
1154  0,
1155  OCI_ATTR_DATA_SIZE, /* in bytes */
1156  p->err);
1157  if (r != 0)
1158  qOraWarning("qMakeOraField:", p->err);
1159 
1160 #ifdef OCI_ATTR_CHAR_SIZE
1161  r = OCIAttrGet(param,
1162  OCI_DTYPE_PARAM,
1163  &colFieldLength,
1164  0,
1165  OCI_ATTR_CHAR_SIZE,
1166  p->err);
1167  if (r != 0)
1168  qOraWarning("qMakeOraField:", p->err);
1169 #else
1170  // for Oracle8.
1171  colFieldLength = colLength;
1172 #endif
1173 
1174  r = OCIAttrGet(param,
1175  OCI_DTYPE_PARAM,
1176  &colPrecision,
1177  0,
1178  OCI_ATTR_PRECISION,
1179  p->err);
1180  if (r != 0)
1181  qOraWarning("qMakeOraField:", p->err);
1182 
1183  r = OCIAttrGet(param,
1184  OCI_DTYPE_PARAM,
1185  &colScale,
1186  0,
1187  OCI_ATTR_SCALE,
1188  p->err);
1189  if (r != 0)
1190  qOraWarning("qMakeOraField:", p->err);
1191  r = OCIAttrGet(param,
1192  OCI_DTYPE_PARAM,
1193  &colType,
1194  0,
1195  OCI_ATTR_DATA_TYPE,
1196  p->err);
1197  if (r != 0)
1198  qOraWarning("qMakeOraField:", p->err);
1199  r = OCIAttrGet(param,
1200  OCI_DTYPE_PARAM,
1201  &colIsNull,
1202  0,
1203  OCI_ATTR_IS_NULL,
1204  p->err);
1205  if (r != 0)
1206  qOraWarning("qMakeOraField:", p->err);
1207 
1208  type = qDecodeOCIType(colType, p->q->numericalPrecisionPolicy());
1209 
1210  if (type == QVariant::Int) {
1211  if (colLength == 22 && colPrecision == 0 && colScale == 0)
1213  if (colScale > 0)
1215  }
1216 
1217  // bind as double if the precision policy asks for it
1218  if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
1221  }
1222 
1223  // bind as int32 or int64 if the precision policy asks for it
1224  if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
1225  || (colType == SQLT_INT)) {
1229  type = QVariant::Int;
1230  }
1231 
1232  if (colType == SQLT_BLOB)
1233  colLength = 0;
1234 
1235  // colNameLen is length in bytes
1236  ofi.name = QString(reinterpret_cast<const QChar*>(colName), colNameLen / 2);
1237  ofi.type = type;
1238  ofi.oraType = colType;
1239  ofi.oraFieldLength = colFieldLength;
1240  ofi.oraLength = colLength;
1241  ofi.oraScale = colScale;
1242  ofi.oraPrecision = colPrecision;
1243  ofi.oraIsNull = colIsNull;
1244 
1245  return ofi;
1246 }
int type
Definition: qmetatype.cpp:239
QVariant::Type qDecodeOCIType(const QString &ocitype, QSql::NumericalPrecisionPolicy precisionPolicy)
Definition: qsql_oci.cpp:561
ub4 oraFieldLength
Definition: qsql_oci.cpp:508
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const
The QString class provides a Unicode character string.
Definition: qstring.h:83
QOCIResult * q
Definition: qsql_oci.cpp:170
QString name
Definition: qsql_oci.cpp:502
Type
This enum type defines the types of variable that a QVariant can contain.
Definition: qvariant.h:95
OCIError * err
Definition: qsql_oci.cpp:172
sb2 oraPrecision
Definition: qsql_oci.cpp:509
static void qOraWarning(const char *msg, OCIError *err)
Definition: qsql_oci.cpp:531
QVariant::Type type
Definition: qsql_oci.cpp:503
#define text
Definition: qobjectdefs.h:80

◆ readLOBs()

int QOCICols::readLOBs ( QVector< QVariant > &  values,
int  index = 0 
)

Definition at line 1679 of file qsql_oci.cpp.

Referenced by QOCIResult::gotoNext().

1680 {
1681  OCILobLocator *lob;
1682  int r = OCI_SUCCESS;
1683 
1684  for (int i = 0; i < size(); ++i) {
1685  const OraFieldInf &fi = fieldInf.at(i);
1686  if (fi.ind == -1 || !(lob = fi.lob))
1687  continue;
1688 
1689  bool isClob = fi.oraType == SQLT_CLOB;
1690  QVariant var;
1691 
1692  if (isClob) {
1693  QString str;
1694  r = qReadLob<QString, sizeof(QChar)>(str, d, lob);
1695  var = str;
1696  } else {
1697  QByteArray buf;
1698  r = qReadLob<QByteArray, sizeof(char)>(buf, d, lob);
1699  var = buf;
1700  }
1701  if (r == OCI_SUCCESS)
1702  values[index + i] = var;
1703  else
1704  break;
1705  }
1706  return r;
1707 }
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int size()
Definition: qsql_oci.cpp:798
The QString class provides a Unicode character string.
Definition: qstring.h:83
QVector< OraFieldInf > fieldInf
Definition: qsql_oci.cpp:823
const QOCIResultPrivate *const d
Definition: qsql_oci.cpp:824
quint16 index

◆ readPiecewise()

int QOCICols::readPiecewise ( QVector< QVariant > &  values,
int  index = 0 
)

Definition at line 1055 of file qsql_oci.cpp.

Referenced by QOCIResult::gotoNext().

1056 {
1057  OCIDefine* dfn;
1058  ub4 typep;
1059  ub1 in_outp;
1060  ub4 iterp;
1061  ub4 idxp;
1062  ub1 piecep;
1063  sword status;
1064  text col [QOCI_DYNAMIC_CHUNK_SIZE+1];
1065  int fieldNum = -1;
1066  int r = 0;
1067  bool nullField;
1068 
1069  do {
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);
1074  fieldNum = fieldFromDefine(dfn);
1075  bool isStringField = fieldInf.at(fieldNum).oraType == SQLT_LNG;
1076  ub4 chunkSize = QOCI_DYNAMIC_CHUNK_SIZE;
1077  nullField = false;
1078  r = OCIStmtSetPieceInfo(dfn, OCI_HTYPE_DEFINE,
1079  d->err, col,
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);
1084  if (status == -1) {
1085  sb4 errcode;
1086  OCIErrorGet(d->err, 1, 0, &errcode, 0, 0,OCI_HTYPE_ERROR);
1087  switch (errcode) {
1088  case 1405: /* NULL */
1089  nullField = true;
1090  break;
1091  default:
1092  qOraWarning("OCIResultPrivate::readPiecewise: unable to fetch next:", d->err);
1093  break;
1094  }
1095  }
1096  if (status == OCI_NO_DATA)
1097  break;
1098  if (nullField || !chunkSize) {
1099  fieldInf[fieldNum].ind = -1;
1100  } else {
1101  if (isStringField) {
1102  QString str = values.at(fieldNum + index).toString();
1103  str += QString(reinterpret_cast<const QChar *>(col), chunkSize / 2);
1104  values[fieldNum + index] = str;
1105  fieldInf[fieldNum].ind = 0;
1106  } else {
1107  QByteArray ba = values.at(fieldNum + index).toByteArray();
1108  int sz = ba.size();
1109  ba.resize(sz + chunkSize);
1110  memcpy(ba.data() + sz, reinterpret_cast<char *>(col), chunkSize);
1111  values[fieldNum + index] = ba;
1112  fieldInf[fieldNum].ind = 0;
1113  }
1114  }
1115  } while (status == OCI_SUCCESS_WITH_INFO || status == OCI_NEED_DATA);
1116  return r;
1117 }
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
The QString class provides a Unicode character string.
Definition: qstring.h:83
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Definition: qvariant.cpp:2383
QVector< OraFieldInf > fieldInf
Definition: qsql_oci.cpp:823
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
OCIError * err
Definition: qsql_oci.cpp:172
#define QOCI_DYNAMIC_CHUNK_SIZE
Definition: qsql_oci.cpp:75
const QOCIResultPrivate *const d
Definition: qsql_oci.cpp:824
void resize(int size)
Sets the size of the byte array to size bytes.
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
quint16 index
int fieldFromDefine(OCIDefine *d)
Definition: qsql_oci.cpp:1709
static void qOraWarning(const char *msg, OCIError *err)
Definition: qsql_oci.cpp:531
#define text
Definition: qobjectdefs.h:80

◆ size()

int QOCICols::size ( )
inline

Definition at line 798 of file qsql_oci.cpp.

Referenced by create(), and readLOBs().

798 { return fieldInf.size(); }
QVector< OraFieldInf > fieldInf
Definition: qsql_oci.cpp:823

Properties

◆ d

const QOCIResultPrivate* const QOCICols::d
private

Definition at line 824 of file qsql_oci.cpp.

Referenced by fieldFromDefine(), getValues(), QOCICols(), readLOBs(), and readPiecewise().

◆ fieldInf

QVector<OraFieldInf> QOCICols::fieldInf
private

◆ rec

QSqlRecord QOCICols::rec

Definition at line 801 of file qsql_oci.cpp.

Referenced by QOCICols(), and QOCIResult::record().


The documentation for this class was generated from the following file: