2018-11-11 20:48:01 -05:00
|
|
|
#ifndef QT_DB_HELPERS_HPP_
|
|
|
|
#define QT_DB_HELPERS_HPP_
|
|
|
|
|
|
|
|
#include <utility>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <QString>
|
|
|
|
#include <QSqlError>
|
|
|
|
#include <QSqlTableModel>
|
2019-05-30 17:20:09 -04:00
|
|
|
#include "boost/core/noncopyable.hpp"
|
2018-11-11 20:48:01 -05:00
|
|
|
|
|
|
|
template<typename T, typename Func, typename... Args>
|
|
|
|
void SQL_error_check (T&& object, Func func, Args&&... args)
|
|
|
|
{
|
|
|
|
if (!(std::forward<T> (object).*func) (std::forward<Args> (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)
|
2018-11-14 20:31:21 -05:00
|
|
|
: model_ (model)
|
2018-11-11 20:48:01 -05:00
|
|
|
, submitted_ {false}
|
|
|
|
{
|
|
|
|
model_.database ().transaction ();
|
|
|
|
}
|
2018-11-25 17:19:41 -05:00
|
|
|
|
2018-11-11 20:48:01 -05:00
|
|
|
bool submit (bool throw_on_error = true)
|
|
|
|
{
|
|
|
|
bool ok {true};
|
|
|
|
if (throw_on_error)
|
|
|
|
{
|
2018-11-25 17:19:41 -05:00
|
|
|
SQL_error_check (model_
|
|
|
|
, QSqlTableModel::OnManualSubmit == model_.editStrategy ()
|
|
|
|
? &QSqlTableModel::submitAll
|
|
|
|
: &QSqlTableModel::submit);
|
2018-11-11 20:48:01 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-11-25 17:19:41 -05:00
|
|
|
ok = QSqlTableModel::OnManualSubmit == model_.editStrategy ()
|
|
|
|
? model_.submitAll () : model_.submit ();
|
2018-11-11 20:48:01 -05:00
|
|
|
}
|
|
|
|
submitted_ = submitted_ || ok;
|
|
|
|
return ok;
|
|
|
|
}
|
2018-11-25 17:19:41 -05:00
|
|
|
|
2018-11-11 20:48:01 -05:00
|
|
|
void revert ()
|
|
|
|
{
|
2018-11-25 17:19:41 -05:00
|
|
|
if (QSqlTableModel::OnManualSubmit == model_.editStrategy ())
|
|
|
|
{
|
|
|
|
model_.revertAll ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
model_.revert ();
|
|
|
|
}
|
2018-11-11 20:48:01 -05:00
|
|
|
}
|
2018-11-25 17:19:41 -05:00
|
|
|
|
2018-11-11 20:48:01 -05:00
|
|
|
~ConditionalTransaction ()
|
|
|
|
{
|
|
|
|
if (model_.isDirty ())
|
|
|
|
{
|
|
|
|
// abandon un-submitted changes to the model
|
2018-11-25 17:19:41 -05:00
|
|
|
if (QSqlTableModel::OnManualSubmit == model_.editStrategy ())
|
|
|
|
{
|
|
|
|
model_.revertAll ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
model_.revert ();
|
|
|
|
}
|
2018-11-11 20:48:01 -05:00
|
|
|
}
|
|
|
|
auto database = model_.database ();
|
|
|
|
if (submitted_)
|
|
|
|
{
|
|
|
|
SQL_error_check (database, &QSqlDatabase::commit);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
database.rollback ();
|
|
|
|
}
|
|
|
|
}
|
2018-11-25 17:19:41 -05:00
|
|
|
|
2018-11-11 20:48:01 -05:00
|
|
|
private:
|
|
|
|
QSqlTableModel& model_;
|
|
|
|
bool submitted_;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|