diff Resources/Orthanc/Databases/ISqlLookupFormatter.cpp @ 401:a8774581adfc db-protobuf

replaced "WithLabels" and "WithoutLabels", by "Labels" and "LabelsConstraint"
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 07 Apr 2023 22:32:15 +0200
parents 8dedfd982b83
children 3cd39c8cade9
line wrap: on
line diff
--- a/Resources/Orthanc/Databases/ISqlLookupFormatter.cpp	Fri Apr 07 15:43:42 2023 +0200
+++ b/Resources/Orthanc/Databases/ISqlLookupFormatter.cpp	Fri Apr 07 22:32:15 2023 +0200
@@ -307,8 +307,8 @@
                                   ISqlLookupFormatter& formatter,
                                   const std::vector<DatabaseConstraint>& lookup,
                                   ResourceType queryLevel,
-                                  const std::set<std::string>& withLabels,
-                                  const std::set<std::string>& withoutLabels,
+                                  const std::set<std::string>& labels,
+                                  LabelsConstraint labelsConstraint,
                                   size_t limit)
   {
     assert(ResourceType_Patient < ResourceType_Study &&
@@ -384,20 +384,7 @@
 
     std::list<std::string> where;
 
-    if (!withLabels.empty())
-    {
-      std::list<std::string> labels;
-      for (std::set<std::string>::const_iterator it = withLabels.begin(); it != withLabels.end(); ++it)
-      {
-        labels.push_back(formatter.GenerateParameter(*it));
-      }
-
-      where.push_back(boost::lexical_cast<std::string>(withLabels.size()) +
-                      " = (SELECT COUNT(1) FROM Labels WHERE internalId = " + FormatLevel(queryLevel) +
-                      ".internalId AND label IN (" + Join(labels, "", ", ") + "))");
-    }
-    
-    if (!withoutLabels.empty())
+    if (!labels.empty())
     {
       /**
        * "In SQL Server, NOT EXISTS and NOT IN predicates are the best
@@ -405,14 +392,34 @@
        * question are NOT NULL."
        * https://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/
        **/
-      std::list<std::string> labels;
-      for (std::set<std::string>::const_iterator it = withoutLabels.begin(); it != withoutLabels.end(); ++it)
+
+      std::list<std::string> formattedLabels;
+      for (std::set<std::string>::const_iterator it = labels.begin(); it != labels.end(); ++it)
       {
-        labels.push_back(formatter.GenerateParameter(*it));
+        formattedLabels.push_back(formatter.GenerateParameter(*it));
       }
 
-      where.push_back("NOT EXISTS (SELECT 1 FROM Labels WHERE internalId = " + FormatLevel(queryLevel) +
-                      ".internalId AND label IN (" + Join(labels, "", ", ") + "))");
+      std::string condition;
+      switch (labelsConstraint)
+      {
+        case LabelsConstraint_Any:
+          condition = "> 0";
+          break;
+          
+        case LabelsConstraint_All:
+          condition = "= " + boost::lexical_cast<std::string>(labels.size());
+          break;
+          
+        case LabelsConstraint_None:
+          condition = "= 0";
+          break;
+          
+        default:
+          throw OrthancException(ErrorCode_ParameterOutOfRange);
+      }
+      
+      where.push_back("(SELECT COUNT(1) FROM Labels WHERE internalId = " + FormatLevel(queryLevel) +
+                      ".internalId AND label IN (" + Join(formattedLabels, "", ", ") + ")) " + condition);
     }
     
     where.push_back(FormatLevel(queryLevel) + ".resourceType = " +