~ubuntu-branches/ubuntu/wily/orthanc-postgresql/wily

« back to all changes in this revision

Viewing changes to Orthanc/Sdk-0.9.1/orthanc/OrthancCppDatabasePlugin.h

  • Committer: Package Import Robot
  • Author(s): Sebastien Jodogne, Sebastien Jodogne, Karsten Hilbert
  • Date: 2015-08-03 09:23:28 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20150803092328-swn3mnpj0fz34v42
Tags: 1.2-1
[ Sebastien Jodogne ]
* New upstream version

[ Karsten Hilbert ]
* Enhancements for README.Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Orthanc - A Lightweight, RESTful DICOM Store
 
3
 * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
 
4
 * Department, University Hospital of Liege, Belgium
 
5
 *
 
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.
 
10
 *
 
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.
 
22
 * 
 
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.
 
27
 *
 
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/>.
 
30
 **/
 
31
 
 
32
 
 
33
 
 
34
#pragma once
 
35
 
 
36
#include "OrthancCDatabasePlugin.h"
 
37
 
 
38
#include <stdexcept>
 
39
#include <list>
 
40
#include <string>
 
41
 
 
42
namespace OrthancPlugins
 
43
{
 
44
  // This class mimics "boost::noncopyable"
 
45
  class NonCopyable
 
46
  {
 
47
  private:
 
48
    NonCopyable(const NonCopyable&);
 
49
 
 
50
    NonCopyable& operator= (const NonCopyable&);
 
51
 
 
52
  protected:
 
53
    NonCopyable()
 
54
    {
 
55
    }
 
56
 
 
57
    ~NonCopyable()
 
58
    {
 
59
    }
 
60
  };
 
61
 
 
62
 
 
63
 
 
64
  class DatabaseBackendOutput : public NonCopyable
 
65
  {
 
66
    friend class DatabaseBackendAdapter;
 
67
 
 
68
  private:
 
69
    enum AllowedAnswers
 
70
    {
 
71
      AllowedAnswers_All,
 
72
      AllowedAnswers_None,
 
73
      AllowedAnswers_Attachment,
 
74
      AllowedAnswers_Change,
 
75
      AllowedAnswers_DicomTag,
 
76
      AllowedAnswers_ExportedResource
 
77
    };
 
78
 
 
79
    OrthancPluginContext*         context_;
 
80
    OrthancPluginDatabaseContext* database_;
 
81
    AllowedAnswers                allowedAnswers_;
 
82
 
 
83
    void SetAllowedAnswers(AllowedAnswers allowed)
 
84
    {
 
85
      allowedAnswers_ = allowed;
 
86
    }
 
87
 
 
88
  public:
 
89
    DatabaseBackendOutput(OrthancPluginContext*         context,
 
90
                          OrthancPluginDatabaseContext* database) :
 
91
      context_(context),
 
92
      database_(database),
 
93
      allowedAnswers_(AllowedAnswers_All /* for unit tests */)
 
94
    {
 
95
    }
 
96
 
 
97
    void LogError(const std::string& message)
 
98
    {
 
99
      OrthancPluginLogError(context_, message.c_str());
 
100
    }
 
101
 
 
102
    void LogWarning(const std::string& message)
 
103
    {
 
104
      OrthancPluginLogWarning(context_, message.c_str());
 
105
    }
 
106
 
 
107
    void LogInfo(const std::string& message)
 
108
    {
 
109
      OrthancPluginLogInfo(context_, message.c_str());
 
110
    }
 
111
 
 
112
    void SignalDeletedAttachment(const std::string& uuid,
 
113
                                 int32_t            contentType,
 
114
                                 uint64_t           uncompressedSize,
 
115
                                 const std::string& uncompressedHash,
 
116
                                 int32_t            compressionType,
 
117
                                 uint64_t           compressedSize,
 
118
                                 const std::string& compressedHash)
 
119
    {
 
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();
 
128
 
 
129
      OrthancPluginDatabaseSignalDeletedAttachment(context_, database_, &attachment);
 
130
    }
 
131
 
 
132
    void SignalDeletedResource(const std::string& publicId,
 
133
                               OrthancPluginResourceType resourceType)
 
134
    {
 
135
      OrthancPluginDatabaseSignalDeletedResource(context_, database_, publicId.c_str(), resourceType);
 
136
    }
 
137
 
 
138
    void SignalRemainingAncestor(const std::string& ancestorId,
 
139
                                 OrthancPluginResourceType ancestorType)
 
140
    {
 
141
      OrthancPluginDatabaseSignalRemainingAncestor(context_, database_, ancestorId.c_str(), ancestorType);
 
142
    }
 
143
 
 
144
    void AnswerAttachment(const std::string& uuid,
 
145
                          int32_t            contentType,
 
146
                          uint64_t           uncompressedSize,
 
147
                          const std::string& uncompressedHash,
 
148
                          int32_t            compressionType,
 
149
                          uint64_t           compressedSize,
 
150
                          const std::string& compressedHash)
 
151
    {
 
152
      if (allowedAnswers_ != AllowedAnswers_All &&
 
153
          allowedAnswers_ != AllowedAnswers_Attachment)
 
154
      {
 
155
        throw std::runtime_error("Cannot answer with an attachment in the current state");
 
156
      }
 
157
 
 
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();
 
166
 
 
167
      OrthancPluginDatabaseAnswerAttachment(context_, database_, &attachment);
 
168
    }
 
169
 
 
170
    void AnswerChange(int64_t                    seq,
 
171
                      int32_t                    changeType,
 
172
                      OrthancPluginResourceType  resourceType,
 
173
                      const std::string&         publicId,
 
174
                      const std::string&         date)
 
175
    {
 
176
      if (allowedAnswers_ != AllowedAnswers_All &&
 
177
          allowedAnswers_ != AllowedAnswers_Change)
 
178
      {
 
179
        throw std::runtime_error("Cannot answer with a change in the current state");
 
180
      }
 
181
 
 
182
      OrthancPluginChange change;
 
183
      change.seq = seq;
 
184
      change.changeType = changeType;
 
185
      change.resourceType = resourceType;
 
186
      change.publicId = publicId.c_str();
 
187
      change.date = date.c_str();
 
188
 
 
189
      OrthancPluginDatabaseAnswerChange(context_, database_, &change);
 
190
    }
 
191
 
 
192
    void AnswerDicomTag(uint16_t group,
 
193
                        uint16_t element,
 
194
                        const std::string& value)
 
195
    {
 
196
      if (allowedAnswers_ != AllowedAnswers_All &&
 
197
          allowedAnswers_ != AllowedAnswers_DicomTag)
 
198
      {
 
199
        throw std::runtime_error("Cannot answer with a DICOM tag in the current state");
 
200
      }
 
201
 
 
202
      OrthancPluginDicomTag tag;
 
203
      tag.group = group;
 
204
      tag.element = element;
 
205
      tag.value = value.c_str();
 
206
 
 
207
      OrthancPluginDatabaseAnswerDicomTag(context_, database_, &tag);
 
208
    }
 
209
 
 
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)
 
219
    {
 
220
      if (allowedAnswers_ != AllowedAnswers_All &&
 
221
          allowedAnswers_ != AllowedAnswers_ExportedResource)
 
222
      {
 
223
        throw std::runtime_error("Cannot answer with an exported resource in the current state");
 
224
      }
 
225
 
 
226
      OrthancPluginExportedResource exported;
 
227
      exported.seq = seq;
 
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();
 
236
 
 
237
      OrthancPluginDatabaseAnswerExportedResource(context_, database_, &exported);
 
238
    }
 
239
  };
 
