Mercurial > hg > orthanc-databases
comparison Framework/Plugins/StorageBackend.cpp @ 230:675f8322eb7c
refactored StorageBackend by introducing an accessor class
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 06 Apr 2021 11:17:00 +0200 |
parents | a4918d57435c |
children | 0a9b48d19643 |
comparison
equal
deleted
inserted
replaced
229:5744f09b0b1b | 230:675f8322eb7c |
---|---|
82 return *manager_; | 82 return *manager_; |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 | 86 |
87 void StorageBackend::Create(DatabaseManager::Transaction& transaction, | 87 void StorageBackend::Accessor::Create(const std::string& uuid, |
88 const std::string& uuid, | 88 const void* content, |
89 const void* content, | 89 size_t size, |
90 size_t size, | 90 OrthancPluginContentType type) |
91 OrthancPluginContentType type) | 91 { |
92 { | 92 DatabaseManager::Transaction transaction(manager_, TransactionType_ReadWrite); |
93 DatabaseManager::CachedStatement statement( | 93 |
94 STATEMENT_FROM_HERE, GetManager(), | 94 { |
95 "INSERT INTO StorageArea VALUES (${uuid}, ${content}, ${type})"); | 95 DatabaseManager::CachedStatement statement( |
96 | 96 STATEMENT_FROM_HERE, manager_, |
97 statement.SetParameterType("uuid", ValueType_Utf8String); | 97 "INSERT INTO StorageArea VALUES (${uuid}, ${content}, ${type})"); |
98 statement.SetParameterType("content", ValueType_File); | 98 |
99 statement.SetParameterType("type", ValueType_Integer64); | 99 statement.SetParameterType("uuid", ValueType_Utf8String); |
100 | 100 statement.SetParameterType("content", ValueType_File); |
101 Dictionary args; | 101 statement.SetParameterType("type", ValueType_Integer64); |
102 args.SetUtf8Value("uuid", uuid); | 102 |
103 args.SetFileValue("content", content, size); | 103 Dictionary args; |
104 args.SetIntegerValue("type", type); | 104 args.SetUtf8Value("uuid", uuid); |
105 | 105 args.SetFileValue("content", content, size); |
106 statement.Execute(args); | 106 args.SetIntegerValue("type", type); |
107 } | 107 |
108 | 108 statement.Execute(args); |
109 | 109 } |
110 void StorageBackend::Read(StorageBackend::IFileContentVisitor& target, | 110 |
111 DatabaseManager::Transaction& transaction, | 111 transaction.Commit(); |
112 const std::string& uuid, | 112 } |
113 OrthancPluginContentType type) | 113 |
114 { | 114 |
115 DatabaseManager::CachedStatement statement( | 115 void StorageBackend::Accessor::Read(StorageBackend::IFileContentVisitor& visitor, |
116 STATEMENT_FROM_HERE, GetManager(), | 116 const std::string& uuid, |
117 "SELECT content FROM StorageArea WHERE uuid=${uuid} AND type=${type}"); | 117 OrthancPluginContentType type) |
118 | 118 { |
119 statement.SetParameterType("uuid", ValueType_Utf8String); | 119 DatabaseManager::Transaction transaction(manager_, TransactionType_ReadOnly); |
120 statement.SetParameterType("type", ValueType_Integer64); | 120 |
121 | 121 { |
122 Dictionary args; | 122 DatabaseManager::CachedStatement statement( |
123 args.SetUtf8Value("uuid", uuid); | 123 STATEMENT_FROM_HERE, manager_, |
124 args.SetIntegerValue("type", type); | 124 "SELECT content FROM StorageArea WHERE uuid=${uuid} AND type=${type}"); |
125 | 125 |
126 statement.Execute(args); | 126 statement.SetParameterType("uuid", ValueType_Utf8String); |
127 | 127 statement.SetParameterType("type", ValueType_Integer64); |
128 if (statement.IsDone()) | 128 |
129 { | 129 Dictionary args; |
130 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); | 130 args.SetUtf8Value("uuid", uuid); |
131 } | 131 args.SetIntegerValue("type", type); |
132 else if (statement.GetResultFieldsCount() != 1) | 132 |
133 { | 133 statement.Execute(args); |
134 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | 134 |
135 } | 135 if (statement.IsDone()) |
136 else | 136 { |
137 { | 137 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); |
138 const IValue& value = statement.GetResultField(0); | 138 } |
139 | 139 else if (statement.GetResultFieldsCount() != 1) |
140 switch (value.GetType()) | 140 { |
141 { | 141 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); |
142 case ValueType_File: | 142 } |
143 target.Assign(dynamic_cast<const FileValue&>(value).GetContent()); | 143 else |
144 break; | 144 { |
145 | 145 const IValue& value = statement.GetResultField(0); |
146 case ValueType_BinaryString: | 146 |
147 target.Assign(dynamic_cast<const BinaryStringValue&>(value).GetContent()); | 147 switch (value.GetType()) |
148 break; | 148 { |
149 | 149 case ValueType_File: |
150 default: | 150 visitor.Assign(dynamic_cast<const FileValue&>(value).GetContent()); |
151 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | 151 break; |
152 } | 152 |
153 } | 153 case ValueType_BinaryString: |
154 } | 154 visitor.Assign(dynamic_cast<const BinaryStringValue&>(value).GetContent()); |
155 | 155 break; |
156 | 156 |
157 void StorageBackend::Remove(DatabaseManager::Transaction& transaction, | 157 default: |
158 const std::string& uuid, | 158 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); |
159 OrthancPluginContentType type) | 159 } |
160 { | 160 } |
161 DatabaseManager::CachedStatement statement( | 161 } |
162 STATEMENT_FROM_HERE, GetManager(), | 162 |
163 "DELETE FROM StorageArea WHERE uuid=${uuid} AND type=${type}"); | 163 transaction.Commit(); |
164 | 164 |
165 statement.SetParameterType("uuid", ValueType_Utf8String); | 165 if (!visitor.IsSuccess()) |
166 statement.SetParameterType("type", ValueType_Integer64); | 166 { |
167 | 167 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database, "Could not read attachment from the storage area"); |
168 Dictionary args; | 168 } |
169 args.SetUtf8Value("uuid", uuid); | 169 } |
170 args.SetIntegerValue("type", type); | 170 |
171 | 171 |
172 statement.Execute(args); | 172 void StorageBackend::Accessor::Remove(const std::string& uuid, |
173 OrthancPluginContentType type) | |
174 { | |
175 DatabaseManager::Transaction transaction(manager_, TransactionType_ReadWrite); | |
176 | |
177 { | |
178 DatabaseManager::CachedStatement statement( | |
179 STATEMENT_FROM_HERE, manager_, | |
180 "DELETE FROM StorageArea WHERE uuid=${uuid} AND type=${type}"); | |
181 | |
182 statement.SetParameterType("uuid", ValueType_Utf8String); | |
183 statement.SetParameterType("type", ValueType_Integer64); | |
184 | |
185 Dictionary args; | |
186 args.SetUtf8Value("uuid", uuid); | |
187 args.SetIntegerValue("type", type); | |
188 | |
189 statement.Execute(args); | |
190 } | |
191 | |
192 transaction.Commit(); | |
173 } | 193 } |
174 | 194 |
175 | 195 |
176 | 196 |
177 static OrthancPluginContext* context_ = NULL; | 197 static OrthancPluginContext* context_ = NULL; |
187 { | 207 { |
188 if (backend_.get() == NULL) | 208 if (backend_.get() == NULL) |
189 { | 209 { |
190 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | 210 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
191 } | 211 } |
192 | 212 else |
193 DatabaseManager::Transaction transaction(backend_->GetManager(), TransactionType_ReadWrite); | 213 { |
194 backend_->Create(transaction, uuid, content, static_cast<size_t>(size), type); | 214 StorageBackend::Accessor accessor(*backend_); |
195 transaction.Commit(); | 215 accessor.Create(uuid, content, static_cast<size_t>(size), type); |
196 return OrthancPluginErrorCode_Success; | 216 return OrthancPluginErrorCode_Success; |
217 } | |
197 } | 218 } |
198 ORTHANC_PLUGINS_DATABASE_CATCH; | 219 ORTHANC_PLUGINS_DATABASE_CATCH; |
199 } | 220 } |
200 | 221 |
201 | 222 |
215 target_(target), | 236 target_(target), |
216 success_(false) | 237 success_(false) |
217 { | 238 { |
218 } | 239 } |
219 | 240 |
220 bool IsSuccess() const | 241 virtual bool IsSuccess() const ORTHANC_OVERRIDE |
221 { | 242 { |
222 return success_; | 243 return success_; |
223 } | 244 } |
224 | 245 |
225 virtual void Assign(const std::string& content) ORTHANC_OVERRIDE | 246 virtual void Assign(const std::string& content) ORTHANC_OVERRIDE |
252 { | 273 { |
253 if (backend_.get() == NULL) | 274 if (backend_.get() == NULL) |
254 { | 275 { |
255 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | 276 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
256 } | 277 } |
257 | 278 else if (target == NULL) |
258 if (target == NULL) | |
259 { | 279 { |
260 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | 280 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); |
261 } | 281 } |
262 | 282 else |
263 Visitor visitor(target); | 283 { |
264 | 284 Visitor visitor(target); |
265 { | 285 |
266 DatabaseManager::Transaction transaction(backend_->GetManager(), TransactionType_ReadOnly); | 286 { |
267 backend_->Read(visitor, transaction, uuid, type); | 287 StorageBackend::Accessor accessor(*backend_); |
268 | 288 accessor.Read(visitor, uuid, type); |
269 if (!visitor.IsSuccess()) | 289 } |
270 { | 290 |
271 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | 291 return OrthancPluginErrorCode_Success; |
272 } | 292 } |
273 | |
274 transaction.Commit(); | |
275 } | |
276 | |
277 return OrthancPluginErrorCode_Success; | |
278 } | 293 } |
279 ORTHANC_PLUGINS_DATABASE_CATCH; | 294 ORTHANC_PLUGINS_DATABASE_CATCH; |
280 } | 295 } |
281 #endif | 296 #endif |
282 | 297 |
300 size_(size), | 315 size_(size), |
301 success_(false) | 316 success_(false) |
302 { | 317 { |
303 } | 318 } |
304 | 319 |
305 bool IsSuccess() const | 320 virtual bool IsSuccess() const ORTHANC_OVERRIDE |
306 { | 321 { |
307 return success_; | 322 return success_; |
308 } | 323 } |
309 | 324 |
310 virtual void Assign(const std::string& content) ORTHANC_OVERRIDE | 325 virtual void Assign(const std::string& content) ORTHANC_OVERRIDE |
349 { | 364 { |
350 if (backend_.get() == NULL) | 365 if (backend_.get() == NULL) |
351 { | 366 { |
352 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | 367 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
353 } | 368 } |
354 | 369 else if (data == NULL || |
355 if (data == NULL || | 370 size == NULL) |
356 size == NULL) | |
357 { | 371 { |
358 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | 372 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); |
359 } | 373 } |
360 | 374 else |
361 Visitor visitor(data, size); | 375 { |
362 | 376 Visitor visitor(data, size); |
363 { | 377 |
364 DatabaseManager::Transaction transaction(backend_->GetManager(), TransactionType_ReadOnly); | 378 { |
365 backend_->Read(visitor, transaction, uuid, type); | 379 StorageBackend::Accessor accessor(*backend_); |
366 | 380 accessor.Read(visitor, uuid, type); |
367 if (!visitor.IsSuccess()) | 381 } |
368 { | 382 |
369 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | 383 return OrthancPluginErrorCode_Success; |
370 } | 384 } |
371 | |
372 transaction.Commit(); | |
373 } | |
374 | |
375 return OrthancPluginErrorCode_Success; | |
376 } | 385 } |
377 ORTHANC_PLUGINS_DATABASE_CATCH; | 386 ORTHANC_PLUGINS_DATABASE_CATCH; |
378 } | 387 } |
379 | 388 |
380 | 389 |
381 static OrthancPluginErrorCode StorageRemove(const char* uuid, | 390 static OrthancPluginErrorCode StorageRemove(const char* uuid, |
382 OrthancPluginContentType type) | 391 OrthancPluginContentType type) |
383 { | 392 { |
384 try | 393 try |
385 { | 394 { |
386 DatabaseManager::Transaction transaction(backend_->GetManager(), TransactionType_ReadWrite); | 395 if (backend_.get() == NULL) |
387 backend_->Remove(transaction, uuid, type); | 396 { |
388 transaction.Commit(); | 397 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
389 return OrthancPluginErrorCode_Success; | 398 } |
399 else | |
400 { | |
401 StorageBackend::Accessor accessor(*backend_); | |
402 accessor.Remove(uuid, type); | |
403 return OrthancPluginErrorCode_Success; | |
404 } | |
390 } | 405 } |
391 ORTHANC_PLUGINS_DATABASE_CATCH; | 406 ORTHANC_PLUGINS_DATABASE_CATCH; |
392 } | 407 } |
393 | 408 |
394 | 409 |
438 backend_.reset(NULL); | 453 backend_.reset(NULL); |
439 context_ = NULL; | 454 context_ = NULL; |
440 } | 455 } |
441 | 456 |
442 | 457 |
443 void StorageBackend::ReadToString(std::string& target, | 458 void StorageBackend::Accessor::ReadToString(std::string& target, |
444 DatabaseManager::Transaction& transaction, | 459 const std::string& uuid, |
445 const std::string& uuid, | 460 OrthancPluginContentType type) |
446 OrthancPluginContentType type) | |
447 { | 461 { |
448 class Visitor : public StorageBackend::IFileContentVisitor | 462 class Visitor : public StorageBackend::IFileContentVisitor |
449 { | 463 { |
450 private: | 464 private: |
451 std::string& target_; | 465 std::string& target_; |
456 target_(target), | 470 target_(target), |
457 success_(false) | 471 success_(false) |
458 { | 472 { |
459 } | 473 } |
460 | 474 |
461 bool IsSuccess() const | 475 virtual bool IsSuccess() const ORTHANC_OVERRIDE |
462 { | 476 { |
463 return success_; | 477 return success_; |
464 } | 478 } |
465 | 479 |
466 virtual void Assign(const std::string& content) ORTHANC_OVERRIDE | 480 virtual void Assign(const std::string& content) ORTHANC_OVERRIDE |
477 } | 491 } |
478 }; | 492 }; |
479 | 493 |
480 | 494 |
481 Visitor visitor(target); | 495 Visitor visitor(target); |
482 | 496 Read(visitor, uuid, type); |
483 Read(visitor, transaction, uuid, type); | |
484 | |
485 if (!visitor.IsSuccess()) | |
486 { | |
487 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | |
488 } | |
489 } | 497 } |
490 } | 498 } |