Mercurial > hg > orthanc-databases
comparison Framework/Common/ImplicitTransaction.cpp @ 23:b2ff1cd2907a
handling of implicit transactions in DatabaseManager
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 12 Jul 2018 10:44:17 +0200 |
parents | |
children | 69a94267cdea |
comparison
equal
deleted
inserted
replaced
22:1e9bad493475 | 23:b2ff1cd2907a |
---|---|
1 /** | |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "ImplicitTransaction.h" | |
23 | |
24 #include <Core/Logging.h> | |
25 #include <Core/OrthancException.h> | |
26 | |
27 #include <memory> | |
28 | |
29 namespace OrthancDatabases | |
30 { | |
31 ImplicitTransaction::ImplicitTransaction() : | |
32 state_(State_Ready), | |
33 readOnly_(true) | |
34 { | |
35 } | |
36 | |
37 | |
38 ImplicitTransaction::~ImplicitTransaction() | |
39 { | |
40 switch (state_) | |
41 { | |
42 case State_Committed: | |
43 case State_Ready: | |
44 break; | |
45 | |
46 case State_Executed: | |
47 LOG(ERROR) << "An implicit transaction has not been committed"; | |
48 break; | |
49 | |
50 default: | |
51 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
52 } | |
53 } | |
54 | |
55 | |
56 void ImplicitTransaction::Rollback() | |
57 { | |
58 LOG(ERROR) << "Cannot rollback an implicit transaction"; | |
59 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
60 } | |
61 | |
62 | |
63 void ImplicitTransaction::Commit() | |
64 { | |
65 switch (state_) | |
66 { | |
67 case State_Ready: | |
68 LOG(ERROR) << "Cannot commit an implicit transaction that has not been executed yet"; | |
69 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
70 | |
71 case State_Executed: | |
72 state_ = State_Committed; | |
73 break; | |
74 | |
75 case State_Committed: | |
76 LOG(ERROR) << "Cannot commit twice an implicit transaction"; | |
77 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
78 | |
79 default: | |
80 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
81 } | |
82 } | |
83 | |
84 | |
85 void ImplicitTransaction::CheckStateForExecution() | |
86 { | |
87 switch (state_) | |
88 { | |
89 case State_Ready: | |
90 // OK | |
91 break; | |
92 | |
93 case State_Executed: | |
94 #if defined(NDEBUG) | |
95 // Release build. Ignore such errors. | |
96 LOG(INFO) << "Cannot execute more than one statement in an implicit transaction"; | |
97 break; | |
98 #else | |
99 /** | |
100 * Debug build. This allows to detect errors wrt. the handling | |
101 * of transactions in the Orthanc core. | |
102 * | |
103 * In Orthanc <= 1.3.2: problems in "/changes" (a transaction | |
104 * was missing because of GetPublicId()). | |
105 **/ | |
106 LOG(ERROR) << "Cannot execute more than one statement in an implicit transaction"; | |
107 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
108 #endif | |
109 | |
110 case State_Committed: | |
111 LOG(ERROR) << "Cannot commit twice an implicit transaction"; | |
112 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
113 | |
114 default: | |
115 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
116 } | |
117 } | |
118 | |
119 | |
120 IResult* ImplicitTransaction::Execute(IPrecompiledStatement& statement, | |
121 const Dictionary& parameters) | |
122 { | |
123 CheckStateForExecution(); | |
124 std::auto_ptr<IResult> result(ExecuteInternal(statement, parameters)); | |
125 | |
126 if (!statement.IsReadOnly()) | |
127 { | |
128 readOnly_ = false; | |
129 } | |
130 | |
131 state_ = State_Executed; | |
132 return result.release(); | |
133 } | |
134 | |
135 | |
136 void ImplicitTransaction::ExecuteWithoutResult(IPrecompiledStatement& statement, | |
137 const Dictionary& parameters) | |
138 { | |
139 CheckStateForExecution(); | |
140 ExecuteWithoutResultInternal(statement, parameters); | |
141 | |
142 if (!statement.IsReadOnly()) | |
143 { | |
144 readOnly_ = false; | |
145 } | |
146 | |
147 state_ = State_Executed; | |
148 } | |
149 } | |
150 |