diff --git a/qt_db_helpers.hpp b/qt_db_helpers.hpp new file mode 100644 index 000000000..3f159a889 --- /dev/null +++ b/qt_db_helpers.hpp @@ -0,0 +1,75 @@ +#ifndef QT_DB_HELPERS_HPP_ +#define QT_DB_HELPERS_HPP_ + +#include +#include +#include +#include +#include + +template +void SQL_error_check (T&& object, Func func, Args&&... args) +{ + if (!(std::forward (object).*func) (std::forward (args)...)) + { + auto error = object.lastError (); + if (QSqlError::NoError != error.type ()) + { + throw std::runtime_error {("Database Error: " + error.text ()).toStdString ()}; + } + } +} + +class ConditionalTransaction final + : private boost::noncopyable +{ +public: + explicit ConditionalTransaction (QSqlTableModel& model) + : model_ {model} + , submitted_ {false} + { + model_.database ().transaction (); + } + bool submit (bool throw_on_error = true) + { + Q_ASSERT (model_.isDirty ()); + bool ok {true}; + if (throw_on_error) + { + SQL_error_check (model_, &QSqlTableModel::submitAll); + } + else + { + ok = model_.submitAll (); + } + submitted_ = submitted_ || ok; + return ok; + } + void revert () + { + Q_ASSERT (model_.isDirty ()); + model_.revertAll (); + } + ~ConditionalTransaction () + { + if (model_.isDirty ()) + { + // abandon un-submitted changes to the model + model_.revertAll (); + } + auto database = model_.database (); + if (submitted_) + { + SQL_error_check (database, &QSqlDatabase::commit); + } + else + { + database.rollback (); + } + } +private: + QSqlTableModel& model_; + bool submitted_; +}; + +#endif diff --git a/wsjtx.pro b/wsjtx.pro index 7b05335d0..f480a8ebd 100644 --- a/wsjtx.pro +++ b/wsjtx.pro @@ -70,7 +70,7 @@ SOURCES += \ EqualizationToolsDialog.cpp \ LotWUsers.cpp TraceFile.cpp -HEADERS += qt_helpers.hpp \ +HEADERS += qt_helpers.hpp qt_db_helpers.hpp \ pimpl_h.hpp pimpl_impl.hpp \ Radio.hpp NetworkServerLookup.hpp revision_utils.hpp \ soundin.h soundout.h \