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 
70  {
71  private:
73 
74  public:
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:
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,
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 
484  {
485  private:
486  // This class cannot be instantiated
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);
509  }
510  catch (std::runtime_error& e)
511  {
512  LogError(backend, e);
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);
533  }
534  catch (std::runtime_error& e)
535  {
536  LogError(backend, e);
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();
555  }
556  catch (std::runtime_error& e)
557  {
558  LogError(backend, e);
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();
577  }
578  catch (std::runtime_error& e)
579  {
580  LogError(backend, e);
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);
602  }
603  catch (std::runtime_error& e)
604  {
605  LogError(backend, e);
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);
626  }
627  catch (std::runtime_error& e)
628  {
629  LogError(backend, e);
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);
650  }
651  catch (std::runtime_error& e)
652  {
653  LogError(backend, e);
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);
673  }
674  catch (std::runtime_error& e)
675  {
676  LogError(backend, e);
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 
706  }
707  catch (std::runtime_error& e)
708  {
709  LogError(backend, e);
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 
740  }
741  catch (std::runtime_error& e)
742  {
743  LogError(backend, e);
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 
776  }
777  catch (std::runtime_error& e)
778  {
779  LogError(backend, e);
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 
809  }
810  catch (std::runtime_error& e)
811  {
812  LogError(backend, e);
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 
842  }
843  catch (std::runtime_error& e)
844  {
845  LogError(backend, e);
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 
876  }
877  catch (std::runtime_error& e)
878  {
879  LogError(backend, e);
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  }
908  }
909  catch (std::runtime_error& e)
910  {
911  LogError(backend, e);
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();
931  }
932  catch (std::runtime_error& e)
933  {
934  LogError(backend, e);
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();
954  }
955  catch (std::runtime_error& e)
956  {
957  LogError(backend, e);
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);
978  }
979  catch (std::runtime_error& e)
980  {
981  LogError(backend, e);
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 
1006  }
1007  catch (std::runtime_error& e)
1008  {
1009  LogError(backend, e);
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);
1030  }
1031  catch (std::runtime_error& e)
1032  {
1033  LogError(backend, e);
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);
1054  }
1055  catch (std::runtime_error& e)
1056  {
1057  LogError(backend, e);
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();
1077  }
1078  catch (std::runtime_error& e)
1079  {
1080  LogError(backend, e);
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();
1100  }
1101  catch (std::runtime_error& e)
1102  {
1103  LogError(backend, e);
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);
1124  }
1125  catch (std::runtime_error& e)
1126  {
1127  LogError(backend, e);
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);
1148  }
1149  catch (std::runtime_error& e)
1150  {
1151  LogError(backend, e);
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 
1182  }
1183  catch (std::runtime_error& e)
1184  {
1185  LogError(backend, e);
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 
1216  }
1217  catch (std::runtime_error& e)
1218  {
1219  LogError(backend, e);
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);
1239  }
1240  catch (std::runtime_error& e)
1241  {
1242  LogError(backend, e);
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);
1262  }
1263  catch (std::runtime_error& e)
1264  {
1265  LogError(backend, e);
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);
1287  }
1288  catch (std::runtime_error& e)
1289  {
1290  LogError(backend, e);
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 
1318  }
1319  catch (std::runtime_error& e)
1320  {
1321  LogError(backend, e);
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,
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 
1353  }
1354  catch (std::runtime_error& e)
1355  {
1356  LogError(backend, e);
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 
1384  }
1385  catch (std::runtime_error& e)
1386  {
1387  LogError(backend, e);
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 
1414  }
1415  catch (std::runtime_error& e)
1416  {
1417  LogError(backend, e);
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;
1438  if (backend->LookupResource(id, type, publicId))
1439  {
1440  OrthancPluginDatabaseAnswerResource(backend->GetOutput().context_,
1441  backend->GetOutput().database_,
1442  id, type);
1443  }
1444 
1446  }
1447  catch (std::runtime_error& e)
1448  {
1449  LogError(backend, e);
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 
1475  }
1476  catch (std::runtime_error& e)
1477  {
1478  LogError(backend, e);
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 
1505  }
1506  catch (std::runtime_error& e)
1507  {
1508  LogError(backend, e);
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);
1529  }
1530  catch (std::runtime_error& e)
1531  {
1532  LogError(backend, e);
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);
1553  }
1554  catch (std::runtime_error& e)
1555  {
1556  LogError(backend, e);
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);
1577  }
1578  catch (std::runtime_error& e)
1579  {
1580  LogError(backend, e);
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);
1602  }
1603  catch (std::runtime_error& e)
1604  {
1605  LogError(backend, e);
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));
1626  }
1627  catch (std::runtime_error& e)
1628  {
1629  LogError(backend, e);
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();
1648  }
1649  catch (std::runtime_error& e)
1650  {
1651  LogError(backend, e);
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();
1670  }
1671  catch (std::runtime_error& e)
1672  {
1673  LogError(backend, e);
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();
1692  }
1693  catch (std::runtime_error& e)
1694  {
1695  LogError(backend, e);
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();
1714  }
1715  catch (std::runtime_error& e)
1716  {
1717  LogError(backend, e);
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();
1736  }
1737  catch (std::runtime_error& e)
1738  {
1739  LogError(backend, e);
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();
1758  }
1759  catch (std::runtime_error& e)
1760  {
1761  LogError(backend, e);
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);
1781  }
1782  catch (std::runtime_error& e)
1783  {
1784  LogError(backend, e);
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);
1803  }
1804  catch (std::runtime_error& e)
1805  {
1806  LogError(backend, e);
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 }
void OrthancPluginLogInfo(OrthancPluginContext *context, const char *message)
Log an information.
Definition: OrthancCPlugin.h:1374
Definition: OrthancCPlugin.h:222
OrthancPluginErrorCode
Definition: OrthancCPlugin.h:188
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:829
OrthancPluginResourceType
Definition: OrthancCPlugin.h:595
virtual void UpgradeDatabase(uint32_t targetVersion, OrthancPluginStorageArea *storageArea)=0
static void Register(OrthancPluginContext *context, IDatabaseBackend &backend)
Definition: OrthancCppDatabasePlugin.h:1824
Definition: OrthancCppDatabasePlugin.h:43
void OrthancPluginLogError(OrthancPluginContext *context, const char *message)
Log an error.
Definition: OrthancCPlugin.h:1342
Definition: OrthancCppDatabasePlugin.h:69
Bridge between C and C++ database engines.
Definition: OrthancCppDatabasePlugin.h:483
Definition: OrthancCppDatabasePlugin.h:93
Definition: OrthancCPlugin.h:191
struct _OrthancPluginDatabaseContext_t OrthancPluginDatabaseContext
Definition: OrthancCDatabasePlugin.h:56
OrthancPluginDatabaseContext * OrthancPluginRegisterDatabaseBackendV2(OrthancPluginContext *context, const OrthancPluginDatabaseBackend *backend, const OrthancPluginDatabaseExtensions *extensions, void *payload)
Definition: OrthancCDatabasePlugin.h:769
void OrthancPluginLogWarning(OrthancPluginContext *context, const char *message)
Log a warning.
Definition: OrthancCPlugin.h:1358
OrthancPluginIdentifierConstraint
Definition: OrthancCPlugin.h:753
Definition: OrthancCppDatabasePlugin.h:279