# HG changeset patch # User Sebastien Jodogne # Date 1680900897 -7200 # Node ID f22c8fac764bc85e68b6e3637d07c056557e8c42 # Parent a7d95f951f8a8d4128dfc03ba2bf217a2d849270 added "/tools/labels" to list all the labels that are associated with any resource diff -r a7d95f951f8a -r f22c8fac764b NEWS --- 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 diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp --- 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& target) ORTHANC_OVERRIDE + { + throw OrthancException(ErrorCode_InternalError); // Not supported + } }; diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp --- 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& target) ORTHANC_OVERRIDE + { + throw OrthancException(ErrorCode_InternalError); // Not supported + } }; diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp --- 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& 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& 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& target) ORTHANC_OVERRIDE + { + ListLabelsInternal(target, false, -1); } }; diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto --- 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; diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Sources/Database/IDatabaseWrapper.h --- 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& target, int64_t resource) = 0; + + // List all the labels that are present in any resource + virtual void ListAllLabels(std::set& target) = 0; }; diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp --- 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& 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)); + } + } }; diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp --- 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& target) + { + class Operations : public ReadOnlyOperationsT1& > + { + 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, diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Sources/Database/StatelessDatabaseOperations.h --- 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& target) + { + transaction_.ListAllLabels(target); + } }; @@ -762,6 +767,8 @@ const std::string& publicId, ResourceType level); + void ListAllLabels(std::set& target); + void ModifyLabel(const std::string& publicId, ResourceType level, const std::string& label, diff -r a7d95f951f8a -r f22c8fac764b OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp --- 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 labels; + OrthancRestApi::GetIndex(call).ListAllLabels(labels); + + Json::Value json = Json::arrayValue; + for (std::set::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 } }