Mercurial > hg > orthanc-databases
diff Framework/Plugins/DatabaseConstraint.cpp @ 569:f18e46d7dbf8 attach-custom-data
merged find-refactoring -> attach-custom-data
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 24 Sep 2024 15:04:21 +0200 |
parents | 1a74fc1bea2d |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Plugins/DatabaseConstraint.cpp Tue Sep 24 15:04:21 2024 +0200 @@ -0,0 +1,289 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium + * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +/** + * NB: Until 2024-09-09, this file was synchronized with the following + * folder from the Orthanc main project: + * https://orthanc.uclouvain.be/hg/orthanc/file/default/OrthancServer/Sources/Search/ + **/ + + +#include "DatabaseConstraint.h" + +#include <OrthancException.h> + +#include <boost/lexical_cast.hpp> +#include <cassert> + + +namespace OrthancDatabases +{ + DatabaseConstraint::DatabaseConstraint(Orthanc::ResourceType level, + const Orthanc::DicomTag& tag, + bool isIdentifier, + ConstraintType type, + const std::vector<std::string>& values, + bool caseSensitive, + bool mandatory) : + level_(level), + tag_(tag), + isIdentifier_(isIdentifier), + constraintType_(type), + values_(values), + caseSensitive_(caseSensitive), + mandatory_(mandatory) + { + if (type != ConstraintType_List && + values_.size() != 1) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + +#if ORTHANC_PLUGINS_HAS_DATABASE_CONSTRAINT == 1 + DatabaseConstraint::DatabaseConstraint(const OrthancPluginDatabaseConstraint& constraint) : + level_(MessagesToolbox::Convert(constraint.level)), + tag_(constraint.tagGroup, constraint.tagElement), + isIdentifier_(constraint.isIdentifierTag), + constraintType_(MessagesToolbox::Convert(constraint.type)), + caseSensitive_(constraint.isCaseSensitive), + mandatory_(constraint.isMandatory) + { + if (constraintType_ != ConstraintType_List && + constraint.valuesCount != 1) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + values_.resize(constraint.valuesCount); + + for (uint32_t i = 0; i < constraint.valuesCount; i++) + { + assert(constraint.values[i] != NULL); + values_[i].assign(constraint.values[i]); + } + } +#endif + + +#if ORTHANC_PLUGINS_HAS_INTEGRATED_FIND == 1 + DatabaseConstraint::DatabaseConstraint(const Orthanc::DatabasePluginMessages::DatabaseConstraint& constraint) : + level_(MessagesToolbox::Convert(constraint.level())), + tag_(constraint.tag_group(), constraint.tag_element()), + isIdentifier_(constraint.is_identifier_tag()), + caseSensitive_(constraint.is_case_sensitive()), + mandatory_(constraint.is_mandatory()) + { + switch (constraint.type()) + { + case Orthanc::DatabasePluginMessages::CONSTRAINT_EQUAL: + constraintType_ = ConstraintType_Equal; + break; + + case Orthanc::DatabasePluginMessages::CONSTRAINT_SMALLER_OR_EQUAL: + constraintType_ = ConstraintType_SmallerOrEqual; + break; + + case Orthanc::DatabasePluginMessages::CONSTRAINT_GREATER_OR_EQUAL: + constraintType_ = ConstraintType_GreaterOrEqual; + break; + + case Orthanc::DatabasePluginMessages::CONSTRAINT_WILDCARD: + constraintType_ = ConstraintType_Wildcard; + break; + + case Orthanc::DatabasePluginMessages::CONSTRAINT_LIST: + constraintType_ = ConstraintType_List; + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + if (constraintType_ != ConstraintType_List && + constraint.values().size() != 1) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + values_.resize(constraint.values().size()); + + for (int i = 0; i < constraint.values().size(); i++) + { + values_[i] = constraint.values(i); + } + } +#endif + + + const std::string& DatabaseConstraint::GetValue(size_t index) const + { + if (index >= values_.size()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + return values_[index]; + } + } + + + const std::string& DatabaseConstraint::GetSingleValue() const + { + if (values_.size() != 1) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + else + { + return values_[0]; + } + } + + +#if ORTHANC_PLUGINS_HAS_DATABASE_CONSTRAINT == 1 + void DatabaseConstraint::EncodeForPlugins(OrthancPluginDatabaseConstraint& constraint, + std::vector<const char*>& tmpValues) const + { + memset(&constraint, 0, sizeof(constraint)); + + tmpValues.resize(values_.size()); + + for (size_t i = 0; i < values_.size(); i++) + { + tmpValues[i] = values_[i].c_str(); + } + + constraint.level = MessagesToolbox::ConvertToPlainC(level_); + constraint.tagGroup = tag_.GetGroup(); + constraint.tagElement = tag_.GetElement(); + constraint.isIdentifierTag = isIdentifier_; + constraint.isCaseSensitive = caseSensitive_; + constraint.isMandatory = mandatory_; + constraint.type = MessagesToolbox::ConvertToPlainC(constraintType_); + constraint.valuesCount = values_.size(); + constraint.values = (tmpValues.empty() ? NULL : &tmpValues[0]); + } +#endif + + + void DatabaseConstraints::Clear() + { + for (size_t i = 0; i < constraints_.size(); i++) + { + assert(constraints_[i] != NULL); + delete constraints_[i]; + } + + constraints_.clear(); + } + + + void DatabaseConstraints::AddConstraint(DatabaseConstraint* constraint) + { + if (constraint == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + } + else + { + constraints_.push_back(constraint); + } + } + + + const DatabaseConstraint& DatabaseConstraints::GetConstraint(size_t index) const + { + if (index >= constraints_.size()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + assert(constraints_[index] != NULL); + return *constraints_[index]; + } + } + + + std::string DatabaseConstraints::Format() const + { + std::string s; + + for (size_t i = 0; i < constraints_.size(); i++) + { + assert(constraints_[i] != NULL); + const DatabaseConstraint& constraint = *constraints_[i]; + s += "Constraint " + boost::lexical_cast<std::string>(i) + " at " + EnumerationToString(constraint.GetLevel()) + + ": " + constraint.GetTag().Format(); + + switch (constraint.GetConstraintType()) + { + case ConstraintType_Equal: + s += " == " + constraint.GetSingleValue(); + break; + + case ConstraintType_SmallerOrEqual: + s += " <= " + constraint.GetSingleValue(); + break; + + case ConstraintType_GreaterOrEqual: + s += " >= " + constraint.GetSingleValue(); + break; + + case ConstraintType_Wildcard: + s += " ~~ " + constraint.GetSingleValue(); + break; + + case ConstraintType_List: + { + s += " in [ "; + bool first = true; + for (size_t j = 0; j < constraint.GetValuesCount(); j++) + { + if (first) + { + first = false; + } + else + { + s += ", "; + } + s += constraint.GetValue(j); + } + s += "]"; + break; + } + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + s += "\n"; + } + + return s; + } +}