camper/src/database.cpp

104 lines
2.9 KiB
C++

#include "database.h"
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
Database::Database(QObject *parent)
: QObject{parent}
, m_pool{}
{
m_pool.setMaxThreadCount(1);
m_pool.setExpiryTimeout(-1);
}
Database &Database::getInstance()
{
static Database instance;
return instance;
}
Database *Database::create(QQmlEngine *qmlEngine, QJSEngine *)
{
Database &instance = getInstance();
Q_ASSERT(qmlEngine->thread() == instance.thread());
static QQmlEngine *engine = nullptr;
if (engine) {
Q_ASSERT(qmlEngine == engine);
} else {
engine = qmlEngine;
}
QJSEngine::setObjectOwnership(&instance, QJSEngine::CppOwnership);
return &instance;
}
QFuture<void> Database::open(const QString &user,
const QString &password,
const QString &hostName,
bool usePort,
int portNumber,
const QString &databaseName,
const QString &connectOptions)
{
return QtConcurrent::run(
&m_pool,
[this, user, password, hostName, usePort, portNumber, databaseName, connectOptions]() {
QString errorMessage;
QString connectionName;
{
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName(hostName);
if (usePort) {
db.setPort(portNumber);
}
db.setDatabaseName(databaseName);
db.setConnectOptions(connectOptions);
if (db.open(user, password)) {
QSqlQuery q(db);
if (q.exec("SET search_path TO camper, public")) {
emit opened();
return;
}
errorMessage = q.lastError().text();
} else {
errorMessage = db.lastError().text();
}
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
emit errorOcurred(errorMessage);
});
}
QFuture<void> Database::close()
{
return QtConcurrent::run(&m_pool, [this]() {
QString connectionName;
{
QSqlDatabase db = QSqlDatabase::database();
if (!db.isValid()) {
return;
}
connectionName = db.connectionName();
db.close();
}
QSqlDatabase::removeDatabase(connectionName);
emit closed();
});
}
void Database::checkError(const QSqlQuery &query)
{
QSqlError lastError = query.lastError();
if (!lastError.isValid()) {
return;
}
QString errorMessage = lastError.text();
emit getInstance().errorOcurred(errorMessage);
throw std::runtime_error(errorMessage.toStdString());
}
#include "moc_database.cpp"