changeset 5249:f22c8fac764b db-protobuf

added "/tools/labels" to list all the labels that are associated with any resource
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 07 Apr 2023 22:54:57 +0200
parents a7d95f951f8a
children 1acd709c8772
files NEWS OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto OrthancServer/Sources/Database/IDatabaseWrapper.h OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp OrthancServer/Sources/Database/StatelessDatabaseOperations.h OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp
diffstat 10 files changed, 121 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Apr 07 22:18:37 2023 +0200
+++ b/NEWS	Fri Apr 07 22:54:57 2023 +0200
@@ -11,9 +11,10 @@
 
 * API version upgraded to 20
 * New URIs "/.../{id}/labels/{label}" to test/set/remove labels
-* "/tools/find" accepts the "Labels" and "LabelsConstraint" arguments
 * "/patients/{id}", "/studies/{id}", "/series/{id}" and "/instances/{id}"
   contain the "Labels" field
+* "/tools/find" now accepts the "Labels" and "LabelsConstraint" arguments
+* "/tools/labels" lists all the labels that are associated with any resource
 * "/system": added "UserMetadata" and "HasLabels"
 
 Plugins
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp	Fri Apr 07 22:54:57 2023 +0200
@@ -1441,6 +1441,12 @@
     {
       throw OrthancException(ErrorCode_InternalError);  // Not supported
     }
+    
+
+    virtual void ListAllLabels(std::set<std::string>& target) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_InternalError);  // Not supported
+    }
   };
 
 
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Fri Apr 07 22:54:57 2023 +0200
@@ -1055,6 +1055,12 @@
     {
       throw OrthancException(ErrorCode_InternalError);  // Not supported
     }
+    
+
+    virtual void ListAllLabels(std::set<std::string>& target) ORTHANC_OVERRIDE
+    {
+      throw OrthancException(ErrorCode_InternalError);  // Not supported
+    }
   };
 
   
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp	Fri Apr 07 22:54:57 2023 +0200
@@ -223,6 +223,33 @@
     }
 
 
+    void ListLabelsInternal(std::set<std::string>& target,
+                            bool isSingleResource,
+                            int64_t resource)
+    {
+      if (database_.HasLabelsSupport())
+      {
+        DatabasePluginMessages::TransactionRequest request;
+        request.mutable_list_labels()->set_single_resource(isSingleResource);
+        request.mutable_list_labels()->set_id(resource);
+
+        DatabasePluginMessages::TransactionResponse response;
+        ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LIST_LABELS, request);
+
+        target.clear();
+        for (int i = 0; i < response.list_labels().labels().size(); i++)
+        {
+          target.insert(response.list_labels().labels(i));
+        }
+      }
+      else
+      {
+        // This method shouldn't have been called
+        throw OrthancException(ErrorCode_InternalError);
+      }
+    }
+    
+
   public:
     Transaction(OrthancPluginDatabaseV4& database,
                 IDatabaseListener& listener,
@@ -1206,25 +1233,13 @@
     virtual void ListLabels(std::set<std::string>& target,
                             int64_t resource) ORTHANC_OVERRIDE
     {
-      if (database_.HasLabelsSupport())
-      {
-        DatabasePluginMessages::TransactionRequest request;
-        request.mutable_list_labels()->set_id(resource);
-
-        DatabasePluginMessages::TransactionResponse response;
-        ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LIST_LABELS, request);
+      ListLabelsInternal(target, true, resource);
+    }
 
-        target.clear();
-        for (int i = 0; i < response.list_labels().labels().size(); i++)
-        {
-          target.insert(response.list_labels().labels(i));
-        }
-      }
-      else
-      {
-        // This method shouldn't have been called
-        throw OrthancException(ErrorCode_InternalError);
-      }
+    
+    virtual void ListAllLabels(std::set<std::string>& target) ORTHANC_OVERRIDE
+    {
+      ListLabelsInternal(target, false, -1);
     }
   };
 
--- a/OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto	Fri Apr 07 22:54:57 2023 +0200
@@ -265,9 +265,9 @@
   OPERATION_GET_CHILDREN_METADATA = 42;
   OPERATION_GET_LAST_CHANGE_INDEX = 43;
   OPERATION_LOOKUP_RESOURCE_AND_PARENT = 44;
