forked from qt-creator/qt-creator
Sqlite: Improve ownership
Using the compile option instead of a function pointer makes the code less brittle. Change-Id: Id7f3b42c044d47f13e099f50c5bb33b72c05cde1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -27,17 +27,11 @@ extern "C" int sqlite3_carray_bind(
|
|||||||
namespace Sqlite {
|
namespace Sqlite {
|
||||||
|
|
||||||
BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database)
|
BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database)
|
||||||
: m_compiledStatement(nullptr, deleteCompiledStatement)
|
: m_database(database)
|
||||||
, m_database(database)
|
|
||||||
{
|
{
|
||||||
prepare(sqlStatement);
|
prepare(sqlStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseStatement::deleteCompiledStatement(sqlite3_stmt *compiledStatement)
|
|
||||||
{
|
|
||||||
sqlite3_finalize(compiledStatement);
|
|
||||||
}
|
|
||||||
|
|
||||||
class UnlockNotification
|
class UnlockNotification
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -485,4 +479,9 @@ ValueView BaseStatement::fetchValueView(int column) const
|
|||||||
return ValueView::create(NullValue{});
|
return ValueView::create(NullValue{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseStatement::Deleter::operator()(sqlite3_stmt *statement)
|
||||||
|
{
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Sqlite
|
} // namespace Sqlite
|
||||||
|
@@ -50,8 +50,6 @@ public:
|
|||||||
BaseStatement(const BaseStatement &) = delete;
|
BaseStatement(const BaseStatement &) = delete;
|
||||||
BaseStatement &operator=(const BaseStatement &) = delete;
|
BaseStatement &operator=(const BaseStatement &) = delete;
|
||||||
|
|
||||||
static void deleteCompiledStatement(sqlite3_stmt *m_compiledStatement);
|
|
||||||
|
|
||||||
bool next() const;
|
bool next() const;
|
||||||
void step() const;
|
void step() const;
|
||||||
void reset() const noexcept;
|
void reset() const noexcept;
|
||||||
@@ -123,7 +121,13 @@ protected:
|
|||||||
~BaseStatement() = default;
|
~BaseStatement() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt *)> m_compiledStatement;
|
struct Deleter
|
||||||
|
{
|
||||||
|
SQLITE_EXPORT void operator()(sqlite3_stmt *statement);
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<sqlite3_stmt, Deleter> m_compiledStatement;
|
||||||
Database &m_database;
|
Database &m_database;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -90,14 +90,16 @@ void DatabaseBackend::open(Utils::SmallStringView databaseFilePath,
|
|||||||
{
|
{
|
||||||
checkCanOpenDatabase(databaseFilePath);
|
checkCanOpenDatabase(databaseFilePath);
|
||||||
|
|
||||||
|
sqlite3 *handle = m_databaseHandle.get();
|
||||||
int resultCode = sqlite3_open_v2(std::string(databaseFilePath).c_str(),
|
int resultCode = sqlite3_open_v2(std::string(databaseFilePath).c_str(),
|
||||||
&m_databaseHandle,
|
&handle,
|
||||||
createOpenFlags(openMode, journalMode),
|
createOpenFlags(openMode, journalMode),
|
||||||
nullptr);
|
nullptr);
|
||||||
|
m_databaseHandle.reset(handle);
|
||||||
|
|
||||||
checkDatabaseCouldBeOpened(resultCode);
|
checkDatabaseCouldBeOpened(resultCode);
|
||||||
|
|
||||||
resultCode = sqlite3_carray_init(m_databaseHandle, nullptr, nullptr);
|
resultCode = sqlite3_carray_init(m_databaseHandle.get(), nullptr, nullptr);
|
||||||
|
|
||||||
checkCarrayCannotBeIntialized(resultCode);
|
checkCarrayCannotBeIntialized(resultCode);
|
||||||
}
|
}
|
||||||
@@ -105,7 +107,7 @@ void DatabaseBackend::open(Utils::SmallStringView databaseFilePath,
|
|||||||
sqlite3 *DatabaseBackend::sqliteDatabaseHandle() const
|
sqlite3 *DatabaseBackend::sqliteDatabaseHandle() const
|
||||||
{
|
{
|
||||||
checkDatabaseHandleIsNotNull();
|
checkDatabaseHandleIsNotNull();
|
||||||
return m_databaseHandle;
|
return m_databaseHandle.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseBackend::setPragmaValue(Utils::SmallStringView pragmaKey, Utils::SmallStringView newPragmaValue)
|
void DatabaseBackend::setPragmaValue(Utils::SmallStringView pragmaKey, Utils::SmallStringView newPragmaValue)
|
||||||
@@ -216,12 +218,11 @@ void DatabaseBackend::close()
|
|||||||
{
|
{
|
||||||
checkForOpenDatabaseWhichCanBeClosed();
|
checkForOpenDatabaseWhichCanBeClosed();
|
||||||
|
|
||||||
int resultCode = sqlite3_close(m_databaseHandle);
|
int resultCode = sqlite3_close(m_databaseHandle.get());
|
||||||
|
|
||||||
checkDatabaseClosing(resultCode);
|
checkDatabaseClosing(resultCode);
|
||||||
|
|
||||||
m_databaseHandle = nullptr;
|
m_databaseHandle.release();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseBackend::databaseIsOpen() const
|
bool DatabaseBackend::databaseIsOpen() const
|
||||||
@@ -231,12 +232,7 @@ bool DatabaseBackend::databaseIsOpen() const
|
|||||||
|
|
||||||
void DatabaseBackend::closeWithoutException()
|
void DatabaseBackend::closeWithoutException()
|
||||||
{
|
{
|
||||||
if (m_databaseHandle) {
|
m_databaseHandle.reset();
|
||||||
int resultCode = sqlite3_close_v2(m_databaseHandle);
|
|
||||||
m_databaseHandle = nullptr;
|
|
||||||
if (resultCode != SQLITE_OK)
|
|
||||||
qWarning() << "SqliteDatabaseBackend::closeWithoutException: Unexpected error at closing the database!";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -414,12 +410,12 @@ int DatabaseBackend::createOpenFlags(OpenMode openMode, JournalMode journalMode)
|
|||||||
|
|
||||||
void DatabaseBackend::setBusyTimeout(std::chrono::milliseconds timeout)
|
void DatabaseBackend::setBusyTimeout(std::chrono::milliseconds timeout)
|
||||||
{
|
{
|
||||||
sqlite3_busy_timeout(m_databaseHandle, int(timeout.count()));
|
sqlite3_busy_timeout(m_databaseHandle.get(), int(timeout.count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseBackend::walCheckpointFull()
|
void DatabaseBackend::walCheckpointFull()
|
||||||
{
|
{
|
||||||
int resultCode = sqlite3_wal_checkpoint_v2(m_databaseHandle,
|
int resultCode = sqlite3_wal_checkpoint_v2(m_databaseHandle.get(),
|
||||||
nullptr,
|
nullptr,
|
||||||
SQLITE_CHECKPOINT_TRUNCATE,
|
SQLITE_CHECKPOINT_TRUNCATE,
|
||||||
nullptr,
|
nullptr,
|
||||||
@@ -433,12 +429,12 @@ void DatabaseBackend::setUpdateHook(
|
|||||||
void *object,
|
void *object,
|
||||||
void (*callback)(void *object, int, char const *database, char const *, long long rowId))
|
void (*callback)(void *object, int, char const *database, char const *, long long rowId))
|
||||||
{
|
{
|
||||||
sqlite3_update_hook(m_databaseHandle, callback, object);
|
sqlite3_update_hook(m_databaseHandle.get(), callback, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseBackend::resetUpdateHook()
|
void DatabaseBackend::resetUpdateHook()
|
||||||
{
|
{
|
||||||
sqlite3_update_hook(m_databaseHandle, nullptr, nullptr);
|
sqlite3_update_hook(m_databaseHandle.get(), nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseBackend::setBusyHandler(DatabaseBackend::BusyHandler &&busyHandler)
|
void DatabaseBackend::setBusyHandler(DatabaseBackend::BusyHandler &&busyHandler)
|
||||||
@@ -491,4 +487,14 @@ Type DatabaseBackend::toValue(Utils::SmallStringView sqlStatement) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseBackend::Deleter::operator()(sqlite3 *database)
|
||||||
|
{
|
||||||
|
if (database) {
|
||||||
|
int resultCode = sqlite3_close_v2(database);
|
||||||
|
if (resultCode != SQLITE_OK)
|
||||||
|
qWarning() << "SqliteDatabaseBackend::closeWithoutException: Unexpected error at "
|
||||||
|
"closing the database!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Sqlite
|
} // namespace Sqlite
|
||||||
|
@@ -108,9 +108,15 @@ protected:
|
|||||||
static Utils::SmallStringView journalModeToPragma(JournalMode journalMode);
|
static Utils::SmallStringView journalModeToPragma(JournalMode journalMode);
|
||||||
static JournalMode pragmaToJournalMode(Utils::SmallStringView pragma);
|
static JournalMode pragmaToJournalMode(Utils::SmallStringView pragma);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Deleter
|
||||||
|
{
|
||||||
|
SQLITE_EXPORT void operator()(sqlite3 *database);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Database &m_database;
|
Database &m_database;
|
||||||
sqlite3 *m_databaseHandle;
|
std::unique_ptr<sqlite3, Deleter> m_databaseHandle;
|
||||||
BusyHandler m_busyHandler;
|
BusyHandler m_busyHandler;
|
||||||
ProgressHandler m_progressHandler;
|
ProgressHandler m_progressHandler;
|
||||||
};
|
};
|
||||||
|
@@ -173,4 +173,9 @@ SessionChangeSets Sessions::changeSets() const
|
|||||||
return selectChangeSets.values<SessionChangeSet>(1024);
|
return selectChangeSets.values<SessionChangeSet>(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sessions::Deleter::operator()(sqlite3_session *session)
|
||||||
|
{
|
||||||
|
sqlite3session_delete(session);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Sqlite
|
} // namespace Sqlite
|
||||||
|
@@ -8,10 +8,6 @@
|
|||||||
#include "sqlitesessionchangeset.h"
|
#include "sqlitesessionchangeset.h"
|
||||||
#include "sqlitewritestatement.h"
|
#include "sqlitewritestatement.h"
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
void sqlite3session_delete(sqlite3_session *pSession);
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Sqlite {
|
namespace Sqlite {
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -44,7 +40,6 @@ public:
|
|||||||
{"INSERT INTO ", sessionsTableName, "(changeset) VALUES(?)"}),
|
{"INSERT INTO ", sessionsTableName, "(changeset) VALUES(?)"}),
|
||||||
database}
|
database}
|
||||||
, databaseName(databaseName)
|
, databaseName(databaseName)
|
||||||
, session{nullptr, sqlite3session_delete}
|
|
||||||
{}
|
{}
|
||||||
~Sessions();
|
~Sessions();
|
||||||
|
|
||||||
@@ -64,12 +59,17 @@ public:
|
|||||||
private:
|
private:
|
||||||
void attachTables(const Utils::SmallStringVector &tables);
|
void attachTables(const Utils::SmallStringVector &tables);
|
||||||
|
|
||||||
|
struct Deleter
|
||||||
|
{
|
||||||
|
SQLITE_EXPORT void operator()(sqlite3_session *statement);
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Database &database;
|
Database &database;
|
||||||
WriteStatement<1> insertSession;
|
WriteStatement<1> insertSession;
|
||||||
Utils::SmallString databaseName;
|
Utils::SmallString databaseName;
|
||||||
Utils::SmallStringVector tableNames;
|
Utils::SmallStringVector tableNames;
|
||||||
std::unique_ptr<sqlite3_session, decltype(&sqlite3session_delete)> session;
|
std::unique_ptr<sqlite3_session, Deleter> session;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Sqlite
|
} // namespace Sqlite
|
||||||
|
Reference in New Issue
Block a user