# HG changeset patch # User Sebastien Jodogne # Date 1680899535 -7200 # Node ID a8774581adfc2fd0d995e76b58e98e55d3692024 # Parent 897253c21208b04cac420e237fc6d761e4bae7f1 replaced "WithLabels" and "WithoutLabels", by "Labels" and "LabelsConstraint" diff -r 897253c21208 -r a8774581adfc Framework/Plugins/DatabaseBackendAdapterV2.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV2.cpp Fri Apr 07 15:43:42 2023 +0200 +++ b/Framework/Plugins/DatabaseBackendAdapterV2.cpp Fri Apr 07 22:32:15 2023 +0200 @@ -1419,9 +1419,9 @@ lookup.push_back(Orthanc::DatabaseConstraint(constraints[i])); } - std::set noLabels; - adapter->GetBackend().LookupResources(*output, accessor.GetManager(), lookup, queryLevel, - noLabels, noLabels, limit, (requestSomeInstance != 0)); + std::set noLabel; + adapter->GetBackend().LookupResources(*output, accessor.GetManager(), lookup, queryLevel, noLabel, + Orthanc::LabelsConstraint_All, limit, (requestSomeInstance != 0)); return OrthancPluginErrorCode_Success; } diff -r 897253c21208 -r a8774581adfc Framework/Plugins/DatabaseBackendAdapterV3.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV3.cpp Fri Apr 07 15:43:42 2023 +0200 +++ b/Framework/Plugins/DatabaseBackendAdapterV3.cpp Fri Apr 07 22:32:15 2023 +0200 @@ -1646,9 +1646,9 @@ lookup.push_back(Orthanc::DatabaseConstraint(constraints[i])); } - std::set noLabels; - t->GetBackend().LookupResources(t->GetOutput(), t->GetManager(), lookup, queryLevel, - noLabels, noLabels, limit, (requestSomeInstanceId != 0)); + std::set noLabel; + t->GetBackend().LookupResources(t->GetOutput(), t->GetManager(), lookup, queryLevel, noLabel, + Orthanc::LabelsConstraint_All, limit, (requestSomeInstanceId != 0)); return OrthancPluginErrorCode_Success; } ORTHANC_PLUGINS_DATABASE_CATCH(t->GetBackend().GetContext()); diff -r 897253c21208 -r a8774581adfc Framework/Plugins/DatabaseBackendAdapterV4.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV4.cpp Fri Apr 07 15:43:42 2023 +0200 +++ b/Framework/Plugins/DatabaseBackendAdapterV4.cpp Fri Apr 07 22:32:15 2023 +0200 @@ -568,21 +568,35 @@ assert(values.size() == countValues); - std::set withLabels, withoutLabels; + std::set labels; - for (int i = 0; i < request.with_labels().size(); i++) + for (int i = 0; i < request.labels().size(); i++) { - withLabels.insert(request.with_labels(i)); + labels.insert(request.labels(i)); } - for (int i = 0; i < request.without_labels().size(); i++) + Orthanc::LabelsConstraint labelsConstraint; + switch (request.labels_constraint()) { - withoutLabels.insert(request.without_labels(i)); + case Orthanc::DatabasePluginMessages::LABELS_CONSTRAINT_ALL: + labelsConstraint = Orthanc::LabelsConstraint_All; + break; + + case Orthanc::DatabasePluginMessages::LABELS_CONSTRAINT_ANY: + labelsConstraint = Orthanc::LabelsConstraint_Any; + break; + + case Orthanc::DatabasePluginMessages::LABELS_CONSTRAINT_NONE: + labelsConstraint = Orthanc::LabelsConstraint_None; + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - + Output output(response); backend.LookupResources(output, manager, lookup, Convert(request.query_level()), - withLabels, withoutLabels, request.limit(), request.retrieve_instances_ids()); + labels, labelsConstraint, request.limit(), request.retrieve_instances_ids()); } diff -r 897253c21208 -r a8774581adfc Framework/Plugins/IDatabaseBackend.h --- a/Framework/Plugins/IDatabaseBackend.h Fri Apr 07 15:43:42 2023 +0200 +++ b/Framework/Plugins/IDatabaseBackend.h Fri Apr 07 22:32:15 2023 +0200 @@ -23,9 +23,10 @@ #pragma once -#include "IDatabaseBackendOutput.h" +#include "../../Resources/Orthanc/Databases/ISqlLookupFormatter.h" +#include "../Common/DatabaseManager.h" #include "../Common/DatabasesEnumerations.h" -#include "../Common/DatabaseManager.h" +#include "IDatabaseBackendOutput.h" #include @@ -271,8 +272,8 @@ DatabaseManager& manager, const std::vector& lookup, OrthancPluginResourceType queryLevel, - const std::set& withLabels, // New in Orthanc 1.12.0 - const std::set& withoutLabels, // New in Orthanc 1.12.0 + const std::set& labels, // New in Orthanc 1.12.0 + Orthanc::LabelsConstraint labelsConstraint, // New in Orthanc 1.12.0 uint32_t limit, bool requestSomeInstance) = 0; #endif diff -r 897253c21208 -r a8774581adfc Framework/Plugins/IndexBackend.cpp --- a/Framework/Plugins/IndexBackend.cpp Fri Apr 07 15:43:42 2023 +0200 +++ b/Framework/Plugins/IndexBackend.cpp Fri Apr 07 22:32:15 2023 +0200 @@ -22,7 +22,6 @@ #include "IndexBackend.h" -#include "../../Resources/Orthanc/Databases/ISqlLookupFormatter.h" #include "../Common/BinaryStringValue.h" #include "../Common/Integer64Value.h" #include "../Common/Utf8StringValue.h" @@ -2065,17 +2064,16 @@ DatabaseManager& manager, const std::vector& lookup, OrthancPluginResourceType queryLevel, - const std::set& withLabels, - const std::set& withoutLabels, + const std::set& labels, + Orthanc::LabelsConstraint labelsConstraint, uint32_t limit, bool requestSomeInstance) { LookupFormatter formatter(manager.GetDialect()); std::string sql; - Orthanc::ISqlLookupFormatter::Apply( - sql, formatter, lookup, Orthanc::Plugins::Convert(queryLevel), - withLabels, withoutLabels, limit); + Orthanc::ISqlLookupFormatter::Apply(sql, formatter, lookup, Orthanc::Plugins::Convert(queryLevel), + labels, labelsConstraint, limit); if (requestSomeInstance) { diff -r 897253c21208 -r a8774581adfc Framework/Plugins/IndexBackend.h --- a/Framework/Plugins/IndexBackend.h Fri Apr 07 15:43:42 2023 +0200 +++ b/Framework/Plugins/IndexBackend.h Fri Apr 07 22:32:15 2023 +0200 @@ -302,8 +302,8 @@ DatabaseManager& manager, const std::vector& lookup, OrthancPluginResourceType queryLevel, - const std::set& withLabels, - const std::set& withoutLabels, + const std::set& labels, + Orthanc::LabelsConstraint labelsConstraint, uint32_t limit, bool requestSomeInstance) ORTHANC_OVERRIDE; #endif diff -r 897253c21208 -r a8774581adfc Resources/Orthanc/Databases/ISqlLookupFormatter.cpp --- a/Resources/Orthanc/Databases/ISqlLookupFormatter.cpp Fri Apr 07 15:43:42 2023 +0200 +++ b/Resources/Orthanc/Databases/ISqlLookupFormatter.cpp Fri Apr 07 22:32:15 2023 +0200 @@ -307,8 +307,8 @@ ISqlLookupFormatter& formatter, const std::vector& lookup, ResourceType queryLevel, - const std::set& withLabels, - const std::set& withoutLabels, + const std::set& labels, + LabelsConstraint labelsConstraint, size_t limit) { assert(ResourceType_Patient < ResourceType_Study && @@ -384,20 +384,7 @@ std::list where; - if (!withLabels.empty()) - { - std::list labels; - for (std::set::const_iterator it = withLabels.begin(); it != withLabels.end(); ++it) - { - labels.push_back(formatter.GenerateParameter(*it)); - } - - where.push_back(boost::lexical_cast(withLabels.size()) + - " = (SELECT COUNT(1) FROM Labels WHERE internalId = " + FormatLevel(queryLevel) + - ".internalId AND label IN (" + Join(labels, "", ", ") + "))"); - } - - if (!withoutLabels.empty()) + if (!labels.empty()) { /** * "In SQL Server, NOT EXISTS and NOT IN predicates are the best @@ -405,14 +392,34 @@ * question are NOT NULL." * https://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/ **/ - std::list labels; - for (std::set::const_iterator it = withoutLabels.begin(); it != withoutLabels.end(); ++it) + + std::list formattedLabels; + for (std::set::const_iterator it = labels.begin(); it != labels.end(); ++it) { - labels.push_back(formatter.GenerateParameter(*it)); + formattedLabels.push_back(formatter.GenerateParameter(*it)); } - where.push_back("NOT EXISTS (SELECT 1 FROM Labels WHERE internalId = " + FormatLevel(queryLevel) + - ".internalId AND label IN (" + Join(labels, "", ", ") + "))"); + std::string condition; + switch (labelsConstraint) + { + case LabelsConstraint_Any: + condition = "> 0"; + break; + + case LabelsConstraint_All: + condition = "= " + boost::lexical_cast(labels.size()); + break; + + case LabelsConstraint_None: + condition = "= 0"; + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + + where.push_back("(SELECT COUNT(1) FROM Labels WHERE internalId = " + FormatLevel(queryLevel) + + ".internalId AND label IN (" + Join(formattedLabels, "", ", ") + ")) " + condition); } where.push_back(FormatLevel(queryLevel) + ".resourceType = " + diff -r 897253c21208 -r a8774581adfc Resources/Orthanc/Databases/ISqlLookupFormatter.h --- a/Resources/Orthanc/Databases/ISqlLookupFormatter.h Fri Apr 07 15:43:42 2023 +0200 +++ b/Resources/Orthanc/Databases/ISqlLookupFormatter.h Fri Apr 07 22:32:15 2023 +0200 @@ -35,6 +35,13 @@ { class DatabaseConstraint; + enum LabelsConstraint + { + LabelsConstraint_All, + LabelsConstraint_Any, + LabelsConstraint_None + }; + // This class is also used by the "orthanc-databases" project class ISqlLookupFormatter : public boost::noncopyable { @@ -60,8 +67,8 @@ ISqlLookupFormatter& formatter, const std::vector& lookup, ResourceType queryLevel, - const std::set& withLabels, // New in Orthanc 1.12.0 - const std::set& withoutLabels, // New in Orthanc 1.12.0 + const std::set& labels, // New in Orthanc 1.12.0 + LabelsConstraint labelsConstraint, // New in Orthanc 1.12.0 size_t limit); }; }