summaryrefslogtreecommitdiffstats
path: root/src/sql/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql/kernel')
-rw-r--r--src/sql/kernel/qsqlcachedresult.cpp13
-rw-r--r--src/sql/kernel/qsqlcachedresult_p.h1
-rw-r--r--src/sql/kernel/qsqldatabase.cpp56
-rw-r--r--src/sql/kernel/qsqldatabase.h2
-rw-r--r--src/sql/kernel/qsqldriver.cpp164
-rw-r--r--src/sql/kernel/qsqldriver.h9
-rw-r--r--src/sql/kernel/qsqlerror.cpp2
-rw-r--r--src/sql/kernel/qsqlfield.cpp4
-rw-r--r--src/sql/kernel/qsqlquery.cpp23
-rw-r--r--src/sql/kernel/qsqlrecord.cpp2
-rw-r--r--src/sql/kernel/qsqlresult.cpp19
-rw-r--r--src/sql/kernel/qsqlresult.h1
12 files changed, 255 insertions, 41 deletions
diff --git a/src/sql/kernel/qsqlcachedresult.cpp b/src/sql/kernel/qsqlcachedresult.cpp
index 3cace06..ca51dc0 100644
--- a/src/sql/kernel/qsqlcachedresult.cpp
+++ b/src/sql/kernel/qsqlcachedresult.cpp
@@ -294,4 +294,17 @@ QSqlCachedResult::ValueCache &QSqlCachedResult::cache()
return d->cache;
}
+void QSqlCachedResult::virtual_hook(int id, void *data)
+{
+ switch (id) {
+ case QSqlResult::DetachFromResultSet:
+ case QSqlResult::SetNumericalPrecision:
+ cleanup();
+ break;
+ default:
+ QSqlResult::virtual_hook(id, data);
+ }
+}
+
+
QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqlcachedresult_p.h b/src/sql/kernel/qsqlcachedresult_p.h
index d19435c..a384b2e 100644
--- a/src/sql/kernel/qsqlcachedresult_p.h
+++ b/src/sql/kernel/qsqlcachedresult_p.h
@@ -89,6 +89,7 @@ protected:
int colCount() const;
ValueCache &cache();
+ void virtual_hook(int id, void *data);
private:
bool cacheNext();
QSqlCachedResultPrivate *d;
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index 848f213..5aef39e 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -129,11 +129,16 @@ Q_GLOBAL_STATIC(QConnectionDict, dbDict)
class QSqlDatabasePrivate
{
public:
- QSqlDatabasePrivate(QSqlDriver *dr = 0):
+ QSqlDatabasePrivate(QSqlDatabase *d, QSqlDriver *dr = 0):
+ q(d),
driver(dr),
port(-1)
{
ref = 1;
+ if(driver)
+ precisionPolicy = driver->numericalPrecisionPolicy();
+ else
+ precisionPolicy= QSql::LowPrecisionDouble;
}
QSqlDatabasePrivate(const QSqlDatabasePrivate &other);
~QSqlDatabasePrivate();
@@ -142,6 +147,7 @@ public:
void disable();
QAtomicInt ref;
+ QSqlDatabase *q;
QSqlDriver* driver;
QString dbname;
QString uname;
@@ -151,6 +157,7 @@ public:
int port;
QString connOptions;
QString connName;
+ QSql::NumericalPrecisionPolicy precisionPolicy;
static QSqlDatabasePrivate *shared_null();
static QSqlDatabase database(const QString& name, bool open);
@@ -164,6 +171,7 @@ public:
QSqlDatabasePrivate::QSqlDatabasePrivate(const QSqlDatabasePrivate &other)
{
ref = 1;
+ q = other.q;
dbname = other.dbname;
uname = other.uname;
pword = other.pword;
@@ -172,6 +180,7 @@ QSqlDatabasePrivate::QSqlDatabasePrivate(const QSqlDatabasePrivate &other)
port = other.port;
connOptions = other.connOptions;
driver = other.driver;
+ precisionPolicy = other.precisionPolicy;
}
QSqlDatabasePrivate::~QSqlDatabasePrivate()
@@ -216,7 +225,7 @@ DriverDict &QSqlDatabasePrivate::driverDict()
QSqlDatabasePrivate *QSqlDatabasePrivate::shared_null()
{
static QSqlNullDriver dr;
- static QSqlDatabasePrivate n(&dr);
+ static QSqlDatabasePrivate n(NULL, &dr);
return &n;
}
@@ -281,6 +290,7 @@ QSqlDatabase QSqlDatabasePrivate::database(const QString& name, bool open)
*/
void QSqlDatabasePrivate::copy(const QSqlDatabasePrivate *other)
{
+ q = other->q;
dbname = other->dbname;
uname = other->uname;
pword = other->pword;
@@ -288,6 +298,7 @@ void QSqlDatabasePrivate::copy(const QSqlDatabasePrivate *other)
drvName = other->drvName;
port = other->port;
connOptions = other->connOptions;
+ precisionPolicy = other->precisionPolicy;
}
void QSqlDatabasePrivate::disable()
@@ -658,7 +669,7 @@ QStringList QSqlDatabase::connectionNames()
QSqlDatabase::QSqlDatabase(const QString &type)
{
- d = new QSqlDatabasePrivate();
+ d = new QSqlDatabasePrivate(this);
d->init(type);
}
@@ -670,7 +681,7 @@ QSqlDatabase::QSqlDatabase(const QString &type)
QSqlDatabase::QSqlDatabase(QSqlDriver *driver)
{
- d = new QSqlDatabasePrivate(driver);
+ d = new QSqlDatabasePrivate(this, driver);
}
/*!
@@ -949,7 +960,7 @@ bool QSqlDatabase::rollback()
connection, set the database name, and call open() again. \note
The \e{database name} is not the \e{connection name}. The
connection name must be passed to addDatabase() at connection
- object create time.
+ object create time.
For the QOCI (Oracle) driver, the database name is the TNS
Service Name.
@@ -1469,6 +1480,41 @@ QString QSqlDatabase::connectionName() const
return d->connName;
}
+/*!
+ Sets the default numerical precision policy used by queries created
+ on this database connection to \a precisionPolicy.
+
+ Note: Drivers that don't support fetching numerical values with low
+ precision will ignore the precision policy. You can use
+ QSqlDriver::hasFeature() to find out whether a driver supports this
+ feature.
+
+ Note: Setting the default precision policy to \a precisionPolicy
+ doesn't affect any currently active queries.
+
+ \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy()
+*/
+void QSqlDatabase::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
+{
+ if(driver())
+ driver()->setNumericalPrecisionPolicy(precisionPolicy);
+ d->precisionPolicy = precisionPolicy;
+}
+
+/*!
+ Returns the current default precision policy for the database connection.
+
+ \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy()
+*/
+QSql::NumericalPrecisionPolicy QSqlDatabase::numericalPrecisionPolicy() const
+{
+ if(driver())
+ return driver()->numericalPrecisionPolicy();
+ else
+ return d->precisionPolicy;
+}
+
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QSqlDatabase &d)
{
diff --git a/src/sql/kernel/qsqldatabase.h b/src/sql/kernel/qsqldatabase.h
index 74e6315..d28c888 100644
--- a/src/sql/kernel/qsqldatabase.h
+++ b/src/sql/kernel/qsqldatabase.h
@@ -120,6 +120,8 @@ public:
int port() const;
QString connectOptions() const;
QString connectionName() const;
+ void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
+ QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
QSqlDriver* driver() const;
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index 135ec306..77e389f 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -49,6 +49,17 @@
QT_BEGIN_NAMESPACE
+static QString prepareIdentifier(const QString &identifier,
+ QSqlDriver::IdentifierType type, const QSqlDriver *driver)
+{
+ Q_ASSERT( driver != NULL );
+ QString ret = identifier;
+ if (!driver->isIdentifierEscaped(identifier, type)) {
+ ret = driver->escapeIdentifier(identifier, type);
+ }
+ return ret;
+}
+
class QSqlDriverPrivate : public QObjectPrivate
{
public:
@@ -61,10 +72,11 @@ public:
uint isOpen : 1;
uint isOpenError : 1;
QSqlError error;
+ QSql::NumericalPrecisionPolicy precisionPolicy;
};
inline QSqlDriverPrivate::QSqlDriverPrivate()
- : QObjectPrivate(), isOpen(false), isOpenError(false)
+ : QObjectPrivate(), isOpen(false), isOpenError(false), precisionPolicy(QSql::LowPrecisionDouble)
{
}
@@ -372,6 +384,7 @@ QSqlRecord QSqlDriver::record(const QString & /* tableName */) const
on \a type.
The default implementation does nothing.
+ \sa isIdentifierEscaped()
*/
QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const
{
@@ -379,6 +392,55 @@ QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType)
}
/*!
+ Returns whether \a identifier is escaped according to the database rules.
+ \a identifier can either be a table name or field name, dependent
+ on \a type.
+
+ \warning Because of binary compatability constraints, this function is not virtual.
+ If you want to provide your own implementation in your QSqlDriver subclass,
+ reimplement the isIdentifierEscapedImplementation() slot in your subclass instead.
+ The isIdentifierEscapedFunction() will dynamically detect the slot and call it.
+
+ \sa stripDelimiters(), escapeIdentifier()
+ */
+bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType type) const
+{
+ bool result;
+ QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this),
+ "isIdentifierEscapedImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(bool, result),
+ Q_ARG(QString, identifier),
+ Q_ARG(IdentifierType, type));
+ return result;
+}
+
+/*!
+ Returns the \a identifier with the leading and trailing delimiters removed,
+ \a identifier can either be a table name or field name,
+ dependent on \a type. If \a identifier does not have leading
+ and trailing delimiter characters, \a identifier is returned without
+ modification.
+
+ \warning Because of binary compatability constraints, this function is not virtual,
+ If you want to provide your own implementation in your QSqlDriver subclass,
+ reimplement the stripDelimitersImplementation() slot in your subclass instead.
+ The stripDelimiters() function will dynamically detect the slot and call it.
+
+ \since 4.5
+ \sa isIdentifierEscaped()
+ */
+QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const
+{
+ QString result;
+ QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this),
+ "stripDelimitersImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(QString, result),
+ Q_ARG(QString, identifier),
+ Q_ARG(IdentifierType, type));
+ return result;
+}
+
+/*!
Returns a SQL statement of type \a type for the table \a tableName
with the values from \a rec. If \a preparedStatement is true, the
string will contain placeholders instead of values.
@@ -397,17 +459,17 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
case SelectStatement:
for (i = 0; i < rec.count(); ++i) {
if (rec.isGenerated(i))
- s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));
+ s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", "));
}
if (s.isEmpty())
return s;
s.chop(2);
- s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(escapeIdentifier(tableName, TableName));
+ s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName);
break;
case WhereStatement:
if (preparedStatement) {
for (int i = 0; i < rec.count(); ++i) {
- s.append(escapeIdentifier(rec.fieldName(i), FieldName));
+ s.append(prepareIdentifier(rec.fieldName(i), FieldName,this));
if (rec.isNull(i))
s.append(QLatin1String(" IS NULL"));
else
@@ -416,7 +478,7 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
}
} else {
for (i = 0; i < rec.count(); ++i) {
- s.append(escapeIdentifier(rec.fieldName(i), FieldName));
+ s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this));
QString val = formatValue(rec.field(i));
if (val == QLatin1String("NULL"))
s.append(QLatin1String(" IS NULL"));
@@ -431,12 +493,12 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
}
break;
case UpdateStatement:
- s.append(QLatin1String("UPDATE ")).append(escapeIdentifier(tableName, TableName)).append(
+ s.append(QLatin1String("UPDATE ")).append(tableName).append(
QLatin1String(" SET "));
for (i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i) || !rec.value(i).isValid())
continue;
- s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1Char('='));
+ s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1Char('='));
if (preparedStatement)
s.append(QLatin1Char('?'));
else
@@ -449,17 +511,17 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
s.clear();
break;
case DeleteStatement:
- s.append(QLatin1String("DELETE FROM ")).append(escapeIdentifier(tableName, TableName));
+ s.append(QLatin1String("DELETE FROM ")).append(tableName);
break;
case InsertStatement: {
- s.append(QLatin1String("INSERT INTO ")).append(escapeIdentifier(tableName, TableName)).append(QLatin1String(" ("));
+ s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" ("));
QString vals;
for (i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i) || !rec.value(i).isValid())
continue;
- s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));
+ s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", "));
if (preparedStatement)
- vals.append(QLatin1String("?"));
+ vals.append(QLatin1Char('?'));
else
vals.append(formatValue(rec.field(i)));
vals.append(QLatin1String(", "));
@@ -469,7 +531,7 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
} else {
vals.chop(2); // remove trailing comma
s[s.length() - 2] = QLatin1Char(')');
- s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1String(")"));
+ s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1Char(')'));
}
break; }
}
@@ -564,10 +626,7 @@ QString QSqlDriver::formatValue(const QSqlField &field, bool trimStrings) const
break;
}
case QVariant::Bool:
- if (field.value().toBool())
- r = QLatin1String("1");
- else
- r = QLatin1String("0");
+ r = QString::number(field.value().toBool());
break;
case QVariant::ByteArray : {
if (hasFeature(BLOB)) {
@@ -805,4 +864,77 @@ QStringList QSqlDriver::subscribedToNotificationsImplementation() const
return QStringList();
}
+/*!
+ This slot returns whether \a identifier is escaped according to the database rules.
+ \a identifier can either be a table name or field name, dependent
+ on \a type.
+
+ Because of binary compatability constraints, isIdentifierEscaped() function
+ (introduced in Qt 4.5) is not virtual. Instead, isIdentifierEscaped() will
+ dynamically detect and call \e this slot. The default implementation
+ assumes the escape/delimiter character is a double quote. Reimplement this
+ slot in your own QSqlDriver if your database engine uses a different
+ delimiter character.
+
+ \since 4.5
+ \sa isIdentifierEscaped()
+ */
+bool QSqlDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const
+{
+ Q_UNUSED(type);
+ return identifier.size() > 2
+ && identifier.startsWith(QLatin1Char('"')) //left delimited
+ && identifier.endsWith(QLatin1Char('"')); //right delimited
+}
+
+/*!
+ This slot returns \a identifier with the leading and trailing delimiters removed,
+ \a identifier can either be a tablename or field name, dependent on \a type.
+ If \a identifier does not have leading and trailing delimiter characters, \a
+ identifier is returned without modification.
+
+ Because of binary compatability constraints, the stripDelimiters() function
+ (introduced in Qt 4.5) is not virtual. Instead, stripDelimiters() will
+ dynamically detect and call \e this slot. It generally unnecessary
+ to reimplement this slot.
+
+ \since 4.5
+ \sa stripDelimiters()
+ */
+QString QSqlDriver::stripDelimitersImplementation(const QString &identifier, IdentifierType type) const
+{
+ QString ret;
+ if (this->isIdentifierEscaped(identifier, type)) {
+ ret = identifier.mid(1);
+ ret.chop(1);
+ } else {
+ ret = identifier;
+ }
+ return ret;
+}
+
+/*!
+ Sets the default numerical precision policy used by queries created
+ by this driver to \a precisionPolicy.
+
+ Note: Setting the default precision policy to \a precisionPolicy
+ doesn't affect any currently active queries.
+
+ \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy()
+*/
+void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
+{
+ d_func()->precisionPolicy = precisionPolicy;
+}
+
+/*!
+ Returns the current default precision policy for the database connection.
+
+ \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy()
+*/
+QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const
+{
+ return d_func()->precisionPolicy;
+}
+
QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h
index 9e3d291..3052be6 100644
--- a/src/sql/kernel/qsqldriver.h
+++ b/src/sql/kernel/qsqldriver.h
@@ -127,6 +127,12 @@ public:
bool unsubscribeFromNotification(const QString &name); // ### Qt 5: make virtual
QStringList subscribedToNotifications() const; // ### Qt 5: make virtual
+ bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual
+ QString stripDelimiters(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual
+
+ void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
+ QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
+
Q_SIGNALS:
void notification(const QString &name);
@@ -140,6 +146,9 @@ protected Q_SLOTS:
bool unsubscribeFromNotificationImplementation(const QString &name); // ### Qt 5: eliminate, see unsubscribeFromNotification()
QStringList subscribedToNotificationsImplementation() const; // ### Qt 5: eliminate, see subscribedNotifications()
+ bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; // ### Qt 5: eliminate, see isIdentifierEscaped()
+ QString stripDelimitersImplementation(const QString &identifier, IdentifierType type) const; // ### Qt 5: eliminate, see stripDelimiters()
+
private:
Q_DISABLE_COPY(QSqlDriver)
};
diff --git a/src/sql/kernel/qsqlerror.cpp b/src/sql/kernel/qsqlerror.cpp
index b59e7bc..bb2e7a1 100644
--- a/src/sql/kernel/qsqlerror.cpp
+++ b/src/sql/kernel/qsqlerror.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
QDebug operator<<(QDebug dbg, const QSqlError &s)
{
dbg.nospace() << "QSqlError(" << s.number() << ", " << s.driverText() <<
- ", " << s.databaseText() << ")";
+ ", " << s.databaseText() << ')';
return dbg.space();
}
#endif
diff --git a/src/sql/kernel/qsqlfield.cpp b/src/sql/kernel/qsqlfield.cpp
index f4124b2..b528850 100644
--- a/src/sql/kernel/qsqlfield.cpp
+++ b/src/sql/kernel/qsqlfield.cpp
@@ -514,8 +514,8 @@ QDebug operator<<(QDebug dbg, const QSqlField &f)
if (f.typeID() >= 0)
dbg.nospace() << ", typeID: " << f.typeID();
if (!f.defaultValue().isNull())
- dbg.nospace() << ", auto-value: \"" << f.defaultValue() << "\"";
- dbg.nospace() << ")";
+ dbg.nospace() << ", auto-value: \"" << f.defaultValue() << '\"';
+ dbg.nospace() << ')';
return dbg.space();
#else
qWarning("This compiler doesn't support streaming QSqlField to QDebug");
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index 778fd28..f55b86e 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -61,7 +61,6 @@ public:
~QSqlQueryPrivate();
QAtomicInt ref;
QSqlResult* sqlResult;
- QSql::NumericalPrecisionPolicy precisionPolicy;
static QSqlQueryPrivate* shared_null();
};
@@ -81,7 +80,7 @@ QSqlQueryPrivate* QSqlQueryPrivate::shared_null()
\internal
*/
QSqlQueryPrivate::QSqlQueryPrivate(QSqlResult* result)
- : ref(1), sqlResult(result), precisionPolicy(QSql::HighPrecision)
+ : ref(1), sqlResult(result)
{
if (!sqlResult)
sqlResult = nullResult();
@@ -351,14 +350,14 @@ bool QSqlQuery::exec(const QString& query)
if (d->ref != 1) {
bool fo = isForwardOnly();
*this = QSqlQuery(driver()->createResult());
- d->sqlResult->setNumericalPrecisionPolicy(d->precisionPolicy);
+ d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
setForwardOnly(fo);
} else {
d->sqlResult->clear();
d->sqlResult->setActive(false);
d->sqlResult->setLastError(QSqlError());
d->sqlResult->setAt(QSql::BeforeFirstRow);
- d->sqlResult->setNumericalPrecisionPolicy(d->precisionPolicy);
+ d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
}
d->sqlResult->setQuery(query.trimmed());
if (!driver()->isOpen() || driver()->isOpenError()) {
@@ -891,12 +890,12 @@ bool QSqlQuery::prepare(const QString& query)
bool fo = isForwardOnly();
*this = QSqlQuery(driver()->createResult());
setForwardOnly(fo);
- d->sqlResult->setNumericalPrecisionPolicy(d->precisionPolicy);
+ d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
} else {
d->sqlResult->setActive(false);
d->sqlResult->setLastError(QSqlError());
d->sqlResult->setAt(QSql::BeforeFirstRow);
- d->sqlResult->setNumericalPrecisionPolicy(d->precisionPolicy);
+ d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
}
if (!driver()) {
qWarning("QSqlQuery::prepare: no driver");
@@ -1126,10 +1125,10 @@ QVariant QSqlQuery::lastInsertId() const
Instruct the database driver to return numerical values with a
precision specified by \a precisionPolicy.
- The Oracle driver, for example, retrieves numerical values as
- strings by default to prevent the loss of precision. If the high
- precision doesn't matter, use this method to increase execution
- speed by bypassing string conversions.
+ The Oracle driver, for example, can retrieve numerical values as
+ strings to prevent the loss of precision. If high precision doesn't
+ matter, use this method to increase execution speed by bypassing
+ string conversions.
Note: Drivers that don't support fetching numerical values with low
precision will ignore the precision policy. You can use
@@ -1144,7 +1143,7 @@ QVariant QSqlQuery::lastInsertId() const
*/
void QSqlQuery::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
{
- d->precisionPolicy = precisionPolicy;
+ d->sqlResult->setNumericalPrecisionPolicy(precisionPolicy);
}
/*!
@@ -1154,7 +1153,7 @@ void QSqlQuery::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy preci
*/
QSql::NumericalPrecisionPolicy QSqlQuery::numericalPrecisionPolicy() const
{
- return d->precisionPolicy;
+ return d->sqlResult->numericalPrecisionPolicy();
}
/*!
diff --git a/src/sql/kernel/qsqlrecord.cpp b/src/sql/kernel/qsqlrecord.cpp
index e599d37..64e52be 100644
--- a/src/sql/kernel/qsqlrecord.cpp
+++ b/src/sql/kernel/qsqlrecord.cpp
@@ -589,7 +589,7 @@ void QSqlRecord::detach()
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QSqlRecord &r)
{
- dbg << "QSqlRecord(" << r.count() << ")";
+ dbg << "QSqlRecord(" << r.count() << ')';
for (int i = 0; i < r.count(); ++i)
dbg << '\n' << QString::fromLatin1("%1:").arg(i, 2) << r.field(i) << r.value(i).toString();
return dbg;
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp
index 932bcf1..93c9d9f 100644
--- a/src/sql/kernel/qsqlresult.cpp
+++ b/src/sql/kernel/qsqlresult.cpp
@@ -48,6 +48,7 @@
#include "qsqlresult.h"
#include "qvector.h"
#include "qsqldriver.h"
+#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -64,7 +65,7 @@ class QSqlResultPrivate
public:
QSqlResultPrivate(QSqlResult* d)
: q(d), sqldriver(0), idx(QSql::BeforeFirstRow), active(false),
- isSel(false), forwardOnly(false), bindCount(0), binds(QSqlResult::PositionalBinding)
+ isSel(false), forwardOnly(false), precisionPolicy(QSql::LowPrecisionDouble), bindCount(0), binds(QSqlResult::PositionalBinding)
{}
void clearValues()
@@ -104,6 +105,7 @@ public:
bool isSel;
QSqlError error;
bool forwardOnly;
+ QSql::NumericalPrecisionPolicy precisionPolicy;
int bindCount;
QSqlResult::BindingSyntax binds;
@@ -249,6 +251,9 @@ QSqlResult::QSqlResult(const QSqlDriver *db)
{
d = new QSqlResultPrivate(this);
d->sqldriver = db;
+ if(db) {
+ setNumericalPrecisionPolicy(db->numericalPrecisionPolicy());
+ }
}
/*!
@@ -900,7 +905,6 @@ QVariant QSqlResult::lastInsertId() const
*/
void QSqlResult::virtual_hook(int, void *)
{
- Q_ASSERT(false);
}
/*! \internal
@@ -965,8 +969,15 @@ void QSqlResult::detachFromResultSet()
*/
void QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy)
{
- if (driver()->hasFeature(QSqlDriver::LowPrecisionNumbers))
- virtual_hook(SetNumericalPrecision, &policy);
+ d->precisionPolicy = policy;
+ virtual_hook(SetNumericalPrecision, &policy);
+}
+
+/*! \internal
+ */
+QSql::NumericalPrecisionPolicy QSqlResult::numericalPrecisionPolicy() const
+{
+ return d->precisionPolicy;
}
/*! \internal
diff --git a/src/sql/kernel/qsqlresult.h b/src/sql/kernel/qsqlresult.h
index 94e7f0e..6d8f42e 100644
--- a/src/sql/kernel/qsqlresult.h
+++ b/src/sql/kernel/qsqlresult.h
@@ -135,6 +135,7 @@ protected:
bool execBatch(bool arrayBind = false);
void detachFromResultSet();
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy);
+ QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
bool nextResult();
private: