changeset 206:6dcf57074dd4

starting OrthancPluginDatabaseBackendV3 wrapper
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 19 Mar 2021 10:11:17 +0100
parents 873e37048f96
children d9ef3f16e6a2
files Framework/Plugins/IDatabaseBackendOutput.h SQLite/Plugins/IndexPlugin.cpp
diffstat 2 files changed, 378 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Plugins/IDatabaseBackendOutput.h	Thu Mar 18 18:32:05 2021 +0100
+++ b/Framework/Plugins/IDatabaseBackendOutput.h	Fri Mar 19 10:11:17 2021 +0100
@@ -83,6 +83,7 @@
                                         const std::string&         studyInstanceUid,
                                         const std::string&         seriesInstanceUid,
                                         const std::string&         sopInstanceUid) = 0;
+    
 #if ORTHANC_PLUGINS_HAS_DATABASE_CONSTRAINT == 1
     virtual void AnswerMatchingResource(const std::string& resourceId) = 0;
 #endif
--- a/SQLite/Plugins/IndexPlugin.cpp	Thu Mar 18 18:32:05 2021 +0100
+++ b/SQLite/Plugins/IndexPlugin.cpp	Fri Mar 19 10:11:17 2021 +0100
@@ -28,6 +28,383 @@
 static std::unique_ptr<OrthancDatabases::SQLiteIndex> backend_;
 
 
+
+#if defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE)         // Macro introduced in Orthanc 1.3.1
+#  if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 10, 0)
+
+namespace OrthancDatabases
+{
+  class Output : public IDatabaseBackendOutput
+  {
+  private:
+    _OrthancPluginDatabaseAnswerType            answerType_;
+    std::list<std::string>                      strings_;
+    
+    std::vector<OrthancPluginAttachment>        attachments_;
+    std::vector<OrthancPluginChange>            changes_;
+    std::vector<OrthancPluginDicomTag>          tags_;
+    std::vector<OrthancPluginExportedResource>  exported_;
+    std::vector<OrthancPluginDatabaseEvent>     events_;
+    
+    const char* StoreString(const std::string& s)
+    {
+      strings_.push_back(s);
+      return strings_.back().c_str();
+    }
+
+    void SetupAnswerType(_OrthancPluginDatabaseAnswerType type)
+    {
+      if (answerType_ == _OrthancPluginDatabaseAnswerType_None)
+      {
+        answerType_ = type;
+      }
+      else if (answerType_ != type)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+      }
+    }
+    
+  public:
+    Output() :
+      answerType_(_OrthancPluginDatabaseAnswerType_None)
+    {
+    }
+    
+    
+    void Clear()
+    {
+      answerType_ = _OrthancPluginDatabaseAnswerType_None;
+      strings_.clear();
+      
+      attachments_.clear();
+      changes_.clear();
+      tags_.clear();
+      exported_.clear();
+      events_.clear();
+    }
+
+
+    static OrthancPluginErrorCode ReadAnswersCount(OrthancPluginDatabaseTransaction* transaction,
+                                                   uint32_t* target /* out */)
+    {
+      const Output& that = *reinterpret_cast<const Output*>(transaction);
+
+      size_t size;
+      
+      switch (that.answerType_)
+      {
+        case _OrthancPluginDatabaseAnswerType_None:
+          size = 0;
+          break;
+        
+        case _OrthancPluginDatabaseAnswerType_Attachment:
+          size = that.attachments_.size();
+          break;
+        
+        case _OrthancPluginDatabaseAnswerType_Change:
+          size = that.changes_.size();
+          break;
+        
+        case _OrthancPluginDatabaseAnswerType_DicomTag:
+          size = that.tags_.size();
+          break;
+        
+        case _OrthancPluginDatabaseAnswerType_ExportedResource:
+          size = that.exported_.size();
+          break;
+        
+        default:
+          return OrthancPluginErrorCode_InternalError;
+      }
+
+      *target = static_cast<uint32_t>(size);
+      return OrthancPluginErrorCode_Success;
+    }
+
+
+    static OrthancPluginErrorCode ReadAnswerAttachment(OrthancPluginDatabaseTransaction* transaction,
+                                                       OrthancPluginAttachment* target /* out */,
+                                                       uint32_t index)
+    {
+      const Output& that = *reinterpret_cast<const Output*>(transaction);
+
+      if (index < that.attachments_.size())
+      {
+        *target = that.attachments_[index];
+        return OrthancPluginErrorCode_Success;        
+      }
+      else
+      {
+        return OrthancPluginErrorCode_ParameterOutOfRange;        
+      }
+    }
+
+
+    static OrthancPluginErrorCode ReadAnswerChange(OrthancPluginDatabaseTransaction* transaction,
+                                                       OrthancPluginChange* target /* out */,
+                                                       uint32_t index)
+    {
+      const Output& that = *reinterpret_cast<const Output*>(transaction);
+
+      if (index < that.changes_.size())
+      {
+        *target = that.changes_[index];
+        return OrthancPluginErrorCode_Success;        
+      }
+      else
+      {
+        return OrthancPluginErrorCode_ParameterOutOfRange;        
+      }
+    }
+
+
+    static OrthancPluginErrorCode ReadAnswerDicomTag(OrthancPluginDatabaseTransaction* transaction,
+                                                     uint16_t* group,
+                                                     uint16_t* element,
+                                                     const char** value,
+                                                     uint32_t index)
+    {
+      const Output& that = *reinterpret_cast<const Output*>(transaction);
+
+      if (index < that.tags_.size())
+      {
+        const OrthancPluginDicomTag& tag = that.tags_[index];
+        *group = tag.group;
+        *element = tag.element;
+        *value = tag.value;
+        return OrthancPluginErrorCode_Success;        
+      }
+      else
+      {
+        return OrthancPluginErrorCode_ParameterOutOfRange;        
+      }
+    }
+
+
+    static OrthancPluginErrorCode ReadAnswerExportedResource(OrthancPluginDatabaseTransaction* transaction,
+                                                             OrthancPluginExportedResource* target /* out */,
+                                                             uint32_t index)
+    {
+      const Output& that = *reinterpret_cast<const Output*>(transaction);
+
+      if (index < that.exported_.size())
+      {
+        *target = that.exported_[index];
+        return OrthancPluginErrorCode_Success;        
+      }
+      else
+      {
+        return OrthancPluginErrorCode_ParameterOutOfRange;        
+      }
+    }
+
+
+    static OrthancPluginErrorCode ReadEventsCount(OrthancPluginDatabaseTransaction* transaction,
+                                                  uint32_t* target /* out */)
+    {
+      const Output& that = *reinterpret_cast<const Output*>(transaction);
+      *target = static_cast<uint32_t>(that.events_.size());
+      return OrthancPluginErrorCode_Success;
+    }
+
+    
+    static OrthancPluginErrorCode ReadEvent(OrthancPluginDatabaseTransaction* transaction,
+                                            OrthancPluginDatabaseEvent* event /* out */,
+                                            uint32_t index)
+    {
+      const Output& that = *reinterpret_cast<const Output*>(transaction);
+
+      if (index < that.events_.size())
+      {
+        *event = that.events_[index];
+        return OrthancPluginErrorCode_Success;
+      }
+      else
+      {
+        return OrthancPluginErrorCode_ParameterOutOfRange;
+      }
+    }
+
+    
+    virtual void SignalDeletedAttachment(const std::string& uuid,
+                                         int32_t            contentType,
+                                         uint64_t           uncompressedSize,
+                                         const std::string& uncompressedHash,
+                                         int32_t            compressionType,
+                                         uint64_t           compressedSize,
+                                         const std::string& compressedHash) ORTHANC_OVERRIDE
+    {
+      OrthancPluginDatabaseEvent event;
+      event.type = OrthancPluginDatabaseEventType_DeletedAttachment;
+      event.content.attachment.uuid = StoreString(uuid);
+      event.content.attachment.contentType = contentType;
+      event.content.attachment.uncompressedSize = uncompressedSize;
+      event.content.attachment.uncompressedHash = StoreString(uncompressedHash);
+      event.content.attachment.compressionType = compressionType;
+      event.content.attachment.compressedSize = compressedSize;
+      event.content.attachment.compressedHash = StoreString(compressedHash);
+        
+      events_.push_back(event);
+    }
+    
+    
+    virtual void SignalDeletedResource(const std::string& publicId,
+                                       OrthancPluginResourceType resourceType) ORTHANC_OVERRIDE
+    {
+      OrthancPluginDatabaseEvent event;
+      event.type = OrthancPluginDatabaseEventType_DeletedResource;
+      event.content.resource.level = resourceType;
+      event.content.resource.publicId = StoreString(publicId);
+        
+      events_.push_back(event);
+    }
+    
+
+    virtual void SignalRemainingAncestor(const std::string& ancestorId,
+                                         OrthancPluginResourceType ancestorType) ORTHANC_OVERRIDE
+    {
+      OrthancPluginDatabaseEvent event;
+      event.type = OrthancPluginDatabaseEventType_RemainingAncestor;
+      event.content.resource.level = ancestorType;
+      event.content.resource.publicId = StoreString(ancestorId);
+        
+      events_.push_back(event);
+    }
+    
+    
+    virtual void AnswerAttachment(const std::string& uuid,
+                                  int32_t            contentType,
+                                  uint64_t           uncompressedSize,
+                                  const std::string& uncompressedHash,
+                                  int32_t            compressionType,
+                                  uint64_t           compressedSize,
+                                  const std::string& compressedHash) ORTHANC_OVERRIDE
+    {
+      SetupAnswerType(_OrthancPluginDatabaseAnswerType_Attachment);
+
+      OrthancPluginAttachment attachment;
+      attachment.uuid = StoreString(uuid);
+      attachment.contentType = contentType;
+      attachment.uncompressedSize = uncompressedSize;
+      attachment.uncompressedHash = StoreString(uncompressedHash);
+      attachment.compressionType = compressionType;
+      attachment.compressedSize = compressedSize;
+      attachment.compressedHash = StoreString(compressedHash);
+
+      attachments_.push_back(attachment);
+    }
+    
+
+    virtual void AnswerChange(int64_t                    seq,
+                              int32_t                    changeType,
+                              OrthancPluginResourceType  resourceType,
+                              const std::string&         publicId,
+                              const std::string&         date) ORTHANC_OVERRIDE
+    {
+      SetupAnswerType(_OrthancPluginDatabaseAnswerType_Change);
+
+      OrthancPluginChange change;
+      change.seq = seq;
+      change.changeType = changeType;
+      change.resourceType = resourceType;
+      change.publicId = StoreString(publicId);
+      change.date = StoreString(date);
+
+      changes_.push_back(change);
+    }
+    
+
+    virtual void AnswerDicomTag(uint16_t group,
+                                uint16_t element,
+                                const std::string& value) ORTHANC_OVERRIDE
+    {
+      SetupAnswerType(_OrthancPluginDatabaseAnswerType_DicomTag);
+
+      OrthancPluginDicomTag tag;
+      tag.group = group;
+      tag.element = element;
+      tag.value = StoreString(value);
+
+      tags_.push_back(tag);      
+    }
+    
+
+    virtual void AnswerExportedResource(int64_t                    seq,
+                                        OrthancPluginResourceType  resourceType,
+                                        const std::string&         publicId,
+                                        const std::string&         modality,
+                                        const std::string&         date,
+                                        const std::string&         patientId,
+                                        const std::string&         studyInstanceUid,
+                                        const std::string&         seriesInstanceUid,
+                                        const std::string&         sopInstanceUid) ORTHANC_OVERRIDE
+    {
+      SetupAnswerType(_OrthancPluginDatabaseAnswerType_ExportedResource);
+
+      OrthancPluginExportedResource exported;
+      exported.seq = seq;
+      exported.resourceType = resourceType;
+      exported.publicId = StoreString(publicId);
+      exported.modality = StoreString(modality);
+      exported.date = StoreString(date);
+      exported.patientId = StoreString(patientId);
+      exported.studyInstanceUid = StoreString(studyInstanceUid);
+      exported.seriesInstanceUid = StoreString(seriesInstanceUid);
+      exported.sopInstanceUid = StoreString(sopInstanceUid);
+  
+      exported_.push_back(exported);
+    }
+
+    
+    virtual void AnswerMatchingResource(const std::string& resourceId) ORTHANC_OVERRIDE
+    {
+
+    }
+    
+    
+    virtual void AnswerMatchingResource(const std::string& resourceId,
+                                        const std::string& someInstanceId) ORTHANC_OVERRIDE
+    {
+
+    }
+  };
+
+
+  class Factory : public IDatabaseBackendOutput::IFactory
+  {
+  public:
+    Factory()
+    {
+    }
+
+    virtual IDatabaseBackendOutput* CreateOutput()
+    {
+      return new Output;
+    }
+  };
+
+  
+  static void Register()
+  {
+    OrthancPluginDatabaseBackendV3 backend;
+    memset(&backend, 0, sizeof(backend));
+
+    backend.readAnswersCount = Output::ReadAnswersCount;
+    backend.readAnswerAttachment = Output::ReadAnswerAttachment;
+    backend.readAnswerChange = Output::ReadAnswerChange;
+    backend.readAnswerDicomTag = Output::ReadAnswerDicomTag;
+    backend.readAnswerExportedResource = Output::ReadAnswerExportedResource;
+    
+    backend.readEventsCount = Output::ReadEventsCount;
+    backend.readEvent = Output::ReadEvent;
+  }
+}
+
+#  endif
+#endif
+
+
+
 extern "C"
 {
   ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context)