# HG changeset patch # User Sebastien Jodogne # Date 1714764366 -7200 # Node ID 1e2631b8b9af6edc3282969b75bf6c2013ef2855 # Parent 043c8016ed6a7987e8c403a365e5c1f0f868bef0 GenericFind::Execute() is working for a basic request diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/Database/Compatibility/GenericFind.cpp --- a/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp Fri May 03 21:26:06 2024 +0200 @@ -22,6 +22,7 @@ #include "GenericFind.h" +#include "../../../../OrthancFramework/Sources/DicomFormat/DicomArray.h" #include "../../../../OrthancFramework/Sources/OrthancException.h" @@ -38,10 +39,6 @@ !request.GetOrthancIdentifiers().HasInstanceId() && request.GetDicomTagConstraintsCount() == 0 && request.GetMetadataConstraintsCount() == 0 && - !request.IsRetrieveTagsAtLevel(ResourceType_Patient) && - !request.IsRetrieveTagsAtLevel(ResourceType_Study) && - !request.IsRetrieveTagsAtLevel(ResourceType_Series) && - !request.IsRetrieveTagsAtLevel(ResourceType_Instance) && request.GetOrdering().empty() && request.GetLabels().empty()) { @@ -58,7 +55,53 @@ for (std::list::const_iterator it = ids.begin(); it != ids.end(); ++it) { - response.Add(new FindResponse::Resource(request.GetLevel(), *it)); + int64_t internalId; + ResourceType t; + if (!transaction_.LookupResource(internalId, t, *it) || + t != request.GetLevel()) + { + throw OrthancException(ErrorCode_InternalError); + } + + std::unique_ptr resource(new FindResponse::Resource(request.GetLevel(), *it)); + + if (request.IsRetrieveMainDicomTags()) + { + DicomMap m; + transaction_.GetMainDicomTags(m, internalId); + + DicomArray a(m); + for (size_t i = 0; i < a.GetSize(); i++) + { + const DicomElement& element = a.GetElement(i); + if (element.GetValue().IsString()) + { + resource->AddStringDicomTag(element.GetTag().GetGroup(), element.GetTag().GetElement(), + element.GetValue().GetContent()); + } + else + { + throw OrthancException(ErrorCode_BadParameterType); + } + } + } + + if (request.IsRetrieveParentIdentifier()) + { + int64_t parentId; + if (transaction_.LookupParent(parentId, internalId)) + { + resource->SetParentIdentifier(transaction_.GetPublicId(parentId)); + } + else + { + throw OrthancException(ErrorCode_InternalError); + } + } + + // TODO-FIND: Continue + + response.Add(resource.release()); } } else @@ -75,10 +118,10 @@ { const FindResponse::Resource& resource = response.GetResource(i); - if (request.IsRetrieveTagsAtLevel(request.GetLevel())) + if (request.IsRetrieveMainDicomTags()) { DicomMap tmp; - resource.GetDicomTagsAtLevel(tmp, request.GetLevel()); + resource.GetMainDicomTags(tmp); if (tmp.GetSize() == 0) { throw OrthancException(ErrorCode_InternalError); diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/Database/FindRequest.cpp --- a/OrthancServer/Sources/Database/FindRequest.cpp Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/Database/FindRequest.cpp Fri May 03 21:26:06 2024 +0200 @@ -29,43 +29,12 @@ namespace Orthanc { - bool FindRequest::IsCompatibleLevel(ResourceType levelOfInterest) const - { - switch (level_) - { - case ResourceType_Patient: - return (levelOfInterest == ResourceType_Patient); - - case ResourceType_Study: - return (levelOfInterest == ResourceType_Patient || - levelOfInterest == ResourceType_Study); - - case ResourceType_Series: - return (levelOfInterest == ResourceType_Patient || - levelOfInterest == ResourceType_Study || - levelOfInterest == ResourceType_Series); - - case ResourceType_Instance: - return (levelOfInterest == ResourceType_Patient || - levelOfInterest == ResourceType_Study || - levelOfInterest == ResourceType_Series || - levelOfInterest == ResourceType_Instance); - - default: - throw OrthancException(ErrorCode_ParameterOutOfRange); - } - } - - FindRequest::FindRequest(ResourceType level) : level_(level), hasLimits_(false), limitsSince_(0), limitsCount_(0), - retrievePatientTags_(false), - retrieveStudyTags_(false), - retrieveSeriesTags_(false), - retrieveInstanceTags_(false), + retrieveMainDicomTags_(false), retrieveMetadata_(false), retrieveLabels_(false), retrieveAttachments_(false), @@ -146,66 +115,13 @@ } - void FindRequest::SetRetrieveTagsAtLevel(ResourceType levelOfInterest, - bool retrieve) - { - if (!IsCompatibleLevel(levelOfInterest)) - { - throw OrthancException(ErrorCode_ParameterOutOfRange); - } - - switch (levelOfInterest) - { - case ResourceType_Patient: - retrievePatientTags_ = true; - break; - - case ResourceType_Study: - retrieveStudyTags_ = true; - break; - - case ResourceType_Series: - retrieveSeriesTags_ = true; - break; - - case ResourceType_Instance: - retrieveInstanceTags_ = true; - break; - - default: - throw OrthancException(ErrorCode_ParameterOutOfRange); - } - } - - - bool FindRequest::IsRetrieveTagsAtLevel(ResourceType levelOfInterest) const - { - switch (levelOfInterest) - { - case ResourceType_Patient: - return retrievePatientTags_; - - case ResourceType_Study: - return retrieveStudyTags_; - - case ResourceType_Series: - return retrieveSeriesTags_; - - case ResourceType_Instance: - return retrieveInstanceTags_; - - default: - throw OrthancException(ErrorCode_ParameterOutOfRange); - } - } - - void FindRequest::AddOrdering(const DicomTag& tag, OrderingDirection direction) { ordering_.push_back(new Ordering(Key(tag), direction)); } + void FindRequest::AddOrdering(MetadataType metadataType, OrderingDirection direction) { diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/Database/FindRequest.h --- a/OrthancServer/Sources/Database/FindRequest.h Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/Database/FindRequest.h Fri May 03 21:26:06 2024 +0200 @@ -165,11 +165,7 @@ LabelsConstraint labelsContraint_; std::deque ordering_; // The ordering criteria (note: the order is important !) - bool retrievePatientTags_; - bool retrieveStudyTags_; - bool retrieveSeriesTags_; - bool retrieveInstanceTags_; - + bool retrieveMainDicomTags_; bool retrieveMetadata_; bool retrieveLabels_; bool retrieveAttachments_; @@ -177,8 +173,6 @@ bool retrieveChildrenIdentifiers_; bool retrieveChildrenMetadata_; - bool IsCompatibleLevel(ResourceType levelOfInterest) const; - public: explicit FindRequest(ResourceType level); @@ -240,11 +234,6 @@ uint64_t GetLimitsCount() const; - void SetRetrieveTagsAtLevel(ResourceType levelOfInterest, - bool retrieve); - - bool IsRetrieveTagsAtLevel(ResourceType levelOfInterest) const; - void AddOrdering(const DicomTag& tag, OrderingDirection direction); void AddOrdering(MetadataType metadataType, OrderingDirection direction); @@ -274,6 +263,16 @@ retrieveMetadata_ = retrieve; } + bool IsRetrieveMainDicomTags() const + { + return retrieveMainDicomTags_; + } + + void SetRetrieveMainDicomTags(bool retrieve) + { + retrieveMainDicomTags_ = retrieve; + } + bool IsRetrieveMetadata() const { return retrieveMetadata_; diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/Database/FindResponse.cpp --- a/OrthancServer/Sources/Database/FindResponse.cpp Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/Database/FindResponse.cpp Fri May 03 21:26:06 2024 +0200 @@ -30,7 +30,7 @@ namespace Orthanc { - class FindResponse::DicomTagsAtLevel::DicomValue : public boost::noncopyable + class FindResponse::Resource::DicomValue : public boost::noncopyable { public: enum ValueType @@ -73,24 +73,14 @@ }; - FindResponse::DicomTagsAtLevel::~DicomTagsAtLevel() - { - for (Content::iterator it = content_.begin(); it != content_.end(); ++it) - { - assert(it->second != NULL); - delete it->second; - } - } - - - void FindResponse::DicomTagsAtLevel::AddNullValue(uint16_t group, - uint16_t element) + void FindResponse::Resource::AddNullDicomTag(uint16_t group, + uint16_t element) { const DicomTag tag(group, element); - if (content_.find(tag) == content_.end()) + if (mainDicomTags_.find(tag) == mainDicomTags_.end()) { - content_[tag] = new DicomValue(DicomValue::ValueType_Null, ""); + mainDicomTags_[tag] = new DicomValue(DicomValue::ValueType_Null, ""); } else { @@ -99,15 +89,15 @@ } - void FindResponse::DicomTagsAtLevel::AddStringValue(uint16_t group, - uint16_t element, - const std::string& value) + void FindResponse::Resource::AddStringDicomTag(uint16_t group, + uint16_t element, + const std::string& value) { const DicomTag tag(group, element); - if (content_.find(tag) == content_.end()) + if (mainDicomTags_.find(tag) == mainDicomTags_.end()) { - content_[tag] = new DicomValue(DicomValue::ValueType_String, value); + mainDicomTags_[tag] = new DicomValue(DicomValue::ValueType_String, value); } else { @@ -116,9 +106,9 @@ } - void FindResponse::DicomTagsAtLevel::Fill(DicomMap& target) const + void FindResponse::Resource::GetMainDicomTags(DicomMap& target) const { - for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it) + for (MainDicomTags::const_iterator it = mainDicomTags_.begin(); it != mainDicomTags_.end(); ++it) { assert(it->second != NULL); @@ -152,28 +142,6 @@ } - FindResponse::DicomTagsAtLevel& FindResponse::Resource::GetDicomTagsAtLevel(ResourceType level) - { - switch (level) - { - case ResourceType_Patient: - return patientTags_; - - case ResourceType_Study: - return studyTags_; - - case ResourceType_Series: - return seriesTags_; - - case ResourceType_Instance: - return instanceTags_; - - default: - throw OrthancException(ErrorCode_ParameterOutOfRange); - } - } - - FindResponse::ChildrenAtLevel& FindResponse::Resource::GetChildrenAtLevel(ResourceType level) { switch (level) @@ -275,6 +243,16 @@ } + FindResponse::Resource::~Resource() + { + for (MainDicomTags::iterator it = mainDicomTags_.begin(); it != mainDicomTags_.end(); ++it) + { + assert(it->second != NULL); + delete it->second; + } + } + + void FindResponse::Resource::SetParentIdentifier(const std::string& id) { if (level_ == ResourceType_Patient) diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/Database/FindResponse.h --- a/OrthancServer/Sources/Database/FindResponse.h Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/Database/FindResponse.h Fri May 03 21:26:06 2024 +0200 @@ -41,29 +41,6 @@ class FindResponse : public boost::noncopyable { private: - class DicomTagsAtLevel : public boost::noncopyable - { - private: - class DicomValue; - - typedef std::map Content; - - Content content_; - - public: - ~DicomTagsAtLevel(); - - void AddNullValue(uint16_t group, - uint16_t element); - - void AddStringValue(uint16_t group, - uint16_t element, - const std::string& value); - - void Fill(DicomMap& target) const; - }; - - class ChildrenAtLevel : public boost::noncopyable { private: @@ -83,13 +60,14 @@ class Resource : public boost::noncopyable { private: + class DicomValue; + + typedef std::map MainDicomTags; + ResourceType level_; std::string identifier_; std::unique_ptr parentIdentifier_; - DicomTagsAtLevel patientTags_; - DicomTagsAtLevel studyTags_; - DicomTagsAtLevel seriesTags_; - DicomTagsAtLevel instanceTags_; + MainDicomTags mainDicomTags_; ChildrenAtLevel childrenStudies_; ChildrenAtLevel childrenSeries_; ChildrenAtLevel childrenInstances_; @@ -97,18 +75,18 @@ std::map metadata_; std::map attachments_; - DicomTagsAtLevel& GetDicomTagsAtLevel(ResourceType level); - ChildrenAtLevel& GetChildrenAtLevel(ResourceType level); public: - explicit Resource(ResourceType level, - const std::string& identifier) : + Resource(ResourceType level, + const std::string& identifier) : level_(level), identifier_(identifier) { } + ~Resource(); + ResourceType GetLevel() const { return level_; @@ -125,29 +103,16 @@ bool HasParentIdentifier() const; - void AddStringDicomTag(ResourceType level, - uint16_t group, + void AddStringDicomTag(uint16_t group, uint16_t element, - const std::string& value) - { - GetDicomTagsAtLevel(level).AddStringValue(group, element, value); - } + const std::string& value); // The "Null" value could be used in the future to indicate a // value that is not available, typically a new "ExtraMainDicomTag" - void AddNullDicomTag(ResourceType level, - uint16_t group, - uint16_t element, - const std::string& value) - { - GetDicomTagsAtLevel(level).AddNullValue(group, element); - } + void AddNullDicomTag(uint16_t group, + uint16_t element); - void GetDicomTagsAtLevel(DicomMap& target, - ResourceType level) const - { - const_cast(*this).GetDicomTagsAtLevel(level).Fill(target); - } + void GetMainDicomTags(DicomMap& target) const; void AddChildIdentifier(ResourceType level, const std::string& childId) diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Fri May 03 21:26:06 2024 +0200 @@ -1188,7 +1188,7 @@ } // request Each response content through INNER JOIN with the temporary table - if (request.IsRetrieveTagsAtLevel(request.GetLevel())) + if (request.IsRetrieveMainDicomTags()) { // TODO-FIND: handle the case where we request tags from multiple levels SQLite::Statement statement(db_, SQLITE_FROM_HERE, @@ -1200,8 +1200,7 @@ { const std::string& resourceId = statement.ColumnString(0); assert(response.HasResource(resourceId)); - response.GetResource(resourceId).AddStringDicomTag(request.GetLevel(), - statement.ColumnInt(1), + response.GetResource(resourceId).AddStringDicomTag(statement.ColumnInt(1), statement.ColumnInt(2), statement.ColumnString(3)); } diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp --- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp Fri May 03 21:26:06 2024 +0200 @@ -3877,9 +3877,9 @@ throw OrthancException(ErrorCode_InternalError); } - if (request.IsRetrieveTagsAtLevel(request.GetLevel())) + if (request.IsRetrieveMainDicomTags()) { - resource.GetDicomTagsAtLevel(tags_, request.GetLevel()); + resource.GetMainDicomTags(tags_); } if (request.IsRetrieveChildrenIdentifiers()) diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Fri May 03 21:26:06 2024 +0200 @@ -245,7 +245,7 @@ if (expand) { // compatibility with default expand option - request.SetRetrieveTagsAtLevel(resourceType, true); + request.SetRetrieveMainDicomTags(true); request.SetRetrieveMetadata(true); request.SetRetrieveLabels(true); @@ -267,11 +267,6 @@ { request.SetRetrieveParentIdentifier(true); } - - if (resourceType == ResourceType_Study) - { - request.SetRetrieveTagsAtLevel(ResourceType_Patient, true); - } } if (call.HasArgument("limit") || diff -r 043c8016ed6a -r 1e2631b8b9af OrthancServer/Sources/ServerContext.cpp --- a/OrthancServer/Sources/ServerContext.cpp Fri May 03 18:30:29 2024 +0200 +++ b/OrthancServer/Sources/ServerContext.cpp Fri May 03 21:26:06 2024 +0200 @@ -2736,7 +2736,7 @@ { expandFlags = static_cast(expandFlags | ExpandResourceFlags_IncludeAllMetadata | ExpandResourceFlags_IncludeMetadata ); } - if (request.IsRetrieveTagsAtLevel(request.GetLevel())) + if (request.IsRetrieveMainDicomTags()) { expandFlags = static_cast(expandFlags | ExpandResourceFlags_IncludeMainDicomTags); }