diff options
author | Bill King <bill.king@nokia.com> | 2009-06-12 00:29:44 (GMT) |
---|---|---|
committer | Bill King <bill.king@nokia.com> | 2009-06-15 00:31:07 (GMT) |
commit | c9f77564df14f91276e9ca693a9b3f339dab9334 (patch) | |
tree | 5c87e861a3973433c2b01ece730164d63a5dab95 /src/sql/drivers/oci | |
parent | ba097c23159c1ec026b8b8772d1a9c5e72f2a681 (diff) | |
download | Qt-c9f77564df14f91276e9ca693a9b3f339dab9334.zip Qt-c9f77564df14f91276e9ca693a9b3f339dab9334.tar.gz Qt-c9f77564df14f91276e9ca693a9b3f339dab9334.tar.bz2 |
Stage 1 of incorporating database level precision policy.
Queries now ask the database object what precision they should be,
allows for setting precision policies on sql models, where previously
this was not available. Also fixes some failing precisionpolicy implementations,
as well as working around the fact qstring can't convert from "123.00" to
an int based type.
Diffstat (limited to 'src/sql/drivers/oci')
-rw-r--r-- | src/sql/drivers/oci/qsql_oci.cpp | 280 |
1 files changed, 137 insertions, 143 deletions
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index e6ee63d..0f45aad 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -148,7 +148,6 @@ struct QOCIResultPrivate bool transaction; int serverVersion; int prefetchRows, prefetchMem; - QSql::NumericalPrecisionPolicy precisionPolicy; void setCharset(OCIBind* hbnd); void setStatementAttributes(); @@ -405,7 +404,6 @@ struct QOCIDriverPrivate int serverVersion; ub4 prefetchRows; ub2 prefetchMem; - QSql::NumericalPrecisionPolicy precisionPolicy; QString user; void allocErrorHandle(); @@ -413,7 +411,7 @@ struct QOCIDriverPrivate QOCIDriverPrivate::QOCIDriverPrivate() : env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false), serverVersion(-1), - prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM), precisionPolicy(QSql::HighPrecision) + prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM) { } @@ -621,136 +619,6 @@ static QSqlField qFromOraInf(const OraFieldInfo &ofi) return f; } -static OraFieldInfo qMakeOraField(const QOCIResultPrivate* p, OCIParam* param) -{ - OraFieldInfo ofi; - ub2 colType(0); - text *colName = 0; - ub4 colNameLen(0); - sb1 colScale(0); - ub2 colLength(0); - ub2 colFieldLength(0); - sb2 colPrecision(0); - ub1 colIsNull(0); - int r(0); - QVariant::Type type(QVariant::Invalid); - - r = OCIAttrGet(param, - OCI_DTYPE_PARAM, - &colType, - 0, - OCI_ATTR_DATA_TYPE, - p->err); - if (r != 0) - qOraWarning("qMakeOraField:", p->err); - - r = OCIAttrGet(param, - OCI_DTYPE_PARAM, - &colName, - &colNameLen, - OCI_ATTR_NAME, - p->err); - if (r != 0) - qOraWarning("qMakeOraField:", p->err); - - r = OCIAttrGet(param, - OCI_DTYPE_PARAM, - &colLength, - 0, - OCI_ATTR_DATA_SIZE, /* in bytes */ - p->err); - if (r != 0) - qOraWarning("qMakeOraField:", p->err); - -#ifdef OCI_ATTR_CHAR_SIZE - r = OCIAttrGet(param, - OCI_DTYPE_PARAM, - &colFieldLength, - 0, - OCI_ATTR_CHAR_SIZE, - p->err); - if (r != 0) - qOraWarning("qMakeOraField:", p->err); -#else - // for Oracle8. - colFieldLength = colLength; -#endif - - r = OCIAttrGet(param, - OCI_DTYPE_PARAM, - &colPrecision, - 0, - OCI_ATTR_PRECISION, - p->err); - if (r != 0) - qOraWarning("qMakeOraField:", p->err); - - r = OCIAttrGet(param, - OCI_DTYPE_PARAM, - &colScale, - 0, - OCI_ATTR_SCALE, - p->err); - if (r != 0) - qOraWarning("qMakeOraField:", p->err); - r = OCIAttrGet(param, - OCI_DTYPE_PARAM, - &colType, - 0, - OCI_ATTR_DATA_TYPE, - p->err); - if (r != 0) - qOraWarning("qMakeOraField:", p->err); - r = OCIAttrGet(param, - OCI_DTYPE_PARAM, - &colIsNull, - 0, - OCI_ATTR_IS_NULL, - p->err); - if (r != 0) - qOraWarning("qMakeOraField:", p->err); - - type = qDecodeOCIType(colType, p->precisionPolicy); - - if (type == QVariant::Int) { - if (colLength == 22 && colPrecision == 0 && colScale == 0) - type = QVariant::String; - if (colScale > 0) - type = QVariant::String; - } - - // bind as double if the precision policy asks for it - if (((colType == SQLT_FLT) || (colType == SQLT_NUM)) - && (p->precisionPolicy == QSql::LowPrecisionDouble)) { - type = QVariant::Double; - } - - // bind as int32 or int64 if the precision policy asks for it - if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN) - || (colType == SQLT_INT)) { - if (p->precisionPolicy == QSql::LowPrecisionInt64) - type = QVariant::LongLong; - else if (p->precisionPolicy == QSql::LowPrecisionInt32) - type = QVariant::Int; - } - - if (colType == SQLT_BLOB) - colLength = 0; - - // colNameLen is length in bytes - ofi.name = QString(reinterpret_cast<const QChar*>(colName), colNameLen / 2); - ofi.type = type; - ofi.oraType = colType; - ofi.oraFieldLength = colFieldLength; - ofi.oraLength = colLength; - ofi.oraScale = colScale; - ofi.oraPrecision = colPrecision; - ofi.oraIsNull = colIsNull; - - return ofi; -} - - /*! \internal @@ -806,6 +674,7 @@ public: private: char* create(int position, int size); OCILobLocator ** createLobLocator(int position, OCIEnv* env); + OraFieldInfo qMakeOraField(const QOCIResultPrivate* p, OCIParam* param) const; class OraFieldInf { @@ -1137,6 +1006,135 @@ int QOCICols::readPiecewise(QVector<QVariant> &values, int index) return r; } +OraFieldInfo QOCICols::qMakeOraField(const QOCIResultPrivate* p, OCIParam* param) const +{ + OraFieldInfo ofi; + ub2 colType(0); + text *colName = 0; + ub4 colNameLen(0); + sb1 colScale(0); + ub2 colLength(0); + ub2 colFieldLength(0); + sb2 colPrecision(0); + ub1 colIsNull(0); + int r(0); + QVariant::Type type(QVariant::Invalid); + + r = OCIAttrGet(param, + OCI_DTYPE_PARAM, + &colType, + 0, + OCI_ATTR_DATA_TYPE, + p->err); + if (r != 0) + qOraWarning("qMakeOraField:", p->err); + + r = OCIAttrGet(param, + OCI_DTYPE_PARAM, + &colName, + &colNameLen, + OCI_ATTR_NAME, + p->err); + if (r != 0) + qOraWarning("qMakeOraField:", p->err); + + r = OCIAttrGet(param, + OCI_DTYPE_PARAM, + &colLength, + 0, + OCI_ATTR_DATA_SIZE, /* in bytes */ + p->err); + if (r != 0) + qOraWarning("qMakeOraField:", p->err); + +#ifdef OCI_ATTR_CHAR_SIZE + r = OCIAttrGet(param, + OCI_DTYPE_PARAM, + &colFieldLength, + 0, + OCI_ATTR_CHAR_SIZE, + p->err); + if (r != 0) + qOraWarning("qMakeOraField:", p->err); +#else + // for Oracle8. + colFieldLength = colLength; +#endif + + r = OCIAttrGet(param, + OCI_DTYPE_PARAM, + &colPrecision, + 0, + OCI_ATTR_PRECISION, + p->err); + if (r != 0) + qOraWarning("qMakeOraField:", p->err); + + r = OCIAttrGet(param, + OCI_DTYPE_PARAM, + &colScale, + 0, + OCI_ATTR_SCALE, + p->err); + if (r != 0) + qOraWarning("qMakeOraField:", p->err); + r = OCIAttrGet(param, + OCI_DTYPE_PARAM, + &colType, + 0, + OCI_ATTR_DATA_TYPE, + p->err); + if (r != 0) + qOraWarning("qMakeOraField:", p->err); + r = OCIAttrGet(param, + OCI_DTYPE_PARAM, + &colIsNull, + 0, + OCI_ATTR_IS_NULL, + p->err); + if (r != 0) + qOraWarning("qMakeOraField:", p->err); + + type = qDecodeOCIType(colType, p->q->numericalPrecisionPolicy()); + + if (type == QVariant::Int) { + if (colLength == 22 && colPrecision == 0 && colScale == 0) + type = QVariant::String; + if (colScale > 0) + type = QVariant::String; + } + + // bind as double if the precision policy asks for it + if (((colType == SQLT_FLT) || (colType == SQLT_NUM)) + && (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)) { + type = QVariant::Double; + } + + // bind as int32 or int64 if the precision policy asks for it + if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN) + || (colType == SQLT_INT)) { + if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64) + type = QVariant::LongLong; + else if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32) + type = QVariant::Int; + } + + if (colType == SQLT_BLOB) + colLength = 0; + + // colNameLen is length in bytes + ofi.name = QString(reinterpret_cast<const QChar*>(colName), colNameLen / 2); + ofi.type = type; + ofi.oraType = colType; + ofi.oraFieldLength = colFieldLength; + ofi.oraLength = colLength; + ofi.oraScale = colScale; + ofi.oraPrecision = colPrecision; + ofi.oraIsNull = colIsNull; + + return ofi; +} + struct QOCIBatchColumn { inline QOCIBatchColumn() @@ -1580,19 +1578,19 @@ void QOCICols::getValues(QVector<QVariant> &v, int index) case QVariant::Double: case QVariant::Int: case QVariant::LongLong: - if (d->precisionPolicy != QSql::HighPrecision) { - if ((d->precisionPolicy == QSql::LowPrecisionDouble) + if (d->q->numericalPrecisionPolicy() != QSql::HighPrecision) { + if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble) && (fld.typ == QVariant::Double)) { v[index + i] = *reinterpret_cast<double *>(fld.data); break; - } else if ((d->precisionPolicy == QSql::LowPrecisionInt64) + } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64) && (fld.typ == QVariant::LongLong)) { qint64 qll = 0; OCINumberToInt(d->err, reinterpret_cast<OCINumber *>(fld.data), sizeof(qint64), OCI_NUMBER_SIGNED, &qll); v[index + i] = qll; break; - } else if ((d->precisionPolicy == QSql::LowPrecisionInt32) + } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32) && (fld.typ == QVariant::Int)) { v[index + i] = *reinterpret_cast<int *>(fld.data); break; @@ -1618,8 +1616,7 @@ void QOCICols::getValues(QVector<QVariant> &v, int index) QOCIResultPrivate::QOCIResultPrivate(QOCIResult *result, const QOCIDriverPrivate *driver) : cols(0), q(result), env(driver->env), err(0), svc(const_cast<OCISvcCtx*&>(driver->svc)), sql(0), transaction(driver->transaction), serverVersion(driver->serverVersion), - prefetchRows(driver->prefetchRows), prefetchMem(driver->prefetchMem), - precisionPolicy(driver->precisionPolicy) + prefetchRows(driver->prefetchRows), prefetchMem(driver->prefetchMem) { int r = OCIHandleAlloc(env, reinterpret_cast<void **>(&err), @@ -1901,9 +1898,6 @@ void QOCIResult::virtual_hook(int id, void *data) case QSqlResult::BatchOperation: QOCICols::execBatch(d, boundValues(), *reinterpret_cast<bool *>(data)); break; - case QSqlResult::SetNumericalPrecision: - d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data); - break; default: QSqlResult::virtual_hook(id, data); } @@ -2314,7 +2308,7 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const << QLatin1String("BINARY_DOUBLE"); if (buildRecordInfo) { do { - QVariant::Type ty = qDecodeOCIType(t.value(1).toString(),t.numericalPrecisionPolicy()); + QVariant::Type ty = qDecodeOCIType(t.value(1).toString(), t.numericalPrecisionPolicy()); QSqlField f(t.value(0).toString(), ty); f.setRequired(t.value(5).toString() == QLatin1String("N")); f.setPrecision(t.value(4).toInt()); |