changeset 5220:df39c7583a49 db-protobuf

preparing virtual methods for labels
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 03 Apr 2023 18:09:04 +0200
parents afa96af2eb5a
children d0f7c742d397
files OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabase.h OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto OrthancServer/Sources/Database/IDatabaseWrapper.h OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp OrthancServer/Sources/Database/StatelessDatabaseOperations.h OrthancServer/Sources/Search/DatabaseLookup.cpp OrthancServer/Sources/Search/DatabaseLookup.h OrthancServer/Sources/ServerContext.cpp OrthancServer/UnitTestsSources/ServerIndexTests.cpp
diffstat 16 files changed, 255 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp	Mon Apr 03 18:09:04 2023 +0200
@@ -565,8 +565,16 @@
                                       std::list<std::string>* instancesId,
                                       const std::vector<DatabaseConstraint>& lookup,
                                       ResourceType queryLevel,
+                                      const std::set<std::string>& withLabels,
+                                      const std::set<std::string>& withoutLabels,
                                       uint32_t limit) ORTHANC_OVERRIDE
     {
+      if (!withLabels.empty() ||
+          !withoutLabels.empty())
+      {
+        throw OrthancException(ErrorCode_InternalError);  // "HasLabelsSupport()" has returned "false"
+      }
+      
       if (that_.extensions_.lookupResources == NULL)
       {
         // Fallback to compatibility mode
@@ -1413,6 +1421,27 @@
         CheckSuccess(that_.extensions_.tagMostRecentPatient(that_.payload_, patient));
       }
     }
+
+
+    virtual void AddLabel(int64_t resource,
+                          const std::string& label) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_InternalError);  // Not supported
+    }
+
+
+    virtual void RemoveLabel(int64_t resource,
+                             const std::string& label) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_InternalError);  // Not supported
+    }
+
+
+    virtual void GetLabels(std::set<std::string>& target,
+                           int64_t resource) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_InternalError);  // Not supported
+    }
   };
 
 
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h	Mon Apr 03 18:09:04 2023 +0200
@@ -113,6 +113,11 @@
       return false;  // No support for revisions in old API
     }
 
+    virtual bool HasLabelsSupport() const ORTHANC_OVERRIDE
+    {
+      return false;
+    }
+
     void AnswerReceived(const _OrthancPluginDatabaseAnswer& answer);
   };
 }
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Mon Apr 03 18:09:04 2023 +0200
@@ -800,8 +800,16 @@
                                       std::list<std::string>* instancesId, // Can be NULL if not needed
                                       const std::vector<DatabaseConstraint>& lookup,
                                       ResourceType queryLevel,
+                                      const std::set<std::string>& withLabels,
+                                      const std::set<std::string>& withoutLabels,
                                       uint32_t limit) ORTHANC_OVERRIDE
     {
+      if (!withLabels.empty() ||
+          !withoutLabels.empty())
+      {
+        throw OrthancException(ErrorCode_InternalError);  // "HasLabelsSupport()" has returned "false"
+      }
+      
       std::vector<OrthancPluginDatabaseConstraint> constraints;
       std::vector< std::vector<const char*> > constraintsValues;
 
@@ -1027,6 +1035,27 @@
         return false;
       }
     }
+
+
+    virtual void AddLabel(int64_t resource,
+                          const std::string& label) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_InternalError);  // Not supported
+    }
+
+
+    virtual void RemoveLabel(int64_t resource,
+                             const std::string& label) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_InternalError);  // Not supported
+    }
+
+
+    virtual void GetLabels(std::set<std::string>& target,
+                           int64_t resource) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_InternalError);  // Not supported
+    }
   };
 
   
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h	Mon Apr 03 18:09:04 2023 +0200
@@ -82,6 +82,11 @@
                          IStorageArea& storageArea) ORTHANC_OVERRIDE;    
 
     virtual bool HasRevisionsSupport() const ORTHANC_OVERRIDE;
+
+    virtual bool HasLabelsSupport() const ORTHANC_OVERRIDE
+    {
+      return false;
+    }
   };
 }
 
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp	Mon Apr 03 18:09:04 2023 +0200
@@ -915,8 +915,17 @@
                                       std::list<std::string>* instancesId, // Can be NULL if not needed
                                       const std::vector<DatabaseConstraint>& lookup,
                                       ResourceType queryLevel,
+                                      const std::set<std::string>& withLabels,
+                                      const std::set<std::string>& withoutLabels,
                                       uint32_t limit) ORTHANC_OVERRIDE
     {
+      if (!database_.HasLabelsSupport() &&
+          (!withLabels.empty() ||
+           !withoutLabels.empty()))
+      {
+        throw OrthancException(ErrorCode_InternalError);
+      }
+
       DatabasePluginMessages::TransactionRequest request;
       request.mutable_lookup_resources()->set_query_level(Convert(queryLevel));
       request.mutable_lookup_resources()->set_limit(limit);
@@ -966,6 +975,12 @@
             throw OrthancException(ErrorCode_ParameterOutOfRange);
         }
       }
+
+      if (!withLabels.empty() ||
+          !withoutLabels.empty())
+      {
+        throw OrthancException(ErrorCode_NotImplemented);  // TODO
+      }
       
       DatabasePluginMessages::TransactionResponse response;
       ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCES, request);
@@ -1132,6 +1147,27 @@
         return false;
       }
     }
+
+    
+    virtual void AddLabel(int64_t resource,
+                          const std::string& label) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_NotImplemented);
+    }
+
+
+    virtual void RemoveLabel(int64_t resource,
+                             const std::string& label) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_NotImplemented);
+    }
+
+
+    virtual void GetLabels(std::set<std::string>& target,
+                           int64_t resource) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_NotImplemented);
+    }
   };
 
 
@@ -1146,7 +1182,8 @@
     open_(false),
     databaseVersion_(0),
     hasFlushToDisk_(false),
-    hasRevisionsSupport_(false)
+    hasRevisionsSupport_(false),
+    hasLabelsSupport_(false)
   {
     CLOG(INFO, PLUGINS) << "Identifier of this Orthanc server for the global properties "
                         << "of the custom database: \"" << serverIdentifier << "\"";
@@ -1186,6 +1223,7 @@
       databaseVersion_ = response.get_system_information().database_version();
       hasFlushToDisk_ = response.get_system_information().supports_flush_to_disk();
       hasRevisionsSupport_ = response.get_system_information().supports_revisions();
+      hasLabelsSupport_ = response.get_system_information().supports_labels();
     }
 
     open_ = true;    
@@ -1307,4 +1345,17 @@
       return hasRevisionsSupport_;
     }
   }
+
+  
+  bool OrthancPluginDatabaseV4::HasLabelsSupport() const
+  {
+    if (!open_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      return hasLabelsSupport_;
+    }
+  }
 }
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h	Mon Apr 03 18:09:04 2023 +0200
@@ -44,6 +44,7 @@
     unsigned int                            databaseVersion_;
     bool                                    hasFlushToDisk_;
     bool                                    hasRevisionsSupport_;
+    bool                                    hasLabelsSupport_;
 
     void CheckSuccess(OrthancPluginErrorCode code) const;
 
@@ -93,6 +94,8 @@
                          IStorageArea& storageArea) ORTHANC_OVERRIDE;    
 
     virtual bool HasRevisionsSupport() const ORTHANC_OVERRIDE;
+
+    virtual bool HasLabelsSupport() const ORTHANC_OVERRIDE;
   };
 }
 
--- a/OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto	Mon Apr 03 18:09:04 2023 +0200
@@ -129,6 +129,7 @@
     uint32 database_version = 1;
     bool supports_flush_to_disk = 2;
     bool supports_revisions = 3;
+    bool supports_labels = 4;
   }
 }
 
--- a/OrthancServer/Sources/Database/IDatabaseWrapper.h	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Sources/Database/IDatabaseWrapper.h	Mon Apr 03 18:09:04 2023 +0200
@@ -200,6 +200,8 @@
                                         std::list<std::string>* instancesId, // Can be NULL if not needed
                                         const std::vector<DatabaseConstraint>& lookup,
                                         ResourceType queryLevel,
+                                        const std::set<std::string>& withLabels,
+                                        const std::set<std::string>& withoutLabels,
                                         uint32_t limit) = 0;
 
       // Returns "true" iff. the instance is new and has been inserted
@@ -236,6 +238,20 @@
                                            ResourceType& type,
                                            std::string& parentPublicId,
                                            const std::string& publicId) = 0;
+
+
+      /**
+       * Primitives introduced in Orthanc 1.12.0
+       **/
+
+      virtual void AddLabel(int64_t resource,
+                            const std::string& label) = 0;
+
+      virtual void RemoveLabel(int64_t resource,
+                               const std::string& label) = 0;
+
+      virtual void GetLabels(std::set<std::string>& target,
+                             int64_t resource) = 0;
     };
 
 
@@ -260,5 +276,7 @@
                          IStorageArea& storageArea) = 0;
 
     virtual bool HasRevisionsSupport() const = 0;
+
+    virtual bool HasLabelsSupport() const = 0;
   };
 }
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Mon Apr 03 18:09:04 2023 +0200
@@ -341,8 +341,16 @@
                                       std::list<std::string>* instancesId,
                                       const std::vector<DatabaseConstraint>& lookup,
                                       ResourceType queryLevel,
+                                      const std::set<std::string>& withLabels,
+                                      const std::set<std::string>& withoutLabels,
                                       uint32_t limit) ORTHANC_OVERRIDE
     {
+      if (!withLabels.empty() ||
+          !withoutLabels.empty())
+      {
+        throw OrthancException(ErrorCode_NotImplemented);
+      }
+      
       LookupFormatter formatter;
 
       std::string sql;
@@ -1071,6 +1079,27 @@
         s.Run();
       }
     }
+
+
+    virtual void AddLabel(int64_t resource,
+                          const std::string& label) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_NotImplemented);
+    }
+
+
+    virtual void RemoveLabel(int64_t resource,
+                             const std::string& label) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_NotImplemented);
+    }
+
+
+    virtual void GetLabels(std::set<std::string>& target,
+                           int64_t resource) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_NotImplemented);
+    }
   };
 
 
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h	Mon Apr 03 18:09:04 2023 +0200
@@ -97,6 +97,11 @@
       return false;  // TODO - REVISIONS
     }
 
+    virtual bool HasLabelsSupport() const ORTHANC_OVERRIDE
+    {
+      return true;
+    }
+
 
     /**
      * The "StartTransaction()" method is guaranteed to return a class
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Mon Apr 03 18:09:04 2023 +0200
@@ -1066,7 +1066,7 @@
   void StatelessDatabaseOperations::GetAllUuids(std::list<std::string>& target,
                                                 ResourceType resourceType,
                                                 size_t since,
-                                                size_t limit)
+                                                uint32_t limit)
   {
     if (limit == 0)
     {
@@ -1646,7 +1646,9 @@
       {
         // TODO - CANDIDATE FOR "TransactionType_Implicit"
         std::list<std::string> tmp;
-        transaction.ApplyLookupResources(tmp, NULL, query_, level_, 0);
+        std::set<std::string> withLabels;
+        std::set<std::string> withoutLabels;
+        transaction.ApplyLookupResources(tmp, NULL, query_, level_, withLabels, withoutLabels, 0);
         CopyListToVector(result_, tmp);
       }
     };
@@ -1915,9 +1917,12 @@
                                                          std::vector<std::string>* instancesId,
                                                          const DatabaseLookup& lookup,
                                                          ResourceType queryLevel,
-                                                         size_t limit)
+                                                         const std::set<std::string>& withLabels,
+                                                         const std::set<std::string>& withoutLabels,
+                                                         uint32_t limit)
   {
-    class Operations : public ReadOnlyOperationsT4<bool, const std::vector<DatabaseConstraint>&, ResourceType, size_t>
+    class Operations : public ReadOnlyOperationsT6<bool, const std::vector<DatabaseConstraint>&, ResourceType,
+                                                   const std::set<std::string>&, const std::set<std::string>&, size_t>
     {
     private:
       std::list<std::string>  resourcesList_;
@@ -1940,11 +1945,13 @@
         // TODO - CANDIDATE FOR "TransactionType_Implicit"
         if (tuple.get<0>())
         {
-          transaction.ApplyLookupResources(resourcesList_, &instancesList_, tuple.get<1>(), tuple.get<2>(), tuple.get<3>());
+          transaction.ApplyLookupResources(
+            resourcesList_, &instancesList_, tuple.get<1>(), tuple.get<2>(), tuple.get<3>(), tuple.get<4>(), tuple.get<5>());
         }
         else
         {
-          transaction.ApplyLookupResources(resourcesList_, NULL, tuple.get<1>(), tuple.get<2>(), tuple.get<3>());
+          transaction.ApplyLookupResources(
+            resourcesList_, NULL, tuple.get<1>(), tuple.get<2>(), tuple.get<3>(), tuple.get<4>(), tuple.get<5>());
         }
       }
     };
@@ -1954,7 +1961,7 @@
     NormalizeLookup(normalized, lookup, queryLevel);
 
     Operations operations;
-    operations.Apply(*this, (instancesId != NULL), normalized, queryLevel, limit);
+    operations.Apply(*this, (instancesId != NULL), normalized, queryLevel, withLabels, withoutLabels, limit);
     
     CopyListToVector(resourcesId, operations.GetResourcesList());
 
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Mon Apr 03 18:09:04 2023 +0200
@@ -157,9 +157,11 @@
                                 std::list<std::string>* instancesId, // Can be NULL if not needed
                                 const std::vector<DatabaseConstraint>& lookup,
                                 ResourceType queryLevel,
-                                size_t limit)
+                                const std::set<std::string>& withLabels,
+                                const std::set<std::string>& withoutLabels,
+                                uint32_t limit)
       {
-        return transaction_.ApplyLookupResources(resourcesId, instancesId, lookup, queryLevel, limit);
+        return transaction_.ApplyLookupResources(resourcesId, instancesId, lookup, queryLevel, withLabels, withoutLabels, limit);
       }
 
       void GetAllMetadata(std::map<MetadataType, std::string>& target,
@@ -177,7 +179,7 @@
       void GetAllPublicIds(std::list<std::string>& target,
                            ResourceType resourceType,
                            size_t since,
-                           size_t limit)
+                           uint32_t limit)
       {
         return transaction_.GetAllPublicIds(target, resourceType, since, limit);
       }  
@@ -185,9 +187,9 @@
       void GetChanges(std::list<ServerIndexChange>& target /*out*/,
                       bool& done /*out*/,
                       int64_t since,
-                      uint32_t maxResults)
+                      uint32_t limit)
       {
-        transaction_.GetChanges(target, done, since, maxResults);
+        transaction_.GetChanges(target, done, since, limit);
       }
 
       void GetChildrenInternalId(std::list<int64_t>& target,
@@ -205,9 +207,9 @@
       void GetExportedResources(std::list<ExportedResource>& target /*out*/,
                                 bool& done /*out*/,
                                 int64_t since,
-                                uint32_t maxResults)
+                                uint32_t limit)
       {
-        return transaction_.GetExportedResources(target, done, since, maxResults);
+        return transaction_.GetExportedResources(target, done, since, limit);
       }
 
       void GetLastChange(std::list<ServerIndexChange>& target /*out*/)
@@ -515,7 +517,7 @@
     void GetAllUuids(std::list<std::string>& target,
                      ResourceType resourceType,
                      size_t since,
-                     size_t limit);
+                     uint32_t limit);
 
     void GetGlobalStatistics(/* out */ uint64_t& diskSize,
                              /* out */ uint64_t& uncompressedSize,
@@ -531,13 +533,13 @@
 
     void GetChanges(Json::Value& target,
                     int64_t since,
-                    unsigned int maxResults);
+                    uint32_t limit);
 
     void GetLastChange(Json::Value& target);
 
     void GetExportedResources(Json::Value& target,
                               int64_t since,
-                              unsigned int maxResults);
+                              uint32_t limit);
 
     void GetLastExportedResource(Json::Value& target);
 
