changeset 7147:c7f7f0a6aa5e

test: do not filter against resourceType when a publicId is provided
author Alain Mazy <am@orthanc.team>
date Tue, 15 Sep 2026 11:42:07 +0200
parents 0dd4240ea372
children 7021c0ff2a14
files OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp OrthancServer/Sources/Search/ISqlLookupFormatter.cpp
diffstat 2 files changed, 43 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Wed Sep 09 18:23:13 2026 +0200
+++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Tue Sep 15 11:42:07 2026 +0200
@@ -622,7 +622,7 @@
              "  NULL AS c4_string2, "
              "  NULL AS c5_string3, "
              "  NULL AS c6_string4, "
-             "  NULL AS c7_int1, "
+             "  Lookup.resourceType AS c7_int1, "
              "  NULL AS c8_int2, "
              "  NULL AS c9_int3, "
              "  NULL AS c10_big_int1, "
@@ -1105,13 +1105,23 @@
         // LOG(INFO) << queryId << ": " << internalId;
         // continue;
 
-        assert(queryId == QUERY_LOOKUP || response.HasResource(internalId)); // the QUERY_LOOKUP must be read first and must create the response before any other query tries to populate the fields
-
+        // assert(queryId == QUERY_LOOKUP || response.HasResource(internalId)); // the QUERY_LOOKUP must be read first and must create the response before any other query tries to populate the fields
+
+        if (queryId != QUERY_LOOKUP && !response.HasResource(internalId)) // this happens when e.g, accessing an instance level with a series id
+        {
+          continue;
+        }        
+    
         switch (queryId)
         {
           case QUERY_LOOKUP:
-            response.Add(new FindResponse::Resource(requestLevel, internalId, s.ColumnString(C3_STRING_1)));
-            break;
+          {
+            int resourceType = s.ColumnInt(C7_INT_1);
+            if (static_cast<ResourceType>(resourceType) == request.GetLevel()) // this happens when e.g, accessing an instance level with a series id
+            {
+              response.Add(new FindResponse::Resource(requestLevel, internalId, s.ColumnString(C3_STRING_1)));
+            }
+          };  break;
 
           case QUERY_LABELS:
           {
--- a/OrthancServer/Sources/Search/ISqlLookupFormatter.cpp	Wed Sep 09 18:23:13 2026 +0200
+++ b/OrthancServer/Sources/Search/ISqlLookupFormatter.cpp	Tue Sep 15 11:42:07 2026 +0200
@@ -812,11 +812,13 @@
     sql = ("SELECT " +
            strQueryLevel + ".publicId, " +
            strQueryLevel + ".internalId, " +
+           strQueryLevel + ".resourceType, " +
            ordering +
            " FROM Resources AS " + strQueryLevel);
 
 
-    std::string joins, comparisons;
+    std::string joins; //, comparisons
+    std::vector<std::string> comparisons;
 
     // handle parent constraints
     if (request.GetOrthancIdentifiers().IsDefined() && request.GetOrthancIdentifiers().DetectLevel() <= queryLevel)
@@ -825,11 +827,11 @@
 
       if (topParentLevel == queryLevel)
       {
-        comparisons += " AND " + FormatLevel(topParentLevel) + ".publicId = " + formatter.GenerateParameter(request.GetOrthancIdentifiers().GetLevel(topParentLevel));
+        comparisons.push_back(FormatLevel(topParentLevel) + ".publicId = " + formatter.GenerateParameter(request.GetOrthancIdentifiers().GetLevel(topParentLevel)));
       }
       else
       {
-        comparisons += " AND " + FormatLevel("parent", topParentLevel) + ".publicId = " + formatter.GenerateParameter(request.GetOrthancIdentifiers().GetLevel(topParentLevel));
+        comparisons.push_back(FormatLevel("parent", topParentLevel) + ".publicId = " + formatter.GenerateParameter(request.GetOrthancIdentifiers().GetLevel(topParentLevel)));
 
         for (int level = queryLevel; level > topParentLevel; level--)
         {
@@ -877,7 +879,7 @@
 
         if (!comparison.empty())
         {
-          comparisons += " AND " + comparison;
+          comparisons.push_back(comparison);
         }
 
         count ++;
@@ -896,7 +898,7 @@
 
         if (!comparison.empty())
         {
-          comparisons += " AND " + comparison;
+          comparisons.push_back(comparison);
         }
 
         count ++;
@@ -921,9 +923,28 @@
     // }
 
     std::list<std::string> where;
-    where.push_back(strQueryLevel + ".resourceType = " +
-                    formatter.FormatResourceType(queryLevel) + comparisons);
+    std::string comparisonsStr;
+    if (comparisons.size() > 0)
+    {
+      Orthanc::Toolbox::JoinStrings(comparisonsStr, comparisons, " AND ");
+    }
 
+    if (request.GetOrthancIdentifiers().IsDefined())
+    {
+      // if there is a filter on the publicId, there is no need to filter on the resourceType.  Filtering for resourceType=X AND publicId=Y 
+      // would return the same result as publicId=Y since publicIds are unique.
+      assert(comparisons.size() > 0); // at least "publicId=Y"
+      where.push_back(comparisonsStr);
+    }
+    else
+    {
+      if (comparisonsStr.size() > 0)
+      {
+        comparisonsStr = " AND " + comparisonsStr;
+      }
+      where.push_back(strQueryLevel + ".resourceType = " +
+                      formatter.FormatResourceType(queryLevel) + comparisonsStr);
+    }
 
     if (!request.GetLabels().empty())
     {