Use database “advanced options” and persist them

I only want to store these options if the connection to the database is
established, to avoid saving incorrect values by error. I, then, did not
use property alias, as the documentation reccomends, and instead have a
function to save the parameters when the application sees the database
open.

I have to use the function because a Connections inside LoginPage gets
called _after_ the Connections in Main, meaning that i would get deleted
before it has the chance to save the settings.

Now i can’t assume connect options will include search_path, as it is
unreasonable to request people to know the internal schemas of the
application.
This commit is contained in:
jordi fita mas 2024-12-23 20:54:04 +01:00
parent dd2beba676
commit 7eeccbb033
4 changed files with 75 additions and 23 deletions

View File

@ -1,4 +1,5 @@
pragma ComponentBehavior: Bound
import QtCore
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
@ -6,6 +7,14 @@ import QtQuick.Layouts
Page {
id: page
function saveSettings() {
settings.connectOptions = connectOptions.text;
settings.databaseName = databaseName.text;
settings.hostName = hostName.text;
settings.port = port.value;
settings.usePort = usePort.checked;
}
title: qsTr("Login")
ColumnLayout {
@ -63,33 +72,36 @@ Page {
id: hostName
Layout.fillWidth: true
text: settings.hostName
onAccepted: loginAction.trigger()
}
CheckBox {
id: port
id: usePort
Layout.alignment: Qt.AlignRight
Mnemonic.label: qsTr("Por&t:")
checked: settings.usePort
text: Mnemonic.richTextLabel
Shortcut {
sequence: port.Mnemonic.sequence
sequence: usePort.Mnemonic.sequence
onActivated: port.click()
onActivated: usePort.click()
}
}
SpinBox {
id: portNumber
id: port
Accessible.name: qsTr("Port number")
Layout.fillWidth: true
editable: true
enabled: port.checked
enabled: usePort.checked
from: 1
to: 65535
value: settings.port
}
MnemonicLabel {
@ -102,6 +114,7 @@ Page {
id: databaseName
Layout.fillWidth: true
text: settings.databaseName
onAccepted: loginAction.trigger()
}
@ -116,6 +129,7 @@ Page {
id: connectOptions
Layout.fillWidth: true
text: settings.connectOptions
onAccepted: loginAction.trigger()
}
@ -128,13 +142,25 @@ Page {
}
}
Settings {
id: settings
property string connectOptions: ""
property string databaseName: ""
property string hostName: ""
property int port: 5432
property bool usePort: false
category: "database"
}
MnemonicAction {
id: loginAction
mnemonic: qsTr("Log &in")
onTriggered: function () {
Database.open(user.text, password.text);
Database.open(user.text.trim(), password.text.trim(), hostName.text.trim(), usePort.checked, port.value, databaseName.text.trim(), connectOptions.text.trim());
}
}
}

View File

@ -55,6 +55,7 @@ ApplicationWindow {
}
function onOpened() {
(pageStack.currentItem as LoginPage)?.saveSettings();
pageStack.replace(reservationsPage);
}

View File

@ -1,6 +1,7 @@
#include "database.h"
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QtConcurrent>
Database::Database(QObject *parent)
@ -11,24 +12,42 @@ Database::Database(QObject *parent)
m_pool.setExpiryTimeout(-1);
}
QFuture<void> Database::open(const QString &user, const QString &password)
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]() {
QString errorMessage;
QString connectionName;
{
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setConnectOptions("service=camper; options=-csearch_path=camper,public");
if (db.open(user, password)) {
emit opened();
return;
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();
}
errorMessage = db.lastError().text();
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
emit errorOcurred(errorMessage);
});
QSqlDatabase::removeDatabase(connectionName);
emit errorOcurred(errorMessage);
});
}
QFuture<void> Database::close()

View File

@ -15,7 +15,13 @@ class Database : public QObject
public:
explicit Database(QObject *parent = nullptr);
Q_INVOKABLE QFuture<void> open(const QString &user, const QString &password);
Q_INVOKABLE QFuture<void> open(const QString &user,
const QString &password,
const QString &hostName,
bool usePort,
int portNumber,
const QString &databaseName,
const QString &connectOptions);
Q_INVOKABLE QFuture<void> close();
signals: