# HG changeset patch # User Sebastien Jodogne # Date 1680188880 -7200 # Node ID cb91096fef06a6cc6e2d1c95f4adf733ec8c5c97 # Parent 33b2aaffdd6c40c48fdc09991813847f7024c1de implemented full protobuf api diff -r 33b2aaffdd6c -r cb91096fef06 Framework/Plugins/DatabaseBackendAdapterV4.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV4.cpp Wed Mar 29 08:47:35 2023 +0200 +++ b/Framework/Plugins/DatabaseBackendAdapterV4.cpp Thu Mar 30 17:08:00 2023 +0200 @@ -101,6 +101,7 @@ Orthanc::DatabasePluginMessages::GetLastExportedResource::Response* getLastExportedResource_; Orthanc::DatabasePluginMessages::GetMainDicomTags::Response* getMainDicomTags_; Orthanc::DatabasePluginMessages::LookupAttachment::Response* lookupAttachment_; + Orthanc::DatabasePluginMessages::LookupResources::Response* lookupResources_; void Clear() { @@ -110,7 +111,9 @@ getExportedResources_ = NULL; getLastChange_ = NULL; getLastExportedResource_ = NULL; + getMainDicomTags_ = NULL; lookupAttachment_ = NULL; + lookupResources_ = NULL; } public: @@ -162,6 +165,12 @@ lookupAttachment_ = &lookupAttachment; } + Output(Orthanc::DatabasePluginMessages::LookupResources::Response& lookupResources) + { + Clear(); + lookupResources_ = &lookupResources; + } + virtual void SignalDeletedAttachment(const std::string& uuid, int32_t contentType, uint64_t uncompressedSize, @@ -307,7 +316,8 @@ if (getMainDicomTags_ != NULL) { Orthanc::DatabasePluginMessages::GetMainDicomTags_Response_Tag* tag = getMainDicomTags_->add_tags(); - tag->set_key((static_cast(group) << 16) + static_cast(element)); + tag->set_group(group); + tag->set_element(element); tag->set_value(value); } else @@ -360,13 +370,28 @@ virtual void AnswerMatchingResource(const std::string& resourceId) ORTHANC_OVERRIDE { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + if (lookupResources_ != NULL) + { + lookupResources_->add_resources_ids(resourceId); + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } } virtual void AnswerMatchingResource(const std::string& resourceId, const std::string& someInstanceId) ORTHANC_OVERRIDE { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + if (lookupResources_ != NULL) + { + lookupResources_->add_resources_ids(resourceId); + lookupResources_->add_instances_ids(someInstanceId); + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } } }; @@ -440,6 +465,97 @@ } } + + static void ApplyLookupResources(Orthanc::DatabasePluginMessages::LookupResources_Response& response, + const Orthanc::DatabasePluginMessages::LookupResources_Request& request, + IndexBackend& backend, + DatabaseManager& manager) + { + std::vector lookup; + lookup.reserve(request.lookup().size()); + + size_t countValues = 0; + + for (int i = 0; i < request.lookup().size(); i++) + { + const Orthanc::DatabasePluginMessages::DatabaseConstraint& constraint = request.lookup(i); + countValues += constraint.values().size(); + } + + std::vector values; + values.reserve(countValues); + + for (int i = 0; i < request.lookup().size(); i++) + { + const Orthanc::DatabasePluginMessages::DatabaseConstraint& constraint = request.lookup(i); + + if (constraint.tag_group() > 0xffffu || + constraint.tag_element() > 0xffffu) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + OrthancPluginDatabaseConstraint c; + c.level = Convert(constraint.level()); + c.tagGroup = constraint.tag_group(); + c.tagElement = constraint.tag_element(); + c.isIdentifierTag = (constraint.is_identifier_tag() ? 1 : 0); + c.isCaseSensitive = (constraint.is_case_sensitive() ? 1 : 0); + c.isMandatory = (constraint.is_mandatory() ? 1 : 0); + + switch (constraint.type()) + { + case Orthanc::DatabasePluginMessages::CONSTRAINT_EQUAL: + c.type = OrthancPluginConstraintType_Equal; + break; + + case Orthanc::DatabasePluginMessages::CONSTRAINT_SMALLER_OR_EQUAL: + c.type = OrthancPluginConstraintType_SmallerOrEqual; + break; + + case Orthanc::DatabasePluginMessages::CONSTRAINT_GREATER_OR_EQUAL: + c.type = OrthancPluginConstraintType_GreaterOrEqual; + break; + + case Orthanc::DatabasePluginMessages::CONSTRAINT_WILDCARD: + c.type = OrthancPluginConstraintType_Wildcard; + break; + + case Orthanc::DatabasePluginMessages::CONSTRAINT_LIST: + c.type = OrthancPluginConstraintType_List; + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + c.valuesCount = constraint.values().size(); + + if (c.valuesCount == 0) + { + c.values = NULL; + } + else + { + c.values = &values[values.size()]; + + for (int j = 0; j < constraint.values().size(); j++) + { + assert(values.size() < countValues); + values.push_back(constraint.values(j).c_str()); + } + } + + lookup.push_back(Orthanc::DatabaseConstraint(c)); + } + + assert(values.size() == countValues); + + Output output(response); + backend.LookupResources(output, manager, lookup, Convert(request.query_level()), + request.limit(), request.retrieve_instances_ids()); + } + static void ProcessTransactionOperation(Orthanc::DatabasePluginMessages::TransactionResponse& response, const Orthanc::DatabasePluginMessages::TransactionRequest& request, @@ -859,6 +975,144 @@ break; } + case Orthanc::DatabasePluginMessages::OPERATION_LOOKUP_RESOURCES: + { + ApplyLookupResources(*response.mutable_lookup_resources(), request.lookup_resources(), backend, manager); + break; + } + + case Orthanc::DatabasePluginMessages::OPERATION_CREATE_INSTANCE: + { + const char* hashPatient = request.create_instance().patient().c_str(); + const char* hashStudy = request.create_instance().study().c_str(); + const char* hashSeries = request.create_instance().series().c_str(); + const char* hashInstance = request.create_instance().instance().c_str(); + + OrthancPluginCreateInstanceResult result; + + if (backend.HasCreateInstance()) + { + backend.CreateInstance(result, manager, hashPatient, hashStudy, hashSeries, hashInstance); + } + else + { + backend.CreateInstanceGeneric(result, manager, hashPatient, hashStudy, hashSeries, hashInstance); + } + + response.mutable_create_instance()->set_is_new_instance(result.isNewInstance); + response.mutable_create_instance()->set_instance_id(result.instanceId); + + if (result.isNewInstance) + { + response.mutable_create_instance()->set_is_new_patient(result.isNewPatient); + response.mutable_create_instance()->set_is_new_study(result.isNewStudy); + response.mutable_create_instance()->set_is_new_series(result.isNewSeries); + response.mutable_create_instance()->set_patient_id(result.patientId); + response.mutable_create_instance()->set_study_id(result.studyId); + response.mutable_create_instance()->set_series_id(result.seriesId); + } + + break; + } + + case Orthanc::DatabasePluginMessages::OPERATION_SET_RESOURCES_CONTENT: + { + std::vector identifierTags; + std::vector mainDicomTags; + + identifierTags.reserve(request.set_resources_content().tags().size()); + mainDicomTags.reserve(request.set_resources_content().tags().size()); + + for (int i = 0; i < request.set_resources_content().tags().size(); i++) + { + if (request.set_resources_content().tags(i).group() > 0xffff || + request.set_resources_content().tags(i).element() > 0xffff) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + OrthancPluginResourcesContentTags tag; + tag.resource = request.set_resources_content().tags(i).resource_id(); + tag.group = request.set_resources_content().tags(i).group(); + tag.element = request.set_resources_content().tags(i).element(); + tag.value = request.set_resources_content().tags(i).value().c_str(); + + if (request.set_resources_content().tags(i).is_identifier()) + { + identifierTags.push_back(tag); + } + else + { + mainDicomTags.push_back(tag); + } + } + + std::vector metadata(request.set_resources_content().metadata().size()); + for (int i = 0; i < request.set_resources_content().metadata().size(); i++) + { + OrthancPluginResourcesContentMetadata item; + item.resource = request.set_resources_content().metadata(i).resource_id(); + item.metadata = request.set_resources_content().metadata(i).metadata(); + item.value = request.set_resources_content().metadata(i).value().c_str(); + metadata.push_back(item); + } + + backend.SetResourcesContent(manager, + identifierTags.size(), (identifierTags.empty() ? NULL : &identifierTags[0]), + mainDicomTags.size(), (mainDicomTags.empty() ? NULL : &mainDicomTags[0]), + metadata.size(), (metadata.empty() ? NULL : &metadata[0])); + break; + } + + case Orthanc::DatabasePluginMessages::OPERATION_GET_CHILDREN_METADATA: + { + std::list values; + backend.GetChildrenMetadata(values, manager, request.get_children_metadata().id(), request.get_children_metadata().metadata()); + + for (std::list::const_iterator it = values.begin(); it != values.end(); ++it) + { + response.mutable_get_children_metadata()->add_values(*it); + } + + break; + } + + case Orthanc::DatabasePluginMessages::OPERATION_GET_LAST_CHANGE_INDEX: + { + response.mutable_get_last_change_index()->set_result(backend.GetLastChangeIndex(manager)); + break; + } + + case Orthanc::DatabasePluginMessages::OPERATION_LOOKUP_RESOURCE_AND_PARENT: + { + int64_t id; + OrthancPluginResourceType type; + std::string parent; + + if (backend.LookupResourceAndParent(id, type, parent, manager, request.lookup_resource_and_parent().public_id().c_str())) + { + response.mutable_lookup_resource_and_parent()->set_found(true); + response.mutable_lookup_resource_and_parent()->set_id(id); + response.mutable_lookup_resource_and_parent()->set_type(Convert(type)); + + if (parent.empty()) + { + response.mutable_lookup_resource_and_parent()->set_has_parent(true); + } + else + { + response.mutable_lookup_resource_and_parent()->set_has_parent(false); + response.mutable_lookup_resource_and_parent()->set_parent_public_id(parent); + } + } + else + { + response.mutable_lookup_resource_and_parent()->set_found(false); + } + + break; + } + default: LOG(ERROR) << "Not implemented transaction operation from protobuf: " << request.operation(); throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);