# HG changeset patch # User Sebastien Jodogne # Date 1680510585 -7200 # Node ID 27e6ec2811e3202afd8cf3c5a3013dc72c1bae9d # Parent 6a7a244c777d31adcdfe99d7f4a20fc0c0e8701f completed first implementation of OrthancPluginDatabaseV4 diff -r 6a7a244c777d -r 27e6ec2811e3 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp Sun Apr 02 12:53:33 2023 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp Mon Apr 03 10:29:45 2023 +0200 @@ -29,9 +29,10 @@ #include "../../../OrthancFramework/Sources/Logging.h" #include "../../../OrthancFramework/Sources/OrthancException.h" +#include "../../Sources/Database/ResourcesContent.h" #include "PluginsEnumerations.h" -#include "OrthancDatabasePlugin.pb.h" +#include "OrthancDatabasePlugin.pb.h" // Auto-generated file #include @@ -659,6 +660,23 @@ int64_t id, FileContentType contentType) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_lookup_attachment()->set_id(id); + request.mutable_lookup_attachment()->set_content_type(contentType); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_ATTACHMENT, request); + + if (response.lookup_attachment().found()) + { + attachment = Convert(response.lookup_attachment().attachment()); + revision = response.lookup_attachment().revision(); + return true; + } + else + { + return false; + } } @@ -666,6 +684,22 @@ GlobalProperty property, bool shared) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_lookup_global_property()->set_server_id(shared ? "" : database_.GetServerIdentifier()); + request.mutable_lookup_global_property()->set_property(property); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_GLOBAL_PROPERTY, request); + + if (response.lookup_global_property().found()) + { + target = response.lookup_global_property().value(); + return true; + } + else + { + return false; + } } @@ -674,12 +708,44 @@ int64_t id, MetadataType type) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_lookup_metadata()->set_id(id); + request.mutable_lookup_metadata()->set_metadata_type(type); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_METADATA, request); + + if (response.lookup_metadata().found()) + { + target = response.lookup_metadata().value(); + revision = response.lookup_metadata().revision(); + return true; + } + else + { + return false; + } } virtual bool LookupParent(int64_t& parentId, int64_t resourceId) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_lookup_parent()->set_id(resourceId); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_PARENT, request); + + if (response.lookup_parent().found()) + { + parentId = response.lookup_parent().parent(); + return true; + } + else + { + return false; + } } @@ -687,17 +753,60 @@ ResourceType& type, const std::string& publicId) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_lookup_resource()->set_public_id(publicId); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCE, request); + + if (response.lookup_resource().found()) + { + id = response.lookup_resource().internal_id(); + type = Convert(response.lookup_resource().type()); + return true; + } + else + { + return false; + } } virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_SELECT_PATIENT_TO_RECYCLE); + + if (response.select_patient_to_recycle().found()) + { + internalId = response.select_patient_to_recycle().patient_id(); + return true; + } + else + { + return false; + } } virtual bool SelectPatientToRecycle(int64_t& internalId, int64_t patientIdToAvoid) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_select_patient_to_recycle_with_avoid()->set_patient_id_to_avoid(patientIdToAvoid); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_SELECT_PATIENT_TO_RECYCLE_WITH_AVOID, request); + + if (response.select_patient_to_recycle_with_avoid().found()) + { + internalId = response.select_patient_to_recycle_with_avoid().patient_id(); + return true; + } + else + { + return false; + } } @@ -705,11 +814,21 @@ bool shared, const std::string& value) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_set_global_property()->set_server_id(shared ? "" : database_.GetServerIdentifier()); + request.mutable_set_global_property()->set_property(property); + request.mutable_set_global_property()->set_value(value); + + ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_GLOBAL_PROPERTY, request); } virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_clear_main_dicom_tags()->set_id(id); + + ExecuteTransaction(DatabasePluginMessages::OPERATION_CLEAR_MAIN_DICOM_TAGS, request); } @@ -718,17 +837,36 @@ const std::string& value, int64_t revision) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_set_metadata()->set_id(id); + request.mutable_set_metadata()->set_metadata_type(type); + request.mutable_set_metadata()->set_value(value); + request.mutable_set_metadata()->set_revision(revision); + + ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_METADATA, request); } virtual void SetProtectedPatient(int64_t internalId, bool isProtected) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_set_protected_patient()->set_patient_id(internalId); + request.mutable_set_protected_patient()->set_protected_patient(isProtected); + + ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_PROTECTED_PATIENT, request); } virtual bool IsDiskSizeAbove(uint64_t threshold) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_is_disk_size_above()->set_threshold(threshold); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_IS_DISK_SIZE_ABOVE, request); + + return response.is_disk_size_above().result(); } @@ -738,6 +876,80 @@ ResourceType queryLevel, size_t limit) ORTHANC_OVERRIDE { + // TODO => "size_t limit" : uint32_t + + DatabasePluginMessages::TransactionRequest request; + request.mutable_lookup_resources()->set_query_level(Convert(queryLevel)); + request.mutable_lookup_resources()->set_limit(limit); + request.mutable_lookup_resources()->set_retrieve_instances_ids(instancesId != NULL); + + request.mutable_lookup_resources()->mutable_lookup()->Reserve(lookup.size()); + + for (size_t i = 0; i < lookup.size(); i++) + { + DatabasePluginMessages::DatabaseConstraint* constraint = request.mutable_lookup_resources()->add_lookup(); + constraint->set_level(Convert(lookup[i].GetLevel())); + constraint->set_tag_group(lookup[i].GetTag().GetGroup()); + constraint->set_tag_element(lookup[i].GetTag().GetElement()); + constraint->set_is_identifier_tag(lookup[i].IsIdentifier()); + constraint->set_is_case_sensitive(lookup[i].IsCaseSensitive()); + constraint->set_is_mandatory(lookup[i].IsMandatory()); + + constraint->mutable_values()->Reserve(lookup[i].GetValuesCount()); + for (size_t j = 0; j < lookup[i].GetValuesCount(); j++) + { + constraint->add_values(lookup[i].GetValue(j)); + } + + switch (lookup[i].GetConstraintType()) + { + case ConstraintType_Equal: + constraint->set_type(DatabasePluginMessages::CONSTRAINT_EQUAL); + break; + + case ConstraintType_SmallerOrEqual: + constraint->set_type(DatabasePluginMessages::CONSTRAINT_SMALLER_OR_EQUAL); + break; + + case ConstraintType_GreaterOrEqual: + constraint->set_type(DatabasePluginMessages::CONSTRAINT_GREATER_OR_EQUAL); + break; + + case ConstraintType_Wildcard: + constraint->set_type(DatabasePluginMessages::CONSTRAINT_WILDCARD); + break; + + case ConstraintType_List: + constraint->set_type(DatabasePluginMessages::CONSTRAINT_LIST); + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCES, request); + + for (int i = 0; i < response.lookup_resources().resources_ids().size(); i++) + { + resourcesId.push_back(response.lookup_resources().resources_ids(i)); + } + + if (instancesId != NULL) + { + if (response.lookup_resources().resources_ids().size() != response.lookup_resources().instances_ids().size()) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + else + { + for (int i = 0; i < response.lookup_resources().instances_ids().size(); i++) + { + instancesId->push_back(response.lookup_resources().instances_ids(i)); + } + } + } } @@ -748,11 +960,63 @@ const std::string& series, const std::string& instance) ORTHANC_OVERRIDE { + // TODO: "CreateInstanceResult" => constructor and getters + + DatabasePluginMessages::TransactionRequest request; + request.mutable_create_instance()->set_patient(patient); + request.mutable_create_instance()->set_study(study); + request.mutable_create_instance()->set_series(series); + request.mutable_create_instance()->set_instance(instance); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_CREATE_INSTANCE, request); + + instanceId = response.create_instance().instance_id(); + + if (response.create_instance().is_new_instance()) + { + result.isNewPatient_ = response.create_instance().is_new_patient(); + result.isNewStudy_ = response.create_instance().is_new_study(); + result.isNewSeries_ = response.create_instance().is_new_series(); + result.patientId_ = response.create_instance().patient_id(); + result.studyId_ = response.create_instance().study_id(); + result.seriesId_ = response.create_instance().series_id(); + return true; + } + else + { + return false; + } } virtual void SetResourcesContent(const ResourcesContent& content) ORTHANC_OVERRIDE { + // TODO: "ResourcesContent" => getters + + DatabasePluginMessages::TransactionRequest request; + + request.mutable_set_resources_content()->mutable_tags()->Reserve(content.GetListTags().size()); + for (ResourcesContent::ListTags::const_iterator it = content.GetListTags().begin(); it != content.GetListTags().end(); ++it) + { + DatabasePluginMessages::SetResourcesContent_Request_Tag* tag = request.mutable_set_resources_content()->add_tags(); + tag->set_resource_id(it->resourceId_); + tag->set_is_identifier(it->isIdentifier_); + tag->set_group(it->tag_.GetGroup()); + tag->set_element(it->tag_.GetElement()); + tag->set_value(it->value_); + } + + request.mutable_set_resources_content()->mutable_metadata()->Reserve(content.GetListMetadata().size()); + for (ResourcesContent::ListMetadata::const_iterator it = content.GetListMetadata().begin(); it != content.GetListMetadata().end(); ++it) + { + DatabasePluginMessages::SetResourcesContent_Request_Metadata* metadata = request.mutable_set_resources_content()->add_metadata(); + metadata->set_resource_id(it->resourceId_); + metadata->set_metadata(it->metadata_); + metadata->set_value(it->value_); + } + + ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_RESOURCES_CONTENT, request); } @@ -760,11 +1024,25 @@ int64_t resourceId, MetadataType metadata) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_get_children_metadata()->set_id(resourceId); + request.mutable_get_children_metadata()->set_metadata(metadata); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_CHILDREN_METADATA, request); + + for (int i = 0; i < response.get_children_metadata().values().size(); i++) + { + target.push_back(response.get_children_metadata().values(i)); + } } virtual int64_t GetLastChangeIndex() ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_LAST_CHANGE_INDEX); + return response.get_last_change_index().result(); } @@ -773,6 +1051,49 @@ std::string& parentPublicId, const std::string& publicId) ORTHANC_OVERRIDE { + DatabasePluginMessages::TransactionRequest request; + request.mutable_lookup_resource_and_parent()->set_public_id(publicId); + + DatabasePluginMessages::TransactionResponse response; + ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCE_AND_PARENT, request); + + if (response.lookup_resource_and_parent().found()) + { + id = response.lookup_resource_and_parent().id(); + type = Convert(response.lookup_resource_and_parent().type()); + + switch (type) + { + case ResourceType_Patient: + if (!response.lookup_resource_and_parent().parent_public_id().empty()) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + break; + + case ResourceType_Study: + case ResourceType_Series: + case ResourceType_Instance: + if (response.lookup_resource_and_parent().parent_public_id().empty()) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + else + { + parentPublicId = response.lookup_resource_and_parent().parent_public_id(); + } + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + + return true; + } + else + { + return false; + } } }; diff -r 6a7a244c777d -r 27e6ec2811e3 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h Sun Apr 02 12:53:33 2023 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h Mon Apr 03 10:29:45 2023 +0200 @@ -65,6 +65,11 @@ return errorDictionary_; } + const std::string& GetServerIdentifier() const + { + return serverIdentifier_; + } + virtual void Open() ORTHANC_OVERRIDE; virtual void Close() ORTHANC_OVERRIDE; diff -r 6a7a244c777d -r 27e6ec2811e3 OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto --- a/OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto Sun Apr 02 12:53:33 2023 +0200 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto Mon Apr 03 10:29:45 2023 +0200 @@ -726,8 +726,7 @@ bool found = 1; int64 id = 2; ResourceType type = 3; - bool has_parent = 4; - string parent_public_id = 5; + string parent_public_id = 4; // Only for study, series, or instance } }