comparison OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp @ 5209:154d37a56500 db-protobuf

started implementation of transactions
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 31 Mar 2023 17:33:33 +0200
parents e7529e6241d2
children 6a7a244c777d
comparison
equal deleted inserted replaced
5207:e7529e6241d2 5209:154d37a56500
36 #include <cassert> 36 #include <cassert>
37 37
38 38
39 namespace Orthanc 39 namespace Orthanc
40 { 40 {
41 static void CheckSuccess(PluginsErrorDictionary& errorDictionary,
42 OrthancPluginErrorCode code)
43 {
44 if (code != OrthancPluginErrorCode_Success)
45 {
46 errorDictionary.LogError(code, true);
47 throw OrthancException(static_cast<ErrorCode>(code));
48 }
49 }
50
51
52 static FileInfo Convert(const DatabasePluginMessages::FileInfo& source)
53 {
54 return FileInfo(source.uuid(),
55 static_cast<FileContentType>(source.content_type()),
56 source.uncompressed_size(),
57 source.uncompressed_hash(),
58 static_cast<CompressionType>(source.compression_type()),
59 source.compressed_size(),
60 source.compressed_hash());
61 }
62
63
64 static ResourceType Convert(DatabasePluginMessages::ResourceType type)
65 {
66 switch (type)
67 {
68 case DatabasePluginMessages::RESOURCE_PATIENT:
69 return ResourceType_Patient;
70
71 case DatabasePluginMessages::RESOURCE_STUDY:
72 return ResourceType_Study;
73
74 case DatabasePluginMessages::RESOURCE_SERIES:
75 return ResourceType_Series;
76
77 case DatabasePluginMessages::RESOURCE_INSTANCE:
78 return ResourceType_Instance;
79
80 default:
81 throw OrthancException(ErrorCode_ParameterOutOfRange);
82 }
83 }
84
85
86 static DatabasePluginMessages::ResourceType Convert(ResourceType type)
87 {
88 switch (type)
89 {
90 case ResourceType_Patient:
91 return DatabasePluginMessages::RESOURCE_PATIENT;
92
93 case ResourceType_Study:
94 return DatabasePluginMessages::RESOURCE_STUDY;
95
96 case ResourceType_Series:
97 return DatabasePluginMessages::RESOURCE_SERIES;
98
99 case ResourceType_Instance:
100 return DatabasePluginMessages::RESOURCE_INSTANCE;
101
102 default:
103 throw OrthancException(ErrorCode_ParameterOutOfRange);
104 }
105 }
106
107
108 static void Execute(DatabasePluginMessages::Response& response,
109 const OrthancPluginDatabaseV4& database,
110 const DatabasePluginMessages::Request& request)
111 {
112 std::string requestSerialized;
113 request.SerializeToString(&requestSerialized);
114
115 OrthancPluginMemoryBuffer64 responseSerialized;
116 CheckSuccess(database.GetErrorDictionary(), database.GetDefinition().operations(
117 &responseSerialized, database.GetDefinition().backend,
118 requestSerialized.empty() ? NULL : requestSerialized.c_str(),
119 requestSerialized.size()));
120
121 bool success = response.ParseFromArray(responseSerialized.data, responseSerialized.size);
122
123 if (responseSerialized.size > 0)
124 {
125 free(responseSerialized.data);
126 }
127
128 if (!success)
129 {
130 throw OrthancException(ErrorCode_DatabasePlugin, "Cannot unserialize protobuf originating from the database plugin");
131 }
132 }
133
134
135 static void ExecuteDatabase(DatabasePluginMessages::DatabaseResponse& response,
136 const OrthancPluginDatabaseV4& database,
137 DatabasePluginMessages::DatabaseOperation operation,
138 const DatabasePluginMessages::DatabaseRequest& request)
139 {
140 DatabasePluginMessages::Request fullRequest;
141 fullRequest.set_type(DatabasePluginMessages::REQUEST_DATABASE);
142 fullRequest.mutable_database_request()->CopyFrom(request);
143 fullRequest.mutable_database_request()->set_operation(operation);
144
145 DatabasePluginMessages::Response fullResponse;
146 Execute(fullResponse, database, fullRequest);
147
148 response.CopyFrom(fullResponse.database_response());
149 }
150
151
41 class OrthancPluginDatabaseV4::Transaction : public IDatabaseWrapper::ITransaction 152 class OrthancPluginDatabaseV4::Transaction : public IDatabaseWrapper::ITransaction
42 { 153 {
43 private: 154 private:
44 OrthancPluginDatabaseV4& that_; 155 OrthancPluginDatabaseV4& database_;
45 IDatabaseListener& listener_; 156 IDatabaseListener& listener_;
46 void* transaction_; 157 void* transaction_;
47 158
48 void CheckSuccess(OrthancPluginErrorCode code) const 159 void ExecuteTransaction(DatabasePluginMessages::TransactionResponse& response,
49 { 160 DatabasePluginMessages::TransactionOperation operation,
50 that_.CheckSuccess(code); 161 const DatabasePluginMessages::TransactionRequest& request)
51 } 162 {
52 163 DatabasePluginMessages::Request fullRequest;
164 fullRequest.set_type(DatabasePluginMessages::REQUEST_TRANSACTION);
165 fullRequest.mutable_transaction_request()->CopyFrom(request);
166 fullRequest.mutable_transaction_request()->set_transaction(reinterpret_cast<intptr_t>(transaction_));
167 fullRequest.mutable_transaction_request()->set_operation(operation);
168
169 DatabasePluginMessages::Response fullResponse;
170 Execute(fullResponse, database_, fullRequest);
171
172 response.CopyFrom(fullResponse.transaction_response());
173 }
174
175
176 void ExecuteTransaction(DatabasePluginMessages::TransactionOperation operation,
177 const DatabasePluginMessages::TransactionRequest& request)
178 {
179 DatabasePluginMessages::TransactionResponse response; // Ignored
180 ExecuteTransaction(response, operation, request);
181 }
182
183
184 void ExecuteTransaction(DatabasePluginMessages::TransactionOperation operation)
185 {
186 DatabasePluginMessages::TransactionResponse response; // Ignored
187 DatabasePluginMessages::TransactionRequest request; // Ignored
188 ExecuteTransaction(response, operation, request);
189 }
190
191
53 public: 192 public:
54 Transaction(OrthancPluginDatabaseV4& that, 193 Transaction(OrthancPluginDatabaseV4& database,
55 IDatabaseListener& listener, 194 IDatabaseListener& listener,
56 TransactionType type) : 195 void* transaction) :
57 that_(that), 196 database_(database),
58 listener_(listener) 197 listener_(listener),
59 { 198 transaction_(transaction)
60 #if 0 199 {
61 CheckSuccess(that.database_.startTransaction(that.database_, &transaction_, type)); 200 }
62 if (transaction_ == NULL) 201
63 { 202
64 throw OrthancException(ErrorCode_DatabasePlugin); 203 virtual ~Transaction()
204 {
205 {
206 DatabasePluginMessages::DatabaseRequest request;
207 request.mutable_finalize_transaction()->set_transaction(reinterpret_cast<intptr_t>(transaction_));
208
209 DatabasePluginMessages::DatabaseResponse response;
210 ExecuteDatabase(response, database_, DatabasePluginMessages::OPERATION_FINALIZE_TRANSACTION, request);
65 } 211 }
66 #endif
67 }
68
69
70 virtual ~Transaction()
71 {
72 #if 0
73 OrthancPluginErrorCode code = that_.database_.destructTransaction(transaction_);
74 if (code != OrthancPluginErrorCode_Success)
75 {
76 // Don't throw exception in destructors
77 that_.errorDictionary_.LogError(code, true);
78 }
79 #endif
80 } 212 }
81 213
82 214
83 virtual void Rollback() ORTHANC_OVERRIDE 215 virtual void Rollback() ORTHANC_OVERRIDE
84 { 216 {
217 ExecuteTransaction(DatabasePluginMessages::OPERATION_ROLLBACK);
85 } 218 }
86 219
87 220
88 virtual void Commit(int64_t fileSizeDelta) ORTHANC_OVERRIDE 221 virtual void Commit(int64_t fileSizeDelta) ORTHANC_OVERRIDE
89 { 222 {
223 {
224 DatabasePluginMessages::TransactionRequest request;
225 request.mutable_commit()->set_file_size_delta(fileSizeDelta);
226
227 ExecuteTransaction(DatabasePluginMessages::OPERATION_COMMIT, request);
228 }
90 } 229 }
91 230
92 231
93 virtual void AddAttachment(int64_t id, 232 virtual void AddAttachment(int64_t id,
94 const FileInfo& attachment, 233 const FileInfo& attachment,
95 int64_t revision) ORTHANC_OVERRIDE 234 int64_t revision) ORTHANC_OVERRIDE
96 { 235 {
236 {
237 DatabasePluginMessages::TransactionRequest request;
238 request.mutable_add_attachment()->set_id(id);
239 request.mutable_add_attachment()->mutable_attachment()->set_uuid(attachment.GetUuid());
240 request.mutable_add_attachment()->mutable_attachment()->set_content_type(attachment.GetContentType());
241 request.mutable_add_attachment()->mutable_attachment()->set_uncompressed_size(attachment.GetUncompressedSize());
242 request.mutable_add_attachment()->mutable_attachment()->set_uncompressed_hash(attachment.GetUncompressedMD5());
243 request.mutable_add_attachment()->mutable_attachment()->set_compression_type(attachment.GetCompressionType());
244 request.mutable_add_attachment()->mutable_attachment()->set_compressed_size(attachment.GetCompressedSize());
245 request.mutable_add_attachment()->mutable_attachment()->set_compressed_hash(attachment.GetCompressedMD5());
246 request.mutable_add_attachment()->set_revision(revision);
247
248 ExecuteTransaction(DatabasePluginMessages::OPERATION_ADD_ATTACHMENT, request);
249 }
97 } 250 }
98 251
99 252
100 virtual void ClearChanges() ORTHANC_OVERRIDE 253 virtual void ClearChanges() ORTHANC_OVERRIDE
101 { 254 {
255 ExecuteTransaction(DatabasePluginMessages::OPERATION_CLEAR_CHANGES);
102 } 256 }
103 257
104 258
105 virtual void ClearExportedResources() ORTHANC_OVERRIDE 259 virtual void ClearExportedResources() ORTHANC_OVERRIDE
106 { 260 {
107 } 261 ExecuteTransaction(DatabasePluginMessages::OPERATION_CLEAR_EXPORTED_RESOURCES);
108 262 }
109 263
264
110 virtual void DeleteAttachment(int64_t id, 265 virtual void DeleteAttachment(int64_t id,
111 FileContentType attachment) ORTHANC_OVERRIDE 266 FileContentType attachment) ORTHANC_OVERRIDE
112 { 267 {
268 {
269 DatabasePluginMessages::TransactionRequest request;
270 request.mutable_delete_attachment()->set_id(id);
271 request.mutable_delete_attachment()->set_type(attachment);
272
273 DatabasePluginMessages::TransactionResponse response;
274 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_DELETE_ATTACHMENT, request);
275
276 listener_.SignalAttachmentDeleted(Convert(response.delete_attachment().deleted_attachment()));
277 }
113 } 278 }
114 279
115 280
116 virtual void DeleteMetadata(int64_t id, 281 virtual void DeleteMetadata(int64_t id,
117 MetadataType type) ORTHANC_OVERRIDE 282 MetadataType type) ORTHANC_OVERRIDE
118 { 283 {
284 {
285 DatabasePluginMessages::TransactionRequest request;
286 request.mutable_delete_metadata()->set_id(id);
287 request.mutable_delete_metadata()->set_type(type);
288
289 ExecuteTransaction(DatabasePluginMessages::OPERATION_DELETE_METADATA, request);
290 }
119 } 291 }
120 292
121 293
122 virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE 294 virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE
123 { 295 {
296 {
297 DatabasePluginMessages::TransactionRequest request;
298 request.mutable_delete_resource()->set_id(id);
299
300 DatabasePluginMessages::TransactionResponse response;
301 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_DELETE_RESOURCE, request);
302
303 for (int i = 0; i < response.delete_resource().deleted_attachments().size(); i++)
304 {
305 listener_.SignalAttachmentDeleted(Convert(response.delete_resource().deleted_attachments(i)));
306 }
307
308 for (int i = 0; i < response.delete_resource().deleted_resources().size(); i++)
309 {
310 listener_.SignalResourceDeleted(Convert(response.delete_resource().deleted_resources(i).level()),
311 response.delete_resource().deleted_resources(i).public_id());
312 }
313
314 if (response.delete_resource().is_remaining_ancestor())
315 {
316 listener_.SignalRemainingAncestor(Convert(response.delete_resource().remaining_ancestor().level()),
317 response.delete_resource().remaining_ancestor().public_id());
318 }
319 }
124 } 320 }
125 321
126 322
127 virtual void GetAllMetadata(std::map<MetadataType, std::string>& target, 323 virtual void GetAllMetadata(std::map<MetadataType, std::string>& target,
128 int64_t id) ORTHANC_OVERRIDE 324 int64_t id) ORTHANC_OVERRIDE
129 { 325 {
326 {
327 DatabasePluginMessages::TransactionRequest request;
328 request.mutable_get_all_metadata()->set_id(id);
329
330 DatabasePluginMessages::TransactionResponse response;
331 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_ALL_METADATA, request);
332
333 target.clear();
334 for (int i = 0; i < response.get_all_metadata().metadata().size(); i++)
335 {
336 MetadataType key = static_cast<MetadataType>(response.get_all_metadata().metadata(i).type());
337
338 if (target.find(key) == target.end())
339 {
340 target[key] = response.get_all_metadata().metadata(i).value();
341 }
342 else
343 {
344 throw OrthancException(ErrorCode_DatabasePlugin);
345 }
346 }
347 }
130 } 348 }
131 349
132 350
133 virtual void GetAllPublicIds(std::list<std::string>& target, 351 virtual void GetAllPublicIds(std::list<std::string>& target,
134 ResourceType resourceType) ORTHANC_OVERRIDE 352 ResourceType resourceType) ORTHANC_OVERRIDE
135 { 353 {
354 {
355 DatabasePluginMessages::TransactionRequest request;
356 request.mutable_get_all_public_ids()->set_resource_type(Convert(resourceType));
357
358 DatabasePluginMessages::TransactionResponse response;
359 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_ALL_PUBLIC_IDS, request);
360
361 target.clear();
362 for (int i = 0; i < response.get_all_public_ids().ids().size(); i++)
363 {
364 target.push_back(response.get_all_public_ids().ids(i));
365 }
366 }
136 } 367 }
137 368
138 369
139 virtual void GetAllPublicIds(std::list<std::string>& target, 370 virtual void GetAllPublicIds(std::list<std::string>& target,
140 ResourceType resourceType, 371 ResourceType resourceType,
141 size_t since, 372 size_t since,
142 size_t limit) ORTHANC_OVERRIDE 373 size_t limit) ORTHANC_OVERRIDE
143 { 374 {
375 {
376 DatabasePluginMessages::TransactionRequest request;
377 request.mutable_get_all_public_ids_with_limits()->set_resource_type(Convert(resourceType));
378 request.mutable_get_all_public_ids_with_limits()->set_since(since);
379 request.mutable_get_all_public_ids_with_limits()->set_limit(limit);
380
381 DatabasePluginMessages::TransactionResponse response;
382 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_ALL_PUBLIC_IDS_WITH_LIMITS, request);
383
384 target.clear();
385 for (int i = 0; i < response.get_all_public_ids_with_limits().ids().size(); i++)
386 {
387 target.push_back(response.get_all_public_ids_with_limits().ids(i));
388 }
389 }
144 } 390 }
145 391
146 392
147 virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/, 393 virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/,
148 bool& done /*out*/, 394 bool& done /*out*/,
169 int64_t since, 415 int64_t since,
170 uint32_t maxResults) ORTHANC_OVERRIDE 416 uint32_t maxResults) ORTHANC_OVERRIDE
171 { 417 {
172 } 418 }
173 419
174 420
421 virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/) ORTHANC_OVERRIDE
422 {
423 }
424
425
175 virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/) ORTHANC_OVERRIDE 426 virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/) ORTHANC_OVERRIDE
176 { 427 {
177 } 428 }
178 429
179 430
351 { 602 {
352 } 603 }
353 }; 604 };
354 605
355 606
356 static void CheckSuccess(PluginsErrorDictionary& errorDictionary,
357 OrthancPluginErrorCode code)
358 {
359 if (code != OrthancPluginErrorCode_Success)
360 {
361 errorDictionary.LogError(code, true);
362 throw OrthancException(static_cast<ErrorCode>(code));
363 }
364 }
365
366
367 static void Execute(DatabasePluginMessages::Response& response,
368 const _OrthancPluginRegisterDatabaseBackendV4& database,
369 PluginsErrorDictionary& errorDictionary,
370 const DatabasePluginMessages::Request& request)
371 {
372 std::string requestSerialized;
373 request.SerializeToString(&requestSerialized);
374
375 OrthancPluginMemoryBuffer64 responseSerialized;
376 CheckSuccess(errorDictionary, database.operations(
377 &responseSerialized, database.backend,
378 requestSerialized.empty() ? NULL : requestSerialized.c_str(),
379 requestSerialized.size()));
380
381 bool success = response.ParseFromArray(responseSerialized.data, responseSerialized.size);
382
383 if (responseSerialized.size > 0)
384 {
385 free(responseSerialized.data);
386 }
387
388 if (!success)
389 {
390 throw OrthancException(ErrorCode_DatabasePlugin, "Cannot unserialize protobuf originating from the database plugin");
391 }
392 }
393
394 static void ExecuteDatabase(DatabasePluginMessages::DatabaseResponse& response,
395 const _OrthancPluginRegisterDatabaseBackendV4& database,
396 PluginsErrorDictionary& errorDictionary,
397 DatabasePluginMessages::DatabaseOperation operation,
398 const DatabasePluginMessages::DatabaseRequest& request)
399 {
400 DatabasePluginMessages::Request fullRequest;
401 fullRequest.set_type(DatabasePluginMessages::REQUEST_DATABASE);
402 fullRequest.mutable_database_request()->CopyFrom(request);
403 fullRequest.mutable_database_request()->set_operation(operation);
404
405 DatabasePluginMessages::Response fullResponse;
406 Execute(fullResponse, database, errorDictionary, fullRequest);
407
408 response.CopyFrom(fullResponse.database_response());
409 }
410
411
412 OrthancPluginDatabaseV4::OrthancPluginDatabaseV4(SharedLibrary& library, 607 OrthancPluginDatabaseV4::OrthancPluginDatabaseV4(SharedLibrary& library,
413 PluginsErrorDictionary& errorDictionary, 608 PluginsErrorDictionary& errorDictionary,
414 const _OrthancPluginRegisterDatabaseBackendV4& database, 609 const _OrthancPluginRegisterDatabaseBackendV4& database,
415 const std::string& serverIdentifier) : 610 const std::string& serverIdentifier) :
416 library_(library), 611 library_(library),
417 errorDictionary_(errorDictionary), 612 errorDictionary_(errorDictionary),
418 database_(database), 613 definition_(database),
419 serverIdentifier_(serverIdentifier), 614 serverIdentifier_(serverIdentifier),
420 open_(false), 615 open_(false),
421 databaseVersion_(0), 616 databaseVersion_(0),
422 hasFlushToDisk_(false), 617 hasFlushToDisk_(false),
423 hasRevisionsSupport_(false) 618 hasRevisionsSupport_(false)
424 { 619 {
425 CLOG(INFO, PLUGINS) << "Identifier of this Orthanc server for the global properties " 620 CLOG(INFO, PLUGINS) << "Identifier of this Orthanc server for the global properties "
426 << "of the custom database: \"" << serverIdentifier << "\""; 621 << "of the custom database: \"" << serverIdentifier << "\"";
427 622
428 if (database_.backend == NULL || 623 if (definition_.backend == NULL ||
429 database_.operations == NULL || 624 definition_.operations == NULL ||
430 database_.finalize == NULL) 625 definition_.finalize == NULL)
431 { 626 {
432 throw OrthancException(ErrorCode_NullPointer); 627 throw OrthancException(ErrorCode_NullPointer);
433 } 628 }
434 } 629 }
435 630
436 631
437 OrthancPluginDatabaseV4::~OrthancPluginDatabaseV4() 632 OrthancPluginDatabaseV4::~OrthancPluginDatabaseV4()
438 { 633 {
439 database_.finalize(database_.backend); 634 definition_.finalize(definition_.backend);
440 } 635 }
441 636
442 637
443 void OrthancPluginDatabaseV4::Open() 638 void OrthancPluginDatabaseV4::Open()
444 { 639 {
448 } 643 }
449 644
450 { 645 {
451 DatabasePluginMessages::DatabaseRequest request; 646 DatabasePluginMessages::DatabaseRequest request;
452 DatabasePluginMessages::DatabaseResponse response; 647 DatabasePluginMessages::DatabaseResponse response;
453 ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_OPEN, request); 648 ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_OPEN, request);
454 } 649 }
455 650
456 { 651 {
457 DatabasePluginMessages::DatabaseRequest request; 652 DatabasePluginMessages::DatabaseRequest request;
458 DatabasePluginMessages::DatabaseResponse response; 653 DatabasePluginMessages::DatabaseResponse response;
459 ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_GET_SYSTEM_INFORMATION, request); 654 ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_GET_SYSTEM_INFORMATION, request);
655 databaseVersion_ = response.get_system_information().database_version();
460 hasFlushToDisk_ = response.get_system_information().supports_flush_to_disk(); 656 hasFlushToDisk_ = response.get_system_information().supports_flush_to_disk();
461 hasRevisionsSupport_ = response.get_system_information().supports_revisions(); 657 hasRevisionsSupport_ = response.get_system_information().supports_revisions();
462 } 658 }
463 659
464 open_ = true; 660 open_ = true;
473 } 669 }
474 else 670 else
475 { 671 {
476 DatabasePluginMessages::DatabaseRequest request; 672 DatabasePluginMessages::DatabaseRequest request;
477 DatabasePluginMessages::DatabaseResponse response; 673 DatabasePluginMessages::DatabaseResponse response;
478 ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_CLOSE, request); 674 ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_CLOSE, request);
479 } 675 }
480 } 676 }
481 677
482 678
483 bool OrthancPluginDatabaseV4::HasFlushToDisk() const 679 bool OrthancPluginDatabaseV4::HasFlushToDisk() const
502 } 698 }
503 else 699 else
504 { 700 {
505 DatabasePluginMessages::DatabaseRequest request; 701 DatabasePluginMessages::DatabaseRequest request;
506 DatabasePluginMessages::DatabaseResponse response; 702 DatabasePluginMessages::DatabaseResponse response;
507 ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_FLUSH_TO_DISK, request); 703 ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_FLUSH_TO_DISK, request);
508 } 704 }
509 } 705 }
510 706
511 707
512 IDatabaseWrapper::ITransaction* OrthancPluginDatabaseV4::StartTransaction(TransactionType type, 708 IDatabaseWrapper::ITransaction* OrthancPluginDatabaseV4::StartTransaction(TransactionType type,
515 if (!open_) 711 if (!open_)
516 { 712 {
517 throw OrthancException(ErrorCode_BadSequenceOfCalls); 713 throw OrthancException(ErrorCode_BadSequenceOfCalls);
518 } 714 }
519 715
716 DatabasePluginMessages::DatabaseRequest request;
717
520 switch (type) 718 switch (type)
521 { 719 {
522 case TransactionType_ReadOnly: 720 case TransactionType_ReadOnly:
721 request.mutable_start_transaction()->set_type(DatabasePluginMessages::TRANSACTION_READ_ONLY);
722 break;
523 723
524 case TransactionType_ReadWrite: 724 case TransactionType_ReadWrite:
725 request.mutable_start_transaction()->set_type(DatabasePluginMessages::TRANSACTION_READ_WRITE);
726 break;
525 727
526 default: 728 default:
527 throw OrthancException(ErrorCode_InternalError); 729 throw OrthancException(ErrorCode_InternalError);
528 } 730 }
731
732 DatabasePluginMessages::DatabaseResponse response;
733 ExecuteDatabase(response, *this, DatabasePluginMessages::OPERATION_START_TRANSACTION, request);
734
735 return new Transaction(*this, listener, reinterpret_cast<void*>(response.start_transaction().transaction()));
529 } 736 }
530 737
531 738
532 unsigned int OrthancPluginDatabaseV4::GetDatabaseVersion() 739 unsigned int OrthancPluginDatabaseV4::GetDatabaseVersion()
533 { 740 {
550 throw OrthancException(ErrorCode_BadSequenceOfCalls); 757 throw OrthancException(ErrorCode_BadSequenceOfCalls);
551 } 758 }
552 else 759 else
553 { 760 {
554 // TODO 761 // TODO
762 throw OrthancException(ErrorCode_NotImplemented);
555 } 763 }
556 } 764 }
557 765
558 766
559 bool OrthancPluginDatabaseV4::HasRevisionsSupport() const 767 bool OrthancPluginDatabaseV4::HasRevisionsSupport() const