2
* Orthanc - A Lightweight, RESTful DICOM Store
3
* Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
4
* Department, University Hospital of Liege, Belgium
6
* This program is free software: you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License as
8
* published by the Free Software Foundation, either version 3 of the
9
* License, or (at your option) any later version.
11
* In addition, as a special exception, the copyright holders of this
12
* program give permission to link the code of its release with the
13
* OpenSSL project's "OpenSSL" library (or with modified versions of it
14
* that use the same license as the "OpenSSL" library), and distribute
15
* the linked executables. You must obey the GNU General Public License
16
* in all respects for all of the code used other than "OpenSSL". If you
17
* modify file(s) with this exception, you may extend this exception to
18
* your version of the file(s), but you are not obligated to do so. If
19
* you do not wish to do so, delete this exception statement from your
20
* version. If you delete this exception statement from all source files
21
* in the program, then also delete it here.
23
* This program is distributed in the hope that it will be useful, but
24
* WITHOUT ANY WARRANTY; without even the implied warranty of
25
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26
* General Public License for more details.
28
* You should have received a copy of the GNU General Public License
29
* along with this program. If not, see <http://www.gnu.org/licenses/>.
36
#include "OrthancCDatabasePlugin.h"
42
namespace OrthancPlugins
44
// This class mimics "boost::noncopyable"
48
NonCopyable(const NonCopyable&);
50
NonCopyable& operator= (const NonCopyable&);
64
class DatabaseBackendOutput : public NonCopyable
66
friend class DatabaseBackendAdapter;
73
AllowedAnswers_Attachment,
74
AllowedAnswers_Change,
75
AllowedAnswers_DicomTag,
76
AllowedAnswers_ExportedResource
79
OrthancPluginContext* context_;
80
OrthancPluginDatabaseContext* database_;
81
AllowedAnswers allowedAnswers_;
83
void SetAllowedAnswers(AllowedAnswers allowed)
85
allowedAnswers_ = allowed;
89
DatabaseBackendOutput(OrthancPluginContext* context,
90
OrthancPluginDatabaseContext* database) :
93
allowedAnswers_(AllowedAnswers_All /* for unit tests */)
97
void LogError(const std::string& message)
99
OrthancPluginLogError(context_, message.c_str());
102
void LogWarning(const std::string& message)
104
OrthancPluginLogWarning(context_, message.c_str());
107
void LogInfo(const std::string& message)
109
OrthancPluginLogInfo(context_, message.c_str());
112
void SignalDeletedAttachment(const std::string& uuid,
114
uint64_t uncompressedSize,
115
const std::string& uncompressedHash,
116
int32_t compressionType,
117
uint64_t compressedSize,
118
const std::string& compressedHash)
120
OrthancPluginAttachment attachment;
121
attachment.uuid = uuid.c_str();
122
attachment.contentType = contentType;
123
attachment.uncompressedSize = uncompressedSize;
124
attachment.uncompressedHash = uncompressedHash.c_str();
125
attachment.compressionType = compressionType;
126
attachment.compressedSize = compressedSize;
127
attachment.compressedHash = compressedHash.c_str();
129
OrthancPluginDatabaseSignalDeletedAttachment(context_, database_, &attachment);
132
void SignalDeletedResource(const std::string& publicId,
133
OrthancPluginResourceType resourceType)
135
OrthancPluginDatabaseSignalDeletedResource(context_, database_, publicId.c_str(), resourceType);
138
void SignalRemainingAncestor(const std::string& ancestorId,
139
OrthancPluginResourceType ancestorType)
141
OrthancPluginDatabaseSignalRemainingAncestor(context_, database_, ancestorId.c_str(), ancestorType);
144
void AnswerAttachment(const std::string& uuid,
146
uint64_t uncompressedSize,
147
const std::string& uncompressedHash,
148
int32_t compressionType,
149
uint64_t compressedSize,
150
const std::string& compressedHash)
152
if (allowedAnswers_ != AllowedAnswers_All &&
153
allowedAnswers_ != AllowedAnswers_Attachment)
155
throw std::runtime_error("Cannot answer with an attachment in the current state");
158
OrthancPluginAttachment attachment;
159
attachment.uuid = uuid.c_str();
160
attachment.contentType = contentType;
161
attachment.uncompressedSize = uncompressedSize;
162
attachment.uncompressedHash = uncompressedHash.c_str();
163
attachment.compressionType = compressionType;
164
attachment.compressedSize = compressedSize;
165
attachment.compressedHash = compressedHash.c_str();
167
OrthancPluginDatabaseAnswerAttachment(context_, database_, &attachment);
170
void AnswerChange(int64_t seq,
172
OrthancPluginResourceType resourceType,
173
const std::string& publicId,
174
const std::string& date)
176
if (allowedAnswers_ != AllowedAnswers_All &&
177
allowedAnswers_ != AllowedAnswers_Change)
179
throw std::runtime_error("Cannot answer with a change in the current state");
182
OrthancPluginChange change;
184
change.changeType = changeType;
185
change.resourceType = resourceType;
186
change.publicId = publicId.c_str();
187
change.date = date.c_str();
189
OrthancPluginDatabaseAnswerChange(context_, database_, &change);
192
void AnswerDicomTag(uint16_t group,
194
const std::string& value)
196
if (allowedAnswers_ != AllowedAnswers_All &&
197
allowedAnswers_ != AllowedAnswers_DicomTag)
199
throw std::runtime_error("Cannot answer with a DICOM tag in the current state");
202
OrthancPluginDicomTag tag;
204
tag.element = element;
205
tag.value = value.c_str();
207
OrthancPluginDatabaseAnswerDicomTag(context_, database_, &tag);
210
void AnswerExportedResource(int64_t seq,
211
OrthancPluginResourceType resourceType,
212
const std::string& publicId,
213
const std::string& modality,
214
const std::string& date,
215
const std::string& patientId,
216
const std::string& studyInstanceUid,
217
const std::string& seriesInstanceUid,
218
const std::string& sopInstanceUid)
220
if (allowedAnswers_ != AllowedAnswers_All &&
221
allowedAnswers_ != AllowedAnswers_ExportedResource)
223
throw std::runtime_error("Cannot answer with an exported resource in the current state");
226
OrthancPluginExportedResource exported;
228
exported.resourceType = resourceType;
229
exported.publicId = publicId.c_str();
230
exported.modality = modality.c_str();
231
exported.date = date.c_str();
232
exported.patientId = patientId.c_str();
233
exported.studyInstanceUid = studyInstanceUid.c_str();
234
exported.seriesInstanceUid = seriesInstanceUid.c_str();
235
exported.sopInstanceUid = sopInstanceUid.c_str();
237
OrthancPluginDatabaseAnswerExportedResource(context_, database_, &exported);
243
class IDatabaseBackend : public NonCopyable
245
friend class DatabaseBackendAdapter;
248
DatabaseBackendOutput* output_;
260
DatabaseBackendOutput& GetOutput()
266
IDatabaseBackend() : output_(NULL)
270
virtual ~IDatabaseBackend()
275
// This takes the ownership
276
void RegisterOutput(DatabaseBackendOutput* output)
282
virtual void Open() = 0;
284
virtual void Close() = 0;
286
virtual void AddAttachment(int64_t id,
287
const OrthancPluginAttachment& attachment) = 0;
289
virtual void AttachChild(int64_t parent,
292
virtual void ClearChanges() = 0;
294
virtual void ClearExportedResources() = 0;
296
virtual int64_t CreateResource(const char* publicId,
297
OrthancPluginResourceType type) = 0;
299
virtual void DeleteAttachment(int64_t id,
300
int32_t attachment) = 0;
302
virtual void DeleteMetadata(int64_t id,
303
int32_t metadataType) = 0;
305
virtual void DeleteResource(int64_t id) = 0;
307
virtual void GetAllPublicIds(std::list<std::string>& target,
308
OrthancPluginResourceType resourceType) = 0;
310
/* Use GetOutput().AnswerChange() */
311
virtual void GetChanges(bool& done /*out*/,
313
uint32_t maxResults) = 0;
315
virtual void GetChildrenInternalId(std::list<int64_t>& target /*out*/,
318
virtual void GetChildrenPublicId(std::list<std::string>& target /*out*/,
321
/* Use GetOutput().AnswerExportedResource() */
322
virtual void GetExportedResources(bool& done /*out*/,
324
uint32_t maxResults) = 0;
326
/* Use GetOutput().AnswerChange() */
327
virtual void GetLastChange() = 0;
329
/* Use GetOutput().AnswerExportedResource() */
330
virtual void GetLastExportedResource() = 0;
332
/* Use GetOutput().AnswerDicomTag() */
333
virtual void GetMainDicomTags(int64_t id) = 0;
335
virtual std::string GetPublicId(int64_t resourceId) = 0;
337
virtual uint64_t GetResourceCount(OrthancPluginResourceType resourceType) = 0;
339
virtual OrthancPluginResourceType GetResourceType(int64_t resourceId) = 0;
341
virtual uint64_t GetTotalCompressedSize() = 0;
343
virtual uint64_t GetTotalUncompressedSize() = 0;
345
virtual bool IsExistingResource(int64_t internalId) = 0;
347
virtual bool IsProtectedPatient(int64_t internalId) = 0;
349
virtual void ListAvailableMetadata(std::list<int32_t>& target /*out*/,
352
virtual void ListAvailableAttachments(std::list<int32_t>& target /*out*/,
355
virtual void LogChange(const OrthancPluginChange& change) = 0;
357
virtual void LogExportedResource(const OrthancPluginExportedResource& resource) = 0;
359
/* Use GetOutput().AnswerAttachment() */
360
virtual bool LookupAttachment(int64_t id,
361
int32_t contentType) = 0;
363
virtual bool LookupGlobalProperty(std::string& target /*out*/,
364
int32_t property) = 0;
367
* "Identifiers" are necessarily one of the following tags:
368
* PatientID (0x0010, 0x0020), StudyInstanceUID (0x0020, 0x000d),
369
* SeriesInstanceUID (0x0020, 0x000e), SOPInstanceUID (0x0008,
370
* 0x0018) or AccessionNumber (0x0008, 0x0050).
372
virtual void LookupIdentifier(std::list<int64_t>& target /*out*/,
375
const char* value) = 0;
377
virtual void LookupIdentifier(std::list<int64_t>& target /*out*/,
378
const char* value) = 0;
380
virtual bool LookupMetadata(std::string& target /*out*/,
382
int32_t metadataType) = 0;
384
virtual bool LookupParent(int64_t& parentId /*out*/,
385
int64_t resourceId) = 0;
387
virtual bool LookupResource(int64_t& id /*out*/,
388
OrthancPluginResourceType& type /*out*/,
389
const char* publicId) = 0;
391
virtual bool SelectPatientToRecycle(int64_t& internalId /*out*/) = 0;
393
virtual bool SelectPatientToRecycle(int64_t& internalId /*out*/,
394
int64_t patientIdToAvoid) = 0;
396
virtual void SetGlobalProperty(int32_t property,
397
const char* value) = 0;
399
virtual void SetMainDicomTag(int64_t id,
402
const char* value) = 0;
404
virtual void SetIdentifierTag(int64_t id,
407
const char* value) = 0;
409
virtual void SetMetadata(int64_t id,
410
int32_t metadataType,
411
const char* value) = 0;
413
virtual void SetProtectedPatient(int64_t internalId,
414
bool isProtected) = 0;
416
virtual void StartTransaction() = 0;
418
virtual void RollbackTransaction() = 0;
420
virtual void CommitTransaction() = 0;
425
class DatabaseBackendAdapter
428
// This class cannot be instantiated
429
DatabaseBackendAdapter()
433
static void LogError(IDatabaseBackend* backend,
434
const std::runtime_error& e)
436
backend->GetOutput().LogError("Exception in database back-end: " + std::string(e.what()));
440
static int32_t AddAttachment(void* payload,
442
const OrthancPluginAttachment* attachment)
444
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
445
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
449
backend->AddAttachment(id, *attachment);
452
catch (std::runtime_error& e)
454
LogError(backend, e);
460
static int32_t AttachChild(void* payload,
464
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
465
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
469
backend->AttachChild(parent, child);
472
catch (std::runtime_error& e)
474
LogError(backend, e);
480
static int32_t ClearChanges(void* payload)
482
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
483
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
487
backend->ClearChanges();
490
catch (std::runtime_error& e)
492
LogError(backend, e);
498
static int32_t ClearExportedResources(void* payload)
500
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
501
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
505
backend->ClearExportedResources();
508
catch (std::runtime_error& e)
510
LogError(backend, e);
516
static int32_t CreateResource(int64_t* id,
518
const char* publicId,
519
OrthancPluginResourceType resourceType)
521
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
522
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
526
*id = backend->CreateResource(publicId, resourceType);
529
catch (std::runtime_error& e)
531
LogError(backend, e);
537
static int32_t DeleteAttachment(void* payload,
541
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
542
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
546
backend->DeleteAttachment(id, contentType);
549
catch (std::runtime_error& e)
551
LogError(backend, e);
557
static int32_t DeleteMetadata(void* payload,
559
int32_t metadataType)
561
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
562
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
566
backend->DeleteMetadata(id, metadataType);
569
catch (std::runtime_error& e)
571
LogError(backend, e);
577
static int32_t DeleteResource(void* payload,
580
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
581
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
585
backend->DeleteResource(id);
588
catch (std::runtime_error& e)
590
LogError(backend, e);
596
static int32_t GetAllPublicIds(OrthancPluginDatabaseContext* context,
598
OrthancPluginResourceType resourceType)
600
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
601
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
605
std::list<std::string> ids;
606
backend->GetAllPublicIds(ids, resourceType);
608
for (std::list<std::string>::const_iterator
609
it = ids.begin(); it != ids.end(); ++it)
611
OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
612
backend->GetOutput().database_,
618
catch (std::runtime_error& e)
620
LogError(backend, e);
626
static int32_t GetChanges(OrthancPluginDatabaseContext* context,
631
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
632
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Change);
637
backend->GetChanges(done, since, maxResult);
641
OrthancPluginDatabaseAnswerChangesDone(backend->GetOutput().context_,
642
backend->GetOutput().database_);
647
catch (std::runtime_error& e)
649
LogError(backend, e);
655
static int32_t GetChildrenInternalId(OrthancPluginDatabaseContext* context,
659
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
660
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
664
std::list<int64_t> target;
665
backend->GetChildrenInternalId(target, id);
667
for (std::list<int64_t>::const_iterator
668
it = target.begin(); it != target.end(); ++it)
670
OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
671
backend->GetOutput().database_, *it);
676
catch (std::runtime_error& e)
678
LogError(backend, e);
684
static int32_t GetChildrenPublicId(OrthancPluginDatabaseContext* context,
688
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
689
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
693
std::list<std::string> ids;
694
backend->GetChildrenPublicId(ids, id);
696
for (std::list<std::string>::const_iterator
697
it = ids.begin(); it != ids.end(); ++it)
699
OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
700
backend->GetOutput().database_,
706
catch (std::runtime_error& e)
708
LogError(backend, e);
714
static int32_t GetExportedResources(OrthancPluginDatabaseContext* context,
719
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
720
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_ExportedResource);
725
backend->GetExportedResources(done, since, maxResult);
729
OrthancPluginDatabaseAnswerExportedResourcesDone(backend->GetOutput().context_,
730
backend->GetOutput().database_);
734
catch (std::runtime_error& e)
736
LogError(backend, e);
742
static int32_t GetLastChange(OrthancPluginDatabaseContext* context,
745
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
746
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Change);
750
backend->GetLastChange();
753
catch (std::runtime_error& e)
755
LogError(backend, e);
761
static int32_t GetLastExportedResource(OrthancPluginDatabaseContext* context,
764
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
765
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_ExportedResource);
769
backend->GetLastExportedResource();
772
catch (std::runtime_error& e)
774
LogError(backend, e);
780
static int32_t GetMainDicomTags(OrthancPluginDatabaseContext* context,
784
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
785
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_DicomTag);
789
backend->GetMainDicomTags(id);
792
catch (std::runtime_error& e)
794
LogError(backend, e);
800
static int32_t GetPublicId(OrthancPluginDatabaseContext* context,
804
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
805
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
809
std::string s = backend->GetPublicId(id);
810
OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
811
backend->GetOutput().database_,
816
catch (std::runtime_error& e)
818
LogError(backend, e);
824
static int32_t GetResourceCount(uint64_t* target,
826
OrthancPluginResourceType resourceType)
828
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
829
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
833
*target = backend->GetResourceCount(resourceType);
836
catch (std::runtime_error& e)
838
LogError(backend, e);
844
static int32_t GetResourceType(OrthancPluginResourceType* resourceType,
848
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
849
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
853
*resourceType = backend->GetResourceType(id);
856
catch (std::runtime_error& e)
858
LogError(backend, e);
864
static int32_t GetTotalCompressedSize(uint64_t* target,
867
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
868
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
872
*target = backend->GetTotalCompressedSize();
875
catch (std::runtime_error& e)
877
LogError(backend, e);
883
static int32_t GetTotalUncompressedSize(uint64_t* target,
886
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
887
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
891
*target = backend->GetTotalUncompressedSize();
894
catch (std::runtime_error& e)
896
LogError(backend, e);
902
static int32_t IsExistingResource(int32_t* existing,
906
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
907
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
911
*existing = backend->IsExistingResource(id);
914
catch (std::runtime_error& e)
916
LogError(backend, e);
922
static int32_t IsProtectedPatient(int32_t* isProtected,
926
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
927
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
931
*isProtected = backend->IsProtectedPatient(id);
934
catch (std::runtime_error& e)
936
LogError(backend, e);
942
static int32_t ListAvailableMetadata(OrthancPluginDatabaseContext* context,
946
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
947
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
951
std::list<int32_t> target;
952
backend->ListAvailableMetadata(target, id);
954
for (std::list<int32_t>::const_iterator
955
it = target.begin(); it != target.end(); ++it)
957
OrthancPluginDatabaseAnswerInt32(backend->GetOutput().context_,
958
backend->GetOutput().database_,
964
catch (std::runtime_error& e)
966
LogError(backend, e);
972
static int32_t ListAvailableAttachments(OrthancPluginDatabaseContext* context,
976
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
977
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
981
std::list<int32_t> target;
982
backend->ListAvailableAttachments(target, id);
984
for (std::list<int32_t>::const_iterator
985
it = target.begin(); it != target.end(); ++it)
987
OrthancPluginDatabaseAnswerInt32(backend->GetOutput().context_,
988
backend->GetOutput().database_,
994
catch (std::runtime_error& e)
996
LogError(backend, e);
1002
static int32_t LogChange(void* payload,
1003
const OrthancPluginChange* change)
1005
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1006
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1010
backend->LogChange(*change);
1013
catch (std::runtime_error& e)
1015
LogError(backend, e);
1021
static int32_t LogExportedResource(void* payload,
1022
const OrthancPluginExportedResource* exported)
1024
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1025
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1029
backend->LogExportedResource(*exported);
1032
catch (std::runtime_error& e)
1034
LogError(backend, e);
1040
static int32_t LookupAttachment(OrthancPluginDatabaseContext* context,
1043
int32_t contentType)
1045
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1046
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Attachment);
1050
backend->LookupAttachment(id, contentType);
1053
catch (std::runtime_error& e)
1055
LogError(backend, e);
1061
static int32_t LookupGlobalProperty(OrthancPluginDatabaseContext* context,
1065
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1066
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1071
if (backend->LookupGlobalProperty(s, property))
1073
OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
1074
backend->GetOutput().database_,
1080
catch (std::runtime_error& e)
1082
LogError(backend, e);
1088
static int32_t LookupIdentifier(OrthancPluginDatabaseContext* context,
1090
const OrthancPluginDicomTag* tag)
1092
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1093
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1097
std::list<int64_t> target;
1098
backend->LookupIdentifier(target, tag->group, tag->element, tag->value);
1100
for (std::list<int64_t>::const_iterator
1101
it = target.begin(); it != target.end(); ++it)
1103
OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1104
backend->GetOutput().database_, *it);
1109
catch (std::runtime_error& e)
1111
LogError(backend, e);
1117
static int32_t LookupIdentifier2(OrthancPluginDatabaseContext* context,
1121
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1122
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1126
std::list<int64_t> target;
1127
backend->LookupIdentifier(target, value);
1129
for (std::list<int64_t>::const_iterator
1130
it = target.begin(); it != target.end(); ++it)
1132
OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1133
backend->GetOutput().database_, *it);
1138
catch (std::runtime_error& e)
1140
LogError(backend, e);
1146
static int32_t LookupMetadata(OrthancPluginDatabaseContext* context,
1151
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1152
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1157
if (backend->LookupMetadata(s, id, metadata))
1159
OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
1160
backend->GetOutput().database_, s.c_str());
1165
catch (std::runtime_error& e)
1167
LogError(backend, e);
1173
static int32_t LookupParent(OrthancPluginDatabaseContext* context,
1177
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1178
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1183
if (backend->LookupParent(parent, id))
1185
OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1186
backend->GetOutput().database_, parent);
1191
catch (std::runtime_error& e)
1193
LogError(backend, e);
1199
static int32_t LookupResource(OrthancPluginDatabaseContext* context,
1201
const char* publicId)
1203
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1204
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1209
OrthancPluginResourceType type;
1210
if (backend->LookupResource(id, type, publicId))
1212
OrthancPluginDatabaseAnswerResource(backend->GetOutput().context_,
1213
backend->GetOutput().database_,
1219
catch (std::runtime_error& e)
1221
LogError(backend, e);
1227
static int32_t SelectPatientToRecycle(OrthancPluginDatabaseContext* context,
1230
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1231
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1236
if (backend->SelectPatientToRecycle(id))
1238
OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1239
backend->GetOutput().database_, id);
1244
catch (std::runtime_error& e)
1246
LogError(backend, e);
1252
static int32_t SelectPatientToRecycle2(OrthancPluginDatabaseContext* context,
1254
int64_t patientIdToAvoid)
1256
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1257
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1262
if (backend->SelectPatientToRecycle(id, patientIdToAvoid))
1264
OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
1265
backend->GetOutput().database_, id);
1270
catch (std::runtime_error& e)
1272
LogError(backend, e);
1278
static int32_t SetGlobalProperty(void* payload,
1282
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1283
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1287
backend->SetGlobalProperty(property, value);
1290
catch (std::runtime_error& e)
1292
LogError(backend, e);
1298
static int32_t SetMainDicomTag(void* payload,
1300
const OrthancPluginDicomTag* tag)
1302
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1303
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1307
backend->SetMainDicomTag(id, tag->group, tag->element, tag->value);
1310
catch (std::runtime_error& e)
1312
LogError(backend, e);
1318
static int32_t SetIdentifierTag(void* payload,
1320
const OrthancPluginDicomTag* tag)
1322
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1323
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1327
backend->SetIdentifierTag(id, tag->group, tag->element, tag->value);
1330
catch (std::runtime_error& e)
1332
LogError(backend, e);
1338
static int32_t SetMetadata(void* payload,
1343
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1344
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1348
backend->SetMetadata(id, metadata, value);
1351
catch (std::runtime_error& e)
1353
LogError(backend, e);
1359
static int32_t SetProtectedPatient(void* payload,
1361
int32_t isProtected)
1363
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1364
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1368
backend->SetProtectedPatient(id, (isProtected != 0));
1371
catch (std::runtime_error& e)
1373
LogError(backend, e);
1379
static int32_t StartTransaction(void* payload)
1381
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1382
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1386
backend->StartTransaction();
1389
catch (std::runtime_error& e)
1391
LogError(backend, e);
1397
static int32_t RollbackTransaction(void* payload)
1399
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1400
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1404
backend->RollbackTransaction();
1407
catch (std::runtime_error& e)
1409
LogError(backend, e);
1415
static int32_t CommitTransaction(void* payload)
1417
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1418
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1422
backend->CommitTransaction();
1425
catch (std::runtime_error& e)
1427
LogError(backend, e);
1433
static int32_t Open(void* payload)
1435
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1436
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1443
catch (std::runtime_error& e)
1445
LogError(backend, e);
1451
static int32_t Close(void* payload)
1453
IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
1454
backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
1461
catch (std::runtime_error& e)
1463
LogError(backend, e);
1470
static void Register(OrthancPluginContext* context,
1471
IDatabaseBackend& backend)
1473
OrthancPluginDatabaseBackend params;
1474
memset(¶ms, 0, sizeof(params));
1476
params.addAttachment = AddAttachment;
1477
params.attachChild = AttachChild;
1478
params.clearChanges = ClearChanges;
1479
params.clearExportedResources = ClearExportedResources;
1480
params.createResource = CreateResource;
1481
params.deleteAttachment = DeleteAttachment;
1482
params.deleteMetadata = DeleteMetadata;
1483
params.deleteResource = DeleteResource;
1484
params.getAllPublicIds = GetAllPublicIds;
1485
params.getChanges = GetChanges;
1486
params.getChildrenInternalId = GetChildrenInternalId;
1487
params.getChildrenPublicId = GetChildrenPublicId;
1488
params.getExportedResources = GetExportedResources;
1489
params.getLastChange = GetLastChange;
1490
params.getLastExportedResource = GetLastExportedResource;
1491
params.getMainDicomTags = GetMainDicomTags;
1492
params.getPublicId = GetPublicId;
1493
params.getResourceCount = GetResourceCount;
1494
params.getResourceType = GetResourceType;
1495
params.getTotalCompressedSize = GetTotalCompressedSize;
1496
params.getTotalUncompressedSize = GetTotalUncompressedSize;
1497
params.isExistingResource = IsExistingResource;
1498
params.isProtectedPatient = IsProtectedPatient;
1499
params.listAvailableMetadata = ListAvailableMetadata;
1500
params.listAvailableAttachments = ListAvailableAttachments;
1501
params.logChange = LogChange;
1502
params.logExportedResource = LogExportedResource;
1503
params.lookupAttachment = LookupAttachment;
1504
params.lookupGlobalProperty = LookupGlobalProperty;
1505
params.lookupIdentifier = LookupIdentifier;
1506
params.lookupIdentifier2 = LookupIdentifier2;
1507
params.lookupMetadata = LookupMetadata;
1508
params.lookupParent = LookupParent;
1509
params.lookupResource = LookupResource;
1510
params.selectPatientToRecycle = SelectPatientToRecycle;
1511
params.selectPatientToRecycle2 = SelectPatientToRecycle2;
1512
params.setGlobalProperty = SetGlobalProperty;
1513
params.setMainDicomTag = SetMainDicomTag;
1514
params.setIdentifierTag = SetIdentifierTag;
1515
params.setMetadata = SetMetadata;
1516
params.setProtectedPatient = SetProtectedPatient;
1517
params.startTransaction = StartTransaction;
1518
params.rollbackTransaction = RollbackTransaction;
1519
params.commitTransaction = CommitTransaction;
1521
params.close = Close;
1523
OrthancPluginDatabaseContext* database = OrthancPluginRegisterDatabaseBackend(context, ¶ms, &backend);
1526
throw std::runtime_error("Unable to register the database backend");
1529
backend.RegisterOutput(new DatabaseBackendOutput(context, database));