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 }