Always reset prepared sql statements

This allow the creation of checkpoints and fixes the growing wal issue

Fixes: #7646
This commit is contained in:
Hannah von Reth 2021-01-15 16:31:57 +01:00 committed by Matthieu Gallien (Rebase PR Action)
parent 6e0a43b570
commit 3b99b11849
4 changed files with 448 additions and 370 deletions

View file

@ -490,18 +490,28 @@ void SqlQuery::reset_and_clear_bindings()
}
}
bool SqlQuery::initOrReset(const QByteArray &sql, OCC::SqlDatabase &db)
PreparedSqlQueryRAII::PreparedSqlQueryRAII(SqlQuery *query)
: _query(query)
{
ENFORCE(!_sqldb || &db == _sqldb);
_sqldb = &db;
_db = db.sqliteDb();
if (_stmt) {
reset_and_clear_bindings();
return true;
} else {
return prepare(sql) == 0;
Q_ASSERT(!sqlite3_stmt_busy(_query->_stmt));
}
PreparedSqlQueryRAII::PreparedSqlQueryRAII(SqlQuery *query, const QByteArray &sql, SqlDatabase &db)
: _query(query)
{
Q_ASSERT(!sqlite3_stmt_busy(_query->_stmt));
ENFORCE(!query->_sqldb || &db == query->_sqldb)
query->_sqldb = &db;
query->_db = db.sqliteDb();
if (!query->_stmt) {
_ok = query->prepare(sql) == 0;
}
}
PreparedSqlQueryRAII::~PreparedSqlQueryRAII()
{
_query->reset_and_clear_bindings();
}
} // namespace OCC

View file

@ -103,12 +103,6 @@ public:
explicit SqlQuery() = default;
explicit SqlQuery(SqlDatabase &db);
explicit SqlQuery(const QByteArray &sql, SqlDatabase &db);
/**
* Prepare the SqlQuery if it was not prepared yet.
* Otherwise, clear the results and the bindings.
* return false if there is an error
*/
bool initOrReset(const QByteArray &sql, SqlDatabase &db);
/**
* Prepare the SqlQuery.
* If the query was already prepared, this will first call finish(), and re-prepare it.
@ -174,8 +168,42 @@ private:
QByteArray _sql;
friend class SqlDatabase;
friend class PreparedSqlQueryRAII;
};
class OCSYNC_EXPORT PreparedSqlQueryRAII
{
public:
/**
* Simple Guard which allow reuse of prepared querys.
* The queries are reset in the destructor to prevent wal locks
*/
PreparedSqlQueryRAII(SqlQuery *query);
/**
* Prepare the SqlQuery if it was not prepared yet.
*/
PreparedSqlQueryRAII(SqlQuery *query, const QByteArray &sql, SqlDatabase &db);
~PreparedSqlQueryRAII();
explicit operator bool() const { return _ok; }
SqlQuery *operator->() const
{
Q_ASSERT(_ok);
return _query;
}
SqlQuery &operator*() const &
{
Q_ASSERT(_ok);
return *_query;
}
private:
SqlQuery *const _query;
bool _ok = true;
Q_DISABLE_COPY(PreparedSqlQueryRAII);
};
} // namespace OCC
#endif // OWNSQL_H

File diff suppressed because it is too large Load diff

View file

@ -137,7 +137,7 @@ private slots:
SqlQuery q3("SELECT * FROM addresses", _db);
SqlQuery q4;
SqlQuery q5;
q5.initOrReset("SELECT * FROM addresses", _db);
PreparedSqlQueryRAII testQuery(&q5, "SELECT * FROM addresses", _db);
db.reset();
}