File: qt_db_helpers.hpp

package info (click to toggle)
wsjtx 3.0.0~rc1%2Brepack-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 86,956 kB
  • sloc: cpp: 105,872; f90: 60,116; python: 27,241; ansic: 13,372; fortran: 2,382; makefile: 197; sh: 135
file content (96 lines) | stat: -rwxr-xr-x 2,228 bytes parent folder | download | duplicates (6)
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