240
 
 
241
 
 
242
 
 
243
  class IDatabaseBackend : public NonCopyable
 
244
  {
 
245
    friend class DatabaseBackendAdapter;
 
246
 
 
247
  private:
 
248
    DatabaseBackendOutput*  output_;
 
249
 
 
250
    void Finalize()
 
251
    {
 
252
      if (output_ != NULL)
 
253
      {
 
254
        delete output_;
 
255
        output_ = NULL;
 
256
      }
 
257
    }
 
258
 
 
259
  protected:
 
260
    DatabaseBackendOutput& GetOutput()
 
261
    {
 
262
      return *output_;
 
263
    }
 
264
 
 
265
  public:
 
266
    IDatabaseBackend() : output_(NULL)
 
267
    {
 
268
    }
 
269
 
 
270
    virtual ~IDatabaseBackend()
 
271
    {
 
272
      Finalize();
 
273
    }
 
274
 
 
275
    // This takes the ownership
 
276
    void RegisterOutput(DatabaseBackendOutput* output)
 
277
    {
 
278
      Finalize();
 
279
      output_ = output;
 
280
    }
 
281
 
 
282
    virtual void Open() = 0;
 
283
 
 
284
    virtual void Close() = 0;
 
285
 
 
286
    virtual void AddAttachment(int64_t id,
 
287
                               const OrthancPluginAttachment& attachment) = 0;
 
288
 
 
289
    virtual void AttachChild(int64_t parent,
 
290
                             int64_t child) = 0;
 
291
 
 
292
    virtual void ClearChanges() = 0;
 
293
 
 
294
    virtual void ClearExportedResources() = 0;
 
295
 
 
296
    virtual int64_t CreateResource(const char* publicId,
 
297
                                   OrthancPluginResourceType type) = 0;
 
298
 
 
299
    virtual void DeleteAttachment(int64_t id,
 
300
                                  int32_t attachment) = 0;
 
301
 
 
302
    virtual void DeleteMetadata(int64_t id,
 
303
                                int32_t metadataType) = 0;
 
304
 
 
305
    virtual void DeleteResource(int64_t id) = 0;
 
306
 
 
307
    virtual void GetAllPublicIds(std::list<std::string>& target,
 
308
                                 OrthancPluginResourceType resourceType) = 0;
 
309
 
 
310
    /* Use GetOutput().AnswerChange() */
 
311
    virtual void GetChanges(bool& done /*out*/,
 
312
                            int64_t since,
 
313
                            uint32_t maxResults) = 0;
 
314
 
 
315
    virtual void GetChildrenInternalId(std::list<int64_t>& target /*out*/,
 
316
                                       int64_t id) = 0;
 
317
 
 
318
    virtual void GetChildrenPublicId(std::list<std::string>& target /*out*/,
 
319
                                     int64_t id) = 0;
 
320
 
 
321
    /* Use GetOutput().AnswerExportedResource() */
 
322
    virtual void GetExportedResources(bool& done /*out*/,
 
323
                                      int64_t since,
 
324
                                      uint32_t maxResults) = 0;
 
325
 
 
326
    /* Use GetOutput().AnswerChange() */
 
327
    virtual void GetLastChange() = 0;
 
328
 
 
329
    /* Use GetOutput().AnswerExportedResource() */
 
330
    virtual void GetLastExportedResource() = 0;
 
331
 
 
332
    /* Use GetOutput().AnswerDicomTag() */
 
333
    virtual void GetMainDicomTags(int64_t id) = 0;
 
334
 
 
335
    virtual std::string GetPublicId(int64_t resourceId) = 0;
 
336
 
 
337
    virtual uint64_t GetResourceCount(OrthancPluginResourceType resourceType) = 0;
 
338
 
 
339
    virtual OrthancPluginResourceType GetResourceType(int64_t resourceId) = 0;
 
340
 
 
341
    virtual uint64_t GetTotalCompressedSize() = 0;
 
342
    
 
343
    virtual uint64_t GetTotalUncompressedSize() = 0;
 
344
 
 
345
    virtual bool IsExistingResource(int64_t internalId) = 0;
 
346
 
 
347
    virtual bool IsProtectedPatient(int64_t internalId) = 0;
 
348
 
 
349
    virtual void ListAvailableMetadata(std::list<int32_t>& target /*out*/,
 
350
                                       int64_t id) = 0;
 
351
 
 
352
    virtual void ListAvailableAttachments(std::list<int32_t>& target /*out*/,
 
353
                                          int64_t id) = 0;
 
354
 
 
355
    virtual void LogChange(const OrthancPluginChange& change) = 0;
 
356
 
 
357
    virtual void LogExportedResource(const OrthancPluginExportedResource& resource) = 0;
 
358
    
 
359
    /* Use GetOutput().AnswerAttachment() */
 
360
    virtual bool LookupAttachment(int64_t id,
 
361
                                  int32_t contentType) = 0;
 
362
 
 
363
    virtual bool LookupGlobalProperty(std::string& target /*out*/,
 
364
                                      int32_t property) = 0;
 
365
 
 
366
    /**
 
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).
 
371
     **/
 
372
    virtual void LookupIdentifier(std::list<int64_t>& target /*out*/,
 
373
                                  uint16_t group,
 
374
                                  uint16_t element,
 
375
                                  const char* value) = 0;
 
376
 
 
377
    virtual void LookupIdentifier(std::list<int64_t>& target /*out*/,
 
378
                                  const char* value) = 0;
 
379
 
 
380
    virtual bool LookupMetadata(std::string& target /*out*/,
 
381
                                int64_t id,
 
382
                                int32_t metadataType) = 0;
 
383
 
 
384
    virtual bool LookupParent(int64_t& parentId /*out*/,
 
385
                              int64_t resourceId) = 0;
 
386
 
 
387
    virtual bool LookupResource(int64_t& id /*out*/,
 
388
                                OrthancPluginResourceType& type /*out*/,
 
389
                                const char* publicId) = 0;
 
390
 
 
391
    virtual bool SelectPatientToRecycle(int64_t& internalId /*out*/) = 0;
 
392
 
 
393
    virtual bool SelectPatientToRecycle(int64_t& internalId /*out*/,
 
394
                                        int64_t patientIdToAvoid) = 0;
 
395
 
 
396
    virtual void SetGlobalProperty(int32_t property,
 
397
                                   const char* value) = 0;
 
398
 
 
399
    virtual void SetMainDicomTag(int64_t id,
 
400
                                 uint16_t group,
 
401
                                 uint16_t element,
 
402
                                 const char* value) = 0;
 
403
 
 
404
    virtual void SetIdentifierTag(int64_t id,
 
405
                                  uint16_t group,
 
406
                                  uint16_t element,
 
407
                                  const char* value) = 0;
 
408
 
 
409
    virtual void SetMetadata(int64_t id,
 
410
                             int32_t metadataType,
 
411
                             const char* value) = 0;
 
412
 
 
413
    virtual void SetProtectedPatient(int64_t internalId, 
 
414
                                     bool isProtected) = 0;
 
415
 
 
416
    virtual void StartTransaction() = 0;
 
417
 
 
418
    virtual void RollbackTransaction() = 0;
 
419
 
 
420
    virtual void CommitTransaction() = 0;
 
421
  };
 
422
 
 
423
 
 
424
 
 
425
  class DatabaseBackendAdapter
 
426
  {
 
427
  private:
 
428
    // This class cannot be instantiated
 
429
    DatabaseBackendAdapter()
 
430
    {
 
431
    }
 
432
 
 
433
    static void LogError(IDatabaseBackend* backend,
 
434
                         const std::runtime_error& e)
 
435
    {
 
436
      backend->GetOutput().LogError("Exception in database back-end: " + std::string(e.what()));
 
437
    }
 
438
 
 
439
 
 
440
    static int32_t  AddAttachment(void* payload,
 
441
                                  int64_t id,
 
442
                                  const OrthancPluginAttachment* attachment)
 
443
    {
 
444
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
445
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
446
 
 
447
      try
 
448
      {
 
449
        backend->AddAttachment(id, *attachment);
 
450
        return 0;
 
451
      }
 
452
      catch (std::runtime_error& e)
 
453
      {
 
454
        LogError(backend, e);
 
455
        return -1;
 
456
      }
 
457
    }
 
458
 
 
459
                             
 
460
    static int32_t  AttachChild(void* payload,
 
461
                                int64_t parent,
 
462
                                int64_t child)
 
463
    {
 
464
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
465
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
466
 
 
467
      try
 
468
      {
 
469
        backend->AttachChild(parent, child);
 
470
        return 0;
 
471
      }
 
472
      catch (std::runtime_error& e)
 
473
      {
 
474
        LogError(backend, e);
 
475
        return -1;
 
476
      }
 
477
    }
 
478
          
 
479
                   
 
480
    static int32_t  ClearChanges(void* payload)
 
481
    {
 
482
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
483
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
484
 
 
485
      try
 
486
      {
 
487
        backend->ClearChanges();
 
488
        return 0;
 
489
      }
 
490
      catch (std::runtime_error& e)
 
491
      {
 
492
        LogError(backend, e);
 
493
        return -1;
 
494
      }
 
495
    }
 
496
                             
 
497
 
 
498
    static int32_t  ClearExportedResources(void* payload)
 
499
    {
 
500
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
501
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
502
 
 
503
      try
 
504
      {
 
505
        backend->ClearExportedResources();
 
506
        return 0;
 
507
      }
 
508
      catch (std::runtime_error& e)
 
509
      {
 
510
        LogError(backend, e);
 
511
        return -1;
 
512
      }
 
513
    }
 
514
 
 
515
 
 
516
    static int32_t  CreateResource(int64_t* id, 
 
517
                                   void* payload,
 
518
                                   const char* publicId,
 
519
                                   OrthancPluginResourceType resourceType)
 
520
    {
 
521
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
522
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
523
 
 
524
      try
 
525
      {
 
526
        *id = backend->CreateResource(publicId, resourceType);
 
527
        return 0;
 
528
      }
 
529
      catch (std::runtime_error& e)
 
530
      {
 
531
        LogError(backend, e);
 
532
        return -1;
 
533
      }
 
534
    }
 
535
          
 
536
         
 
537
    static int32_t  DeleteAttachment(void* payload,
 
538
                                     int64_t id,
 
539
                                     int32_t contentType)
 
540
    {
 
541
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
542
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
543
 
 
544
      try
 
545
      {
 
546
        backend->DeleteAttachment(id, contentType);
 
547
        return 0;
 
548
      }
 
549
      catch (std::runtime_error& e)
 
550
      {
 
551
        LogError(backend, e);
 
552
        return -1;
 
553
      }
 
554
    }
 
555
   
 
556
 
 
557
    static int32_t  DeleteMetadata(void* payload,
 
558
                                   int64_t id,
 
559
                                   int32_t metadataType)
 
560
    {
 
561
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
562
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
563
 
 
564
      try
 
565
      {
 
566
        backend->DeleteMetadata(id, metadataType);
 
567
        return 0;
 
568
      }
 
569
      catch (std::runtime_error& e)
 
570
      {
 
571
        LogError(backend, e);
 
572
        return -1;
 
573
      }
 
574
    }
 
575
   
 
576
 
 
577
    static int32_t  DeleteResource(void* payload,
 
578
                                   int64_t id)
 
579
    {
 
580
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
581
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
582
 
 
583
      try
 
584
      {
 
585
        backend->DeleteResource(id);
 
586
        return 0;
 
587
      }
 
588
      catch (std::runtime_error& e)
 
589
      {
 
590
        LogError(backend, e);
 
591
        return -1;
 
592
      }
 
593
    }
 
594
 
 
595
 
 
596
    static int32_t  GetAllPublicIds(OrthancPluginDatabaseContext* context,
 
597
                                    void* payload,
 
598
                                    OrthancPluginResourceType resourceType)
 
599
    {
 
600
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
601
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
602
 
 
603
      try
 
604
      {
 
605
        std::list<std::string> ids;
 
606
        backend->GetAllPublicIds(ids, resourceType);
 
607
 
 
608
        for (std::list<std::string>::const_iterator
 
609
               it = ids.begin(); it != ids.end(); ++it)
 
610
        {
 
611
          OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
 
612
                                            backend->GetOutput().database_,
 
613
                                            it->c_str());
 
614
        }
 
615
 
 
616
        return 0;
 
617
      }
 
618
      catch (std::runtime_error& e)
 
619
      {
 
620
        LogError(backend, e);
 
621
        return -1;
 
622
      }
 
623
    }
 
624
 
 
625
 
 
626
    static int32_t  GetChanges(OrthancPluginDatabaseContext* context,
 
627
                               void* payload,
 
628
                               int64_t since,
 
629
                               uint32_t maxResult)
 
630
    {
 
631
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
632
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Change);
 
633
 
 
634
      try
 
635
      {
 
636
        bool done;
 
637
        backend->GetChanges(done, since, maxResult);
 
638
        
 
639
        if (done)
 
640
        {
 
641
          OrthancPluginDatabaseAnswerChangesDone(backend->GetOutput().context_,
 
642
                                                 backend->GetOutput().database_);
 
643
        }
 
644
 
 
645
        return 0;
 
646
      }
 
647
      catch (std::runtime_error& e)
 
648
      {
 
649
        LogError(backend, e);
 
650
        return -1;
 
651
      }
 
652
    }
 
653
 
 
654
 
 
655
    static int32_t  GetChildrenInternalId(OrthancPluginDatabaseContext* context,
 
656
                                          void* payload,
 
657
                                          int64_t id)
 
658
    {
 
659
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
660
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
661
 
 
662
      try
 
663
      {
 
664
        std::list<int64_t> target;
 
665
        backend->GetChildrenInternalId(target, id);
 
666
 
 
667
        for (std::list<int64_t>::const_iterator
 
668
               it = target.begin(); it != target.end(); ++it)
 
669
        {
 
670
          OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
 
671
                                           backend->GetOutput().database_, *it);
 
672
        }
 
673
 
 
674
        return 0;
 
675
      }
 
676
      catch (std::runtime_error& e)
 
677
      {
 
678
        LogError(backend, e);
 
679
        return -1;
 
680
      }
 
681
    }
 
682
          
 
683
         
 
684
    static int32_t  GetChildrenPublicId(OrthancPluginDatabaseContext* context,
 
685
                                        void* payload,
 
686
                                        int64_t id)
 
687
    {
 
688
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
689
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
690
 
 
691
      try
 
692
      {
 
693
        std::list<std::string> ids;
 
694
        backend->GetChildrenPublicId(ids, id);
 
695
 
 
696
        for (std::list<std::string>::const_iterator
 
697
               it = ids.begin(); it != ids.end(); ++it)
 
698
        {
 
699
          OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
 
700
                                            backend->GetOutput().database_,
 
701
                                            it->c_str());
 
702
        }
 
703
 
 
704
        return 0;
 
705
      }
 
706
      catch (std::runtime_error& e)
 
707
      {
 
708
        LogError(backend, e);
 
709
        return -1;
 
710
      }
 
711
    }
 
712
 
 
713
 
 
714
    static int32_t  GetExportedResources(OrthancPluginDatabaseContext* context,
 
715
                                         void* payload,
 
716
                                         int64_t  since,
 
717
                                         uint32_t  maxResult)
 
718
    {
 
719
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
720
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_ExportedResource);
 
721
 
 
722
      try
 
723
      {
 
724
        bool done;
 
725
        backend->GetExportedResources(done, since, maxResult);
 
726
 
 
727
        if (done)
 
728
        {
 
729
          OrthancPluginDatabaseAnswerExportedResourcesDone(backend->GetOutput().context_,
 
730
                                                           backend->GetOutput().database_);
 
731
        }
 
732
        return 0;
 
733
      }
 
734
      catch (std::runtime_error& e)
 
735
      {
 
736
        LogError(backend, e);
 
737
        return -1;
 
738
      }
 
739
    }
 
740
          
 
741
         
 
742
    static int32_t  GetLastChange(OrthancPluginDatabaseContext* context,
 
743
                                  void* payload)
 
744
    {
 
745
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
746
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Change);
 
747
 
 
748
      try
 
749
      {
 
750
        backend->GetLastChange();
 
751
        return 0;
 
752
      }
 
753
      catch (std::runtime_error& e)
 
754
      {
 
755
        LogError(backend, e);
 
756
        return -1;
 
757
      }
 
758
    }
 
759
 
 
760
 
 
761
    static int32_t  GetLastExportedResource(OrthancPluginDatabaseContext* context,
 
762
                                            void* payload)
 
763
    {
 
764
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
765
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_ExportedResource);
 
766
 
 
767
      try
 
768
      {
 
769
        backend->GetLastExportedResource();
 
770
        return 0;
 
771
      }
 
772
      catch (std::runtime_error& e)
 
773
      {
 
774
        LogError(backend, e);
 
775
        return -1;
 
776
      }
 
777
    }
 
778
    
 
779
               
 
780
    static int32_t  GetMainDicomTags(OrthancPluginDatabaseContext* context,
 
781
                                     void* payload,
 
782
                                     int64_t id)
 
783
    {
 
784
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
785
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_DicomTag);
 
786
 
 
787
      try
 
788
      {
 
789
        backend->GetMainDicomTags(id);
 
790
        return 0;
 
791
      }
 
792
      catch (std::runtime_error& e)
 
793
      {
 
794
        LogError(backend, e);
 
795
        return -1;
 
796
      }
 
797
    }
 
798
          
 
799
         
 
800
    static int32_t  GetPublicId(OrthancPluginDatabaseContext* context,
 
801
                                void* payload,
 
802
                                int64_t id)
 
803
    {
 
804
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
805
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
806
 
 
807
      try
 
808
      {
 
809
        std::string s = backend->GetPublicId(id);
 
810
        OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
 
811
                                          backend->GetOutput().database_,
 
812
                                          s.c_str());
 
813
 
 
814
        return 0;
 
815
      }
 
816
      catch (std::runtime_error& e)
 
817
      {
 
818
        LogError(backend, e);
 
819
        return -1;
 
820
      }
 
821
    }
 
822
 
 
823
 
 
824
    static int32_t  GetResourceCount(uint64_t* target,
 
825
                                     void* payload,
 
826
                                     OrthancPluginResourceType  resourceType)
 
827
    {
 
828
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
829
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
830
 
 
831
      try
 
832
      {
 
833
        *target = backend->GetResourceCount(resourceType);
 
834
        return 0;
 
835
      }
 
836
      catch (std::runtime_error& e)
 
837
      {
 
838
        LogError(backend, e);
 
839
        return -1;
 
840
      }
 
841
    }
 
842
                   
 
843
 
 
844
    static int32_t  GetResourceType(OrthancPluginResourceType* resourceType,
 
845
                                    void* payload,
 
846
                                    int64_t id)
 
847
    {
 
848
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
849
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
850
 
 
851
      try
 
852
      {
 
853
        *resourceType = backend->GetResourceType(id);
 
854
        return 0;
 
855
      }
 
856
      catch (std::runtime_error& e)
 
857
      {
 
858
        LogError(backend, e);
 
859
        return -1;
 
860
      }
 
861
    }
 
862
 
 
863
 
 
864
    static int32_t  GetTotalCompressedSize(uint64_t* target,
 
865
                                           void* payload)
 
866
    {
 
867
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
868
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
869
 
 
870
      try
 
871
      {
 
872
        *target = backend->GetTotalCompressedSize();
 
873
        return 0;
 
874
      }
 
875
      catch (std::runtime_error& e)
 
876
      {
 
877
        LogError(backend, e);
 
878
        return -1;
 
879
      }
 
880
    }
 
881
          
 
882
         
 
883
    static int32_t  GetTotalUncompressedSize(uint64_t* target,
 
884
                                             void* payload)
 
885
    {
 
886
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
887
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
888
 
 
889
      try
 
890
      {
 
891
        *target = backend->GetTotalUncompressedSize();
 
892
        return 0;
 
893
      }
 
894
      catch (std::runtime_error& e)
 
895
      {
 
896
        LogError(backend, e);
 
897
        return -1;
 
898
      }
 
899
    }
 
900
                   
 
901
 
 
902
    static int32_t  IsExistingResource(int32_t* existing,
 
903
                                       void* payload,
 
904
                                       int64_t id)
 
905
    {
 
906
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
907
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
908
 
 
909
      try
 
910
      {
 
911
        *existing = backend->IsExistingResource(id);
 
912
        return 0;
 
913
      }
 
914
      catch (std::runtime_error& e)
 
915
      {
 
916
        LogError(backend, e);
 
917
        return -1;
 
918
      }
 
919
    }
 
920
 
 
921
 
 
922
    static int32_t  IsProtectedPatient(int32_t* isProtected,
 
923
                                       void* payload,
 
924
                                       int64_t id)
 
925
    {
 
926
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
927
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
928
 
 
929
      try
 
930
      {
 
931
        *isProtected = backend->IsProtectedPatient(id);
 
932
        return 0;
 
933
      }
 
934
      catch (std::runtime_error& e)
 
935
      {
 
936
        LogError(backend, e);
 
937
        return -1;
 
938
      }
 
939
    }
 
940
 
 
941
 
 
942
    static int32_t  ListAvailableMetadata(OrthancPluginDatabaseContext* context,
 
943
                                          void* payload,
 
944
                                          int64_t id)
 
945
    {
 
946
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
947
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
948
 
 
949
      try
 
950
      {
 
951
        std::list<int32_t> target;
 
952
        backend->ListAvailableMetadata(target, id);
 
953
 
 
954
        for (std::list<int32_t>::const_iterator
 
955
               it = target.begin(); it != target.end(); ++it)
 
956
        {
 
957
          OrthancPluginDatabaseAnswerInt32(backend->GetOutput().context_,
 
958
                                           backend->GetOutput().database_,
 
959
                                           *it);
 
960
        }
 
961
 
 
962
        return 0;
 
963
      }
 
964
      catch (std::runtime_error& e)
 
965
      {
 
966
        LogError(backend, e);
 
967
        return -1;
 
968
      }
 
969
    }
 
970
          
 
971
         
 
972
    static int32_t  ListAvailableAttachments(OrthancPluginDatabaseContext* context,
 
973
                                             void* payload,
 
974
                                             int64_t id)
 
975
    {
 
976
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
977
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
978
 
 
979
      try
 
980
      {
 
981
        std::list<int32_t> target;
 
982
        backend->ListAvailableAttachments(target, id);
 
983
 
 
984
        for (std::list<int32_t>::const_iterator
 
985
               it = target.begin(); it != target.end(); ++it)
 
986
        {
 
987
          OrthancPluginDatabaseAnswerInt32(backend->GetOutput().context_,
 
988
                                           backend->GetOutput().database_,
 
989
                                           *it);
 
990
        }
 
991
 
 
992
        return 0;
 
993
      }
 
994
      catch (std::runtime_error& e)
 
995
      {
 
996
        LogError(backend, e);
 
997
        return -1;
 
998
      }
 
999
    }
 
1000
 
 
1001
 
 
1002
    static int32_t  LogChange(void* payload,
 
1003
                              const OrthancPluginChange* change)
 
1004
    {
 
1005
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1006
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1007
 
 
1008
      try
 
1009
      {
 
1010
        backend->LogChange(*change);
 
1011
        return 0;
 
1012
      }
 
1013
      catch (std::runtime_error& e)
 
1014
      {
 
1015
        LogError(backend, e);
 
1016
        return -1;
 
1017
      }
 
1018
    }
 
1019
          
 
1020
         
 
1021
    static int32_t  LogExportedResource(void* payload,
 
1022
                                        const OrthancPluginExportedResource* exported)
 
1023
    {
 
1024
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1025
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1026
 
 
1027
      try
 
1028
      {
 
1029
        backend->LogExportedResource(*exported);
 
1030
        return 0;
 
1031
      }
 
1032
      catch (std::runtime_error& e)
 
1033
      {
 
1034
        LogError(backend, e);
 
1035
        return -1;
 
1036
      }
 
1037
    }
 
1038
          
 
1039
         
 
1040
    static int32_t  LookupAttachment(OrthancPluginDatabaseContext* context,
 
1041
                                     void* payload,
 
1042
                                     int64_t id,
 
1043
                                     int32_t contentType)
 
1044
    {
 
1045
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1046
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_Attachment);
 
1047
 
 
1048
      try
 
1049
      {
 
1050
        backend->LookupAttachment(id, contentType);
 
1051
        return 0;
 
1052
      }
 
1053
      catch (std::runtime_error& e)
 
1054
      {
 
1055
        LogError(backend, e);
 
1056
        return -1;
 
1057
      }
 
1058
    }
 
1059
 
 
1060
 
 
1061
    static int32_t  LookupGlobalProperty(OrthancPluginDatabaseContext* context,
 
1062
                                         void* payload,
 
1063
                                         int32_t property)
 
1064
    {
 
1065
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1066
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1067
 
 
1068
      try
 
1069
      {
 
1070
        std::string s;
 
1071
        if (backend->LookupGlobalProperty(s, property))
 
1072
        {
 
1073
          OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
 
1074
                                            backend->GetOutput().database_,
 
1075
                                            s.c_str());
 
1076
        }
 
1077
 
 
1078
        return 0;
 
1079
      }
 
1080
      catch (std::runtime_error& e)
 
1081
      {
 
1082
        LogError(backend, e);
 
1083
        return -1;
 
1084
      }
 
1085
    }
 
1086
 
 
1087
 
 
1088
    static int32_t  LookupIdentifier(OrthancPluginDatabaseContext* context,
 
1089
                                     void* payload,
 
1090
                                     const OrthancPluginDicomTag* tag)
 
1091
    {
 
1092
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1093
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1094
 
 
1095
      try
 
1096
      {
 
1097
        std::list<int64_t> target;
 
1098
        backend->LookupIdentifier(target, tag->group, tag->element, tag->value);
 
1099
 
 
1100
        for (std::list<int64_t>::const_iterator
 
1101
               it = target.begin(); it != target.end(); ++it)
 
1102
        {
 
1103
          OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
 
1104
                                           backend->GetOutput().database_, *it);
 
1105
        }
 
1106
 
 
1107
        return 0;
 
1108
      }
 
1109
      catch (std::runtime_error& e)
 
1110
      {
 
1111
        LogError(backend, e);
 
1112
        return -1;
 
1113
      }
 
1114
    }
 
1115
 
 
1116
 
 
1117
    static int32_t  LookupIdentifier2(OrthancPluginDatabaseContext* context,
 
1118
                                      void* payload,
 
1119
                                      const char* value)
 
1120
    {
 
1121
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1122
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1123
 
 
1124
      try
 
1125
      {
 
1126
        std::list<int64_t> target;
 
1127
        backend->LookupIdentifier(target, value);
 
1128
 
 
1129
        for (std::list<int64_t>::const_iterator
 
1130
               it = target.begin(); it != target.end(); ++it)
 
1131
        {
 
1132
          OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
 
1133
                                           backend->GetOutput().database_, *it);
 
1134
        }
 
1135
 
 
1136
        return 0;
 
1137
      }
 
1138
      catch (std::runtime_error& e)
 
1139
      {
 
1140
        LogError(backend, e);
 
1141
        return -1;
 
1142
      }
 
1143
    }
 
1144
 
 
1145
 
 
1146
    static int32_t  LookupMetadata(OrthancPluginDatabaseContext* context,
 
1147
                                   void* payload,
 
1148
                                   int64_t id,
 
1149
                                   int32_t metadata)
 
1150
    {
 
1151
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1152
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1153
 
 
1154
      try
 
1155
      {
 
1156
        std::string s;
 
1157
        if (backend->LookupMetadata(s, id, metadata))
 
1158
        {
 
1159
          OrthancPluginDatabaseAnswerString(backend->GetOutput().context_,
 
1160
                                            backend->GetOutput().database_, s.c_str());
 
1161
        }
 
1162
 
 
1163
        return 0;
 
1164
      }
 
1165
      catch (std::runtime_error& e)
 
1166
      {
 
1167
        LogError(backend, e);
 
1168
        return -1;
 
1169
      }
 
1170
    }
 
1171
 
 
1172
 
 
1173
    static int32_t  LookupParent(OrthancPluginDatabaseContext* context,
 
1174
                                 void* payload,
 
1175
                                 int64_t id)
 
1176
    {
 
1177
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1178
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1179
 
 
1180
      try
 
1181
      {
 
1182
        int64_t parent;
 
1183
        if (backend->LookupParent(parent, id))
 
1184
        {
 
1185
          OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
 
1186
                                           backend->GetOutput().database_, parent);
 
1187
        }
 
1188
 
 
1189
        return 0;
 
1190
      }
 
1191
      catch (std::runtime_error& e)
 
1192
      {
 
1193
        LogError(backend, e);
 
1194
        return -1;
 
1195
      }
 
1196
    }
 
1197
 
 
1198
 
 
1199
    static int32_t  LookupResource(OrthancPluginDatabaseContext* context,
 
1200
                                   void* payload,
 
1201
                                   const char* publicId)
 
1202
    {
 
1203
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1204
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1205
 
 
1206
      try
 
1207
      {
 
1208
        int64_t id;
 
1209
        OrthancPluginResourceType type;
 
1210
        if (backend->LookupResource(id, type, publicId))
 
1211
        {
 
1212
          OrthancPluginDatabaseAnswerResource(backend->GetOutput().context_,
 
1213
                                              backend->GetOutput().database_, 
 
1214
                                              id, type);
 
1215
        }
 
1216
 
 
1217
        return 0;
 
1218
      }
 
1219
      catch (std::runtime_error& e)
 
1220
      {
 
1221
        LogError(backend, e);
 
1222
        return -1;
 
1223
      }
 
1224
    }
 
1225
 
 
1226
 
 
1227
    static int32_t  SelectPatientToRecycle(OrthancPluginDatabaseContext* context,
 
1228
                                           void* payload)
 
1229
    {
 
1230
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1231
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1232
 
 
1233
      try
 
1234
      {
 
1235
        int64_t id;
 
1236
        if (backend->SelectPatientToRecycle(id))
 
1237
        {
 
1238
          OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
 
1239
                                           backend->GetOutput().database_, id);
 
1240
        }
 
1241
 
 
1242
        return 0;
 
1243
      }
 
1244
      catch (std::runtime_error& e)
 
1245
      {
 
1246
        LogError(backend, e);
 
1247
        return -1;
 
1248
      }
 
1249
    }
 
1250
 
 
1251
 
 
1252
    static int32_t  SelectPatientToRecycle2(OrthancPluginDatabaseContext* context,
 
1253
                                            void* payload,
 
1254
                                            int64_t patientIdToAvoid)
 
1255
    {
 
1256
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1257
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1258
 
 
1259
      try
 
1260
      {
 
1261
        int64_t id;
 
1262
        if (backend->SelectPatientToRecycle(id, patientIdToAvoid))
 
1263
        {
 
1264
          OrthancPluginDatabaseAnswerInt64(backend->GetOutput().context_,
 
1265
                                           backend->GetOutput().database_, id);
 
1266
        }
 
1267
 
 
1268
        return 0;
 
1269
      }
 
1270
      catch (std::runtime_error& e)
 
1271
      {
 
1272
        LogError(backend, e);
 
1273
        return -1;
 
1274
      }
 
1275
    }
 
1276
 
 
1277
 
 
1278
    static int32_t  SetGlobalProperty(void* payload,
 
1279
                                      int32_t property,
 
1280
                                      const char* value)
 
1281
    {
 
1282
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1283
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1284
 
 
1285
      try
 
1286
      {
 
1287
        backend->SetGlobalProperty(property, value);
 
1288
        return 0;
 
1289
      }
 
1290
      catch (std::runtime_error& e)
 
1291
      {
 
1292
        LogError(backend, e);
 
1293
        return -1;
 
1294
      }
 
1295
    }
 
