changeset 3189:6f89d22a6ec0

New extensions in the database SDK: LookupResourceAndParent and GetAllMetadata
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 04 Feb 2019 15:47:56 +0100
parents 70356580e310
children f451e93cd58b
files NEWS Plugins/Engine/OrthancPluginDatabase.cpp Plugins/Engine/OrthancPluginDatabase.h Plugins/Include/orthanc/OrthancCDatabasePlugin.h
diffstat 4 files changed, 162 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Mon Feb 04 12:09:26 2019 +0100
+++ b/NEWS	Mon Feb 04 15:47:56 2019 +0100
@@ -20,6 +20,7 @@
 -------
 
 * New primitives in the plugin SDK to set and refresh metrics
+* New extensions in the database SDK: LookupResourceAndParent and GetAllMetadata
 
 Maintenance
 -----------
--- a/Plugins/Engine/OrthancPluginDatabase.cpp	Mon Feb 04 12:09:26 2019 +0100
+++ b/Plugins/Engine/OrthancPluginDatabase.cpp	Mon Feb 04 15:47:56 2019 +0100
@@ -135,6 +135,7 @@
     answerDone_ = NULL;
     answerMatchingResources_ = NULL;
     answerMatchingInstances_ = NULL;
+    answerMetadata_ = NULL;
   }
 
 
@@ -390,35 +391,52 @@
   void OrthancPluginDatabase::GetAllMetadata(std::map<MetadataType, std::string>& target,
                                              int64_t id)
   {
-    // TODO - Add primitive in SDK
+    if (extensions_.getAllMetadata == NULL)
+    {
+      // Fallback implementation if extension is missing
+      target.clear();
 
-    target.clear();
+      ResetAnswers();
+      CheckSuccess(backend_.listAvailableMetadata(GetContext(), payload_, id));
 
-    ResetAnswers();
-    CheckSuccess(backend_.listAvailableMetadata(GetContext(), payload_, id));
+      if (type_ != _OrthancPluginDatabaseAnswerType_None &&
+          type_ != _OrthancPluginDatabaseAnswerType_Int32)
+      {
+        throw OrthancException(ErrorCode_DatabasePlugin);
+      }
 
-    if (type_ != _OrthancPluginDatabaseAnswerType_None &&
-        type_ != _OrthancPluginDatabaseAnswerType_Int32)
-    {
-      throw OrthancException(ErrorCode_DatabasePlugin);
-    }
+      target.clear();
 
-    target.clear();
-
-    if (type_ == _OrthancPluginDatabaseAnswerType_Int32)
-    {
-      for (std::list<int32_t>::const_iterator 
-             it = answerInt32_.begin(); it != answerInt32_.end(); ++it)
+      if (type_ == _OrthancPluginDatabaseAnswerType_Int32)
       {
-        MetadataType type = static_cast<MetadataType>(*it);
+        for (std::list<int32_t>::const_iterator 
+               it = answerInt32_.begin(); it != answerInt32_.end(); ++it)
+        {
+          MetadataType type = static_cast<MetadataType>(*it);
 
-        std::string value;
-        if (LookupMetadata(value, id, type))
-        {
-          target[type] = value;
+          std::string value;
+          if (LookupMetadata(value, id, type))
+          {
+            target[type] = value;
+          }
         }
       }
     }
+    else
+    {
+      ResetAnswers();
+
+      answerMetadata_ = &target;
+      target.clear();
+      
+      CheckSuccess(extensions_.getAllMetadata(GetContext(), payload_, id));
+
+      if (type_ != _OrthancPluginDatabaseAnswerType_None &&
+          type_ != _OrthancPluginDatabaseAnswerType_Metadata)
+      {
+        throw OrthancException(ErrorCode_DatabasePlugin);
+      }
+    }
   }
 
 
@@ -1008,6 +1026,11 @@
           
           break;
 
+        case _OrthancPluginDatabaseAnswerType_Metadata:
+          assert(answerMetadata_ != NULL);
+          answerMetadata_->clear();
+          break;
+
         default:
           throw OrthancException(ErrorCode_DatabasePlugin,
                                  "Unhandled type of answer for custom index plugin: " +
@@ -1163,6 +1186,24 @@
         break;
       }
 
+      case _OrthancPluginDatabaseAnswerType_Metadata:
+      {
+        const OrthancPluginResourcesContentMetadata& metadata =
+          *reinterpret_cast<const OrthancPluginResourcesContentMetadata*>(answer.valueGeneric);
+
+        MetadataType type = static_cast<MetadataType>(metadata.metadata);
+
+        if (metadata.value == NULL)
+        {
+          throw OrthancException(ErrorCode_DatabasePlugin);
+        }
+
+        assert(answerMetadata_ != NULL &&
+               answerMetadata_->find(type) == answerMetadata_->end());
+        (*answerMetadata_) [type] = metadata.value;
+        break;
+      }
+
       default:
         throw OrthancException(ErrorCode_DatabasePlugin,
                                "Unhandled type of answer for custom index plugin: " +
@@ -1426,7 +1467,56 @@
                                                       std::string& parentPublicId,
                                                       const std::string& publicId)
   {
-    // TODO - Add primitive in SDK
-    return ILookupResourceAndParent::Apply(*this, id, type, parentPublicId, publicId);
+    if (extensions_.lookupResourceAndParent == NULL)
+    {
+      return ILookupResourceAndParent::Apply(*this, id, type, parentPublicId, publicId);
+    }
+    else
+    {
+      std::list<std::string> parent;
+
+      uint8_t isExisting;
+      OrthancPluginResourceType pluginType = OrthancPluginResourceType_Patient;
+      
+      ResetAnswers();
+      CheckSuccess(extensions_.lookupResourceAndParent
+                   (GetContext(), &isExisting, &id, &pluginType, payload_, publicId.c_str()));
+      ForwardAnswers(parent);
+
+      if (isExisting)
+      {
+        type = Plugins::Convert(pluginType);
+
+        if (parent.empty())
+        {
+          if (type != ResourceType_Patient)
+          {
+            throw OrthancException(ErrorCode_DatabasePlugin);
+          }
+        }
+        else if (parent.size() == 1)
+        {
+          if ((type != ResourceType_Study &&
+               type != ResourceType_Series &&
+               type != ResourceType_Instance) ||
+              parent.front().empty())
+          {
+            throw OrthancException(ErrorCode_DatabasePlugin);
+          }
+
+          parentPublicId = parent.front();
+        }
+        else
+        {
+          throw OrthancException(ErrorCode_DatabasePlugin);
+        }
+
+        return true;
+      }
+      else
+      {
+        return false;
+      }
+    }
   }
 }
--- a/Plugins/Engine/OrthancPluginDatabase.h	Mon Feb 04 12:09:26 2019 +0100
+++ b/Plugins/Engine/OrthancPluginDatabase.h	Mon Feb 04 15:47:56 2019 +0100
@@ -57,7 +57,8 @@
   private:
     class Transaction;
 
-    typedef std::pair<int64_t, ResourceType>  AnswerResource;
+    typedef std::pair<int64_t, ResourceType>     AnswerResource;
+    typedef std::map<MetadataType, std::string>  AnswerMetadata;
 
     SharedLibrary&  library_;
     PluginsErrorDictionary&  errorDictionary_;
@@ -82,6 +83,7 @@
     bool*                          answerDone_;
     std::list<std::string>*        answerMatchingResources_;
     std::list<std::string>*        answerMatchingInstances_;
+    AnswerMetadata*                answerMetadata_;
 
     OrthancPluginDatabaseContext* GetContext()
     {
--- a/Plugins/Include/orthanc/OrthancCDatabasePlugin.h	Mon Feb 04 12:09:26 2019 +0100
+++ b/Plugins/Include/orthanc/OrthancCDatabasePlugin.h	Mon Feb 04 15:47:56 2019 +0100
@@ -76,6 +76,7 @@
     _OrthancPluginDatabaseAnswerType_Resource = 16,
     _OrthancPluginDatabaseAnswerType_String = 17,
     _OrthancPluginDatabaseAnswerType_MatchingResource = 18,  /* New in Orthanc 1.5.2 */
+    _OrthancPluginDatabaseAnswerType_Metadata = 19,          /* New in Orthanc 1.5.4 */
 
     _OrthancPluginDatabaseAnswerType_INTERNAL = 0x7fffffff
   } _OrthancPluginDatabaseAnswerType;
@@ -335,6 +336,25 @@
     context->InvokeService(context, _OrthancPluginService_DatabaseAnswer, &params);
   }
 