-  OPERATION_ADD_LABEL = 45;     // New in Orthanc 1.12.0
-  OPERATION_REMOVE_LABEL = 46;  // New in Orthanc 1.12.0
-  OPERATION_LIST_LABELS = 47;   // New in Orthanc 1.12.0
+  OPERATION_ADD_LABEL = 45;        // New in Orthanc 1.12.0
+  OPERATION_REMOVE_LABEL = 46;     // New in Orthanc 1.12.0
+  OPERATION_LIST_LABELS = 47;      // New in Orthanc 1.12.0
 }
 
 message Rollback {
@@ -767,7 +767,8 @@
 
 message ListLabels {
   message Request {
-    int64 id = 1;
+    bool single_resource = 1;
+    int64 id = 2;  // Only if "single_resource" is "true"
   }
   message Response {
     repeated string labels = 1;
--- a/OrthancServer/Sources/Database/IDatabaseWrapper.h	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Sources/Database/IDatabaseWrapper.h	Fri Apr 07 22:54:57 2023 +0200
@@ -251,8 +251,12 @@
       virtual void RemoveLabel(int64_t resource,
                                const std::string& label) = 0;
 
+      // List the labels of one single resource
       virtual void ListLabels(std::set<std::string>& target,
                               int64_t resource) = 0;
+
+      // List all the labels that are present in any resource
+      virtual void ListAllLabels(std::set<std::string>& target) = 0;
     };
 
 
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Fri Apr 07 22:54:57 2023 +0200
@@ -1123,6 +1123,20 @@
         target.insert(s.ColumnString(0));
       }
     }
+
+
+    virtual void ListAllLabels(std::set<std::string>& target) ORTHANC_OVERRIDE
+    {
+      target.clear();
+
+      SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                          "SELECT DISTINCT label FROM Labels");
+
+      while (s.Step())
+      {
+        target.insert(s.ColumnString(0));
+      }
+    }
   };
 
 
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Fri Apr 07 22:54:57 2023 +0200
@@ -3578,6 +3578,23 @@
   }
 
 
+  void StatelessDatabaseOperations::ListAllLabels(std::set<std::string>& target)
+  {
+    class Operations : public ReadOnlyOperationsT1<std::set<std::string>& >
+    {
+    public:
+      virtual void ApplyTuple(ReadOnlyTransaction& transaction,
+                              const Tuple& tuple) ORTHANC_OVERRIDE
+      {
+        transaction.ListAllLabels(tuple.get<0>());
+      }
+    };
+
+    Operations operations;
+    operations.Apply(*this, target);
+  }
+  
+
   void StatelessDatabaseOperations::ModifyLabel(const std::string& publicId,
                                                 ResourceType level,
                                                 const std::string& label,
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Fri Apr 07 22:54:57 2023 +0200
@@ -369,6 +369,11 @@
       {
         transaction_.ListLabels(target, id);
       }
+
+      void ListAllLabels(std::set<std::string>& target)
+      {
+        transaction_.ListAllLabels(target);
+      }
     };
 
 
@@ -762,6 +767,8 @@
                     const std::string& publicId,
                     ResourceType level);
 
+    void ListAllLabels(std::set<std::string>& target);
+
     void ModifyLabel(const std::string& publicId,
                      ResourceType level,
                      const std::string& label,
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Fri Apr 07 22:18:37 2023 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Fri Apr 07 22:54:57 2023 +0200
@@ -1047,6 +1047,31 @@
   }
 
 
+  static void ListAllLabels(RestApiGetCall& call)
+  {
+    if (call.IsDocumentation())
+    {
+      call.GetDocumentation()
+        .SetTag("System")
+        .SetSummary("Get all the used labels")
+        .SetDescription("List all the labels that are associated with any resource of the Orthanc database")
+        .AddAnswerType(MimeType_Json, "JSON array containing the labels");
+      return;
+    }
+
+    std::set<std::string> labels;
+    OrthancRestApi::GetIndex(call).ListAllLabels(labels);
+
+    Json::Value json = Json::arrayValue;
+    for (std::set<std::string>::const_iterator it = labels.begin(); it != labels.end(); ++it)
+    {
+      json.append(*it);
+    }
+    
+    call.GetOutput().AnswerJson(json);
+   }
+
+
   void OrthancRestApi::RegisterSystem(bool orthancExplorerEnabled)
   {
     if (orthancExplorerEnabled)
@@ -1094,5 +1119,7 @@
     Register("/tools/accepted-transfer-syntaxes", SetAcceptedTransferSyntaxes);
     Register("/tools/unknown-sop-class-accepted", GetUnknownSopClassAccepted);
     Register("/tools/unknown-sop-class-accepted", SetUnknownSopClassAccepted);
+
+    Register("/tools/labels", ListAllLabels);  // New in Orthanc 1.12.0
   }
 }