From 7eeccbb033ed2899dd1b8e3c03de8937629fc9e3 Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Mon, 23 Dec 2024 20:54:04 +0100 Subject: [PATCH] =?UTF-8?q?Use=20database=20=E2=80=9Cadvanced=20options?= =?UTF-8?q?=E2=80=9D=20and=20persist=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/LoginPage.qml | 38 +++++++++++++++++++++++++++++------ src/Main.qml | 1 + src/database.cpp | 51 ++++++++++++++++++++++++++++++++--------------- src/database.h | 8 +++++++- 4 files changed, 75 insertions(+), 23 deletions(-) diff --git a/src/LoginPage.qml b/src/LoginPage.qml index e40876a..57658ff 100644 --- a/src/LoginPage.qml +++ b/src/LoginPage.qml @@ -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()); } } } diff --git a/src/Main.qml b/src/Main.qml index 8e131ac..e3ea3e5 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -55,6 +55,7 @@ ApplicationWindow { } function onOpened() { + (pageStack.currentItem as LoginPage)?.saveSettings(); pageStack.replace(reservationsPage); } diff --git a/src/database.cpp b/src/database.cpp index 537553b..7a0b1db 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -1,6 +1,7 @@ #include "database.h" #include #include +#include #include Database::Database(QObject *parent) @@ -11,24 +12,42 @@ Database::Database(QObject *parent) m_pool.setExpiryTimeout(-1); } -QFuture Database::open(const QString &user, const QString &password) +QFuture 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 Database::close() diff --git a/src/database.h b/src/database.h index 084acd6..59d4289 100644 --- a/src/database.h +++ b/src/database.h @@ -15,7 +15,13 @@ class Database : public QObject public: explicit Database(QObject *parent = nullptr); - Q_INVOKABLE QFuture open(const QString &user, const QString &password); + Q_INVOKABLE QFuture open(const QString &user, + const QString &password, + const QString &hostName, + bool usePort, + int portNumber, + const QString &databaseName, + const QString &connectOptions); Q_INVOKABLE QFuture close(); signals: