Mercurial > hg > orthanc-databases
annotate Framework/PostgreSQL/PostgreSQLDatabase.cpp @ 240:c82c2cf84ae8
added handling of CR_COMMANDS_OUT_OF_SYNC
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 12 Apr 2021 17:07:06 +0200 |
parents | 35598014f140 |
children | 33fa478c119a |
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 | |
237
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
158 void PostgreSQLDatabase::ExecuteMultiLines(const std::string& sql) |
0 | 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 | |
237
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
213 ExecuteMultiLines("SELECT lo_unlink(loid) FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) as loids;"); |
0 | 214 |
215 // http://stackoverflow.com/a/21247009/881731 | |
237
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
216 ExecuteMultiLines("DROP SCHEMA public CASCADE;"); |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
217 ExecuteMultiLines("CREATE SCHEMA public;"); |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
218 ExecuteMultiLines("GRANT ALL ON SCHEMA public TO postgres;"); |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
219 ExecuteMultiLines("GRANT ALL ON SCHEMA public TO public;"); |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
220 ExecuteMultiLines("COMMENT ON SCHEMA public IS 'standard public schema';"); |
0 | 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 { |
237
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
236 private: |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
237 PostgreSQLDatabase& db_; |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
238 |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
239 protected: |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
240 virtual IResult* ExecuteInternal(IPrecompiledStatement& statement, |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
241 const Dictionary& parameters) |
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 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
|
244 } |
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 virtual void ExecuteWithoutResultInternal(IPrecompiledStatement& statement, |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
247 const Dictionary& parameters) |
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 dynamic_cast<PostgreSQLStatement&>(statement).ExecuteWithoutResult(*this, parameters); |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
250 } |
237
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
251 |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
252 public: |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
253 PostgreSQLImplicitTransaction(PostgreSQLDatabase& db) : |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
254 db_(db) |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
255 { |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
256 } |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
257 |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
258 virtual bool DoesTableExist(const std::string& name) ORTHANC_OVERRIDE |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
259 { |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
260 return db_.DoesTableExist(name.c_str()); |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
261 } |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
262 |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
263 virtual bool DoesTriggerExist(const std::string& name) ORTHANC_OVERRIDE |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
264 { |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
265 return false; |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
266 } |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
267 |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
268 virtual void ExecuteMultiLines(const std::string& query) ORTHANC_OVERRIDE |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
269 { |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
270 db_.ExecuteMultiLines(query); |
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
271 } |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
272 }; |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
273 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
274 |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
275 |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
276 ITransaction* PostgreSQLDatabase::CreateTransaction(TransactionType type) |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
277 { |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
278 switch (type) |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
279 { |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
280 case TransactionType_Implicit: |
237
35598014f140
refactoring to remove GlobalProperties.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
226
diff
changeset
|
281 return new PostgreSQLImplicitTransaction(*this); |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
282 |
216
fbb52129158a
TransactionType given to PostgreSQLTransaction constructor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
215
diff
changeset
|
283 case TransactionType_ReadWrite: |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
284 case TransactionType_ReadOnly: |
216
fbb52129158a
TransactionType given to PostgreSQLTransaction constructor
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
215
diff
changeset
|
285 return new PostgreSQLTransaction(*this, type); |
215
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
286 |
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
287 default: |
b40b30075c51
added TransactionType_Implicit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
288 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
289 } |
0 | 290 } |
134
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 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
293 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
|
294 PostgreSQLDatabase& database, |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
295 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
|
296 database_(database), |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
297 lock_(lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
298 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
299 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
|
300 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
301 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
|
302 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
303 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
|
304 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
305 locked = false; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
306 break; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
307 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
308 else |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
309 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
310 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
|
311 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
312 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
313 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
314 if (locked) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
315 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
316 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
|
317 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
|
318 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
319 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
320 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
321 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
322 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
|
323 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
324 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
|
325 } |
226
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 PostgreSQLDatabase* PostgreSQLDatabase::OpenDatabaseConnection(const PostgreSQLParameters& parameters) |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
329 { |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
330 class Factory : public RetryDatabaseFactory |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
331 { |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
332 private: |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
333 const PostgreSQLParameters& parameters_; |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
334 |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
335 protected: |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
336 virtual IDatabase* TryOpen() |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
337 { |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
338 std::unique_ptr<PostgreSQLDatabase> db(new PostgreSQLDatabase(parameters_)); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
339 db->Open(); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
340 return db.release(); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
341 } |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
342 |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
343 public: |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
344 Factory(const PostgreSQLParameters& parameters) : |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
345 RetryDatabaseFactory(parameters.GetMaxConnectionRetries(), |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
346 parameters.GetConnectionRetryInterval()), |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
347 parameters_(parameters) |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
348 { |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
349 } |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
350 }; |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
351 |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
352 Factory factory(parameters); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
353 return dynamic_cast<PostgreSQLDatabase*>(factory.Open()); |
a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
216
diff
changeset
|
354 } |
0 | 355 } |