summaryrefslogtreecommitdiffstats
path: root/src/sql/drivers
diff options
context:
space:
mode:
authorBill King <bill.king@nokia.com>2009-06-12 00:29:44 (GMT)
committerBill King <bill.king@nokia.com>2009-06-15 00:31:07 (GMT)
commitc9f77564df14f91276e9ca693a9b3f339dab9334 (patch)
tree5c87e861a3973433c2b01ece730164d63a5dab95 /src/sql/drivers
parentba097c23159c1ec026b8b8772d1a9c5e72f2a681 (diff)
downloadQt-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')
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp7
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp30
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.h1
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp280
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp63
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp21
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp11
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.cpp7
8 files changed, 202 insertions, 218 deletions
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index c7cbc9b..b8f52f4 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -84,7 +84,7 @@ public:
class QDB2ResultPrivate
{
public:
- QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0), precisionPolicy(QSql::HighPrecision)
+ QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0)
{}
~QDB2ResultPrivate()
{
@@ -107,7 +107,6 @@ public:
SQLHANDLE hStmt;
QSqlRecord recInf;
QVector<QVariant*> valueCache;
- QSql::NumericalPrecisionPolicy precisionPolicy;
};
static QString qFromTChar(SQLTCHAR* str)
@@ -1147,10 +1146,6 @@ void QDB2Result::virtual_hook(int id, void *data)
Q_ASSERT(data);
*static_cast<bool*>(data) = nextResult();
break;
- case QSqlResult::SetNumericalPrecision:
- Q_ASSERT(data);
- d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
- break;
default:
QSqlResult::virtual_hook(id, data);
}
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 82ed124..0ea2f96 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -167,12 +167,11 @@ class QMYSQLResultPrivate : public QObject
{
Q_OBJECT
public:
- QMYSQLResultPrivate(const QMYSQLDriver* dp) : driver(dp), result(0),
+ QMYSQLResultPrivate(const QMYSQLDriver* dp, const QMYSQLResult* d) : driver(dp), result(0), q(d),
rowsAffected(0), hasBlobs(false)
#if MYSQL_VERSION_ID >= 40108
, stmt(0), meta(0), inBinds(0), outBinds(0)
#endif
- , precisionPolicy(QSql::HighPrecision)
{
connect(dp, SIGNAL(destroyed()), this, SLOT(driverDestroyed()));
}
@@ -180,6 +179,7 @@ public:
const QMYSQLDriver* driver;
MYSQL_RES *result;
MYSQL_ROW row;
+ const QMYSQLResult* q;
int rowsAffected;
@@ -209,7 +209,6 @@ public:
MYSQL_BIND *inBinds;
MYSQL_BIND *outBinds;
#endif
- QSql::NumericalPrecisionPolicy precisionPolicy;
private Q_SLOTS:
void driverDestroyed() { driver = NULL; }
};
@@ -254,6 +253,7 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
break;
case FIELD_TYPE_FLOAT :
case FIELD_TYPE_DOUBLE :
+ case FIELD_TYPE_DECIMAL :
type = QVariant::Double;
break;
case FIELD_TYPE_DATE :
@@ -277,7 +277,6 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
default:
case FIELD_TYPE_ENUM :
case FIELD_TYPE_SET :
- case FIELD_TYPE_DECIMAL :
type = QVariant::String;
break;
}
@@ -354,6 +353,7 @@ bool QMYSQLResultPrivate::bindInValues()
while((fieldInfo = mysql_fetch_field(meta))) {
QMyField &f = fields[i];
f.myField = fieldInfo;
+
f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
if (qIsBlob(fieldInfo->type)) {
// the size of a blob-field is available as soon as we call
@@ -384,7 +384,7 @@ bool QMYSQLResultPrivate::bindInValues()
QMYSQLResult::QMYSQLResult(const QMYSQLDriver* db)
: QSqlResult(db)
{
- d = new QMYSQLResultPrivate(db);
+ d = new QMYSQLResultPrivate(db, this);
}
QMYSQLResult::~QMYSQLResult()
@@ -599,15 +599,16 @@ QVariant QMYSQLResult::data(int field)
case QVariant::Double: {
QVariant v;
bool ok=false;
- switch(d->precisionPolicy) {
+ double dbl = val.toDouble(&ok);
+ switch(numericalPrecisionPolicy()) {
case QSql::LowPrecisionInt32:
- v=val.toInt(&ok);
+ v=QVariant(dbl).toInt();
break;
case QSql::LowPrecisionInt64:
- v = val.toLongLong(&ok);
+ v = QVariant(dbl).toLongLong();
break;
case QSql::LowPrecisionDouble:
- v = val.toDouble(&ok);
+ v = QVariant(dbl);
break;
case QSql::HighPrecision:
default:
@@ -620,6 +621,7 @@ QVariant QMYSQLResult::data(int field)
else
return QVariant();
}
+ return QVariant(val.toDouble());
case QVariant::Date:
return qDateFromString(val);
case QVariant::Time:
@@ -679,6 +681,7 @@ bool QMYSQLResult::reset (const QString& query)
setSelect(numFields != 0);
d->fields.resize(numFields);
d->rowsAffected = mysql_affected_rows(d->driver->d->mysql);
+
if (isSelect()) {
for(int i = 0; i < numFields; i++) {
MYSQL_FIELD* field = mysql_fetch_field_direct(d->result, i);
@@ -813,10 +816,6 @@ void QMYSQLResult::virtual_hook(int id, void *data)
Q_ASSERT(data);
*static_cast<bool*>(data) = nextResult();
break;
- case QSqlResult::SetNumericalPrecision:
- Q_ASSERT(data);
- d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
- break;
default:
QSqlResult::virtual_hook(id, data);
}
@@ -1148,7 +1147,6 @@ bool QMYSQLDriver::hasFeature(DriverFeature f) const
case NamedPlaceholders:
case BatchOperations:
case SimpleLocking:
- case LowPrecisionNumbers:
case EventNotifications:
case FinishQuery:
return false;
@@ -1156,6 +1154,7 @@ bool QMYSQLDriver::hasFeature(DriverFeature f) const
case BLOB:
case LastInsertId:
case Unicode:
+ case LowPrecisionNumbers:
return true;
case PreparedQueries:
case PositionalPlaceholders:
@@ -1369,6 +1368,7 @@ QSqlRecord QMYSQLDriver::record(const QString& tablename) const
return info;
}
MYSQL_FIELD* field;
+
while ((field = mysql_fetch_field(r)))
info.append(qToField(field, d->tc));
mysql_free_result(r);
@@ -1485,4 +1485,4 @@ bool QMYSQLDriver::isIdentifierEscapedImplementation(const QString &identifier,
QT_END_NAMESPACE
-#include "qsql_mysql.moc" \ No newline at end of file
+#include "qsql_mysql.moc"
diff --git a/src/sql/drivers/mysql/qsql_mysql.h b/src/sql/drivers/mysql/qsql_mysql.h
index 31d9dcf..3c27d16 100644
--- a/src/sql/drivers/mysql/qsql_mysql.h
+++ b/src/sql/drivers/mysql/qsql_mysql.h
@@ -69,6 +69,7 @@ class QSqlRecordInfo;
class QMYSQLResult : public QSqlResult
{
friend class QMYSQLDriver;
+ friend class QMYSQLResultPrivate;
public:
explicit QMYSQLResult(const QMYSQLDriver* db);
~QMYSQLResult();
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());
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 8eaa8bf..f60c33c 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -127,7 +127,7 @@ class QODBCPrivate
{
public:
QODBCPrivate()
- : hEnv(0), hDbc(0), hStmt(0), useSchema(false), hasSQLFetchScroll(true), precisionPolicy(QSql::HighPrecision)
+ : hEnv(0), hDbc(0), hStmt(0), useSchema(false), hasSQLFetchScroll(true)
{
sql_char_type = sql_varchar_type = sql_longvarchar_type = QVariant::ByteArray;
unicode = false;
@@ -151,7 +151,6 @@ public:
int fieldCacheIdx;
int disconnectCount;
bool hasSQLFetchScroll;
- QSql::NumericalPrecisionPolicy precisionPolicy;
bool isStmtHandleValid(const QSqlDriver *driver);
void updateStmtHandleState(const QSqlDriver *driver);
@@ -444,6 +443,26 @@ static QVariant qGetIntData(SQLHANDLE hStmt, int column, bool isSigned = true)
return uint(intbuf);
}
+static QVariant qGetDoubleData(SQLHANDLE hStmt, int column)
+{
+ SQLDOUBLE dblbuf;
+ SQLINTEGER lengthIndicator = 0;
+ SQLRETURN r = SQLGetData(hStmt,
+ column+1,
+ SQL_C_DOUBLE,
+ (SQLPOINTER) &dblbuf,
+ 0,
+ &lengthIndicator);
+ if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
+ return QVariant(QVariant::Invalid);
+ }
+ if(lengthIndicator == SQL_NULL_DATA)
+ return QVariant(QVariant::Double);
+
+ return (double) dblbuf;
+}
+
+
static QVariant qGetBigIntData(SQLHANDLE hStmt, int column, bool isSigned = true)
{
SQLBIGINT lngbuf = 0;
@@ -1109,29 +1128,21 @@ QVariant QODBCResult::data(int field)
d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), true);
break;
case QVariant::Double:
- {
- QString value=qGetStringData(d->hStmt, i, info.length(), false);
- bool ok=false;
- switch(d->precisionPolicy) {
- case QSql::LowPrecisionInt32:
- d->fieldCache[i] = value.toInt(&ok);
- break;
- case QSql::LowPrecisionInt64:
- d->fieldCache[i] = value.toLongLong(&ok);
- break;
- case QSql::LowPrecisionDouble:
- d->fieldCache[i] = value.toDouble(&ok);
- break;
- case QSql::HighPrecision:
- default:
- d->fieldCache[i] = value;
- ok=true;
- break;
- }
- if(ok==false)
- d->fieldCache[i] = QVariant();
- break;
+ switch(numericalPrecisionPolicy()) {
+ case QSql::LowPrecisionInt32:
+ d->fieldCache[i] = qGetIntData(d->hStmt, i);
+ break;
+ case QSql::LowPrecisionInt64:
+ d->fieldCache[i] = qGetBigIntData(d->hStmt, i);
+ break;
+ case QSql::LowPrecisionDouble:
+ d->fieldCache[i] = qGetDoubleData(d->hStmt, i);
+ break;
+ case QSql::HighPrecision:
+ d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), false);
+ break;
}
+ break;
default:
d->fieldCache[i] = QVariant(qGetStringData(d->hStmt, i, info.length(), false));
break;
@@ -1628,10 +1639,6 @@ void QODBCResult::virtual_hook(int id, void *data)
Q_ASSERT(data);
*static_cast<bool*>(data) = nextResult();
break;
- case QSqlResult::SetNumericalPrecision:
- Q_ASSERT(data);
- d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
- break;
default:
QSqlResult::virtual_hook(id, data);
}
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index ce0b8c5..169a371 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -136,13 +136,12 @@ void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type)
class QPSQLResultPrivate
{
public:
- QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1), precisionPolicy(QSql::HighPrecision) {}
+ QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1) {}
QPSQLResult *q;
const QPSQLDriverPrivate *driver;
PGresult *result;
int currentSize;
- QSql::NumericalPrecisionPolicy precisionPolicy;
bool preparedQueriesEnabled;
QString preparedStmtId;
@@ -320,15 +319,16 @@ QVariant QPSQLResult::data(int i)
return atoi(val);
case QVariant::Double:
if (ptype == QNUMERICOID) {
- if (d->precisionPolicy != QSql::HighPrecision) {
+ if (numericalPrecisionPolicy() != QSql::HighPrecision) {
QVariant retval;
bool convert;
- if (d->precisionPolicy == QSql::LowPrecisionInt64)
- retval = QString::fromAscii(val).toLongLong(&convert);
- else if (d->precisionPolicy == QSql::LowPrecisionInt32)
- retval = QString::fromAscii(val).toInt(&convert);
- else if (d->precisionPolicy == QSql::LowPrecisionDouble)
- retval = QString::fromAscii(val).toDouble(&convert);
+ double dbl=QString::fromAscii(val).toDouble(&convert);
+ if (numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
+ retval = (qlonglong)dbl;
+ else if (numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
+ retval = (int)dbl;
+ else if (numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
+ retval = dbl;
if (!convert)
return QVariant();
return retval;
@@ -467,9 +467,6 @@ void QPSQLResult::virtual_hook(int id, void *data)
Q_ASSERT(data);
switch (id) {
- case QSqlResult::SetNumericalPrecision:
- d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
- break;
default:
QSqlResult::virtual_hook(id, data);
}
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 05d63ca..0f6fb25 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -115,13 +115,12 @@ public:
uint skipRow: 1; // skip the next fetchNext()?
uint utf8: 1;
QSqlRecord rInf;
- QSql::NumericalPrecisionPolicy precisionPolicy;
};
static const uint initial_cache_size = 128;
QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult* res) : q(res), access(0),
- stmt(0), skippedStatus(false), skipRow(false), utf8(false), precisionPolicy(QSql::HighPrecision)
+ stmt(0), skippedStatus(false), skipRow(false), utf8(false)
{
}
@@ -212,7 +211,7 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
values[i + idx] = sqlite3_column_int64(stmt, i);
break;
case SQLITE_FLOAT:
- switch(precisionPolicy) {
+ switch(q->numericalPrecisionPolicy()) {
case QSql::LowPrecisionInt32:
values[i + idx] = sqlite3_column_int(stmt, i);
break;
@@ -289,10 +288,6 @@ void QSQLiteResult::virtual_hook(int id, void *data)
if (d->stmt)
sqlite3_reset(d->stmt);
break;
- case QSqlResult::SetNumericalPrecision:
- Q_ASSERT(data);
- d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
- break;
default:
QSqlResult::virtual_hook(id, data);
}
@@ -481,11 +476,11 @@ bool QSQLiteDriver::hasFeature(DriverFeature f) const
case PositionalPlaceholders:
case SimpleLocking:
case FinishQuery:
+ case LowPrecisionNumbers:
return true;
case QuerySize:
case NamedPlaceholders:
case BatchOperations:
- case LowPrecisionNumbers:
case EventNotifications:
case MultipleResultSets:
return false;
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
index cb72ff0..bd7c367 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
@@ -114,13 +114,12 @@ public:
uint skipRow: 1; // skip the next fetchNext()?
uint utf8: 1;
QSqlRecord rInf;
- QSql::NumericalPrecisionPolicy precisionPolicy;
};
static const uint initial_cache_size = 128;
QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result* res) : q(res), access(0), currentTail(0),
- currentMachine(0), skippedStatus(false), skipRow(false), utf8(false), precisionPolicy(QSql::HighPrecision)
+ currentMachine(0), skippedStatus(false), skipRow(false), utf8(false)
{
}
@@ -260,10 +259,6 @@ void QSQLite2Result::virtual_hook(int id, void *data)
case QSqlResult::DetachFromResultSet:
d->finalize();
break;
- case QSqlResult::SetNumericalPrecision:
- Q_ASSERT(data);
- d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
- break;
default:
QSqlResult::virtual_hook(id, data);
}