Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannah von Reth <hannah.vonreth@owncloud.com>2022-08-19 12:35:52 +0300
committerHannah von Reth <vonreth@kde.org>2022-11-02 12:45:42 +0300
commit18bbbe7c6973d19756b776b13d05f7a418365269 (patch)
treeb3f8fa44fad9fc57997869e7eae74528f8f43bc3
parentf6cff6f7cb4d6b0274ffc770747e227518a7e92a (diff)
When pretty printing sqlit, also log converted type
-rw-r--r--src/common/ownsql.cpp41
-rw-r--r--src/common/ownsql.h28
2 files changed, 47 insertions, 22 deletions
diff --git a/src/common/ownsql.cpp b/src/common/ownsql.cpp
index ab946845a..c317dba2d 100644
--- a/src/common/ownsql.cpp
+++ b/src/common/ownsql.cpp
@@ -272,22 +272,19 @@ int SqlQuery::prepare(const QByteArray &sql, bool allow_failure)
if (_stmt) {
finish();
}
- _boundQuery = QString::fromUtf8(_sql);
if (!_sql.isEmpty()) {
- int rc = {};
for (int n = 0; n < SQLITE_REPEAT_COUNT; ++n) {
qCDebug(lcSql) << "SQL prepare" << _sql << "Try:" << n;
- rc = sqlite3_prepare_v2(_db, _sql.constData(), -1, &_stmt, nullptr);
- if (rc != SQLITE_OK) {
+ _errId = sqlite3_prepare_v2(_db, _sql.constData(), -1, &_stmt, nullptr);
+ if (_errId != SQLITE_OK) {
qCWarning(lcSql) << "SQL prepare failed" << _sql << QString::fromUtf8(sqlite3_errmsg(_db));
- if ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED)) {
+ if ((_errId == SQLITE_BUSY) || (_errId == SQLITE_LOCKED)) {
std::this_thread::sleep_for(SQLITE_SLEEP_TIME);
continue;
}
}
break;
}
- _errId = rc;
if (_errId != SQLITE_OK) {
_error = QString::fromUtf8(sqlite3_errmsg(_db));
@@ -296,6 +293,13 @@ int SqlQuery::prepare(const QByteArray &sql, bool allow_failure)
} else {
OC_ASSERT(_stmt);
_sqldb->_queries.insert(this);
+
+ if (lcSql().isDebugEnabled()) {
+ _boundValues.resize(sqlite3_bind_parameter_count(_stmt));
+ for (int i = 1; i <= _boundValues.size(); ++i) {
+ _boundValues[i - 1].name = QString::fromUtf8(sqlite3_bind_parameter_name(_stmt, i));
+ }
+ }
}
}
return _errId;
@@ -328,20 +332,32 @@ bool SqlQuery::exec()
}
// Don't do anything for selects, that is how we use the lib :-|
if (!isSelect() && !isPragma()) {
- int rc = 0;
for (int n = 0; n < SQLITE_REPEAT_COUNT; ++n) {
- qCDebug(lcSql) << "SQL exec" << _boundQuery << "Try:" << n;
- rc = sqlite3_step(_stmt);
- if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
+ if (lcSql().isDebugEnabled()) {
+ if (!_boundValues.isEmpty()) {
+ // Try to create a pretty printed version of the sql query
+ // the result can be inaccurate
+ QString query = QString::fromUtf8(_sql);
+ for (const auto &v : _boundValues) {
+ query.replace(query.indexOf(v.name), v.name.size(), v.value);
+ }
+ char *actualQuery = sqlite3_expanded_sql(_stmt);
+ qCDebug(lcSql) << "SQL exec: Estimated query:" << query << "Actual query:" << QString::fromUtf8(actualQuery) << "Try:" << n;
+ sqlite3_free(actualQuery);
+ } else {
+ qCDebug(lcSql) << "SQL exec:" << _sql << "Try:" << n;
+ }
+ }
+ _errId = sqlite3_step(_stmt);
+ if (_errId != SQLITE_DONE && _errId != SQLITE_ROW) {
qCWarning(lcSql) << "SQL exec failed" << _sql << QString::fromUtf8(sqlite3_errmsg(_db));
- if (rc == SQLITE_LOCKED || rc == SQLITE_BUSY) {
+ if (_errId == SQLITE_LOCKED || _errId == SQLITE_BUSY) {
std::this_thread::sleep_for(SQLITE_SLEEP_TIME);
continue;
}
}
break;
}
- _errId = rc;
if (_errId != SQLITE_DONE && _errId != SQLITE_ROW) {
_error = QString::fromUtf8(sqlite3_errmsg(_db));
@@ -512,7 +528,6 @@ void SqlQuery::reset_and_clear_bindings()
if (_stmt) {
SQLITE_DO(sqlite3_reset(_stmt));
SQLITE_DO(sqlite3_clear_bindings(_stmt));
- _boundQuery = QString::fromUtf8(_sql);
}
}
diff --git a/src/common/ownsql.h b/src/common/ownsql.h
index 13c4f17b8..0f6963c53 100644
--- a/src/common/ownsql.h
+++ b/src/common/ownsql.h
@@ -136,10 +136,15 @@ public:
template <class T>
void bindValue(int pos, const T &value)
{
- QString s;
- QDebug(&s).noquote().nospace() << '\'' << value << '\'';
- _boundQuery.replace(QStringLiteral("?%1").arg(QString::number(pos)), s);
- bindValueConvert(pos, value);
+ const auto converted = convertValue(value);
+ if (lcSql().isDebugEnabled()) {
+ auto stream = QDebug(&_boundValues[pos - 1].value).noquote().nospace() << '\'' << value;
+ if (typeid(converted) != typeid(value)) {
+ stream << " [" << converted << ']';
+ }
+ stream << '\'';
+ }
+ bindValueInternal(pos, converted);
}
const QByteArray &lastQuery() const;
@@ -148,15 +153,15 @@ public:
private:
template <class T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
- void bindValueConvert(int pos, const T &value)
+ auto convertValue(const T &value)
{
- bindValueInternal(pos, static_cast<int>(value));
+ return static_cast<int>(value);
}
template <class T, typename std::enable_if<!std::is_enum<T>::value, int>::type = 0>
- void bindValueConvert(int pos, const T &value)
+ auto convertValue(const T &value)
{
- bindValueInternal(pos, value);
+ return value;
}
void bindValueInternal(int pos, const QVariant &value);
@@ -168,7 +173,12 @@ private:
QString _error;
int _errId;
QByteArray _sql;
- QString _boundQuery;
+ struct Binding
+ {
+ QString name;
+ QString value;
+ };
+ QVector<Binding> _boundValues;
friend class SqlDatabase;
friend class PreparedSqlQueryManager;