| Orthanc Plugin SDK 1.3.0 Documentation of the plugin interface of Orthanc

OrthancCppDatabasePlugin.h
1
35 #pragma once
36
37 #include "OrthancCDatabasePlugin.h"
38
39 #include <stdexcept>
40 #include <list>
41 #include <string>
42
43 namespace OrthancPlugins
44 {
46 // This class mimics "boost::noncopyable"
47 class NonCopyable
48 {
49 private:
50 NonCopyable(const NonCopyable&);
51
52 NonCopyable& operator= (const NonCopyable&);
53
54 protected:
55 NonCopyable()
56 {
57 }
58
59 ~NonCopyable()
60 {
61 }
62 };
64
65
69 class DatabaseException
70 {
71 private:
72 OrthancPluginErrorCode code_;
73
74 public:
75 DatabaseException() : code_(OrthancPluginErrorCode_DatabasePlugin)
76 {
77 }
78
79 DatabaseException(OrthancPluginErrorCode code) : code_(code)
80 {
81 }
82
83 OrthancPluginErrorCode GetErrorCode() const
84 {
85 return code_;
86 }
87 };
88
89
93 class DatabaseBackendOutput : public NonCopyable
94 {
95 friend class DatabaseBackendAdapter;
96
97 private:
98 enum AllowedAnswers
99 {
100 AllowedAnswers_All,
101 AllowedAnswers_None,
102 AllowedAnswers_Attachment,
103 AllowedAnswers_Change,
104 AllowedAnswers_DicomTag,
105 AllowedAnswers_ExportedResource
106 };
107
108 OrthancPluginContext* context_;
109 OrthancPluginDatabaseContext* database_;
110 AllowedAnswers allowedAnswers_;
111
112 void SetAllowedAnswers(AllowedAnswers allowed)
113 {
114 allowedAnswers_ = allowed;
115 }
116
117 public:
118 DatabaseBackendOutput(OrthancPluginContext* context,
119 OrthancPluginDatabaseContext* database) :
120 context_(context),
121 database_(database),
122 allowedAnswers_(AllowedAnswers_All /* for unit tests */)
123 {
124 }
125
126 OrthancPluginContext* GetContext()
127 {
128 return context_;
129 }
130
131 void LogError(const std::string& message)
132 {
133 OrthancPluginLogError(context_, message.c_str());
134 }
135
136 void LogWarning(const std::string& message)
137 {
138 OrthancPluginLogWarning(context_, message.c_str());
139 }
140
141 void LogInfo(const std::string& message)
142 {
143 OrthancPluginLogInfo(context_, message.c_str());
144 }
145
146 void SignalDeletedAttachment(const std::string& uuid,
147 int32_t contentType,
148 uint64_t uncompressedSize,
149 const std::string& uncompressedHash,
150 int32_t compressionType,
151 uint64_t compressedSize,
152 const std::string& compressedHash)
153 {
154 OrthancPluginAttachment attachment;
155 attachment.uuid = uuid.c_str();
156 attachment.contentType = contentType;
157 attachment.uncompressedSize = uncompressedSize;
158 attachment.uncompressedHash = uncompressedHash.c_str();
159 attachment.compressionType = compressionType;
160 attachment.compressedSize = compressedSize;
161 attachment.compressedHash = compressedHash.c_str();
162
163 OrthancPluginDatabaseSignalDeletedAttachment(context_, database_, &attachment);
164 }
165
166 void SignalDeletedResource(const std::string& publicId,
167 OrthancPluginResourceType resourceType)
168 {
169 OrthancPluginDatabaseSignalDeletedResource(context_, database_, publicId.c_str(), resourceType);
170 }
171
172 void SignalRemainingAncestor(const std::string& ancestorId,
173 OrthancPluginResourceType ancestorType)
174 {
175 OrthancPluginDatabaseSignalRemainingAncestor(context_, database_, ancestorId.c_str(), ancestorType);
176 }
177
178 void AnswerAttachment(const std::string& uuid,
179 int32_t contentType,
180 uint64_t uncompressedSize,
181 const std::string& uncompressedHash,
182 int32_t compressionType,
183 uint64_t compressedSize,
184 const std::string& compressedHash)
185 {
186 if (allowedAnswers_ != AllowedAnswers_All &&
187 allowedAnswers_ != AllowedAnswers_Attachment)
188 {
189 throw std::runtime_error("Cannot answer with an attachment in the current state");
190 }
191
192 OrthancPluginAttachment attachment;
193 attachment.uuid = uuid.c_str();
194 attachment.contentType = contentType;
195 attachment.uncompressedSize = uncompressedSize;
196 attachment.uncompressedHash = uncompressedHash.c_str();
197 attachment.compressionType = compressionType;
198 attachment.compressedSize = compressedSize;
199 attachment.compressedHash = compressedHash.c_str();
200
201 OrthancPluginDatabaseAnswerAttachment(context_, database_, &attachment);
202 }
203
204 void AnswerChange(int64_t seq,
205 int32_t changeType,
206 OrthancPluginResourceType resourceType,
207 const std::string& publicId,
208 const std::string& date)
209 {
210 if (allowedAnswers_ != AllowedAnswers_All &&
211 allowedAnswers_ != AllowedAnswers_Change)
212 {
213 throw std::runtime_error("Cannot answer with a change in the current state");
214 }
215
216 OrthancPluginChange change;
217 change.seq = seq;
218 change.changeType = changeType;
219 change.resourceType = resourceType;
220 change.publicId = publicId.c_str();
221 change.date = date.c_str();
222
223 OrthancPluginDatabaseAnswerChange(context_, database_, &change);
224 }
225
226 void AnswerDicomTag(uint16_t group,
227 uint16_t element,
228 const std::string& value)
229 {
230 if (allowedAnswers_ != AllowedAnswers_All &&
231 allowedAnswers_ != AllowedAnswers_DicomTag)
232 {
233 throw std::runtime_error("Cannot answer with a DICOM tag in the current state");
234 }
235
236 OrthancPluginDicomTag tag;
237 tag.group = group;
238 tag.element = element;
239 tag.value = value.c_str();
240
241 OrthancPluginDatabaseAnswerDicomTag(context_, database_, &tag);
242 }
243
244 void AnswerExportedResource(int64_t seq,
245 OrthancPluginResourceType resourceType,
246 const std::string& publicId,
247 const std::string& modality,
248 const std::string& date,
249 const std::string& patientId,
250 const std::string& studyInstanceUid,
251 const std::string& seriesInstanceUid,
252 const std::string& sopInstanceUid)
253 {
254 if (allowedAnswers_ != AllowedAnswers_All &&
255 allowedAnswers_ != AllowedAnswers_ExportedResource)
256 {
257 throw std::runtime_error("Cannot answer with an exported resource in the current state");
258 }
259
260 OrthancPluginExportedResource exported;
261 exported.seq = seq;
262 exported.resourceType = resourceType;
263 exported.publicId = publicId.c_str();
264 exported.modality = modality.c_str();
265 exported.date = date.c_str();
266 exported.patientId = patientId.c_str();
267 exported.studyInstanceUid = studyInstanceUid.c_str();
268 exported.seriesInstanceUid = seriesInstanceUid.c_str();
269 exported.sopInstanceUid = sopInstanceUid.c_str();
270
271 OrthancPluginDatabaseAnswerExportedResource(context_, database_, &exported);
272 }
273 };
274
275
279 class IDatabaseBackend : public NonCopyable
280 {
281 friend class DatabaseBackendAdapter;
282
283 private:
284 DatabaseBackendOutput* output_;
285
286 void Finalize()
287 {
288 if (output_ != NULL)
289 {
290 delete output_;
291 output_ = NULL;
292 }
293 }
294
295 protected:
296 DatabaseBackendOutput& GetOutput()
297 {
298 return *output_;
299 }
300
301 public:
302 IDatabaseBackend() : output_(NULL)
303 {
304 }
305
306 virtual ~IDatabaseBackend()
307 {
308 Finalize();
309 }
310
311 // This takes the ownership
312 void RegisterOutput(DatabaseBackendOutput* output)
313 {
314 Finalize();
315 output_ = output;
316 }
317
318 virtual void Open() = 0;
319
320 virtual void Close() = 0;
321
322 virtual void AddAttachment(int64_t id,
323 const OrthancPluginAttachment& attachment) = 0;
324
325 virtual void AttachChild(int64_t parent,
326 int64_t child) = 0;
327
328 virtual void ClearChanges() = 0;
329
330 virtual void ClearExportedResources() = 0;
331
332 virtual int64_t CreateResource(const char* publicId,
333 OrthancPluginResourceType type) = 0;
334
335 virtual void DeleteAttachment(int64_t id,
336 int32_t attachment) = 0;
337
338 virtual void DeleteMetadata(int64_t id,
339 int32_t metadataType) = 0;
340
341 virtual void DeleteResource(int64_t id) = 0;
342
343 virtual void GetAllInternalIds(std::list<int64_t>& target,
344 OrthancPluginResourceType resourceType) = 0;
345
346 virtual void GetAllPublicIds(std::list<std::string>& target,
347 OrthancPluginResourceType resourceType) = 0;
348
349 virtual void GetAllPublicIds(std::list<std::string>& target,
350 OrthancPluginResourceType resourceType,
351 uint64_t since,
352 uint64_t limit) = 0;
353
354 /* Use GetOutput().AnswerChange() */
355 virtual void GetChanges(bool& done /*out*/,
356 int64_t since,
357 uint32_t maxResults) = 0;
358
359 virtual void GetChildrenInternalId(std::list<int64_t>& target /*out*/,
360 int64_t id) = 0;
361
362 virtual void GetChildrenPublicId(std::list<std::string>& target /*out*/,
363 int64_t id) = 0;
364
365 /* Use GetOutput().AnswerExportedResource() */
366 virtual void GetExportedResources(bool& done /*out*/,
367 int64_t since,
368 uint32_t maxResults) = 0;
369
370 /* Use GetOutput().AnswerChange() */
371 virtual void GetLastChange() = 0;
372
373 /* Use GetOutput().AnswerExportedResource() */
374 virtual void GetLastExportedResource() = 0;
375
376 /* Use GetOutput().AnswerDicomTag() */
377 virtual void GetMainDicomTags(int64_t id) = 0;
378
379 virtual std::string GetPublicId(int64_t resourceId) = 0;
380
381 virtual uint64_t GetResourceCount(OrthancPluginResourceType resourceType) = 0;
382
383 virtual OrthancPluginResourceType GetResourceType(int64_t resourceId) = 0;
384
385 virtual uint64_t GetTotalCompressedSize() = 0;
386
387 virtual uint64_t GetTotalUncompressedSize() = 0;
388
389 virtual bool IsExistingResource(int64_t internalId) = 0;
390
391 virtual bool IsProtectedPatient(int64_t internalId) = 0;
392
393 virtual void ListAvailableMetadata(std::list<int32_t>& target /*out*/,
394 int64_t id) = 0;
395
396 virtual void ListAvailableAttachments(std::list<int32_t>& target /*out*/,
397 int64_t id) = 0;
398
399 virtual void LogChange(const OrthancPluginChange& change) = 0;
400
401 virtual void LogExportedResource(const OrthancPluginExportedResource& resource) = 0;
402
403 /* Use GetOutput().AnswerAttachment() */
404 virtual bool LookupAttachment(int64_t id,
405 int32_t contentType) = 0;
406
407 virtual bool LookupGlobalProperty(std::string& target /*out*/,
408 int32_t property) = 0;
409
410 virtual void LookupIdentifier(std::list<int64_t>& target /*out*/,
411 OrthancPluginResourceType resourceType,
412 uint16_t group,
413 uint16_t element,
414 OrthancPluginIdentifierConstraint constraint,
415 const char* value) = 0;
416
417 virtual bool LookupMetadata(std::string& target /*out*/,
418 int64_t id,
419 int32_t metadataType) = 0;
420
421 virtual bool LookupParent(int64_t& parentId /*out*/,
422 int64_t resourceId) = 0;
423
424 virtual bool LookupResource(int64_t& id /*out*/,
425 OrthancPluginResourceType& type /*out*/,
426 const char* publicId) = 0;
427
428 virtual bool SelectPatientToRecycle(int64_t& internalId /*out*/) = 0;
429
430 virtual bool SelectPatientToRecycle(int64_t& internalId /*out*/,
431 int64_t patientIdToAvoid) = 0;
432
433 virtual void SetGlobalProperty(int32_t property,
434 const char* value) = 0;
435
436 virtual void SetMainDicomTag(int64_t id,
437 uint16_t group,
438 uint16_t element,
439 const char* value) = 0;
440
441 virtual void SetIdentifierTag(int64_t id,
442 uint16_t group,
443 uint16_t element,
444 const char* value) = 0;
445
446 virtual void SetMetadata(int64_t id,
447 int32_t metadataType,
448 const char* value) = 0;
449
450 virtual void SetProtectedPatient(int64_t internalId,
451 bool isProtected) = 0;
452
453 virtual void StartTransaction() = 0;
454
455 virtual void RollbackTransaction() = 0;
456
457 virtual void CommitTransaction() = 0;
458
459 virtual uint32_t GetDatabaseVersion() = 0;
460
466 virtual void UpgradeDatabase(uint32_t targetVersion,
467 OrthancPluginStorageArea* storageArea) = 0;
468
469 virtual void ClearMainDicomTags(int64_t internalId) = 0;
470 };
471
472
473
483 class DatabaseBackendAdapter
484 {
485 private:
486 // This class cannot be instantiated
487 DatabaseBackendAdapter()
488 {
489 }
490
491 static void LogError(IDatabaseBackend* backend,
492 const std::runtime_error& e)
493 {
494 backend->GetOutput().LogError("Exception in database back-end: " + std::string(e.what()));
495 }
496
497
498 static OrthancPluginErrorCode AddAttachment(void* payload,
499 int64_t id,
500 const OrthancPluginAttachment* attachment)
501 {
502 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
503 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
504
505 try
506 {
507 backend->AddAttachment(id, *attachment);
508 return OrthancPluginErrorCode_Success;
509 }
510 catch (std::runtime_error& e)
511 {
512 LogError(backend, e);
513 return OrthancPluginErrorCode_DatabasePlugin;
514 }
515 catch (DatabaseException& e)
516 {
517 return e.GetErrorCode();
518 }
519 }
520
521
522 static OrthancPluginErrorCode AttachChild(void* payload,
523 int64_t parent,
524 int64_t child)
525 {
526 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
527 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
528
529 try
530 {
531 backend->AttachChild(parent, child);
532 return OrthancPluginErrorCode_Success;
533 }
534 catch (std::runtime_error& e)
535 {
536 LogError(backend, e);
537 return OrthancPluginErrorCode_DatabasePlugin;
538 }
539 catch (DatabaseException& e)
540 {
541 return e.GetErrorCode();
542 }
543 }
544
545
546 static OrthancPluginErrorCode ClearChanges(void* payload)
547 {
548 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
549 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
550
551 try
552 {
553 backend->ClearChanges();
554 return OrthancPluginErrorCode_Success;
555 }
556 catch (std::runtime_error& e)
557 {
558 LogError(backend, e);
559 return OrthancPluginErrorCode_DatabasePlugin;
560 }
561 catch (DatabaseException& e)
562 {
563 return e.GetErrorCode();
564 }
565 }
566
567
568 static OrthancPluginErrorCode ClearExportedResources(void* payload)
569 {
570 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
571 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
572
573 try
574 {
575 backend->ClearExportedResources();
576 return OrthancPluginErrorCode_Success;
577 }
578 catch (std::runtime_error& e)
579 {
580 LogError(backend, e);
581 return OrthancPluginErrorCode_DatabasePlugin;
582 }
583 catch (DatabaseException& e)
584 {
585 return e.GetErrorCode();
586 }
587 }
588
589
590 static OrthancPluginErrorCode CreateResource(int64_t* id,
591 void* payload,
592 const char* publicId,
593 OrthancPluginResourceType resourceType)
594 {
595 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
596 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
597
598 try
599 {
600 *id = backend->CreateResource(publicId, resourceType);
601 return OrthancPluginErrorCode_Success;
602 }
603 catch (std::runtime_error& e)
604 {
605 LogError(backend, e);
606 return OrthancPluginErrorCode_DatabasePlugin;
607 }
608 catch (DatabaseException& e)
609 {
610 return e.GetErrorCode();
611 }
612 }
613
614
615 static OrthancPluginErrorCode DeleteAttachment(void* payload,
616 int64_t id,
617 int32_t contentType)
618 {
619 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
620 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
621
622 try
623 {
624 backend->DeleteAttachment(id, contentType);
625 return OrthancPluginErrorCode_Success;
626 }
627 catch (std::runtime_error& e)
628 {
629 LogError(backend, e);
630 return OrthancPluginErrorCode_DatabasePlugin;
631 }
632 catch (DatabaseException& e)
633 {
634 return e.GetErrorCode();
635 }
636 }
637
638
639 static OrthancPluginErrorCode DeleteMetadata(void* payload,
640 int64_t id,
641 int32_t metadataType)
642 {
643 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
644 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
645
646 try
647 {
648 backend->DeleteMetadata(id, metadataType);
649 return OrthancPluginErrorCode_Success;
650 }
651 catch (std::runtime_error& e)
652 {
653 LogError(backend, e);
654 return OrthancPluginErrorCode_DatabasePlugin;
655 }
656 catch (DatabaseException& e)
657 {
658 return e.GetErrorCode();
659 }
660 }
661
662
663 static OrthancPluginErrorCode DeleteResource(void* payload,
664 int64_t id)
665 {
666 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
667 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
668
669 try
670 {
671 backend->DeleteResource(id);
672 return OrthancPluginErrorCode_Success;
673 }
674 catch (std::runtime_error& e)
675 {
676 LogError(backend, e);
677 return OrthancPluginErrorCode_DatabasePlugin;
678 }
679 catch (DatabaseException& e)
680 {
681 return e.GetErrorCode();
682 }
683 }
684
685
686 static OrthancPluginErrorCode GetAllInternalIds(OrthancPluginDatabaseContext* context,
687 void* payload,
688 OrthancPluginResourceType resourceType)
689 {
690 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
691 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
692
693 try
694 {
695 std::list<int64_t> target;
696 backend->GetAllInternalIds(target, resourceType);
697
698 for (std::list<int64_t>::const_iterator
699 it = target.begin(); it != target.end(); ++it)
700 {
701 OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
702 backend->GetOutput().database_, *it);
703 }
704
705 return OrthancPluginErrorCode_Success;
706 }
707 catch (std::runtime_error& e)
708 {
709 LogError(backend, e);
710 return OrthancPluginErrorCode_DatabasePlugin;
711 }
712 catch (DatabaseException& e)
713 {
714 return e.GetErrorCode();
715 }
716 }
717
718
719 static OrthancPluginErrorCode GetAllPublicIds(OrthancPluginDatabaseContext* context,
720 void* payload,
721 OrthancPluginResourceType resourceType)
722 {
723 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
724 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
725
726 try
727 {
728 std::list<std::string> ids;
729 backend->GetAllPublicIds(ids, resourceType);
730
731 for (std::list<std::string>::const_iterator
732 it = ids.begin(); it != ids.end(); ++it)
733 {
734 OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
735 backend->GetOutput().database_,
736 it->c_str());
737 }
738
739 return OrthancPluginErrorCode_Success;
740 }
741 catch (std::runtime_error& e)
742 {
743 LogError(backend, e);
744 return OrthancPluginErrorCode_DatabasePlugin;
745 }
746 catch (DatabaseException& e)
747 {
748 return e.GetErrorCode();
749 }
750 }
751
752
753 static OrthancPluginErrorCode GetAllPublicIdsWithLimit(OrthancPluginDatabaseContext* context,
754 void* payload,
755 OrthancPluginResourceType resourceType,
756 uint64_t since,
757 uint64_t limit)
758 {
759 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
760 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
761
762 try
763 {
764 std::list<std::string> ids;
765 backend->GetAllPublicIds(ids, resourceType, since, limit);
766
767 for (std::list<std::string>::const_iterator
768 it = ids.begin(); it != ids.end(); ++it)
769 {
770 OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
771 backend->GetOutput().database_,
772 it->c_str());
773 }
774
775 return OrthancPluginErrorCode_Success;
776 }
777 catch (std::runtime_error& e)
778 {
779 LogError(backend, e);
780 return OrthancPluginErrorCode_DatabasePlugin;
781 }
782 catch (DatabaseException& e)
783 {
784 return e.GetErrorCode();
785 }
786 }
787
788
789 static OrthancPluginErrorCode GetChanges(OrthancPluginDatabaseContext* context,
790 void* payload,
791 int64_t since,
792 uint32_t maxResult)
793 {
794 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
795 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Change);
796
797 try
798 {
799 bool done;
800 backend->GetChanges(done, since, maxResult);
801
802 if (done)
803 {
804 OrthancPluginDatabaseAnswerChangesDone(backend->GetOutput().context_,
805 backend->GetOutput().database_);
806 }
807
808 return OrthancPluginErrorCode_Success;
809 }
810 catch (std::runtime_error& e)
811 {
812 LogError(backend, e);
813 return OrthancPluginErrorCode_DatabasePlugin;
814 }
815 catch (DatabaseException& e)
816 {
817 return e.GetErrorCode();
818 }
819 }
820
821
822 static OrthancPluginErrorCode GetChildrenInternalId(OrthancPluginDatabaseContext* context,
823 void* payload,
824 int64_t id)
825 {
826 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
827 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
828
829 try
830 {
831 std::list<int64_t> target;
832 backend->GetChildrenInternalId(target, id);
833
834 for (std::list<int64_t>::const_iterator
835 it = target.begin(); it != target.end(); ++it)
836 {
837 OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
838 backend->GetOutput().database_, *it);
839 }
840
841 return OrthancPluginErrorCode_Success;
842 }
843 catch (std::runtime_error& e)
844 {
845 LogError(backend, e);
846 return OrthancPluginErrorCode_DatabasePlugin;
847 }
848 catch (DatabaseException& e)
849 {
850 return e.GetErrorCode();
851 }
852 }
853
854
855 static OrthancPluginErrorCode GetChildrenPublicId(OrthancPluginDatabaseContext* context,
856 void* payload,
857 int64_t id)
858 {
859 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
860 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
861
862 try
863 {
864 std::list<std::string> ids;
865 backend->GetChildrenPublicId(ids, id);
866
867 for (std::list<std::string>::const_iterator
868 it = ids.begin(); it != ids.end(); ++it)
869 {
870 OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
871 backend->GetOutput().database_,
872 it->c_str());
873 }
874
875 return OrthancPluginErrorCode_Success;
876 }
877 catch (std::runtime_error& e)
878 {
879 LogError(backend, e);
880 return OrthancPluginErrorCode_DatabasePlugin;
881 }
882 catch (DatabaseException& e)
883 {
884 return e.GetErrorCode();
885 }
886 }
887
888
889 static OrthancPluginErrorCode GetExportedResources(OrthancPluginDatabaseContext* context,
890 void* payload,
891 int64_t since,
892 uint32_t maxResult)
893 {
894 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
895 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_ExportedResource);
896
897 try
898 {
899 bool done;
900 backend->GetExportedResources(done, since, maxResult);
901
902 if (done)
903 {
904 OrthancPluginDatabaseAnswerExportedResourcesDone(backend->GetOutput().context_,
905 backend->GetOutput().database_);
906 }
907 return OrthancPluginErrorCode_Success;
908 }
909 catch (std::runtime_error& e)
910 {
911 LogError(backend, e);
912 return OrthancPluginErrorCode_DatabasePlugin;
913 }
914 catch (DatabaseException& e)
915 {
916 return e.GetErrorCode();
917 }
918 }
919
920
921 static OrthancPluginErrorCode GetLastChange(OrthancPluginDatabaseContext* context,
922 void* payload)
923 {
924 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
925 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Change);
926
927 try
928 {
929 backend->GetLastChange();
930 return OrthancPluginErrorCode_Success;
931 }
932 catch (std::runtime_error& e)
933 {
934 LogError(backend, e);
935 return OrthancPluginErrorCode_DatabasePlugin;
936 }
937 catch (DatabaseException& e)
938 {
939 return e.GetErrorCode();
940 }
941 }
942
943
944 static OrthancPluginErrorCode GetLastExportedResource(OrthancPluginDatabaseContext* context,
945 void* payload)
946 {
947 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
948 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_ExportedResource);
949
950 try
951 {
952 backend->GetLastExportedResource();
953 return OrthancPluginErrorCode_Success;
954 }
955 catch (std::runtime_error& e)
956 {
957 LogError(backend, e);
958 return OrthancPluginErrorCode_DatabasePlugin;
959 }
960 catch (DatabaseException& e)
961 {
962 return e.GetErrorCode();
963 }
964 }
965
966
967 static OrthancPluginErrorCode GetMainDicomTags(OrthancPluginDatabaseContext* context,
968 void* payload,
969 int64_t id)
970 {
971 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
972 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_DicomTag);
973
974 try
975 {
976 backend->GetMainDicomTags(id);
977 return OrthancPluginErrorCode_Success;
978 }
979 catch (std::runtime_error& e)
980 {
981 LogError(backend, e);
982 return OrthancPluginErrorCode_DatabasePlugin;
983 }
984 catch (DatabaseException& e)
985 {
986 return e.GetErrorCode();
987 }
988 }
989
990
991 static OrthancPluginErrorCode GetPublicId(OrthancPluginDatabaseContext* context,
992 void* payload,
993 int64_t id)
994 {
995 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
996 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
997
998 try
999 {
1000 std::string s = backend->GetPublicId(id);
1001 OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
1002 backend->GetOutput().database_,
1003 s.c_str());
1004
1005 return OrthancPluginErrorCode_Success;
1006 }
1007 catch (std::runtime_error& e)
1008 {
1009 LogError(backend, e);
1010 return OrthancPluginErrorCode_DatabasePlugin;
1011 }
1012 catch (DatabaseException& e)
1013 {
1014 return e.GetErrorCode();
1015 }
1016 }
1017
1018
1019 static OrthancPluginErrorCode GetResourceCount(uint64_t* target,
1020 void* payload,
1021 OrthancPluginResourceType resourceType)
1022 {
1023 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1024 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1025
1026 try
1027 {
1028 *target = backend->GetResourceCount(resourceType);
1029 return OrthancPluginErrorCode_Success;
1030 }
1031 catch (std::runtime_error& e)
1032 {
1033 LogError(backend, e);
1034 return OrthancPluginErrorCode_DatabasePlugin;
1035 }
1036 catch (DatabaseException& e)
1037 {
1038 return e.GetErrorCode();
1039 }
1040 }
1041
1042
1043 static OrthancPluginErrorCode GetResourceType(OrthancPluginResourceType* resourceType,
1044 void* payload,
1045 int64_t id)
1046 {
1047 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1048 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1049
1050 try
1051 {
1052 *resourceType = backend->GetResourceType(id);
1053 return OrthancPluginErrorCode_Success;
1054 }
1055 catch (std::runtime_error& e)
1056 {
1057 LogError(backend, e);
1058 return OrthancPluginErrorCode_DatabasePlugin;
1059 }
1060 catch (DatabaseException& e)
1061 {
1062 return e.GetErrorCode();
1063 }
1064 }
1065
1066
1067 static OrthancPluginErrorCode GetTotalCompressedSize(uint64_t* target,
1068 void* payload)
1069 {
1070 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1071 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1072
1073 try
1074 {
1075 *target = backend->GetTotalCompressedSize();
1076 return OrthancPluginErrorCode_Success;
1077 }
1078 catch (std::runtime_error& e)
1079 {
1080 LogError(backend, e);
1081 return OrthancPluginErrorCode_DatabasePlugin;
1082 }
1083 catch (DatabaseException& e)
1084 {
1085 return e.GetErrorCode();
1086 }
1087 }
1088
1089
1090 static OrthancPluginErrorCode GetTotalUncompressedSize(uint64_t* target,
1091 void* payload)
1092 {
1093 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1094 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1095
1096 try
1097 {
1098 *target = backend->GetTotalUncompressedSize();
1099 return OrthancPluginErrorCode_Success;
1100 }
1101 catch (std::runtime_error& e)
1102 {
1103 LogError(backend, e);
1104 return OrthancPluginErrorCode_DatabasePlugin;
1105 }
1106 catch (DatabaseException& e)
1107 {
1108 return e.GetErrorCode();
1109 }
1110 }
1111
1112
1113 static OrthancPluginErrorCode IsExistingResource(int32_t* existing,
1114 void* payload,
1115 int64_t id)
1116 {
1117 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1118 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1119
1120 try
1121 {
1122 *existing = backend->IsExistingResource(id);
1123 return OrthancPluginErrorCode_Success;
1124 }
1125 catch (std::runtime_error& e)
1126 {
1127 LogError(backend, e);
1128 return OrthancPluginErrorCode_DatabasePlugin;
1129 }
1130 catch (DatabaseException& e)
1131 {
1132 return e.GetErrorCode();
1133 }
1134 }
1135
1136
1137 static OrthancPluginErrorCode IsProtectedPatient(int32_t* isProtected,
1138 void* payload,
1139 int64_t id)
1140 {
1141 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1142 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1143
1144 try
1145 {
1146 *isProtected = backend->IsProtectedPatient(id);
1147 return OrthancPluginErrorCode_Success;
1148 }
1149 catch (std::runtime_error& e)
1150 {
1151 LogError(backend, e);
1152 return OrthancPluginErrorCode_DatabasePlugin;
1153 }
1154 catch (DatabaseException& e)
1155 {
1156 return e.GetErrorCode();
1157 }
1158 }
1159
1160
1161 static OrthancPluginErrorCode ListAvailableMetadata(OrthancPluginDatabaseContext* context,
1162 void* payload,
1163 int64_t id)
1164 {
1165 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1166 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1167
1168 try
1169 {
1170 std::list<int32_t> target;
1171 backend->ListAvailableMetadata(target, id);
1172
1173 for (std::list<int32_t>::const_iterator
1174 it = target.begin(); it != target.end(); ++it)
1175 {
1176 OrthancPluginDatabaseAnswerInt32(backend->GetOutput().context_,
1177 backend->GetOutput().database_,
1178 *it);
1179 }
1180
1181 return OrthancPluginErrorCode_Success;
1182 }
1183 catch (std::runtime_error& e)
1184 {
1185 LogError(backend, e);
1186 return OrthancPluginErrorCode_DatabasePlugin;
1187 }
1188 catch (DatabaseException& e)
1189 {
1190 return e.GetErrorCode();
1191 }
1192 }
1193
1194
1195 static OrthancPluginErrorCode ListAvailableAttachments(OrthancPluginDatabaseContext* context,
1196 void* payload,
1197 int64_t id)
1198 {
1199 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1200 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1201
1202 try
1203 {
1204 std::list<int32_t> target;
1205 backend->ListAvailableAttachments(target, id);
1206
1207 for (std::list<int32_t>::const_iterator
1208 it = target.begin(); it != target.end(); ++it)
1209 {
1210 OrthancPluginDatabaseAnswerInt32(backend->GetOutput().context_,
1211 backend->GetOutput().database_,
1212 *it);
1213 }
1214
1215 return OrthancPluginErrorCode_Success;
1216 }
1217 catch (std::runtime_error& e)
1218 {
1219 LogError(backend, e);
1220 return OrthancPluginErrorCode_DatabasePlugin;
1221 }
1222 catch (DatabaseException& e)
1223 {
1224 return e.GetErrorCode();
1225 }
1226 }
1227
1228
1229 static OrthancPluginErrorCode LogChange(void* payload,
1230 const OrthancPluginChange* change)
1231 {
1232 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1233 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1234
1235 try
1236 {
1237 backend->LogChange(*change);
1238 return OrthancPluginErrorCode_Success;
1239 }
1240 catch (std::runtime_error& e)
1241 {
1242 LogError(backend, e);
1243 return OrthancPluginErrorCode_DatabasePlugin;
1244 }
1245 catch (DatabaseException& e)
1246 {
1247 return e.GetErrorCode();
1248 }
1249 }
1250
1251
1252 static OrthancPluginErrorCode LogExportedResource(void* payload,
1253 const OrthancPluginExportedResource* exported)
1254 {
1255 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1256 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1257
1258 try
1259 {
1260 backend->LogExportedResource(*exported);
1261 return OrthancPluginErrorCode_Success;
1262 }
1263 catch (std::runtime_error& e)
1264 {
1265 LogError(backend, e);
1266 return OrthancPluginErrorCode_DatabasePlugin;
1267 }
1268 catch (DatabaseException& e)
1269 {
1270 return e.GetErrorCode();
1271 }
1272 }
1273
1274
1275 static OrthancPluginErrorCode LookupAttachment(OrthancPluginDatabaseContext* context,
1276 void* payload,
1277 int64_t id,
1278 int32_t contentType)
1279 {
1280 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1281 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Attachment);
1282
1283 try
1284 {
1285 backend->LookupAttachment(id, contentType);
1286 return OrthancPluginErrorCode_Success;
1287 }
1288 catch (std::runtime_error& e)
1289 {
1290 LogError(backend, e);
1291 return OrthancPluginErrorCode_DatabasePlugin;
1292 }
1293 catch (DatabaseException& e)
1294 {
1295 return e.GetErrorCode();
1296 }
1297 }
1298
1299
1300 static OrthancPluginErrorCode LookupGlobalProperty(OrthancPluginDatabaseContext* context,
1301 void* payload,
1302 int32_t property)
1303 {
1304 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1305 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1306
1307 try
1308 {
1309 std::string s;
1310 if (backend->LookupGlobalProperty(s, property))
1311 {
1312 OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
1313 backend->GetOutput().database_,
1314 s.c_str());
1315 }
1316
1317 return OrthancPluginErrorCode_Success;
1318 }
1319 catch (std::runtime_error& e)
1320 {
1321 LogError(backend, e);
1322 return OrthancPluginErrorCode_DatabasePlugin;
1323 }
1324 catch (DatabaseException& e)
1325 {
1326 return e.GetErrorCode();
1327 }
1328 }
1329
1330
1331 static OrthancPluginErrorCode LookupIdentifier3(OrthancPluginDatabaseContext* context,
1332 void* payload,
1333 OrthancPluginResourceType resourceType,
1334 const OrthancPluginDicomTag* tag,
1335 OrthancPluginIdentifierConstraint constraint)
1336 {
1337 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1338 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1339
1340 try
1341 {
1342 std::list<int64_t> target;
1343 backend->LookupIdentifier(target, resourceType, tag->group, tag->element, constraint, tag->value);
1344
1345 for (std::list<int64_t>::const_iterator
1346 it = target.begin(); it != target.end(); ++it)
1347 {
1348 OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1349 backend->GetOutput().database_, *it);
1350 }
1351
1352 return OrthancPluginErrorCode_Success;
1353 }
1354 catch (std::runtime_error& e)
1355 {
1356 LogError(backend, e);
1357 return OrthancPluginErrorCode_DatabasePlugin;
1358 }
1359 catch (DatabaseException& e)
1360 {
1361 return e.GetErrorCode();
1362 }
1363 }
1364
1365
1366 static OrthancPluginErrorCode LookupMetadata(OrthancPluginDatabaseContext* context,
1367 void* payload,
1368 int64_t id,
1369 int32_t metadata)
1370 {
1371 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1372 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1373
1374 try
1375 {
1376 std::string s;
1377 if (backend->LookupMetadata(s, id, metadata))
1378 {
1379 OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
1380 backend->GetOutput().database_, s.c_str());
1381 }
1382
1383 return OrthancPluginErrorCode_Success;
1384 }
1385 catch (std::runtime_error& e)
1386 {
1387 LogError(backend, e);
1388 return OrthancPluginErrorCode_DatabasePlugin;
1389 }
1390 catch (DatabaseException& e)
1391 {
1392 return e.GetErrorCode();
1393 }
1394 }
1395
1396
1397 static OrthancPluginErrorCode LookupParent(OrthancPluginDatabaseContext* context,
1398 void* payload,
1399 int64_t id)
1400 {
1401 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1402 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1403
1404 try
1405 {
1406 int64_t parent;
1407 if (backend->LookupParent(parent, id))
1408 {
1409 OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1410 backend->GetOutput().database_, parent);
1411 }
1412
1413 return OrthancPluginErrorCode_Success;
1414 }
1415 catch (std::runtime_error& e)
1416 {
1417 LogError(backend, e);
1418 return OrthancPluginErrorCode_DatabasePlugin;
1419 }
1420 catch (DatabaseException& e)
1421 {
1422 return e.GetErrorCode();
1423 }
1424 }
1425
1426
1427 static OrthancPluginErrorCode LookupResource(OrthancPluginDatabaseContext* context,
1428 void* payload,
1429 const char* publicId)
1430 {
1431 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1432 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1433
1434 try
1435 {
1436 int64_t id;
1437 OrthancPluginResourceType type;
1438 if (backend->LookupResource(id, type, publicId))
1439 {
1440 OrthancPluginDatabaseAnswerResource(backend->GetOutput().context_,
1441 backend->GetOutput().database_,
1442 id, type);
1443 }
1444
1445 return OrthancPluginErrorCode_Success;
1446 }
1447 catch (std::runtime_error& e)
1448 {
1449 LogError(backend, e);
1450 return OrthancPluginErrorCode_DatabasePlugin;
1451 }
1452 catch (DatabaseException& e)
1453 {
1454 return e.GetErrorCode();
1455 }
1456 }
1457
1458
1459 static OrthancPluginErrorCode SelectPatientToRecycle(OrthancPluginDatabaseContext* context,
1460 void* payload)
1461 {
1462 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1463 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1464
1465 try
1466 {
1467 int64_t id;
1468 if (backend->SelectPatientToRecycle(id))
1469 {
1470 OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1471 backend->GetOutput().database_, id);
1472 }
1473
1474 return OrthancPluginErrorCode_Success;
1475 }
1476 catch (std::runtime_error& e)
1477 {
1478 LogError(backend, e);
1479 return OrthancPluginErrorCode_DatabasePlugin;
1480 }
1481 catch (DatabaseException& e)
1482 {
1483 return e.GetErrorCode();
1484 }
1485 }
1486
1487
1488 static OrthancPluginErrorCode SelectPatientToRecycle2(OrthancPluginDatabaseContext* context,
1489 void* payload,
1490 int64_t patientIdToAvoid)
1491 {
1492 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1493 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1494
1495 try
1496 {
1497 int64_t id;
1498 if (backend->SelectPatientToRecycle(id, patientIdToAvoid))
1499 {
1500 OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1501 backend->GetOutput().database_, id);
1502 }
1503
1504 return OrthancPluginErrorCode_Success;
1505 }
1506 catch (std::runtime_error& e)
1507 {
1508 LogError(backend, e);
1509 return OrthancPluginErrorCode_DatabasePlugin;
1510 }
1511 catch (DatabaseException& e)
1512 {
1513 return e.GetErrorCode();
1514 }
1515 }
1516
1517
1518 static OrthancPluginErrorCode SetGlobalProperty(void* payload,
1519 int32_t property,
1520 const char* value)
1521 {
1522 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1523 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1524
1525 try
1526 {
1527 backend->SetGlobalProperty(property, value);
1528 return OrthancPluginErrorCode_Success;
1529 }
1530 catch (std::runtime_error& e)
1531 {
1532 LogError(backend, e);
1533 return OrthancPluginErrorCode_DatabasePlugin;
1534 }
1535 catch (DatabaseException& e)
1536 {
1537 return e.GetErrorCode();
1538 }
1539 }
1540
1541
1542 static OrthancPluginErrorCode SetMainDicomTag(void* payload,
1543 int64_t id,
1544 const OrthancPluginDicomTag* tag)
1545 {
1546 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1547 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1548
1549 try
1550 {
1551 backend->SetMainDicomTag(id, tag->group, tag->element, tag->value);
1552 return OrthancPluginErrorCode_Success;
1553 }
1554 catch (std::runtime_error& e)
1555 {
1556 LogError(backend, e);
1557 return OrthancPluginErrorCode_DatabasePlugin;
1558 }
1559 catch (DatabaseException& e)
1560 {
1561 return e.GetErrorCode();
1562 }
1563 }
1564
1565
1566 static OrthancPluginErrorCode SetIdentifierTag(void* payload,
1567 int64_t id,
1568 const OrthancPluginDicomTag* tag)
1569 {
1570 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1571 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1572
1573 try
1574 {
1575 backend->SetIdentifierTag(id, tag->group, tag->element, tag->value);
1576 return OrthancPluginErrorCode_Success;
1577 }
1578 catch (std::runtime_error& e)
1579 {
1580 LogError(backend, e);
1581 return OrthancPluginErrorCode_DatabasePlugin;
1582 }
1583 catch (DatabaseException& e)
1584 {
1585 return e.GetErrorCode();
1586 }
1587 }
1588
1589
1590 static OrthancPluginErrorCode SetMetadata(void* payload,
1591 int64_t id,
1592 int32_t metadata,
1593 const char* value)
1594 {
1595 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1596 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1597
1598 try
1599 {
1600 backend->SetMetadata(id, metadata, value);
1601 return OrthancPluginErrorCode_Success;
1602 }
1603 catch (std::runtime_error& e)
1604 {
1605 LogError(backend, e);
1606 return OrthancPluginErrorCode_DatabasePlugin;
1607 }
1608 catch (DatabaseException& e)
1609 {
1610 return e.GetErrorCode();
1611 }
1612 }
1613
1614
1615 static OrthancPluginErrorCode SetProtectedPatient(void* payload,
1616 int64_t id,
1617 int32_t isProtected)
1618 {
1619 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1620 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1621
1622 try
1623 {
1624 backend->SetProtectedPatient(id, (isProtected != 0));
1625 return OrthancPluginErrorCode_Success;
1626 }
1627 catch (std::runtime_error& e)
1628 {
1629 LogError(backend, e);
1630 return OrthancPluginErrorCode_DatabasePlugin;
1631 }
1632 catch (DatabaseException& e)
1633 {
1634 return e.GetErrorCode();
1635 }
1636 }
1637
1638
1639 static OrthancPluginErrorCode StartTransaction(void* payload)
1640 {
1641 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1642 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1643
1644 try
1645 {
1646 backend->StartTransaction();
1647 return OrthancPluginErrorCode_Success;
1648 }
1649 catch (std::runtime_error& e)
1650 {
1651 LogError(backend, e);
1652 return OrthancPluginErrorCode_DatabasePlugin;
1653 }
1654 catch (DatabaseException& e)
1655 {
1656 return e.GetErrorCode();
1657 }
1658 }
1659
1660
1661 static OrthancPluginErrorCode RollbackTransaction(void* payload)
1662 {
1663 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1664 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1665
1666 try
1667 {
1668 backend->RollbackTransaction();
1669 return OrthancPluginErrorCode_Success;
1670 }
1671 catch (std::runtime_error& e)
1672 {
1673 LogError(backend, e);
1674 return OrthancPluginErrorCode_DatabasePlugin;
1675 }
1676 catch (DatabaseException& e)
1677 {
1678 return e.GetErrorCode();
1679 }
1680 }
1681
1682
1683 static OrthancPluginErrorCode CommitTransaction(void* payload)
1684 {
1685 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1686 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1687
1688 try
1689 {
1690 backend->CommitTransaction();
1691 return OrthancPluginErrorCode_Success;
1692 }
1693 catch (std::runtime_error& e)
1694 {
1695 LogError(backend, e);
1696 return OrthancPluginErrorCode_DatabasePlugin;
1697 }
1698 catch (DatabaseException& e)
1699 {
1700 return e.GetErrorCode();
1701 }
1702 }
1703
1704
1705 static OrthancPluginErrorCode Open(void* payload)
1706 {
1707 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1708 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1709
1710 try
1711 {
1712 backend->Open();
1713 return OrthancPluginErrorCode_Success;
1714 }
1715 catch (std::runtime_error& e)
1716 {
1717 LogError(backend, e);
1718 return OrthancPluginErrorCode_DatabasePlugin;
1719 }
1720 catch (DatabaseException& e)
1721 {
1722 return e.GetErrorCode();
1723 }
1724 }
1725
1726
1727 static OrthancPluginErrorCode Close(void* payload)
1728 {
1729 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1730 backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1731
1732 try
1733 {
1734 backend->Close();
1735 return OrthancPluginErrorCode_Success;
1736 }
1737 catch (std::runtime_error& e)
1738 {
1739 LogError(backend, e);
1740 return OrthancPluginErrorCode_DatabasePlugin;
1741 }
1742 catch (DatabaseException& e)
1743 {
1744 return e.GetErrorCode();
1745 }
1746 }
1747
1748
1749 static OrthancPluginErrorCode GetDatabaseVersion(uint32_t* version,
1750 void* payload)
1751 {
1752 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1753
1754 try
1755 {
1756 *version = backend->GetDatabaseVersion();
1757 return OrthancPluginErrorCode_Success;
1758 }
1759 catch (std::runtime_error& e)
1760 {
1761 LogError(backend, e);
1762 return OrthancPluginErrorCode_DatabasePlugin;
1763 }
1764 catch (DatabaseException& e)
1765 {
1766 return e.GetErrorCode();
1767 }
1768 }
1769
1770
1771 static OrthancPluginErrorCode UpgradeDatabase(void* payload,
1772 uint32_t targetVersion,
1773 OrthancPluginStorageArea* storageArea)
1774 {
1775 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1776
1777 try
1778 {
1779 backend->UpgradeDatabase(targetVersion, storageArea);
1780 return OrthancPluginErrorCode_Success;
1781 }
1782 catch (std::runtime_error& e)
1783 {
1784 LogError(backend, e);
1785 return OrthancPluginErrorCode_DatabasePlugin;
1786 }
1787 catch (DatabaseException& e)
1788 {
1789 return e.GetErrorCode();
1790 }
1791 }
1792
1793
1794 static OrthancPluginErrorCode ClearMainDicomTags(void* payload,
1795 int64_t internalId)
1796 {
1797 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1798
1799 try
1800 {
1801 backend->ClearMainDicomTags(internalId);
1802 return OrthancPluginErrorCode_Success;
1803 }
1804 catch (std::runtime_error& e)
1805 {
1806 LogError(backend, e);
1807 return OrthancPluginErrorCode_DatabasePlugin;
1808 }
1809 catch (DatabaseException& e)
1810 {
1811 return e.GetErrorCode();
1812 }
1813 }
1814
1815
1816 public:
1824 static void Register(OrthancPluginContext* context,
1825 IDatabaseBackend& backend)
1826 {
1827 OrthancPluginDatabaseBackend params;
1828 memset(&params, 0, sizeof(params));
1829
1830 OrthancPluginDatabaseExtensions extensions;
1831 memset(&extensions, 0, sizeof(extensions));
1832
1833 params.addAttachment = AddAttachment;
1834 params.attachChild = AttachChild;
1835 params.clearChanges = ClearChanges;
1836 params.clearExportedResources = ClearExportedResources;
1837 params.createResource = CreateResource;
1838 params.deleteAttachment = DeleteAttachment;
1839 params.deleteMetadata = DeleteMetadata;
1840 params.deleteResource = DeleteResource;
1841 params.getAllPublicIds = GetAllPublicIds;
1842 params.getChanges = GetChanges;
1843 params.getChildrenInternalId = GetChildrenInternalId;
1844 params.getChildrenPublicId = GetChildrenPublicId;
1845 params.getExportedResources = GetExportedResources;
1846 params.getLastChange = GetLastChange;
1847 params.getLastExportedResource = GetLastExportedResource;
1848 params.getMainDicomTags = GetMainDicomTags;
1849 params.getPublicId = GetPublicId;
1850 params.getResourceCount = GetResourceCount;
1851 params.getResourceType = GetResourceType;
1852 params.getTotalCompressedSize = GetTotalCompressedSize;
1853 params.getTotalUncompressedSize = GetTotalUncompressedSize;
1854 params.isExistingResource = IsExistingResource;
1855 params.isProtectedPatient = IsProtectedPatient;
1856 params.listAvailableMetadata = ListAvailableMetadata;
1857 params.listAvailableAttachments = ListAvailableAttachments;
1858 params.logChange = LogChange;
1859 params.logExportedResource = LogExportedResource;
1860 params.lookupAttachment = LookupAttachment;
1861 params.lookupGlobalProperty = LookupGlobalProperty;
1862 params.lookupIdentifier = NULL; // Unused starting with Orthanc 0.9.5 (db v6)
1863 params.lookupIdentifier2 = NULL; // Unused starting with Orthanc 0.9.5 (db v6)
1864 params.lookupMetadata = LookupMetadata;
1865 params.lookupParent = LookupParent;
1866 params.lookupResource = LookupResource;
1867 params.selectPatientToRecycle = SelectPatientToRecycle;
1868 params.selectPatientToRecycle2 = SelectPatientToRecycle2;
1869 params.setGlobalProperty = SetGlobalProperty;
1870 params.setMainDicomTag = SetMainDicomTag;
1871 params.setIdentifierTag = SetIdentifierTag;
1872 params.setMetadata = SetMetadata;
1873 params.setProtectedPatient = SetProtectedPatient;
1874 params.startTransaction = StartTransaction;
1875 params.rollbackTransaction = RollbackTransaction;
1876 params.commitTransaction = CommitTransaction;
1877 params.open = Open;
1878 params.close = Close;
1879
1880 extensions.getAllPublicIdsWithLimit = GetAllPublicIdsWithLimit;
1881 extensions.getDatabaseVersion = GetDatabaseVersion;
1882 extensions.upgradeDatabase = UpgradeDatabase;
1883 extensions.clearMainDicomTags = ClearMainDicomTags;
1884 extensions.getAllInternalIds = GetAllInternalIds; // New in Orthanc 0.9.5 (db v6)
1885 extensions.lookupIdentifier3 = LookupIdentifier3; // New in Orthanc 0.9.5 (db v6)
1886
1887 OrthancPluginDatabaseContext* database = OrthancPluginRegisterDatabaseBackendV2(context, &params, &extensions, &backend);
1888 if (!context)
1889 {
1890 throw std::runtime_error("Unable to register the database backend");
1891 }
1892
1893 backend.RegisterOutput(new DatabaseBackendOutput(context, database));
1894 }
1895 };
1896 }
OrthancPluginLogInfo
void OrthancPluginLogInfo(OrthancPluginContext *context, const char *message)
Log an information.
Definition: OrthancCPlugin.h:1374
OrthancPluginErrorCode_DatabasePlugin
Definition: OrthancCPlugin.h:222
OrthancPluginErrorCode
OrthancPluginErrorCode
Definition: OrthancCPlugin.h:188
OrthancPluginContext
struct _OrthancPluginContext_t OrthancPluginContext
Data structure that contains information about the Orthanc core.
OrthancPluginStorageArea
struct _OrthancPluginStorageArea_t OrthancPluginStorageArea
Opaque structure that represents the storage area that is actually used by Orthanc.
Definition: OrthancCPlugin.h:829
OrthancPluginResourceType
OrthancPluginResourceType
Definition: OrthancCPlugin.h:595
OrthancPlugins::IDatabaseBackend::UpgradeDatabase
virtual void UpgradeDatabase(uint32_t targetVersion, OrthancPluginStorageArea *storageArea)=0
OrthancPlugins::DatabaseBackendAdapter::Register
static void Register(OrthancPluginContext *context, IDatabaseBackend &backend)
Definition: OrthancCppDatabasePlugin.h:1824
OrthancPlugins
Definition: OrthancCppDatabasePlugin.h:43
OrthancPluginLogError
void OrthancPluginLogError(OrthancPluginContext *context, const char *message)
Log an error.
Definition: OrthancCPlugin.h:1342
OrthancPlugins::DatabaseException
Definition: OrthancCppDatabasePlugin.h:69
OrthancPlugins::DatabaseBackendAdapter
Bridge between C and C++ database engines.
Definition: OrthancCppDatabasePlugin.h:483
OrthancPlugins::DatabaseBackendOutput
Definition: OrthancCppDatabasePlugin.h:93
OrthancPluginErrorCode_Success
Definition: OrthancCPlugin.h:191
OrthancPluginDatabaseContext
struct _OrthancPluginDatabaseContext_t OrthancPluginDatabaseContext
Definition: OrthancCDatabasePlugin.h:56
OrthancPluginRegisterDatabaseBackendV2
OrthancPluginDatabaseContext * OrthancPluginRegisterDatabaseBackendV2(OrthancPluginContext *context, const OrthancPluginDatabaseBackend *backend, const OrthancPluginDatabaseExtensions *extensions, void *payload)
Definition: OrthancCDatabasePlugin.h:769
OrthancPluginLogWarning
void OrthancPluginLogWarning(OrthancPluginContext *context, const char *message)
Log a warning.
Definition: OrthancCPlugin.h:1358
OrthancPluginIdentifierConstraint
OrthancPluginIdentifierConstraint
Definition: OrthancCPlugin.h:753
OrthancPlugins::IDatabaseBackend
Definition: OrthancCppDatabasePlugin.h:279