-
Notifications
You must be signed in to change notification settings - Fork 0
/
qt_db_helpers.hpp
96 lines (88 loc) · 2.08 KB
/
qt_db_helpers.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#ifndef QT_DB_HELPERS_HPP_
#define QT_DB_HELPERS_HPP_
#include <utility>
#include <stdexcept>
#include <QString>
#include <QSqlError>
#include <QSqlTableModel>
#include "boost/core/noncopyable.hpp"
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)
: model_ (model)
, submitted_ {false}
{
model_.database ().transaction ();
}
bool submit (bool throw_on_error = true)
{
bool ok {true};
if (throw_on_error)
{
SQL_error_check (model_
, QSqlTableModel::OnManualSubmit == model_.editStrategy ()
? &QSqlTableModel::submitAll
: &QSqlTableModel::submit);
}
else
{
ok = QSqlTableModel::OnManualSubmit == model_.editStrategy ()
? model_.submitAll () : model_.submit ();
}
submitted_ = submitted_ || ok;
return ok;
}
void revert ()
{
if (QSqlTableModel::OnManualSubmit == model_.editStrategy ())
{
model_.revertAll ();
}
else
{
model_.revert ();
}
}
~ConditionalTransaction ()
{
if (model_.isDirty ())
{
// abandon un-submitted changes to the model
if (QSqlTableModel::OnManualSubmit == model_.editStrategy ())
{
model_.revertAll ();
}
else
{
model_.revert ();
}
}
auto database = model_.database ();
if (submitted_)
{
SQL_error_check (database, &QSqlDatabase::commit);
}
else
{
database.rollback ();
}
}
private:
QSqlTableModel& model_;
bool submitted_;
};
#endif