forked from qt-creator/qt-creator
Sqlite: Add exception if statement is called outside of a lock
Sometimes it is really hard to trace if sqlite statement is called outside of a database connection lock. So we know throw an exception in the unit test. So we get failing tests. Change-Id: I71485b9473075751a2fb771ce7e2954e28d8413e Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -195,23 +195,6 @@ public:
|
||||
resetter.reset();
|
||||
}
|
||||
|
||||
template<typename ResultType>
|
||||
std::vector<ResultType> values(std::size_t reserveSize)
|
||||
{
|
||||
Resetter resetter{this};
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(std::max(reserveSize, m_maximumResultCount));
|
||||
|
||||
while (BaseStatement::next())
|
||||
emplaceBackValues(resultValues);
|
||||
|
||||
setMaximumResultCount(resultValues.size());
|
||||
|
||||
resetter.reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template<typename ResultType, typename... QueryTypes>
|
||||
auto values(std::size_t reserveSize, const QueryTypes &...queryValues)
|
||||
{
|
||||
@@ -438,7 +421,10 @@ private:
|
||||
{
|
||||
Resetter(StatementImplementation *statement)
|
||||
: statement(statement)
|
||||
{}
|
||||
{
|
||||
if (statement && !statement->database().isLocked())
|
||||
throw DatabaseIsNotLocked{"Database connection is not locked!"};
|
||||
}
|
||||
|
||||
Resetter(Resetter &) = delete;
|
||||
Resetter &operator=(Resetter &) = delete;
|
||||
|
||||
@@ -70,6 +70,8 @@ Database::Database(Utils::PathString &&databaseFilePath,
|
||||
: m_databaseBackend(*this)
|
||||
, m_busyTimeout(busyTimeout)
|
||||
{
|
||||
std::lock_guard lock{*this};
|
||||
|
||||
setJournalMode(journalMode);
|
||||
open(std::move(databaseFilePath));
|
||||
|
||||
@@ -94,7 +96,6 @@ void Database::open()
|
||||
else
|
||||
m_databaseBackend.registerBusyHandler();
|
||||
registerTransactionStatements();
|
||||
initializeTables();
|
||||
m_isOpen = true;
|
||||
}
|
||||
|
||||
@@ -127,18 +128,6 @@ bool Database::isOpen() const
|
||||
return m_isOpen;
|
||||
}
|
||||
|
||||
Table &Database::addTable()
|
||||
{
|
||||
m_sqliteTables.emplace_back();
|
||||
|
||||
return m_sqliteTables.back();
|
||||
}
|
||||
|
||||
const std::vector<Table> &Database::tables() const
|
||||
{
|
||||
return m_sqliteTables;
|
||||
}
|
||||
|
||||
void Database::setDatabaseFilePath(Utils::PathString &&databaseFilePath)
|
||||
{
|
||||
m_databaseFilePath = std::move(databaseFilePath);
|
||||
@@ -189,20 +178,6 @@ void Database::execute(Utils::SmallStringView sqlStatement)
|
||||
m_databaseBackend.execute(sqlStatement);
|
||||
}
|
||||
|
||||
void Database::initializeTables()
|
||||
{
|
||||
try {
|
||||
ExclusiveTransaction transaction(*this);
|
||||
|
||||
for (Table &table : m_sqliteTables)
|
||||
table.initialize(*this);
|
||||
|
||||
transaction.commit();
|
||||
} catch (const StatementIsBusy &) {
|
||||
initializeTables();
|
||||
}
|
||||
}
|
||||
|
||||
void Database::registerTransactionStatements()
|
||||
{
|
||||
m_statements = std::make_unique<Statements>(*this);
|
||||
@@ -257,9 +232,16 @@ void Database::sessionRollback()
|
||||
void Database::lock()
|
||||
{
|
||||
m_databaseMutex.lock();
|
||||
#ifdef UNIT_TESTS
|
||||
m_isLocked = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Database::unlock()
|
||||
{
|
||||
#ifdef UNIT_TESTS
|
||||
m_isLocked = false;
|
||||
#endif
|
||||
m_databaseMutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -87,9 +87,6 @@ public:
|
||||
|
||||
bool isOpen() const;
|
||||
|
||||
Table &addTable();
|
||||
const std::vector<Table> &tables() const;
|
||||
|
||||
void setDatabaseFilePath(Utils::PathString &&databaseFilePath);
|
||||
const Utils::PathString &databaseFilePath() const;
|
||||
|
||||
@@ -148,14 +145,23 @@ public:
|
||||
|
||||
SessionChangeSets changeSets() const;
|
||||
|
||||
bool isLocked() const
|
||||
{
|
||||
#ifdef UNIT_TESTS
|
||||
return m_isLocked;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
void lock() override;
|
||||
void unlock() override;
|
||||
|
||||
private:
|
||||
void deferredBegin() override;
|
||||
void immediateBegin() override;
|
||||
void exclusiveBegin() override;
|
||||
void commit() override;
|
||||
void rollback() override;
|
||||
void lock() override;
|
||||
void unlock() override;
|
||||
void immediateSessionBegin() override;
|
||||
void sessionCommit() override;
|
||||
void sessionRollback() override;
|
||||
@@ -170,7 +176,6 @@ private:
|
||||
private:
|
||||
Utils::PathString m_databaseFilePath;
|
||||
DatabaseBackend m_databaseBackend;
|
||||
std::vector<Table> m_sqliteTables;
|
||||
std::mutex m_databaseMutex;
|
||||
std::unique_ptr<Statements> m_statements;
|
||||
std::chrono::milliseconds m_busyTimeout;
|
||||
@@ -178,6 +183,7 @@ private:
|
||||
OpenMode m_openMode = OpenMode::ReadWrite;
|
||||
bool m_isOpen = false;
|
||||
bool m_isInitialized = false;
|
||||
bool m_isLocked = false;
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "sqlitedatabasebackend.h"
|
||||
|
||||
#include "sqlitebasestatement.h"
|
||||
#include "sqlitedatabase.h"
|
||||
#include "sqliteexception.h"
|
||||
#include "sqlitereadstatement.h"
|
||||
#include "sqlitereadwritestatement.h"
|
||||
|
||||
@@ -410,4 +410,12 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
class DatabaseIsNotLocked : public Exception
|
||||
{
|
||||
public:
|
||||
DatabaseIsNotLocked(const char *whatErrorHasHappen)
|
||||
: Exception(whatErrorHasHappen)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
||||
Reference in New Issue
Block a user