diff Resources/Orthanc/Databases/ISqlLookupFormatter.cpp @ 415:7e123f047771

LookupResources optimization continued
author Alain Mazy <am@osimis.io>
date Thu, 22 Jun 2023 18:07:41 +0200
parents f2d3b5c5a68d
children 6b16914b6655
line wrap: on
line diff
--- a/Resources/Orthanc/Databases/ISqlLookupFormatter.cpp	Thu Jun 22 12:15:48 2023 +0200
+++ b/Resources/Orthanc/Databases/ISqlLookupFormatter.cpp	Thu Jun 22 18:07:41 2023 +0200
@@ -475,23 +475,14 @@
   }
 
 
-
-  
-
-  void ISqlLookupFormatter::Apply(std::string& sql,
-                                  ISqlLookupFormatter& formatter,
-                                  const std::vector<DatabaseConstraint>& lookup,
-                                  ResourceType queryLevel,
-                                  const std::set<std::string>& labels,
-                                  LabelsConstraint labelsConstraint,
-                                  size_t limit)
+  void ISqlLookupFormatter::GetLookupLevels(ResourceType& lowerLevel, ResourceType& upperLevel, const ResourceType& queryLevel, const std::vector<DatabaseConstraint>& lookup)
   {
     assert(ResourceType_Patient < ResourceType_Study &&
            ResourceType_Study < ResourceType_Series &&
            ResourceType_Series < ResourceType_Instance);
     
-    ResourceType upperLevel = queryLevel;
-    ResourceType lowerLevel = queryLevel;
+    lowerLevel = queryLevel;
+    upperLevel = queryLevel;
 
     for (size_t i = 0; i < lookup.size(); i++)
     {
@@ -507,7 +498,20 @@
         lowerLevel = level;
       }
     }
-    
+  }
+  
+
+  void ISqlLookupFormatter::Apply(std::string& sql,
+                                  ISqlLookupFormatter& formatter,
+                                  const std::vector<DatabaseConstraint>& lookup,
+                                  ResourceType queryLevel,
+                                  const std::set<std::string>& labels,
+                                  LabelsConstraint labelsConstraint,
+                                  size_t limit)
+  {
+    ResourceType lowerLevel, upperLevel;
+    GetLookupLevels(lowerLevel, upperLevel, queryLevel, lookup);
+
     assert(upperLevel <= queryLevel &&
            queryLevel <= lowerLevel);
 
@@ -608,39 +612,20 @@
   }
 
 
-  void ISqlLookupFormatter::ApplyExperimental(std::string& sql,
-                                              ISqlLookupFormatter& formatter,
-                                              const std::vector<DatabaseConstraint>& lookup,
-                                              ResourceType queryLevel,
-                                              const std::set<std::string>& labels,
-                                              LabelsConstraint labelsConstraint,
-                                              size_t limit
-                                              )
+  void ISqlLookupFormatter::ApplySingleLevel(std::string& sql,
+                                             ISqlLookupFormatter& formatter,
+                                             const std::vector<DatabaseConstraint>& lookup,
+                                             ResourceType queryLevel,
+                                             const std::set<std::string>& labels,
+                                             LabelsConstraint labelsConstraint,
+                                             size_t limit
+                                             )
   {
-    assert(ResourceType_Patient < ResourceType_Study &&
-           ResourceType_Study < ResourceType_Series &&
-           ResourceType_Series < ResourceType_Instance);
+    ResourceType lowerLevel, upperLevel;
+    GetLookupLevels(lowerLevel, upperLevel, queryLevel, lookup);
     
-    ResourceType upperLevel = queryLevel;
-    ResourceType lowerLevel = queryLevel;
-
-    for (size_t i = 0; i < lookup.size(); i++)
-    {
-      ResourceType level = lookup[i].GetLevel();
-
-      if (level < upperLevel)
-      {
-        upperLevel = level;
-      }
-
-      if (level > lowerLevel)
-      {
-        lowerLevel = level;
-      }
-    }
-    
-    assert(upperLevel <= queryLevel &&
-           queryLevel <= lowerLevel);
+    assert(upperLevel == queryLevel &&
+           queryLevel == lowerLevel);
 
     const bool escapeBrackets = formatter.IsEscapeBrackets();
     
@@ -703,25 +688,29 @@
       }
 
       std::string condition;
+      std::string inOrNotIn;
       switch (labelsConstraint)
       {
         case LabelsConstraint_Any:
           condition = "> 0";
+          inOrNotIn = "IN";
           break;
           
         case LabelsConstraint_All:
           condition = "= " + boost::lexical_cast<std::string>(labels.size());
+          inOrNotIn = "IN";
           break;
           
         case LabelsConstraint_None:
-          condition = "= 0";
+          condition = "> 0";
+          inOrNotIn = "NOT IN";
           break;
           
         default:
           throw OrthancException(ErrorCode_ParameterOutOfRange);
       }
       
-      sql += (" AND internalId IN (SELECT id"
+      sql += (" AND internalId " + inOrNotIn + " (SELECT id"
                                  " FROM (SELECT id, COUNT(1) AS labelsCount "
                                         "FROM Labels "
                                         "WHERE label IN (" + Join(formattedLabels, "", ", ") + ") GROUP BY id"