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