1296
 
 
1297
 
 
1298
    static int32_t  SetMainDicomTag(void* payload,
 
1299
                                    int64_t id,
 
1300
                                    const OrthancPluginDicomTag* tag)
 
1301
    {
 
1302
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1303
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1304
 
 
1305
      try
 
1306
      {
 
1307
        backend->SetMainDicomTag(id, tag->group, tag->element, tag->value);
 
1308
        return 0;
 
1309
      }
 
1310
      catch (std::runtime_error& e)
 
1311
      {
 
1312
        LogError(backend, e);
 
1313
        return -1;
 
1314
      }
 
1315
    }
 
1316
 
 
1317
 
 
1318
    static int32_t  SetIdentifierTag(void* payload,
 
1319
                                    int64_t id,
 
1320
                                    const OrthancPluginDicomTag* tag)
 
1321
    {
 
1322
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1323
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1324
 
 
1325
      try
 
1326
      {
 
1327
        backend->SetIdentifierTag(id, tag->group, tag->element, tag->value);
 
1328
        return 0;
 
1329
      }
 
1330
      catch (std::runtime_error& e)
 
1331
      {
 
1332
        LogError(backend, e);
 
1333
        return -1;
 
1334
      }
 
1335
    }
 
1336
 
 
1337
 
 
1338
    static int32_t  SetMetadata(void* payload,
 
1339
                                int64_t id,
 
1340
                                int32_t metadata,
 
1341
                                const char* value)
 
1342
    {
 
1343
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1344
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1345
 
 
1346
      try
 
1347
      {
 
1348
        backend->SetMetadata(id, metadata, value);
 
1349
        return 0;
 
1350
      }
 
1351
      catch (std::runtime_error& e)
 
1352
      {
 
1353
        LogError(backend, e);
 
1354
        return -1;
 
1355
      }
 
1356
    }
 
1357
 
 
1358
 
 
1359
    static int32_t  SetProtectedPatient(void* payload,
 
1360
                                        int64_t id,
 
1361
                                        int32_t isProtected)
 
1362
    {
 
1363
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1364
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1365
 
 
1366
      try
 
1367
      {
 
1368
        backend->SetProtectedPatient(id, (isProtected != 0));
 
1369
        return 0;
 
1370
      }
 
1371
      catch (std::runtime_error& e)
 
1372
      {
 
1373
        LogError(backend, e);
 
1374
        return -1;
 
1375
      }
 
1376
    }
 
1377
 
 
1378
 
 
1379
    static int32_t StartTransaction(void* payload)
 
1380
    {
 
1381
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1382
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1383
 
 
1384
      try
 
1385
      {
 
1386
        backend->StartTransaction();
 
1387
        return 0;
 
1388
      }
 
1389
      catch (std::runtime_error& e)
 
1390
      {
 
1391
        LogError(backend, e);
 
1392
        return -1;
 
1393
      }
 
1394
    }
 
1395
 
 
1396
 
 
1397
    static int32_t RollbackTransaction(void* payload)
 
1398
    {
 
1399
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1400
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1401
 
 
1402
      try
 
1403
      {
 
1404
        backend->RollbackTransaction();
 
1405
        return 0;
 
1406
      }
 
1407
      catch (std::runtime_error& e)
 
1408
      {
 
1409
        LogError(backend, e);
 
1410
        return -1;
 
1411
      }
 
1412
    }
 
1413
 
 
1414
 
 
1415
    static int32_t CommitTransaction(void* payload)
 
1416
    {
 
1417
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1418
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1419
 
 
1420
      try
 
1421
      {
 
1422
        backend->CommitTransaction();
 
1423
        return 0;
 
1424
      }
 
1425
      catch (std::runtime_error& e)
 
1426
      {
 
1427
        LogError(backend, e);
 
1428
        return -1;
 
1429
      }
 
1430
    }
 
1431
 
 
1432
 
 
1433
    static int32_t Open(void* payload)
 
1434
    {
 
1435
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1436
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1437
 
 
1438
      try
 
1439
      {
 
1440
        backend->Open();
 
1441
        return 0;
 
1442
      }
 
1443
      catch (std::runtime_error& e)
 
1444
      {
 
1445
        LogError(backend, e);
 
1446
        return -1;
 
1447
      }
 
1448
    }
 
1449
 
 
1450
 
 
1451
    static int32_t Close(void* payload)
 
1452
    {
 
1453
      IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload);
 
1454
      backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None);
 
1455
 
 
1456
      try
 
1457
      {
 
1458
        backend->Close();
 
1459
        return 0;
 
1460
      }
 
1461
      catch (std::runtime_error& e)
 
1462
      {
 
1463
        LogError(backend, e);
 
1464
        return -1;
 
1465
      }
 
1466
    }
 
1467
 
 
1468
    
 
1469
  public:
 
1470
    static void Register(OrthancPluginContext* context,
 
1471
                         IDatabaseBackend& backend)
 
1472
    {
 
1473
      OrthancPluginDatabaseBackend  params;
 
1474
      memset(&params, 0, sizeof(params));
 
1475
 
 
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;
 
1520
      params.open = Open;
 
1521
      params.close = Close;
 
1522
 
 
1523
      OrthancPluginDatabaseContext* database = OrthancPluginRegisterDatabaseBackend(context, &params, &backend);
 
1524
      if (!context)
 
1525
      {
 
1526
        throw std::runtime_error("Unable to register the database backend");
 
1527
      }
 
1528
 
 
1529
      backend.RegisterOutput(new DatabaseBackendOutput(context, database));
 
1530
    }
 
1531
  };
 
1532
}