changeset 5565:def06a42e5ef find-refactoring

Updated FindRequest & FindResponse definitions
author Alain Mazy <am@orthanc.team>
date Tue, 23 Apr 2024 13:07:38 +0200
parents 12d8a1a266e9
children 8b507b1514eb
files OrthancServer/Sources/Database/Compatibility/GenericFind.cpp OrthancServer/Sources/Database/FindRequest.cpp OrthancServer/Sources/Database/FindRequest.h OrthancServer/Sources/Database/FindResponse.cpp OrthancServer/Sources/Database/FindResponse.h OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp
diffstat 6 files changed, 117 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp	Mon Apr 15 16:13:24 2024 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp	Tue Apr 23 13:07:38 2024 +0200
@@ -32,13 +32,12 @@
     void GenericFind::Execute(FindResponse& response,
                               const FindRequest& request)
     {
-      if (request.GetResponseType() == FindRequest::ResponseType_OrthancIdentifiers &&
+      if (request.GetResponseContent() == FindRequest::ResponseContent_IdentifiersOnly &&
           !request.GetOrthancIdentifiers().HasPatientId() &&
           !request.GetOrthancIdentifiers().HasStudyId() &&
           !request.GetOrthancIdentifiers().HasSeriesId() &&
           !request.GetOrthancIdentifiers().HasInstanceId() &&
           request.GetTagConstraintsCount() == 0 &&
-          request.GetMetadataMode() == FindRequest::MetadataMode_None &&
           !request.IsRetrieveTagsAtLevel(ResourceType_Patient) &&
           !request.IsRetrieveTagsAtLevel(ResourceType_Study) &&
           !request.IsRetrieveTagsAtLevel(ResourceType_Series) &&
@@ -63,7 +62,9 @@
           OrthancIdentifiers identifiers;
           identifiers.SetLevel(request.GetLevel(), *it);
 
-          response.Add(new FindResponse::Item(request.GetLevel(), identifiers));
+          response.Add(new FindResponse::Item(request.GetResponseContent(),
+                                              request.GetLevel(), 
+                                              identifiers));
         }
       }
       else
@@ -85,21 +86,13 @@
           throw OrthancException(ErrorCode_InternalError);
         }
 
-        switch (request.GetResponseType())
+        if (request.HasResponseContent(FindRequest::ResponseContent_MainDicomTags)
+            && !item.HasDicomMap())
         {
-          case FindRequest::ResponseType_OrthancIdentifiers:
-            break;
+          throw OrthancException(ErrorCode_InternalError);
+        }
 
-          case FindRequest::ResponseType_DicomMap:
-            if (!item.HasDicomMap())
-            {
-              throw OrthancException(ErrorCode_InternalError);
-            }
-            break;
-
-          default:
-            throw OrthancException(ErrorCode_NotImplemented);
-        }
+        // TODO: other sanity checks
       }
     }
   }
--- a/OrthancServer/Sources/Database/FindRequest.cpp	Mon Apr 15 16:13:24 2024 +0200
+++ b/OrthancServer/Sources/Database/FindRequest.cpp	Tue Apr 23 13:07:38 2024 +0200
@@ -59,11 +59,10 @@
 
   FindRequest::FindRequest(ResourceType level) :
     level_(level),
-    responseType_(ResponseType_OrthancIdentifiers),
+    responseContent_(ResponseContent_IdentifiersOnly),
     hasLimits_(false),
     limitsSince_(0),
     limitsCount_(0),
-    metadataMode_(MetadataMode_None),
     retrievePatientTags_(false),
     retrieveStudyTags_(false),
     retrieveSeriesTags_(false),
--- a/OrthancServer/Sources/Database/FindRequest.h	Mon Apr 15 16:13:24 2024 +0200
+++ b/OrthancServer/Sources/Database/FindRequest.h	Tue Apr 23 13:07:38 2024 +0200
@@ -36,10 +36,19 @@
   class FindRequest : public boost::noncopyable
   {
   public:
-    enum ResponseType
+    enum ResponseContent
     {
-      ResponseType_OrthancIdentifiers,
-      ResponseType_DicomMap
+      ResponseContent_MainDicomTags         = (1 << 0),     // retrieve all tags from MainDicomTags and DicomIdentifiers
+      ResponseContent_Metadata              = (1 << 1),     // retrieve all metadata, their values and revision
+      ResponseContent_Labels                = (1 << 2),     // get all labels
+      ResponseContent_Attachments           = (1 << 3),     // retrieve all attachments, their values and revision
+      ResponseContent_Parent                = (1 << 4),     // get the id of the parent
+      ResponseContent_Children              = (1 << 5),     // retrieve the list of children ids
+      ResponseContent_ChildInstanceId       = (1 << 6),     // When you need to access all tags from a patient/study/series, you might need to open the DICOM file of a child instance
+      ResponseContent_IsStable              = (1 << 7),     // This is currently not saved in DB but it could be in the future.
+
+      ResponseContent_IdentifiersOnly       = 0,
+      ResponseContent_INTERNAL              = 0x7FFFFFFF
     };
 
     enum ConstraintType
@@ -51,12 +60,6 @@
       ConstraintType_List
     };
 