@@ -605,7 +607,9 @@
                               std::vector<std::string>* instancesId,  // Can be NULL if not needed
                               const DatabaseLookup& lookup,
                               ResourceType queryLevel,
-                              size_t limit);
+                              const std::set<std::string>& withLabels,
+                              const std::set<std::string>& withoutLabels,
+                              uint32_t limit);
 
     bool DeleteResource(Json::Value& remainingAncestor /* out */,
                         const std::string& uuid,
--- a/OrthancServer/Sources/Search/DatabaseLookup.cpp	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Sources/Search/DatabaseLookup.cpp	Mon Apr 03 18:09:04 2023 +0200
@@ -368,4 +368,30 @@
 
     return clone.release();
   }
+
+
+  void DatabaseLookup::AddWithLabel(const std::string& label)
+  {
+    if (label.empty())
+    {
+      throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+    else
+    {
+      withLabels_.insert(label);
+    }
+  }
+  
+
+  void DatabaseLookup::AddWithoutLabel(const std::string& label)
+  {
+    if (label.empty())
+    {
+      throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+    else
+    {
+      withoutLabels_.insert(label);
+    }
+  }
 }
--- a/OrthancServer/Sources/Search/DatabaseLookup.h	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Sources/Search/DatabaseLookup.h	Mon Apr 03 18:09:04 2023 +0200
@@ -32,6 +32,8 @@
   {
   private:
     std::vector<DicomTagConstraint*>  constraints_;
+    std::set<std::string>             withLabels_;
+    std::set<std::string>             withoutLabels_;
 
     void AddDicomConstraintInternal(const DicomTag& tag,
                                     ValueRepresentation vr,
@@ -92,5 +94,19 @@
     bool HasTag(const DicomTag& tag) const;
 
     void RemoveConstraint(const DicomTag& tag);
+
+    void AddWithLabel(const std::string& label);
+
+    void AddWithoutLabel(const std::string& label);
+
+    const std::set<std::string>& GetWithLabels() const
+    {
+      return withLabels_;
+    }
+
+    const std::set<std::string>& GetWithoutLabels() const
+    {
+      return withoutLabels_;
+    }
   };
 }
--- a/OrthancServer/Sources/ServerContext.cpp	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/Sources/ServerContext.cpp	Mon Apr 03 18:09:04 2023 +0200
@@ -1448,8 +1448,9 @@
     }
 
     {
-      const size_t lookupLimit = (databaseLimit == 0 ? 0 : databaseLimit + 1);      
-      GetIndex().ApplyLookupResources(resources, &instances, *fastLookup, queryLevel, lookupLimit);
+      const size_t lookupLimit = (databaseLimit == 0 ? 0 : databaseLimit + 1);
+      GetIndex().ApplyLookupResources(resources, &instances, *fastLookup, queryLevel,
+                                      lookup.GetWithLabels(), lookup.GetWithoutLabels(), lookupLimit);
     }
 
     bool complete = (databaseLimit == 0 ||
--- a/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Mon Apr 03 17:00:12 2023 +0200
+++ b/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Mon Apr 03 18:09:04 2023 +0200
@@ -167,8 +167,9 @@
       
       std::vector<DatabaseConstraint> lookup;
       lookup.push_back(c.ConvertToDatabaseConstraint(level, DicomTagType_Identifier));
-      
-      transaction_->ApplyLookupResources(result, NULL, lookup, level, 0 /* no limit */);
+
+      std::set<std::string> noLabel;
+      transaction_->ApplyLookupResources(result, NULL, lookup, level, noLabel, noLabel, 0 /* no limit */);
     }    
 
     void DoLookupIdentifier2(std::list<std::string>& result,
@@ -188,7 +189,8 @@
       lookup.push_back(c1.ConvertToDatabaseConstraint(level, DicomTagType_Identifier));
       lookup.push_back(c2.ConvertToDatabaseConstraint(level, DicomTagType_Identifier));
       
-      transaction_->ApplyLookupResources(result, NULL, lookup, level, 0 /* no limit */);
+      std::set<std::string> noLabel;
+      transaction_->ApplyLookupResources(result, NULL, lookup, level, noLabel, noLabel, 0 /* no limit */);
     }
   };
 }