Store connection configuration as key value pairs
Add migration for the sqlite database. Because the Qt SQL library is a bit hard to work with use sqlite through custom wrapper.
This commit is contained in:
parent
4caccf1000
commit
aac55b0ed1
17 changed files with 276439 additions and 384 deletions
|
|
@ -2,11 +2,10 @@
|
|||
#include "MasterController.h"
|
||||
#include "ConnectionManagerWindow.h"
|
||||
#include "ConnectionListModel.h"
|
||||
#include "PasswordManager.h"
|
||||
#include "utils/PasswordManager.h"
|
||||
#include "DatabaseWindow.h"
|
||||
#include "BackupDialog.h"
|
||||
#include "PasswordPromptDialog.h"
|
||||
#include "ScopeGuard.h"
|
||||
#include "ConnectionConfigurationWidget.h"
|
||||
#include <QSqlQuery>
|
||||
#include <QInputDialog>
|
||||
|
|
@ -133,11 +132,14 @@ void ConnectionController::addGroup()
|
|||
auto result = QInputDialog::getText(nullptr, tr("Add new connection group"),
|
||||
tr("Group name"));
|
||||
if (!result.isEmpty()) {
|
||||
auto res = m_connectionTreeModel->addGroup(result);
|
||||
if (std::holds_alternative<QSqlError>(res)) {
|
||||
try
|
||||
{
|
||||
m_connectionTreeModel->addGroup(result);
|
||||
}
|
||||
catch (const SQLiteException &ex) {
|
||||
QMessageBox::critical(nullptr, tr("Add group failed"),
|
||||
tr("Failed to add group.\n") +
|
||||
std::get<QSqlError>(res).text());
|
||||
QString(ex.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -236,19 +238,11 @@ bool ConnectionController::decodeConnectionPassword(QUuid id, QByteArray encoded
|
|||
|
||||
void ConnectionController::resetPasswordManager()
|
||||
{
|
||||
auto&& user_cfg_db = m_masterController->userConfigDatabase();
|
||||
user_cfg_db.transaction();
|
||||
try
|
||||
{
|
||||
m_passwordManager->resetMasterPassword(user_cfg_db);
|
||||
m_connectionTreeModel->clearAllPasswords();
|
||||
user_cfg_db.commit();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
user_cfg_db.rollback();
|
||||
throw;
|
||||
}
|
||||
SQLiteConnection& user_cfg_db = m_masterController->userConfigDatabase();
|
||||
SQLiteTransaction tx(user_cfg_db);
|
||||
m_passwordManager->resetMasterPassword(user_cfg_db);
|
||||
m_connectionTreeModel->clearAllPasswords();
|
||||
tx.Commit();
|
||||
}
|
||||
|
||||
bool ConnectionController::UnlockPasswordManagerIfNeeded()
|
||||
|
|
|
|||
|
|
@ -56,19 +56,12 @@ SELECT migration_id
|
|||
FROM _migration;)__";
|
||||
|
||||
|
||||
const char * const q_insert_or_replace_into_connection =
|
||||
R"__(INSERT OR REPLACE INTO connection
|
||||
VALUES (:uuid, :name, :conngroup_id, :host, :hostaddr, :port, :user, :dbname,
|
||||
:sslmode, :sslcert, :sslkey, :sslrootcert, :sslcrl, :password);
|
||||
)__" ;
|
||||
|
||||
|
||||
// Keeping migration function name and id DRY
|
||||
#define APPLY_MIGRATION(id) ApplyMigration(#id, &MigrationDirector::id)
|
||||
|
||||
class MigrationDirector {
|
||||
public:
|
||||
explicit MigrationDirector(QSqlDatabase &db)
|
||||
explicit MigrationDirector(SQLiteConnection &db)
|
||||
: db(db)
|
||||
{
|
||||
}
|
||||
|
|
@ -81,12 +74,12 @@ R"__(INSERT OR REPLACE INTO connection
|
|||
}
|
||||
|
||||
private:
|
||||
QSqlDatabase &db;
|
||||
SQLiteConnection &db;
|
||||
std::unordered_set<QString> present;
|
||||
|
||||
void M20250215_0933_Parameters()
|
||||
{
|
||||
Exec(R"__(
|
||||
db.Exec(R"__(
|
||||
CREATE TABLE connection_parameter (
|
||||
connection_uuid TEXT,
|
||||
pname TEXT,
|
||||
|
|
@ -95,16 +88,29 @@ CREATE TABLE connection_parameter (
|
|||
PRIMARY KEY(connection_uuid, pname)
|
||||
);)__");
|
||||
|
||||
db.Exec(R"__(
|
||||
INSERT INTO connection_parameter (connection_uuid, pname, pvalue)
|
||||
SELECT uuid, 'sslmode' AS pname, CASE
|
||||
WHEN sslmode = '0' THEN 'disable'
|
||||
WHEN sslmode = '1' THEN 'allow'
|
||||
WHEN sslmode = '2' THEN 'prefer'
|
||||
WHEN sslmode = '3' THEN 'require'
|
||||
WHEN sslmode = '4' THEN 'verify_ca'
|
||||
WHEN sslmode = '5' THEN 'verify_full'
|
||||
END AS pvalue
|
||||
FROM connection
|
||||
WHERE sslmode is not null and sslmode between 0 and 5)__");
|
||||
|
||||
for (QString key : { "host", "hostaddr", "user", "dbname", "sslmode", "sslcert", "sslkey", "sslrootcert", "sslcrl" })
|
||||
|
||||
for (QString key : { "host", "hostaddr", "user", "dbname", "sslcert", "sslkey", "sslrootcert", "sslcrl" })
|
||||
{
|
||||
Exec(
|
||||
db.Exec(
|
||||
"INSERT INTO connection_parameter (connection_uuid, pname, pvalue)"
|
||||
" SELECT uuid, '" % key % "', " % key % "\n"
|
||||
" FROM connection\n"
|
||||
" WHERE " % key % " IS NOT NULL and " % key % " <> '';");
|
||||
" FROM connection\n"
|
||||
" WHERE " % key % " IS NOT NULL and " % key % " <> '';");
|
||||
}
|
||||
Exec(R"__(
|
||||
db.Exec(R"__(
|
||||
INSERT INTO connection_parameter (connection_uuid, pname, pvalue)
|
||||
SELECT uuid, 'port', port
|
||||
FROM connection
|
||||
|
|
@ -114,118 +120,76 @@ INSERT INTO connection_parameter (connection_uuid, pname, pvalue)
|
|||
for (QString column : { "host", "hostaddr", "user", "dbname", "sslmode", "sslcert", "sslkey", "sslrootcert", "sslcrl", "port" })
|
||||
{
|
||||
// sqlite does not seem to support dropping more then one column per alter table
|
||||
Exec("ALTER TABLE connection DROP COLUMN " % column % ";");
|
||||
db.Exec("ALTER TABLE connection DROP COLUMN " % column % ";");
|
||||
}
|
||||
}
|
||||
|
||||
void Exec(QString query)
|
||||
{
|
||||
QSqlQuery q(query, db);
|
||||
Verify(q);
|
||||
}
|
||||
|
||||
void ApplyMigration(QString migration_id, void (MigrationDirector::*func)())
|
||||
{
|
||||
if (!present.contains(migration_id))
|
||||
{
|
||||
if (!db.transaction())
|
||||
{
|
||||
throw std::runtime_error("Failed to start transaction on user configuration database");
|
||||
}
|
||||
SQLiteTransaction tx(db);
|
||||
(this->*func)();
|
||||
RegisterMigration(migration_id);
|
||||
if (!db.commit())
|
||||
{
|
||||
db.rollback();
|
||||
throw std::runtime_error("Failed to commit transaction on user configuration database");
|
||||
}
|
||||
tx.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_set<QString> LoadMigrations()
|
||||
{
|
||||
std::unordered_set<QString> result;
|
||||
QSqlQuery q(q_load_migrations_present, db);
|
||||
Verify(q);
|
||||
while (q.next())
|
||||
|
||||
auto stmt = db.Prepare(q_load_migrations_present);
|
||||
while (stmt.Step())
|
||||
{
|
||||
result.insert(q.value(0).toString());
|
||||
result.insert(stmt.ColumnText(0));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void RegisterMigration(QString migrationId)
|
||||
{
|
||||
const char * const q_register_migration =
|
||||
R"__(INSERT INTO _migration VALUES (:id);)__" ;
|
||||
|
||||
QSqlQuery q(db);
|
||||
q.prepare(q_register_migration);
|
||||
q.bindValue(":id", migrationId);
|
||||
if (!q.exec()) {
|
||||
Verify(q);
|
||||
}
|
||||
}
|
||||
|
||||
void Verify(QSqlQuery &q)
|
||||
{
|
||||
auto err = q.lastError();
|
||||
if (err.type() == QSqlError::NoError)
|
||||
return;
|
||||
|
||||
db.rollback();
|
||||
QString errString = err.text();
|
||||
throw std::runtime_error(errString.toStdString());
|
||||
auto stmt = db.Prepare("INSERT INTO _migration VALUES (?1);");
|
||||
stmt.Bind(1, migrationId);
|
||||
stmt.Step();
|
||||
}
|
||||
|
||||
void InitConnectionTables()
|
||||
{
|
||||
// Original schema
|
||||
QSqlQuery q_create_table(db);
|
||||
q_create_table.exec(q_create_table_conngroup);
|
||||
Verify(q_create_table);
|
||||
q_create_table.exec(q_create_table_connection);
|
||||
Verify(q_create_table);
|
||||
db.Exec(q_create_table_conngroup);
|
||||
db.Exec(q_create_table_connection);
|
||||
// Start using migrations
|
||||
q_create_table.exec(q_create_table_migrations);
|
||||
Verify(q_create_table);
|
||||
db.Exec(q_create_table_migrations);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
std::optional<QSqlError> SaveConnectionConfig(QSqlDatabase &db, const ConnectionConfig &cc, int conngroup_id)
|
||||
void SaveConnectionConfig(SQLiteConnection &db, const ConnectionConfig &cc, int conngroup_id)
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
q.prepare(q_insert_or_replace_into_connection);
|
||||
q.bindValue(":uuid", cc.uuid().toString());
|
||||
q.bindValue(":name", cc.name());
|
||||
q.bindValue(":conngroup_id", conngroup_id);
|
||||
q.bindValue(":host", cc.host());
|
||||
q.bindValue(":hostaddr", cc.hostAddr());
|
||||
q.bindValue(":port", (int)cc.port());
|
||||
q.bindValue(":user", cc.user());
|
||||
q.bindValue(":dbname", cc.dbname());
|
||||
q.bindValue(":sslmode", static_cast<int>(cc.sslMode()));
|
||||
q.bindValue(":sslcert", cc.sslCert());
|
||||
q.bindValue(":sslkey", cc.sslKey());
|
||||
q.bindValue(":sslrootcert", cc.sslRootCert());
|
||||
q.bindValue(":sslcrl", cc.sslCrl());
|
||||
auto& encodedPassword = cc.encodedPassword();
|
||||
if (encodedPassword.isEmpty())
|
||||
q.bindValue(":password", QVariant());
|
||||
else
|
||||
q.bindValue(":password", encodedPassword);
|
||||
const char * const q_insert_or_replace_into_connection =
|
||||
R"__(INSERT OR REPLACE INTO connection
|
||||
VALUES (?1, ?2, ?3, ?4);
|
||||
)__" ;
|
||||
|
||||
if (!q.exec()) {
|
||||
auto sql_error = q.lastError();
|
||||
return { sql_error };
|
||||
}
|
||||
return {};
|
||||
QByteArray b64; // needs to stay in scope until query is executed
|
||||
SQLiteTransaction tx(db);
|
||||
SQLitePreparedStatement stmt = db.Prepare(q_insert_or_replace_into_connection);
|
||||
stmt.Bind(1, cc.uuid().toString());
|
||||
stmt.Bind(2, cc.name());
|
||||
stmt.Bind(3, conngroup_id);
|
||||
auto& encodedPassword = cc.encodedPassword();
|
||||
if (!encodedPassword.isEmpty())
|
||||
{
|
||||
b64 = encodedPassword.toBase64(QByteArray::Base64Encoding);
|
||||
stmt.Bind(4, b64.data(), b64.length());
|
||||
}
|
||||
stmt.Step();
|
||||
}
|
||||
|
||||
} // end of unnamed namespace
|
||||
|
||||
ConnectionTreeModel::ConnectionTreeModel(QObject *parent, QSqlDatabase &db)
|
||||
ConnectionTreeModel::ConnectionTreeModel(QObject *parent, SQLiteConnection &db)
|
||||
: QAbstractItemModel(parent)
|
||||
, m_db(db)
|
||||
{
|
||||
|
|
@ -237,56 +201,61 @@ void ConnectionTreeModel::load()
|
|||
MigrationDirector md(m_db);
|
||||
md.Execute();
|
||||
|
||||
QSqlQuery q(m_db);
|
||||
q.prepare("SELECT conngroup_id, gname FROM conngroup;");
|
||||
if (!q.exec()) {
|
||||
// auto err = q_create_table.lastError();
|
||||
// return { false, err };
|
||||
throw std::runtime_error("Loading groups failed");
|
||||
}
|
||||
while (q.next()) {
|
||||
int id = q.value(0).toInt();
|
||||
QString name = q.value(1).toString();
|
||||
loadGroups();
|
||||
loadConnections();
|
||||
}
|
||||
|
||||
auto g = std::make_shared<ConnectionGroup>();
|
||||
g->conngroup_id = id;
|
||||
g->name = name;
|
||||
m_groups.push_back(g);
|
||||
}
|
||||
void ConnectionTreeModel::loadGroups()
|
||||
{
|
||||
auto stmt = m_db.Prepare("SELECT conngroup_id, gname FROM conngroup;");
|
||||
while (stmt.Step())
|
||||
{
|
||||
auto g = std::make_shared<ConnectionGroup>();
|
||||
g->conngroup_id = stmt.ColumnInteger(0);
|
||||
g->name = stmt.ColumnText(1);
|
||||
m_groups.push_back(g);
|
||||
}
|
||||
}
|
||||
|
||||
q.prepare("SELECT uuid, cname, conngroup_id, password "
|
||||
"FROM connection ORDER BY conngroup_id, cname;");
|
||||
if (!q.exec()) {
|
||||
// auto err = q_create_table.lastError();
|
||||
// return { false, err };
|
||||
throw std::runtime_error("Loading groups failed");
|
||||
}
|
||||
while (q.next()) {
|
||||
auto cc = std::make_shared<ConnectionConfig>();
|
||||
cc->setUuid(q.value(0).toUuid());
|
||||
cc->setName(q.value(1).toString());
|
||||
cc->setHost(q.value(3).toString());
|
||||
cc->setHostAddr(q.value(4).toString());
|
||||
cc->setPort(static_cast<uint16_t>(q.value(5).toInt()));
|
||||
cc->setUser(q.value(6).toString());
|
||||
cc->setDbname(q.value(7).toString());
|
||||
cc->setSslMode(static_cast<SslMode>(q.value(8).toInt()));
|
||||
cc->setSslCert(q.value(9).toString());
|
||||
cc->setSslKey(q.value(10).toString());
|
||||
cc->setSslRootCert(q.value(11).toString());
|
||||
cc->setSslCrl(q.value(12).toString());
|
||||
cc->setEncodedPassword(q.value(13).toByteArray());
|
||||
void ConnectionTreeModel::loadConnections()
|
||||
{
|
||||
auto stmt = m_db.Prepare(
|
||||
"SELECT uuid, cname, conngroup_id, password "
|
||||
"FROM connection ORDER BY conngroup_id, cname;");
|
||||
|
||||
int group_id = q.value(2).toInt();
|
||||
auto find_res = std::find_if(m_groups.begin(), m_groups.end(),
|
||||
[group_id] (auto item) { return item->conngroup_id == group_id; });
|
||||
if (find_res != m_groups.end()) {
|
||||
(*find_res)->add(cc);
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("conngroup missing");
|
||||
}
|
||||
}
|
||||
while (stmt.Step()) {
|
||||
auto cc = std::make_shared<ConnectionConfig>();
|
||||
cc->setUuid(QUuid::fromString(stmt.ColumnText(0)));
|
||||
cc->setName(stmt.ColumnText(1));
|
||||
cc->setEncodedPassword(QByteArray::fromBase64(stmt.ColumnCharPtr(3), QByteArray::Base64Encoding));
|
||||
loadConnectionParameters(*cc);
|
||||
|
||||
int group_id = stmt.ColumnInteger(2);
|
||||
auto find_res = std::find_if(m_groups.begin(), m_groups.end(),
|
||||
[group_id] (auto item) { return item->conngroup_id == group_id; });
|
||||
if (find_res != m_groups.end()) {
|
||||
(*find_res)->add(cc);
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("conngroup missing");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionTreeModel::loadConnectionParameters(ConnectionConfig &cc)
|
||||
{
|
||||
auto stmt = m_db.Prepare(
|
||||
"SELECT pname, pvalue \n"
|
||||
"FROM connection_parameter\n"
|
||||
"WHERE connection_uuid=?1");
|
||||
stmt.Bind(1, cc.uuid().toString());
|
||||
while (stmt.Step())
|
||||
{
|
||||
cc.setParameter(
|
||||
stmt.ColumnText(0),
|
||||
stmt.ColumnText(1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ConnectionTreeModel::data(const QModelIndex &index, int role) const
|
||||
|
|
@ -408,15 +377,11 @@ bool ConnectionTreeModel::removeRows(int row, int count, const QModelIndex &pare
|
|||
auto grp = m_groups[parent.row()];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
QUuid uuid = grp->connections().at(row + i)->uuid();
|
||||
QSqlQuery q(m_db);
|
||||
q.prepare(
|
||||
auto stmt = m_db.Prepare(
|
||||
"DELETE FROM connection "
|
||||
" WHERE uuid=:uuid");
|
||||
q.bindValue(":uuid", uuid);
|
||||
if (!q.exec()) {
|
||||
auto err = q.lastError();
|
||||
throw std::runtime_error("QqlError");
|
||||
}
|
||||
" WHERE uuid=?0");
|
||||
stmt.Bind(0, uuid.toString());
|
||||
stmt.Step();
|
||||
}
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
SCOPE_EXIT { endRemoveRows(); };
|
||||
|
|
@ -454,14 +419,8 @@ void ConnectionTreeModel::save(const QString &group_name, const ConnectionConfig
|
|||
// We assume the model is in sync with the DB as the DB should not be shared!
|
||||
int new_grp_idx = findGroup(group_name);
|
||||
if (new_grp_idx < 0) {
|
||||
// Group not found we are g
|
||||
auto add_grp_res = addGroup(group_name);
|
||||
if (std::holds_alternative<int>(add_grp_res)) {
|
||||
new_grp_idx = std::get<int>(add_grp_res);
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("SqlError1");
|
||||
}
|
||||
// Group not found we are g
|
||||
new_grp_idx = addGroup(group_name);
|
||||
}
|
||||
auto new_grp = m_groups[new_grp_idx];
|
||||
|
||||
|
|
@ -470,15 +429,8 @@ void ConnectionTreeModel::save(const QString &group_name, const ConnectionConfig
|
|||
beginInsertRows(parent, idx, idx);
|
||||
SCOPE_EXIT { endInsertRows(); };
|
||||
auto node = std::make_shared<ConnectionConfig>(cc);
|
||||
new_grp->add(node);
|
||||
auto save_res = saveToDb(*node);
|
||||
if (save_res) {
|
||||
QString msg = save_res->text()
|
||||
% "\n" % save_res->driverText()
|
||||
% "\n" % save_res->databaseText();
|
||||
|
||||
throw std::runtime_error(msg.toUtf8().data());
|
||||
}
|
||||
new_grp->add(node);
|
||||
saveToDb(*node);
|
||||
}
|
||||
|
||||
void ConnectionTreeModel::save(const ConnectionConfig &cc)
|
||||
|
|
@ -523,17 +475,13 @@ int ConnectionTreeModel::findGroup(const QString &name) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
std::variant<int, QSqlError> ConnectionTreeModel::addGroup(const QString &group_name)
|
||||
int ConnectionTreeModel::addGroup(const QString &group_name)
|
||||
{
|
||||
QSqlQuery q(m_db);
|
||||
q.prepare("INSERT INTO conngroup (gname) VALUES (:name)");
|
||||
q.bindValue(":name", group_name);
|
||||
if (!q.exec()) {
|
||||
auto err = q.lastError();
|
||||
return { err };
|
||||
}
|
||||
auto cg = std::make_shared<ConnectionGroup>();
|
||||
cg->conngroup_id = q.lastInsertId().toInt();
|
||||
auto stmt = m_db.Prepare("INSERT INTO conngroup (gname) VALUES (?1)");
|
||||
stmt.Bind(1, group_name);
|
||||
|
||||
auto cg = std::make_shared<ConnectionGroup>();
|
||||
cg->conngroup_id = m_db.LastInsertRowId();
|
||||
cg->name = group_name;
|
||||
|
||||
int row = m_groups.size();
|
||||
|
|
@ -543,27 +491,21 @@ std::variant<int, QSqlError> ConnectionTreeModel::addGroup(const QString &group_
|
|||
return row;
|
||||
}
|
||||
|
||||
std::optional<QSqlError> ConnectionTreeModel::removeGroup(int row)
|
||||
void ConnectionTreeModel::removeGroup(int row)
|
||||
{
|
||||
beginRemoveRows({}, row, row);
|
||||
SCOPE_EXIT { endRemoveRows(); };
|
||||
auto id = m_groups[row]->conngroup_id;
|
||||
QSqlQuery q(m_db);
|
||||
q.prepare("DELETE FROM connection WHERE conngroup_id=:id");
|
||||
q.bindValue(":id", id);
|
||||
if (!q.exec()) {
|
||||
auto err = q.lastError();
|
||||
return { err };
|
||||
}
|
||||
q.prepare("DELETE FROM conngroup WHERE conngroup_id=:id");
|
||||
q.bindValue(":id", id);
|
||||
if (!q.exec()) {
|
||||
auto err = q.lastError();
|
||||
return { err };
|
||||
}
|
||||
|
||||
auto stmt = m_db.Prepare("DELETE FROM connection WHERE conngroup_id=?1");
|
||||
stmt.Bind(1, id);
|
||||
stmt.Step();
|
||||
|
||||
stmt = m_db.Prepare("DELETE FROM conngroup WHERE conngroup_id=?1");
|
||||
stmt.Bind(1, id);
|
||||
stmt.Step();
|
||||
|
||||
m_groups.remove(row);
|
||||
return {};
|
||||
}
|
||||
|
||||
int ConnectionTreeModel::findGroup(int conngroup_id) const
|
||||
|
|
@ -591,9 +533,9 @@ ConnectionGroup *ConnectionTreeModel::getGroupFromModelIndex(QModelIndex index)
|
|||
return dynamic_cast<ConnectionGroup*>(node);
|
||||
}
|
||||
|
||||
std::optional<QSqlError> ConnectionTreeModel::saveToDb(const ConnectionConfig &cc)
|
||||
void ConnectionTreeModel::saveToDb(const ConnectionConfig &cc)
|
||||
{
|
||||
return SaveConnectionConfig(m_db, cc, cc.parent()->conngroup_id);
|
||||
SaveConnectionConfig(m_db, cc, cc.parent()->conngroup_id);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@
|
|||
#include <variant>
|
||||
#include <QVector>
|
||||
|
||||
#include <QSqlError>
|
||||
class QSqlDatabase;
|
||||
#include "sqlite/SQLiteConnection.h"
|
||||
|
||||
class ConnectionTreeModel : public QAbstractItemModel {
|
||||
Q_OBJECT
|
||||
|
|
@ -27,7 +26,7 @@ public:
|
|||
ColCount
|
||||
};
|
||||
|
||||
ConnectionTreeModel(QObject *parent, QSqlDatabase &db);
|
||||
ConnectionTreeModel(QObject *parent, SQLiteConnection &db);
|
||||
|
||||
void load();
|
||||
|
||||
|
|
@ -61,8 +60,8 @@ public:
|
|||
void save(const ConnectionConfig &cc);
|
||||
void clearAllPasswords();
|
||||
/// Create a new group in the DB and place in the tree
|
||||
std::variant<int, QSqlError> addGroup(const QString &group_name);
|
||||
std::optional<QSqlError> removeGroup(int row);
|
||||
int addGroup(const QString &group_name);
|
||||
void removeGroup(int row);
|
||||
int findGroup(int conngroup_id) const;
|
||||
|
||||
static ConnectionConfig* getConfigFromModelIndex(QModelIndex index);
|
||||
|
|
@ -71,7 +70,7 @@ public:
|
|||
private:
|
||||
using Groups = QVector<std::shared_ptr<ConnectionGroup>>;
|
||||
|
||||
QSqlDatabase &m_db;
|
||||
SQLiteConnection &m_db;
|
||||
Groups m_groups;
|
||||
|
||||
/// Finds the connection with the specified uuid and returns
|
||||
|
|
@ -79,8 +78,11 @@ private:
|
|||
std::tuple<int, int> findConfig(const QUuid uuid) const;
|
||||
int findGroup(const QString &name) const;
|
||||
|
||||
std::optional<QSqlError> saveToDb(const ConnectionConfig &cc);
|
||||
void saveToDb(const ConnectionConfig &cc);
|
||||
|
||||
void loadGroups();
|
||||
void loadConnections();
|
||||
void loadConnectionParameters(ConnectionConfig &cc);
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
|
|
|
|||
|
|
@ -30,15 +30,7 @@ MasterController::~MasterController()
|
|||
|
||||
void MasterController::init()
|
||||
{
|
||||
m_userConfigDatabase = QSqlDatabase::addDatabase("QSQLITE");
|
||||
m_userConfigDatabase.setDatabaseName(GetUserConfigDatabaseName());
|
||||
|
||||
if (!m_userConfigDatabase.open()) {
|
||||
qDebug() << "Error: connection with database fail";
|
||||
}
|
||||
else {
|
||||
qDebug() << "Database: connection ok";
|
||||
}
|
||||
m_userConfigDatabase.Open(GetUserConfigDatabaseName());
|
||||
|
||||
m_connectionController = new ConnectionController(this);
|
||||
m_connectionController->init();
|
||||
|
|
@ -62,7 +54,7 @@ ConnectionController *MasterController::connectionController()
|
|||
return m_connectionController;
|
||||
}
|
||||
|
||||
QSqlDatabase& MasterController::userConfigDatabase()
|
||||
SQLiteConnection& MasterController::userConfigDatabase()
|
||||
{
|
||||
return m_userConfigDatabase;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
#define MASTERCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSqlDatabase>
|
||||
#include <atomic>
|
||||
#include <future>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "sqlite/SQLiteConnection.h"
|
||||
|
||||
|
||||
class ConnectionController;
|
||||
|
|
@ -23,14 +23,14 @@ public:
|
|||
void init();
|
||||
|
||||
ConnectionController* connectionController();
|
||||
QSqlDatabase& userConfigDatabase();
|
||||
SQLiteConnection& userConfigDatabase();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QSqlDatabase m_userConfigDatabase;
|
||||
SQLiteConnection m_userConfigDatabase;
|
||||
ConnectionController* m_connectionController = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue