Mercurial > hg > orthanc-databases
annotate Framework/PostgreSQL/PostgreSQLDatabase.cpp @ 231:0a9b48d19643
removed mutex out of DatabaseManager
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 06 Apr 2021 11:59:31 +0200 |
parents | a4918d57435c |
children | 35598014f140 |
rev | line source |
---|---|
0 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
193
3236894320d6
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium |
0 | 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 | |
107
5765cc5fd268
reverted fix for OS X that breaks other targets
Sebastien Jodogne <s.jodogne@orthanc-labs.com>
parents:
105
diff
changeset
|
22 #include "PostgreSQLIncludes.h" // Must be the first |
105 | 23 #include "PostgreSQLDatabase.h" |
0 | 24 |
226
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
25 #include "../Common/ImplicitTransaction.h" |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
26 #include "../Common/RetryDatabaseFactory.h" |
0 | 27 #include "PostgreSQLResult.h" |
28 #include "PostgreSQLStatement.h" | |
29 #include "PostgreSQLTransaction.h" | |
30 | |
152 | 31 #include <Logging.h> |
32 #include <OrthancException.h> | |
0 | 33 |
34 #include <boost/lexical_cast.hpp> | |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
35 #include <boost/thread.hpp> |
0 | 36 |
37 | |
38 namespace OrthancDatabases | |
39 { | |
40 void PostgreSQLDatabase::ThrowException(bool log) | |
41 { | |
42 if (log) | |
43 { | |
44 LOG(ERROR) << "PostgreSQL error: " | |
45 << PQerrorMessage(reinterpret_cast<PGconn*>(pg_)); | |
46 } | |
47 | |
48 if (PQstatus(reinterpret_cast<PGconn*>(pg_)) == CONNECTION_OK) | |
49 { | |
50 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | |
51 } | |
52 else | |
53 { | |
54 throw Orthanc::OrthancException(Orthanc::ErrorCode_DatabaseUnavailable); | |
55 } | |
56 } | |
57 | |
58 | |
59 void PostgreSQLDatabase::Close() | |
60 { | |
61 if (pg_ != NULL) | |
62 { | |
63 LOG(INFO) << "Closing connection to PostgreSQL"; | |
64 PQfinish(reinterpret_cast<PGconn*>(pg_)); | |
65 pg_ = NULL; | |
66 } | |
67 } | |
68 | |
46
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
69 |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
70 PostgreSQLDatabase::~PostgreSQLDatabase() |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
71 { |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
72 try |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
73 { |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
74 Close(); |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
75 } |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
76 catch (Orthanc::OrthancException&) |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
77 { |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
78 // Ignore possible exceptions due to connection loss |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
79 } |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
80 } |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
81 |
0 | 82 |
83 void PostgreSQLDatabase::Open() | |
84 { | |
85 if (pg_ != NULL) | |
86 { | |
87 // Already connected | |
88 return; | |
89 } | |
90 | |
91 std::string s; | |
92 parameters_.Format(s); | |
93 | |
94 pg_ = PQconnectdb(s.c_str()); | |
95 | |
96 if (pg_ == NULL || | |
97 PQstatus(reinterpret_cast<PGconn*>(pg_)) != CONNECTION_OK) | |
98 { | |
99 std::string message; | |
100 | |
101 if (pg_) | |
102 { | |
103 message = PQerrorMessage(reinterpret_cast<PGconn*>(pg_)); | |
104 PQfinish(reinterpret_cast<PGconn*>(pg_)); | |
105 pg_ = NULL; | |
106 } | |
107 | |
108 LOG(ERROR) << "PostgreSQL error: " << message; | |
109 throw Orthanc::OrthancException(Orthanc::ErrorCode_DatabaseUnavailable); | |
110 } | |
12
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
111 } |
0 | 112 |
113 | |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
114 bool PostgreSQLDatabase::RunAdvisoryLockStatement(const std::string& statement) |
12
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
115 { |
216
fbb52129158a
TransactionType given to PostgreSQLTransaction constructor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
215
diff
changeset
|
116 PostgreSQLTransaction transaction(*this, TransactionType_ReadWrite); |
0 | 117 |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
118 Query query(statement, false); |
29 | 119 PostgreSQLStatement s(*this, query); |
0 | 120 |
12
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
121 PostgreSQLResult result(s); |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
122 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
123 bool success = (!result.IsDone() && |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
124 result.GetBoolean(0)); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
125 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
126 transaction.Commit(); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
127 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
128 return success; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
129 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
130 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
131 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
132 bool PostgreSQLDatabase::AcquireAdvisoryLock(int32_t lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
133 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
134 return RunAdvisoryLockStatement( |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
135 "select pg_try_advisory_lock(" + |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
136 boost::lexical_cast<std::string>(lock) + ")"); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
137 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
138 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
139 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
140 bool PostgreSQLDatabase::ReleaseAdvisoryLock(int32_t lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
141 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
142 return RunAdvisoryLockStatement( |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
143 "select pg_advisory_unlock(" + |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
144 boost::lexical_cast<std::string>(lock) + ")"); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
145 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
146 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
147 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
148 void PostgreSQLDatabase::AdvisoryLock(int32_t lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
149 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
150 if (!AcquireAdvisoryLock(lock)) |
12
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
151 { |
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
152 LOG(ERROR) << "The PostgreSQL database is locked by another instance of Orthanc"; |
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
153 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); |
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
154 } |
0 | 155 } |
156 | |
157 | |
158 void PostgreSQLDatabase::Execute(const std::string& sql) | |
159 { | |
160 LOG(TRACE) << "PostgreSQL: " << sql; | |
161 Open(); | |
162 | |
163 PGresult* result = PQexec(reinterpret_cast<PGconn*>(pg_), sql.c_str()); | |
164 if (result == NULL) | |
165 { | |
166 ThrowException(true); | |
167 } | |
168 | |
169 bool ok = (PQresultStatus(result) == PGRES_COMMAND_OK || | |
170 PQresultStatus(result) == PGRES_TUPLES_OK); | |
171 | |
172 if (ok) | |
173 { | |
174 PQclear(result); | |
175 } | |
176 else | |
177 { | |
178 std::string message = PQresultErrorMessage(result); | |
179 PQclear(result); | |
180 | |
181 LOG(ERROR) << "PostgreSQL error: " << message; | |
182 ThrowException(false); | |
183 } | |
184 } | |
185 | |
186 | |
187 bool PostgreSQLDatabase::DoesTableExist(const char* name) | |
188 { | |
189 std::string lower(name); | |
190 std::transform(lower.begin(), lower.end(), lower.begin(), tolower); | |
191 | |
192 // http://stackoverflow.com/a/24089729/881731 | |
193 | |
194 PostgreSQLStatement statement(*this, | |
195 "SELECT 1 FROM pg_catalog.pg_class c " | |
196 "JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace " | |
197 "WHERE n.nspname = 'public' AND c.relkind='r' " | |
214
ab96698c73a3
removed useless information about read-only in ITransaction and IPrecompiledStatement
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
193
diff
changeset
|
198 "AND c.relname=$1"); |
0 | 199 |
200 statement.DeclareInputString(0); | |
201 statement.BindString(0, lower); | |
202 | |
203 PostgreSQLResult result(statement); | |
204 return !result.IsDone(); | |
205 } | |
206 | |
207 | |
208 void PostgreSQLDatabase::ClearAll() | |
209 { | |
216
fbb52129158a
TransactionType given to PostgreSQLTransaction constructor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
215
diff
changeset
|
210 PostgreSQLTransaction transaction(*this, TransactionType_ReadWrite); |
0 | 211 |
212 // Remove all the large objects | |
213 Execute("SELECT lo_unlink(loid) FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) as loids;"); | |
214 | |
215 // http://stackoverflow.com/a/21247009/881731 | |
216 Execute("DROP SCHEMA public CASCADE;"); | |
217 Execute("CREATE SCHEMA public;"); | |
218 Execute("GRANT ALL ON SCHEMA public TO postgres;"); | |
219 Execute("GRANT ALL ON SCHEMA public TO public;"); | |
220 Execute("COMMENT ON SCHEMA public IS 'standard public schema';"); | |
221 | |
222 transaction.Commit(); | |
223 } | |
224 | |
225 | |
226 IPrecompiledStatement* PostgreSQLDatabase::Compile(const Query& query) | |
227 { | |
228 return new PostgreSQLStatement(*this, query); | |
229 } | |
230 | |
231 | |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
232 namespace |
0 | 233 { |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
234 class PostgreSQLImplicitTransaction : public ImplicitTransaction |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
235 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
236 protected: |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
237 virtual IResult* ExecuteInternal(IPrecompiledStatement& statement, |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
238 const Dictionary& parameters) |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
239 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
240 return dynamic_cast<PostgreSQLStatement&>(statement).Execute(*this, parameters); |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
241 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
242 |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
243 virtual void ExecuteWithoutResultInternal(IPrecompiledStatement& statement, |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
244 const Dictionary& parameters) |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
245 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
246 dynamic_cast<PostgreSQLStatement&>(statement).ExecuteWithoutResult(*this, parameters); |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
247 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
248 }; |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
249 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
250 |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
251 |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
252 ITransaction* PostgreSQLDatabase::CreateTransaction(TransactionType type) |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
253 { |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
254 switch (type) |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
255 { |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
256 case TransactionType_Implicit: |
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
257 return new PostgreSQLImplicitTransaction; |
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
258 |
216
fbb52129158a
TransactionType given to PostgreSQLTransaction constructor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
215
diff
changeset
|
259 case TransactionType_ReadWrite: |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
260 case TransactionType_ReadOnly: |
216
fbb52129158a
TransactionType given to PostgreSQLTransaction constructor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
215
diff
changeset
|
261 return new PostgreSQLTransaction(*this, type); |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
262 |
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
263 default: |
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
264 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
265 } |
0 | 266 } |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
267 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
268 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
269 PostgreSQLDatabase::TransientAdvisoryLock::TransientAdvisoryLock( |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
270 PostgreSQLDatabase& database, |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
271 int32_t lock) : |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
272 database_(database), |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
273 lock_(lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
274 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
275 bool locked = true; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
276 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
277 for (unsigned int i = 0; i < 10; i++) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
278 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
279 if (database_.AcquireAdvisoryLock(lock_)) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
280 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
281 locked = false; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
282 break; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
283 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
284 else |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
285 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
286 boost::this_thread::sleep(boost::posix_time::milliseconds(500)); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
287 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
288 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
289 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
290 if (locked) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
291 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
292 LOG(ERROR) << "Cannot acquire a transient advisory lock"; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
293 throw Orthanc::OrthancException(Orthanc::ErrorCode_Plugin); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
294 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
295 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
296 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
297 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
298 PostgreSQLDatabase::TransientAdvisoryLock::~TransientAdvisoryLock() |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
299 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
300 database_.ReleaseAdvisoryLock(lock_); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
301 } |
226
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
302 |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
303 |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
304 PostgreSQLDatabase* PostgreSQLDatabase::OpenDatabaseConnection(const PostgreSQLParameters& parameters) |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
305 { |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
306 class Factory : public RetryDatabaseFactory |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
307 { |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
308 private: |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
309 const PostgreSQLParameters& parameters_; |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
310 |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
311 protected: |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
312 virtual IDatabase* TryOpen() |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
313 { |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
314 std::unique_ptr<PostgreSQLDatabase> db(new PostgreSQLDatabase(parameters_)); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
315 db->Open(); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
316 return db.release(); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
317 } |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
318 |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
319 public: |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
320 Factory(const PostgreSQLParameters& parameters) : |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
321 RetryDatabaseFactory(parameters.GetMaxConnectionRetries(), |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
322 parameters.GetConnectionRetryInterval()), |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
323 parameters_(parameters) |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
324 { |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
325 } |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
326 }; |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
327 |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
328 Factory factory(parameters); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
329 return dynamic_cast<PostgreSQLDatabase*>(factory.Open()); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
330 } |
0 | 331 } |