changeset 3054:3638de45a08c db-changes

backward compatibility with filtering identifiers
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 21 Dec 2018 12:45:24 +0100
parents 3f986ce336c8
children 71ac4f28176f
files OrthancServer/Search/Compatibility/CompatibilityDatabaseWrapper.h OrthancServer/Search/Compatibility/DatabaseLookup.cpp OrthancServer/ServerEnumerations.h Plugins/Engine/OrthancPluginDatabase.cpp Plugins/Engine/OrthancPluginDatabase.h Plugins/Engine/PluginsEnumerations.cpp Plugins/Engine/PluginsEnumerations.h
diffstat 7 files changed, 160 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Search/Compatibility/CompatibilityDatabaseWrapper.h	Thu Dec 20 17:59:16 2018 +0100
+++ b/OrthancServer/Search/Compatibility/CompatibilityDatabaseWrapper.h	Fri Dec 21 12:45:24 2018 +0100
@@ -39,6 +39,14 @@
 {
   namespace Compatibility
   {
+    enum IdentifierConstraintType
+    {
+      IdentifierConstraintType_Equal,
+      IdentifierConstraintType_SmallerOrEqual,
+      IdentifierConstraintType_GreaterOrEqual,
+      IdentifierConstraintType_Wildcard        /* Case sensitive, "*" or "?" are the only allowed wildcards */
+    };
+
     /**
      * This is a compatibility class that contains database primitives
      * that were used in Orthanc <= 1.5.1, and that have been removed
--- a/OrthancServer/Search/Compatibility/DatabaseLookup.cpp	Thu Dec 20 17:59:16 2018 +0100
+++ b/OrthancServer/Search/Compatibility/DatabaseLookup.cpp	Fri Dec 21 12:45:24 2018 +0100
@@ -34,27 +34,154 @@
 #include "../../PrecompiledHeadersServer.h"
 #include "DatabaseLookup.h"
 
+#include "../../../Core/OrthancException.h"
+#include "../../ServerToolbox.h"
 #include "SetOfResources.h"
-#include "../../../Core/OrthancException.h"
 
 namespace Orthanc
 {
   namespace Compatibility
   {
+    static void ApplyIdentifierConstraint(SetOfResources& candidates,
+                                          CompatibilityDatabaseWrapper& database,
+                                          const DatabaseConstraint& constraint,
+                                          ResourceType level)
+    {
+      std::list<int64_t> matches;
+
+      switch (constraint.GetConstraintType())
+      {
+        case ConstraintType_Equal:
+          database.LookupIdentifier(matches, level, constraint.GetTag(),
+                                    IdentifierConstraintType_Equal, constraint.GetSingleValue());
+          break;
+          
+        case ConstraintType_SmallerOrEqual:
+          database.LookupIdentifier(matches, level, constraint.GetTag(),
+                                    IdentifierConstraintType_SmallerOrEqual, constraint.GetSingleValue());
+          break;
+          
+        case ConstraintType_GreaterOrEqual:
+          database.LookupIdentifier(matches, level, constraint.GetTag(),
+                                    IdentifierConstraintType_GreaterOrEqual, constraint.GetSingleValue());
+
+          break;
+          
+        case ConstraintType_Wildcard:
+          database.LookupIdentifier(matches, level, constraint.GetTag(),
+                                    IdentifierConstraintType_Wildcard, constraint.GetSingleValue());
+
+          break;
+          
+        case ConstraintType_List:
+        {
+          for (size_t i = 0; i < constraint.GetValuesCount(); i++)
+          {
+            std::list<int64_t> tmp;
+            database.LookupIdentifier(tmp, level, constraint.GetTag(),
+                                      IdentifierConstraintType_Wildcard, constraint.GetValue(i));
+            matches.splice(matches.end(), tmp);
+          }
+
+          break;
+        }
+          
+        default:
+          throw OrthancException(ErrorCode_InternalError);
+      }
+
+      candidates.Intersect(matches);
+    }
+
+    
+    static void ApplyIdentifierRange(SetOfResources& candidates,
+                                     CompatibilityDatabaseWrapper& database,
+                                     const DatabaseConstraint& smaller,
+                                     const DatabaseConstraint& greater,
+                                     ResourceType level)
+    {
+      assert(smaller.GetConstraintType() == ConstraintType_SmallerOrEqual &&
+             greater.GetConstraintType() == ConstraintType_GreaterOrEqual &&
+             smaller.GetTag() == greater.GetTag() &&
+             ServerToolbox::IsIdentifier(smaller.GetTag(), level));
+
+      std::list<int64_t> matches;
+      database.LookupIdentifierRange(matches, level, smaller.GetTag(),
+                                     greater.GetSingleValue(), smaller.GetSingleValue());
+      candidates.Intersect(matches);
+    }
+
+    
     static void ApplyLevel(SetOfResources& candidates,
+                           CompatibilityDatabaseWrapper& database,
                            const std::vector<DatabaseConstraint>& lookup,
                            ResourceType level)
     {
-      std::vector<DatabaseConstraint> identifiers;
+      typedef std::set<const DatabaseConstraint*>  SetOfConstraints;
+      typedef std::map<DicomTag, SetOfConstraints> Identifiers;
+
+      Identifiers       identifiers;
+      SetOfConstraints  mainTags;
       
       for (size_t i = 0; i < lookup.size(); i++)
       {
-        if (lookup[i].GetLevel() == level &&
-            lookup[i].IsIdentifier())
+        if (lookup[i].GetLevel() == level)
         {
-          identifiers.push_back(lookup[i]);
+          if (lookup[i].IsIdentifier())
+          {
+            identifiers[lookup[i].GetTag()].insert(&lookup[i]);
+          }
+          else
+          {
+            mainTags.insert(&lookup[i]);
+          }
         }
       }
+
+      for (Identifiers::const_iterator it = identifiers.begin();
+           it != identifiers.end(); ++it)
+      {
+        const DatabaseConstraint* smaller = NULL;
+        const DatabaseConstraint* greater = NULL;
+        
+        for (SetOfConstraints::const_iterator it2 = it->second.begin();
+             it2 != it->second.end(); ++it2)
+        {
+          if ((*it2)->GetConstraintType() == ConstraintType_SmallerOrEqual)
+          {
+            smaller = *it2;
+          }
+
+          if ((*it2)->GetConstraintType() == ConstraintType_GreaterOrEqual)
+          {
+            greater = *it2;
+          }
+        }
+
+        if (smaller != NULL &&
+            greater != NULL)
+        {
+          ApplyIdentifierRange(candidates, database, *smaller, *greater, level);
+        }
+        else
+        {
+          smaller = NULL;
+          greater = NULL;
+        }
+
+        for (SetOfConstraints::const_iterator it2 = it->second.begin();
+             it2 != it->second.end(); ++it2)
+        {
+          if (*it2 != smaller &&
+              *it2 != greater)
+          {
+            ApplyIdentifierConstraint(candidates, database, **it2, level);
+          }
+        }
+      }
+
+
+      // TODO - Fiter main DICOM tags
     }
 
 
@@ -69,14 +196,14 @@
         std::list<int64_t> children;
         database.GetChildrenInternalId(children, resource);
           
-        if (children.size() == 0)
+        if (children.empty())
         {
           throw OrthancException(ErrorCode_Database);
         }
           
         resource = children.front();
       }
-        
+
       return database.GetPublicId(resource);
     }
                            
@@ -119,7 +246,7 @@
 
       for (int level = upperLevel; level <= lowerLevel; level++)
       {
-        ApplyLevel(candidates, lookup, static_cast<ResourceType>(level));
+        ApplyLevel(candidates, database_, lookup, static_cast<ResourceType>(level));
 
         if (level != lowerLevel)
         {
--- a/OrthancServer/ServerEnumerations.h	Thu Dec 20 17:59:16 2018 +0100
+++ b/OrthancServer/ServerEnumerations.h	Fri Dec 21 12:45:24 2018 +0100
@@ -56,15 +56,6 @@
     StoreStatus_FilteredOut     // Removed by NewInstanceFilter
   };
 
-  // TODO REMOVE THIS
-  enum IdentifierConstraintType
-  {
-    IdentifierConstraintType_Equal,
-    IdentifierConstraintType_SmallerOrEqual,
-    IdentifierConstraintType_GreaterOrEqual,
-    IdentifierConstraintType_Wildcard        /* Case sensitive, "*" or "?" are the only allowed wildcards */
-  };
-
   enum DicomTagType
   {
     DicomTagType_Identifier,   // Tag that whose value is stored and indexed in the DB
--- a/Plugins/Engine/OrthancPluginDatabase.cpp	Thu Dec 20 17:59:16 2018 +0100
+++ b/Plugins/Engine/OrthancPluginDatabase.cpp	Fri Dec 21 12:45:24 2018 +0100
@@ -1125,7 +1125,7 @@
   void OrthancPluginDatabase::LookupIdentifier(std::list<int64_t>& result,
                                                ResourceType level,
                                                const DicomTag& tag,
-                                               IdentifierConstraintType type,
+                                               Compatibility::IdentifierConstraintType type,
                                                const std::string& value)
   {
     if (extensions_.lookupIdentifier3 == NULL)
@@ -1156,10 +1156,10 @@
     {
       // Default implementation, for plugins using Orthanc SDK <= 1.3.2
 
-      LookupIdentifier(result, level, tag, IdentifierConstraintType_GreaterOrEqual, start);
+      LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_GreaterOrEqual, start);
 
       std::list<int64_t> b;
-      LookupIdentifier(result, level, tag, IdentifierConstraintType_SmallerOrEqual, end);
+      LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_SmallerOrEqual, end);
 
       result.splice(result.end(), b);
     }
--- a/Plugins/Engine/OrthancPluginDatabase.h	Thu Dec 20 17:59:16 2018 +0100
+++ b/Plugins/Engine/OrthancPluginDatabase.h	Fri Dec 21 12:45:24 2018 +0100
@@ -322,7 +322,7 @@
     virtual void LookupIdentifier(std::list<int64_t>& result,
                                   ResourceType level,
                                   const DicomTag& tag,
-                                  IdentifierConstraintType type,
+                                  Compatibility::IdentifierConstraintType type,
                                   const std::string& value)
       ORTHANC_OVERRIDE;
     
--- a/Plugins/Engine/PluginsEnumerations.cpp	Thu Dec 20 17:59:16 2018 +0100
+++ b/Plugins/Engine/PluginsEnumerations.cpp	Fri Dec 21 12:45:24 2018 +0100
@@ -266,20 +266,20 @@
     }
 
 
-    OrthancPluginIdentifierConstraint Convert(IdentifierConstraintType constraint)
+    OrthancPluginIdentifierConstraint Convert(Compatibility::IdentifierConstraintType constraint)
     {
       switch (constraint)
       {
-        case IdentifierConstraintType_Equal:
+        case Compatibility::IdentifierConstraintType_Equal:
           return OrthancPluginIdentifierConstraint_Equal;
 
-        case IdentifierConstraintType_GreaterOrEqual:
+        case Compatibility::IdentifierConstraintType_GreaterOrEqual:
           return OrthancPluginIdentifierConstraint_GreaterOrEqual;
 
-        case IdentifierConstraintType_SmallerOrEqual:
+        case Compatibility::IdentifierConstraintType_SmallerOrEqual:
           return OrthancPluginIdentifierConstraint_SmallerOrEqual;
 
-        case IdentifierConstraintType_Wildcard:
+        case Compatibility::IdentifierConstraintType_Wildcard:
           return OrthancPluginIdentifierConstraint_Wildcard;
 
         default:
@@ -288,21 +288,21 @@
     }
 
 
-    IdentifierConstraintType Convert(OrthancPluginIdentifierConstraint constraint)
+    Compatibility::IdentifierConstraintType Convert(OrthancPluginIdentifierConstraint constraint)
     {
       switch (constraint)
       {
         case OrthancPluginIdentifierConstraint_Equal:
-          return IdentifierConstraintType_Equal;
+          return Compatibility::IdentifierConstraintType_Equal;
 
         case OrthancPluginIdentifierConstraint_GreaterOrEqual:
-          return IdentifierConstraintType_GreaterOrEqual;
+          return Compatibility::IdentifierConstraintType_GreaterOrEqual;
 
         case OrthancPluginIdentifierConstraint_SmallerOrEqual:
-          return IdentifierConstraintType_SmallerOrEqual;
+          return Compatibility::IdentifierConstraintType_SmallerOrEqual;
 
         case OrthancPluginIdentifierConstraint_Wildcard:
-          return IdentifierConstraintType_Wildcard;
+          return Compatibility::IdentifierConstraintType_Wildcard;
 
         default:
           throw OrthancException(ErrorCode_ParameterOutOfRange);
--- a/Plugins/Engine/PluginsEnumerations.h	Thu Dec 20 17:59:16 2018 +0100
+++ b/Plugins/Engine/PluginsEnumerations.h	Fri Dec 21 12:45:24 2018 +0100
@@ -37,6 +37,7 @@
 
 #include "../Include/orthanc/OrthancCPlugin.h"
 #include "../../OrthancServer/ServerEnumerations.h"
+#include "../../OrthancServer/Search/Compatibility/CompatibilityDatabaseWrapper.h"
 
 namespace Orthanc
 {
@@ -58,9 +59,9 @@
 
     DicomToJsonFormat Convert(OrthancPluginDicomToJsonFormat format);
 
-    OrthancPluginIdentifierConstraint Convert(IdentifierConstraintType constraint);
+    OrthancPluginIdentifierConstraint Convert(Compatibility::IdentifierConstraintType constraint);
 
-    IdentifierConstraintType Convert(OrthancPluginIdentifierConstraint constraint);
+    Compatibility::IdentifierConstraintType Convert(OrthancPluginIdentifierConstraint constraint);
 
     OrthancPluginInstanceOrigin Convert(RequestOrigin origin);