+  ORTHANC_PLUGIN_INLINE void OrthancPluginDatabaseAnswerMetadata(
+    OrthancPluginContext*          context,
+    OrthancPluginDatabaseContext*  database,
+    int64_t                        resourceId,
+    int32_t                        type,
+    const char*                    value)
+  {
+    OrthancPluginResourcesContentMetadata metadata;
+    _OrthancPluginDatabaseAnswer params;
+    metadata.resource = resourceId;
+    metadata.metadata = type;
+    metadata.value = value;
+    memset(&params, 0, sizeof(params));
+    params.database = database;
+    params.type = _OrthancPluginDatabaseAnswerType_Metadata;
+    params.valueGeneric = &metadata;
+    context->InvokeService(context, _OrthancPluginService_DatabaseAnswer, &params);
+  }
+
   ORTHANC_PLUGIN_INLINE void OrthancPluginDatabaseSignalDeletedAttachment(
     OrthancPluginContext*          context,
     OrthancPluginDatabaseContext*  database,
@@ -783,7 +803,6 @@
       OrthancPluginResourceType queryLevel,
       uint32_t limit,
       uint8_t requestSomeInstance);
-
     
     OrthancPluginErrorCode  (*createInstance) (
       /* output */
@@ -825,6 +844,32 @@
       void* payload,
       int64_t patientId);
                    
+    
+    /**
+     * Extensions since Orthanc 1.5.4
+     **/
+
+    /* Ouput: Use OrthancPluginDatabaseAnswerMetadata */
+    OrthancPluginErrorCode  (*getAllMetadata) (
+      /* outputs */
+      OrthancPluginDatabaseContext* context,
+      /* inputs */
+      void* payload,
+      int64_t resourceId);
+    
+    /* Ouput: Use OrthancPluginDatabaseAnswerString to send 
+       the public ID of the parent (if the resource is not a patient) */
+    OrthancPluginErrorCode  (*lookupResourceAndParent) (
+      /* outputs */
+      OrthancPluginDatabaseContext* context,
+      uint8_t* isExisting,
+      int64_t* id,
+      OrthancPluginResourceType* type,
+      
+      /* inputs */
+      void* payload,
+      const char* publicId);
+
   } OrthancPluginDatabaseExtensions;
 
 /*<! @endcond */