# HG changeset patch # User Sebastien Jodogne # Date 1680538144 -7200 # Node ID df39c7583a4907b77e1799a8ed8ab07a4910fa39 # Parent afa96af2eb5a92a0be348650fd1919fc10b9e206 preparing virtual methods for labels diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp --- 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* instancesId, const std::vector& lookup, ResourceType queryLevel, + const std::set& withLabels, + const std::set& 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& target, + int64_t resource) ORTHANC_OVERRIDE + { + throw OrthancException(ErrorCode_InternalError); // Not supported + } }; diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Plugins/Engine/OrthancPluginDatabase.h --- 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); }; } diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp --- 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* instancesId, // Can be NULL if not needed const std::vector& lookup, ResourceType queryLevel, + const std::set& withLabels, + const std::set& withoutLabels, uint32_t limit) ORTHANC_OVERRIDE { + if (!withLabels.empty() || + !withoutLabels.empty()) + { + throw OrthancException(ErrorCode_InternalError); // "HasLabelsSupport()" has returned "false" + } + std::vector constraints; std::vector< std::vector > 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& target, + int64_t resource) ORTHANC_OVERRIDE + { + throw OrthancException(ErrorCode_InternalError); // Not supported + } }; diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h --- 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; + } }; } diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp --- 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* instancesId, // Can be NULL if not needed const std::vector& lookup, ResourceType queryLevel, + const std::set& withLabels, + const std::set& 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& 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_; + } + } } diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h --- 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; }; } diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto --- 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; } } diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Sources/Database/IDatabaseWrapper.h --- 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* instancesId, // Can be NULL if not needed const std::vector& lookup, ResourceType queryLevel, + const std::set& withLabels, + const std::set& 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& target, + int64_t resource) = 0; }; @@ -260,5 +276,7 @@ IStorageArea& storageArea) = 0; virtual bool HasRevisionsSupport() const = 0; + + virtual bool HasLabelsSupport() const = 0; }; } diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp --- 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* instancesId, const std::vector& lookup, ResourceType queryLevel, + const std::set& withLabels, + const std::set& 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& target, + int64_t resource) ORTHANC_OVERRIDE + { + throw OrthancException(ErrorCode_NotImplemented); + } }; diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h --- 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 diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp --- 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& 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 tmp; - transaction.ApplyLookupResources(tmp, NULL, query_, level_, 0); + std::set withLabels; + std::set withoutLabels; + transaction.ApplyLookupResources(tmp, NULL, query_, level_, withLabels, withoutLabels, 0); CopyListToVector(result_, tmp); } }; @@ -1915,9 +1917,12 @@ std::vector* instancesId, const DatabaseLookup& lookup, ResourceType queryLevel, - size_t limit) + const std::set& withLabels, + const std::set& withoutLabels, + uint32_t limit) { - class Operations : public ReadOnlyOperationsT4&, ResourceType, size_t> + class Operations : public ReadOnlyOperationsT6&, ResourceType, + const std::set&, const std::set&, size_t> { private: std::list 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()); diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Sources/Database/StatelessDatabaseOperations.h --- 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* instancesId, // Can be NULL if not needed const std::vector& lookup, ResourceType queryLevel, - size_t limit) + const std::set& withLabels, + const std::set& 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& target, @@ -177,7 +179,7 @@ void GetAllPublicIds(std::list& 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& 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& target, @@ -205,9 +207,9 @@ void GetExportedResources(std::list& 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& target /*out*/) @@ -515,7 +517,7 @@ void GetAllUuids(std::list& 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* instancesId, // Can be NULL if not needed const DatabaseLookup& lookup, ResourceType queryLevel, - size_t limit); + const std::set& withLabels, + const std::set& withoutLabels, + uint32_t limit); bool DeleteResource(Json::Value& remainingAncestor /* out */, const std::string& uuid, diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Sources/Search/DatabaseLookup.cpp --- 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); + } + } } diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Sources/Search/DatabaseLookup.h --- 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 constraints_; + std::set withLabels_; + std::set 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& GetWithLabels() const + { + return withLabels_; + } + + const std::set& GetWithoutLabels() const + { + return withoutLabels_; + } }; } diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/Sources/ServerContext.cpp --- 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 || diff -r afa96af2eb5a -r df39c7583a49 OrthancServer/UnitTestsSources/ServerIndexTests.cpp --- 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 lookup; lookup.push_back(c.ConvertToDatabaseConstraint(level, DicomTagType_Identifier)); - - transaction_->ApplyLookupResources(result, NULL, lookup, level, 0 /* no limit */); + + std::set noLabel; + transaction_->ApplyLookupResources(result, NULL, lookup, level, noLabel, noLabel, 0 /* no limit */); } void DoLookupIdentifier2(std::list& 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 noLabel; + transaction_->ApplyLookupResources(result, NULL, lookup, level, noLabel, noLabel, 0 /* no limit */); } }; }