-    enum MetadataMode
-    {
-      MetadataMode_None,
-      MetadataMode_List,
-      MetadataMode_Retrieve
-    };
 
     enum Ordering
     {
@@ -234,13 +237,12 @@
 
   private:
     ResourceType                         level_;
-    ResponseType                         responseType_;
+    ResponseContent                      responseContent_;
     OrthancIdentifiers                   orthancIdentifiers_;
     std::deque<TagConstraint*>           tagConstraints_;
     bool                                 hasLimits_;
     uint64_t                             limitsSince_;
     uint64_t                             limitsCount_;
-    MetadataMode                         metadataMode_;
     bool                                 retrievePatientTags_;
     bool                                 retrieveStudyTags_;
     bool                                 retrieveSeriesTags_;
@@ -261,14 +263,24 @@
       return level_;
     }
 
-    void SetResponseType(ResponseType type)
+    void SetResponseContent(ResponseContent content)
     {
-      responseType_ = type;
+      responseContent_ = content;
     }
 
-    ResponseType GetResponseType() const
+    void AddResponseContent(ResponseContent content)
+    {
+      responseContent_ = static_cast<ResponseContent>(static_cast<uint32_t>(responseContent_) | content);
+    }
+
+    ResponseContent GetResponseContent() const
     {
-      return responseType_;
+      return responseContent_;
+    }
+
+    bool HasResponseContent(ResponseContent content) const
+    {
+      return (responseContent_ & content) == content;
     }
 
     void SetOrthancPatientId(const std::string& id)
@@ -317,15 +329,6 @@
 
     uint64_t GetLimitsCount() const;
 
-    void SetMetadataMode(MetadataMode mode)
-    {
-      metadataMode_ = mode;
-    }
-
-    MetadataMode GetMetadataMode() const
-    {
-      return metadataMode_;
-    }
 
     void SetRetrieveTagsAtLevel(ResourceType levelOfInterest,
                                 bool retrieve);
--- a/OrthancServer/Sources/Database/FindResponse.cpp	Mon Apr 15 16:13:24 2024 +0200
+++ b/OrthancServer/Sources/Database/FindResponse.cpp	Tue Apr 23 13:07:38 2024 +0200
@@ -114,8 +114,10 @@
   }
 
 
-  FindResponse::Item::Item(ResourceType level,
+  FindResponse::Item::Item(FindRequest::ResponseContent responseContent,
+                           ResourceType level,
                            DicomMap* dicomMap /* takes ownership */) :
+    responseContent_(responseContent),
     level_(level),
     dicomMap_(dicomMap)
   {
@@ -131,7 +133,8 @@
 
 
   void FindResponse::Item::AddMetadata(MetadataType metadata,
-                                       const std::string& value)
+                                       const std::string& value,
+                                       int64_t revision)
   {
     if (metadata_.find(metadata) != metadata_.end())
     {
@@ -139,15 +142,16 @@
     }
     else
     {
-      metadata_[metadata] = value;
+      metadata_[metadata] = StringWithRevision(value, revision);
     }
   }
 
 
   bool FindResponse::Item::LookupMetadata(std::string& value,
+                                          int64_t revision,
                                           MetadataType metadata) const
   {
-    std::map<MetadataType, std::string>::const_iterator found = metadata_.find(metadata);
+    std::map<MetadataType, StringWithRevision>::const_iterator found = metadata_.find(metadata);
 
     if (found == metadata_.end())
     {
@@ -155,17 +159,18 @@
     }
     else
     {
-      value = found->second;
+      value = found->second.GetValue();
+      revision = found->second.GetRevision();
       return true;
     }
   }
 
 
-  void FindResponse::Item::ListMetadata(std::set<MetadataType> target) const
+  void FindResponse::Item::ListMetadata(std::set<MetadataType>& target) const
   {
     target.clear();
 
-    for (std::map<MetadataType, std::string>::const_iterator it = metadata_.begin(); it != metadata_.end(); ++it)
+    for (std::map<MetadataType, StringWithRevision>::const_iterator it = metadata_.begin(); it != metadata_.end(); ++it)
     {
       target.insert(it->first);
     }
--- a/OrthancServer/Sources/Database/FindResponse.h	Mon Apr 15 16:13:24 2024 +0200
+++ b/OrthancServer/Sources/Database/FindResponse.h	Tue Apr 23 13:07:38 2024 +0200
@@ -25,11 +25,13 @@
 #include "../../../OrthancFramework/Sources/DicomFormat/DicomMap.h"
 #include "../ServerEnumerations.h"
 #include "OrthancIdentifiers.h"
+#include "FindRequest.h"
 
 #include <boost/noncopyable.hpp>
 #include <deque>
 #include <map>
 #include <set>
+#include <list>
 
 
 namespace Orthanc
@@ -37,23 +39,67 @@
   class FindResponse : public boost::noncopyable
   {
   public:
+    class StringWithRevision
+    {
+    private:
+      std::string         value_;
+      int64_t             revision_;
+    public:
+      StringWithRevision(const std::string& value,
+                          int64_t revision) :
+        value_(value),
+        revision_(revision)
+      {
+      }
+
+      StringWithRevision(const StringWithRevision& other) :
+        value_(other.value_),
+        revision_(other.revision_)
+      {
+      }
+
+      StringWithRevision() :
+        revision_(-1)
+      {
+      }
+
+      const std::string& GetValue() const
+      {
+        return value_;
+      }
+
+      int64_t GetRevision() const
+      {
+        return revision_;
+      }
+    };
+
+
     class Item : public boost::noncopyable
     {
     private:
-      ResourceType                         level_;
-      OrthancIdentifiers                   identifiers_;
-      std::map<MetadataType, std::string>  metadata_;
-      std::unique_ptr<DicomMap>            dicomMap_;
+      FindRequest::ResponseContent          responseContent_;    // what has been requested
+      ResourceType                          level_;
+      OrthancIdentifiers                    identifiers_;
+      std::unique_ptr<DicomMap>             dicomMap_;
+      std::list<std::string>                children_;
+      std::string                           childInstanceId_;
+      std::list<std::string>                labels_;      
+      std::map<MetadataType, StringWithRevision>    metadata_;
+      std::map<uint16_t, StringWithRevision>        attachments_;
 
     public:
-      Item(ResourceType level,
+      Item(FindRequest::ResponseContent responseContent,
+           ResourceType level,
            const OrthancIdentifiers& identifiers) :
+        responseContent_(responseContent),
         level_(level),
         identifiers_(identifiers)
       {
       }
 
-      Item(ResourceType level,
+      Item(FindRequest::ResponseContent responseContent,
+           ResourceType level,
            DicomMap* dicomMap /* takes ownership */);
 
       ResourceType GetLevel() const
@@ -67,17 +113,18 @@
       }
 
       void AddMetadata(MetadataType metadata,
-                       const std::string& value);
+                       const std::string& value,
+                       int64_t revision);
 
       bool HasMetadata(MetadataType metadata) const
       {
         return metadata_.find(metadata) != metadata_.end();
       }
 
-      bool LookupMetadata(std::string& value,
+      bool LookupMetadata(std::string& value, int64_t revision,
                           MetadataType metadata) const;
 
-      void ListMetadata(std::set<MetadataType> metadata) const;
+      void ListMetadata(std::set<MetadataType>& metadata) const;
 
       bool HasDicomMap() const
       {
@@ -85,6 +132,9 @@
       }
 
       const DicomMap& GetDicomMap() const;
+
+
+      // TODO: add other getters and setters
     };
 
   private:
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Mon Apr 15 16:13:24 2024 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Tue Apr 23 13:07:38 2024 +0200
@@ -238,8 +238,13 @@
       // TODO - This version should be executed if no disk access is needed
       if (expand)
       {
-        request.SetResponseType(FindRequest::ResponseType_DicomMap);
-        request.SetMetadataMode(FindRequest::MetadataMode_Retrieve);
+        request.SetResponseContent(FindRequest::ResponseContent_MainDicomTags |
+                                   FindRequest::ResponseContent_Metadata |
+                                   FindRequest::ResponseContent_Labels |
+                                   FindRequest::ResponseContent_Attachments |
+                                   FindRequest::ResponseContent_Parent |
+                                   FindRequest::ResponseContent_Children)
+
         request.SetRetrieveTagsAtLevel(resourceType, true);
 
         if (resourceType == ResourceType_Study)
@@ -249,12 +254,10 @@
       }
       else
       {
-        request.SetResponseType(FindRequest::ResponseType_OrthancIdentifiers);
-        request.SetMetadataMode(FindRequest::MetadataMode_None);
+        request.SetResponseContent(FindRequest::ResponseContent_IdentifiersOnly);
       }
 #else
-      request.SetResponseType(FindRequest::ResponseType_OrthancIdentifiers);
-      request.SetMetadataMode(FindRequest::MetadataMode_None);
+      request.SetResponseContent(FindRequest::ResponseContent_IdentifiersOnly);
 #endif
 
       if (call.HasArgument("limit") ||