Improved connection error handling.

Just returning a boolean is too limiting. Using expection instead to easily pass on error message.
This commit is contained in:
eelke 2018-12-23 08:43:43 +01:00
parent 646b18ebeb
commit a88af1ac11
5 changed files with 41 additions and 41 deletions

View file

@ -435,8 +435,7 @@ std::tuple<bool, CrudModel::ModifiedRow> CrudModel::updateRow(const PendingRow &
int row_number = pending_row.row(); int row_number = pending_row.row();
Pgsql::Connection db_update_conn; Pgsql::Connection db_update_conn;
auto dbconfig = m_database->config(); auto dbconfig = m_database->config();
bool res = db_update_conn.connect(dbconfig.getKeywords(), dbconfig.getValues(), false); db_update_conn.connect(dbconfig.getKeywords(), dbconfig.getValues(), false);
if (res) {
auto result = db_update_conn.queryParam(buffer, params); auto result = db_update_conn.queryParam(buffer, params);
if (result && result.rows() == 1) { if (result && result.rows() == 1) {
@ -454,8 +453,6 @@ std::tuple<bool, CrudModel::ModifiedRow> CrudModel::updateRow(const PendingRow &
return { true, modified_row }; return { true, modified_row };
} }
} }
}
return { false, {} }; return { false, {} };
} }
@ -527,10 +524,7 @@ std::tuple<bool, QString> CrudModel::removeRows(const std::set<IntegerRange<int>
try { try {
Pgsql::Connection db_update_conn; Pgsql::Connection db_update_conn;
auto dbconfig = m_database->config(); auto dbconfig = m_database->config();
bool res = db_update_conn.connect(dbconfig.getKeywords(), dbconfig.getValues(), false); db_update_conn.connect(dbconfig.getKeywords(), dbconfig.getValues(), false);
if (!res) {
return { false, "Cannot connect to the database" };
}
// First delete rows in table // First delete rows in table
QString delete_statement = createDeleteStatement(); QString delete_statement = createDeleteStatement();

View file

@ -5,15 +5,18 @@
Expected<OpenDatabase::OpenDatabaseSPtr> OpenDatabase::createOpenDatabase(const ConnectionConfig &cfg) Expected<OpenDatabase::OpenDatabaseSPtr> OpenDatabase::createOpenDatabase(const ConnectionConfig &cfg)
{ {
return Expected<OpenDatabase::OpenDatabaseSPtr>::fromCode(
[&cfg] () -> auto {
OpenDatabaseSPtr odb(new OpenDatabase(cfg)); OpenDatabaseSPtr odb(new OpenDatabase(cfg));
if (odb->Init()) { odb->Init();
return odb; return odb;
});
// catch (const PgException &ex) {
// return
// }
} // return Expected<OpenDatabaseSPtr>::fromException(
//return Expected<ConnectionConfig>::fromException(std::out_of_range("Invalid row")); // std::runtime_error("Failed to get database information"));
return Expected<OpenDatabaseSPtr>::fromException(
std::runtime_error("Failed to get database information"));
} }
OpenDatabase::OpenDatabase(const ConnectionConfig& cfg) OpenDatabase::OpenDatabase(const ConnectionConfig& cfg)
@ -24,16 +27,13 @@ OpenDatabase::OpenDatabase(const ConnectionConfig& cfg)
OpenDatabase::~OpenDatabase() = default; OpenDatabase::~OpenDatabase() = default;
bool OpenDatabase::Init() void OpenDatabase::Init()
{ {
Pgsql::Connection conn; Pgsql::Connection conn;
auto kw = m_config.getKeywords(); auto kw = m_config.getKeywords();
auto vals = m_config.getValues(); auto vals = m_config.getValues();
if (conn.connect(kw, vals, 0)) { conn.connect(kw, vals, 0);
m_catalog->loadAll(conn, nullptr); m_catalog->loadAll(conn, nullptr);
return true;
}
return false;
} }
std::shared_ptr<PgDatabaseCatalog> OpenDatabase::catalog() std::shared_ptr<PgDatabaseCatalog> OpenDatabase::catalog()

View file

@ -34,7 +34,7 @@ private:
TypeSelectionItemModel *m_typeSelectionModel = nullptr; TypeSelectionItemModel *m_typeSelectionModel = nullptr;
OpenDatabase(const ConnectionConfig& cfg); OpenDatabase(const ConnectionConfig& cfg);
bool Init(); void Init();
}; };
#endif // OPENDATABASE_H #endif // OPENDATABASE_H

View file

@ -54,15 +54,21 @@ bool Connection::connect(const char *params)
return result; return result;
} }
bool Connection::connect(const char *const * keywords, const char* const * values, int expand_dbname) void Connection::connect(const char *const * keywords, const char* const * values, int expand_dbname)
{ {
bool result = false;
conn = PQconnectdbParams(keywords, values, expand_dbname); conn = PQconnectdbParams(keywords, values, expand_dbname);
std::string error_msg;
if (conn) { if (conn) {
ConnStatusType status = PQstatus(conn); ConnStatusType status = PQstatus(conn);
result = (status == CONNECTION_OK); if (status == CONNECTION_OK)
return;
error_msg = PQerrorMessage(conn);
} }
return result; else {
error_msg = "Unknown connection failure (maybe out of memory?)";
}
throw PgException(error_msg);
} }
bool Connection::connectStart(const char* params) bool Connection::connectStart(const char* params)

View file

@ -50,7 +50,7 @@ namespace Pgsql {
return connect(params.toUtf8().data()); return connect(params.toUtf8().data());
} }
bool connect(const char *const * keywords, const char* const * values, int expand_dbname); void connect(const char *const * keywords, const char* const * values, int expand_dbname);
bool connectStart(const char *params); bool connectStart(const char *params);
bool connectStart(const std::string &params) bool connectStart(const std::string &params)
{ {