comparison Framework/Plugins/DatabaseBackendAdapterV4.cpp @ 380:cb91096fef06 db-protobuf

implemented full protobuf api
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 30 Mar 2023 17:08:00 +0200
parents 33b2aaffdd6c
children 97f12bcd1826
comparison
equal deleted inserted replaced
379:33b2aaffdd6c 380:cb91096fef06
99 Orthanc::DatabasePluginMessages::GetExportedResources::Response* getExportedResources_; 99 Orthanc::DatabasePluginMessages::GetExportedResources::Response* getExportedResources_;
100 Orthanc::DatabasePluginMessages::GetLastChange::Response* getLastChange_; 100 Orthanc::DatabasePluginMessages::GetLastChange::Response* getLastChange_;
101 Orthanc::DatabasePluginMessages::GetLastExportedResource::Response* getLastExportedResource_; 101 Orthanc::DatabasePluginMessages::GetLastExportedResource::Response* getLastExportedResource_;
102 Orthanc::DatabasePluginMessages::GetMainDicomTags::Response* getMainDicomTags_; 102 Orthanc::DatabasePluginMessages::GetMainDicomTags::Response* getMainDicomTags_;
103 Orthanc::DatabasePluginMessages::LookupAttachment::Response* lookupAttachment_; 103 Orthanc::DatabasePluginMessages::LookupAttachment::Response* lookupAttachment_;
104 Orthanc::DatabasePluginMessages::LookupResources::Response* lookupResources_;
104 105
105 void Clear() 106 void Clear()
106 { 107 {
107 deleteAttachment_ = NULL; 108 deleteAttachment_ = NULL;
108 deleteResource_ = NULL; 109 deleteResource_ = NULL;
109 getChanges_ = NULL; 110 getChanges_ = NULL;
110 getExportedResources_ = NULL; 111 getExportedResources_ = NULL;
111 getLastChange_ = NULL; 112 getLastChange_ = NULL;
112 getLastExportedResource_ = NULL; 113 getLastExportedResource_ = NULL;
114 getMainDicomTags_ = NULL;
113 lookupAttachment_ = NULL; 115 lookupAttachment_ = NULL;
116 lookupResources_ = NULL;
114 } 117 }
115 118
116 public: 119 public:
117 Output(Orthanc::DatabasePluginMessages::DeleteAttachment::Response& deleteAttachment) 120 Output(Orthanc::DatabasePluginMessages::DeleteAttachment::Response& deleteAttachment)
118 { 121 {
158 161
159 Output(Orthanc::DatabasePluginMessages::LookupAttachment::Response& lookupAttachment) 162 Output(Orthanc::DatabasePluginMessages::LookupAttachment::Response& lookupAttachment)
160 { 163 {
161 Clear(); 164 Clear();
162 lookupAttachment_ = &lookupAttachment; 165 lookupAttachment_ = &lookupAttachment;
166 }
167
168 Output(Orthanc::DatabasePluginMessages::LookupResources::Response& lookupResources)
169 {
170 Clear();
171 lookupResources_ = &lookupResources;
163 } 172 }
164 173
165 virtual void SignalDeletedAttachment(const std::string& uuid, 174 virtual void SignalDeletedAttachment(const std::string& uuid,
166 int32_t contentType, 175 int32_t contentType,
167 uint64_t uncompressedSize, 176 uint64_t uncompressedSize,
305 const std::string& value) ORTHANC_OVERRIDE 314 const std::string& value) ORTHANC_OVERRIDE
306 { 315 {
307 if (getMainDicomTags_ != NULL) 316 if (getMainDicomTags_ != NULL)
308 { 317 {
309 Orthanc::DatabasePluginMessages::GetMainDicomTags_Response_Tag* tag = getMainDicomTags_->add_tags(); 318 Orthanc::DatabasePluginMessages::GetMainDicomTags_Response_Tag* tag = getMainDicomTags_->add_tags();
310 tag->set_key((static_cast<uint32_t>(group) << 16) + static_cast<uint32_t>(element)); 319 tag->set_group(group);
320 tag->set_element(element);
311 tag->set_value(value); 321 tag->set_value(value);
312 } 322 }
313 else 323 else
314 { 324 {
315 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); 325 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
358 resource->set_sop_instance_uid(sopInstanceUid); 368 resource->set_sop_instance_uid(sopInstanceUid);
359 } 369 }
360 370
361 virtual void AnswerMatchingResource(const std::string& resourceId) ORTHANC_OVERRIDE 371 virtual void AnswerMatchingResource(const std::string& resourceId) ORTHANC_OVERRIDE
362 { 372 {
363 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); 373 if (lookupResources_ != NULL)
374 {
375 lookupResources_->add_resources_ids(resourceId);
376 }
377 else
378 {
379 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
380 }
364 } 381 }
365 382
366 virtual void AnswerMatchingResource(const std::string& resourceId, 383 virtual void AnswerMatchingResource(const std::string& resourceId,
367 const std::string& someInstanceId) ORTHANC_OVERRIDE 384 const std::string& someInstanceId) ORTHANC_OVERRIDE
368 { 385 {
369 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); 386 if (lookupResources_ != NULL)
387 {
388 lookupResources_->add_resources_ids(resourceId);
389 lookupResources_->add_instances_ids(someInstanceId);
390 }
391 else
392 {
393 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
394 }
370 } 395 }
371 }; 396 };
372 397
373 398
374 static void ProcessDatabaseOperation(Orthanc::DatabasePluginMessages::DatabaseResponse& response, 399 static void ProcessDatabaseOperation(Orthanc::DatabasePluginMessages::DatabaseResponse& response,
436 461
437 default: 462 default:
438 LOG(ERROR) << "Not implemented database operation from protobuf: " << request.operation(); 463 LOG(ERROR) << "Not implemented database operation from protobuf: " << request.operation();
439 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 464 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
440 } 465 }
466 }
467
468
469 static void ApplyLookupResources(Orthanc::DatabasePluginMessages::LookupResources_Response& response,
470 const Orthanc::DatabasePluginMessages::LookupResources_Request& request,
471 IndexBackend& backend,
472 DatabaseManager& manager)
473 {
474 std::vector<Orthanc::DatabaseConstraint> lookup;
475 lookup.reserve(request.lookup().size());
476
477 size_t countValues = 0;
478
479 for (int i = 0; i < request.lookup().size(); i++)
480 {
481 const Orthanc::DatabasePluginMessages::DatabaseConstraint& constraint = request.lookup(i);
482 countValues += constraint.values().size();
483 }
484
485 std::vector<const char*> values;
486 values.reserve(countValues);
487
488 for (int i = 0; i < request.lookup().size(); i++)
489 {
490 const Orthanc::DatabasePluginMessages::DatabaseConstraint& constraint = request.lookup(i);
491
492 if (constraint.tag_group() > 0xffffu ||
493 constraint.tag_element() > 0xffffu)
494 {
495 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
496 }
497
498 OrthancPluginDatabaseConstraint c;
499 c.level = Convert(constraint.level());
500 c.tagGroup = constraint.tag_group();
501 c.tagElement = constraint.tag_element();
502 c.isIdentifierTag = (constraint.is_identifier_tag() ? 1 : 0);
503 c.isCaseSensitive = (constraint.is_case_sensitive() ? 1 : 0);
504 c.isMandatory = (constraint.is_mandatory() ? 1 : 0);
505
506 switch (constraint.type())
507 {
508 case Orthanc::DatabasePluginMessages::CONSTRAINT_EQUAL:
509 c.type = OrthancPluginConstraintType_Equal;
510 break;
511
512 case Orthanc::DatabasePluginMessages::CONSTRAINT_SMALLER_OR_EQUAL:
513 c.type = OrthancPluginConstraintType_SmallerOrEqual;
514 break;
515
516 case Orthanc::DatabasePluginMessages::CONSTRAINT_GREATER_OR_EQUAL:
517 c.type = OrthancPluginConstraintType_GreaterOrEqual;
518 break;
519
520 case Orthanc::DatabasePluginMessages::CONSTRAINT_WILDCARD:
521 c.type = OrthancPluginConstraintType_Wildcard;
522 break;
523
524 case Orthanc::DatabasePluginMessages::CONSTRAINT_LIST:
525 c.type = OrthancPluginConstraintType_List;
526 break;
527
528 default:
529 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
530 }
531
532 c.valuesCount = constraint.values().size();
533
534 if (c.valuesCount == 0)
535 {
536 c.values = NULL;
537 }
538 else
539 {
540 c.values = &values[values.size()];
541
542 for (int j = 0; j < constraint.values().size(); j++)
543 {
544 assert(values.size() < countValues);
545 values.push_back(constraint.values(j).c_str());
546 }
547 }
548
549 lookup.push_back(Orthanc::DatabaseConstraint(c));
550 }
551
552 assert(values.size() == countValues);
553
554 Output output(response);
555 backend.LookupResources(output, manager, lookup, Convert(request.query_level()),
556 request.limit(), request.retrieve_instances_ids());
441 } 557 }
442 558
443 559
444 static void ProcessTransactionOperation(Orthanc::DatabasePluginMessages::TransactionResponse& response, 560 static void ProcessTransactionOperation(Orthanc::DatabasePluginMessages::TransactionResponse& response,
445 const Orthanc::DatabasePluginMessages::TransactionRequest& request, 561 const Orthanc::DatabasePluginMessages::TransactionRequest& request,
857 bool above = (backend.GetTotalCompressedSize(manager) >= request.is_disk_size_above().threshold()); 973 bool above = (backend.GetTotalCompressedSize(manager) >= request.is_disk_size_above().threshold());
858 response.mutable_is_disk_size_above()->set_result(above); 974 response.mutable_is_disk_size_above()->set_result(above);
859 break; 975 break;
860 } 976 }
861 977
978 case Orthanc::DatabasePluginMessages::OPERATION_LOOKUP_RESOURCES:
979 {
980 ApplyLookupResources(*response.mutable_lookup_resources(), request.lookup_resources(), backend, manager);
981 break;
982 }
983
984 case Orthanc::DatabasePluginMessages::OPERATION_CREATE_INSTANCE:
985 {
986 const char* hashPatient = request.create_instance().patient().c_str();
987 const char* hashStudy = request.create_instance().study().c_str();
988 const char* hashSeries = request.create_instance().series().c_str();
989 const char* hashInstance = request.create_instance().instance().c_str();
990
991 OrthancPluginCreateInstanceResult result;
992
993 if (backend.HasCreateInstance())
994 {
995 backend.CreateInstance(result, manager, hashPatient, hashStudy, hashSeries, hashInstance);
996 }
997 else
998 {
999 backend.CreateInstanceGeneric(result, manager, hashPatient, hashStudy, hashSeries, hashInstance);
1000 }
1001
1002 response.mutable_create_instance()->set_is_new_instance(result.isNewInstance);
1003 response.mutable_create_instance()->set_instance_id(result.instanceId);
1004
1005 if (result.isNewInstance)
1006 {
1007 response.mutable_create_instance()->set_is_new_patient(result.isNewPatient);
1008 response.mutable_create_instance()->set_is_new_study(result.isNewStudy);
1009 response.mutable_create_instance()->set_is_new_series(result.isNewSeries);
1010 response.mutable_create_instance()->set_patient_id(result.patientId);
1011 response.mutable_create_instance()->set_study_id(result.studyId);
1012 response.mutable_create_instance()->set_series_id(result.seriesId);
1013 }
1014
1015 break;
1016 }
1017
1018 case Orthanc::DatabasePluginMessages::OPERATION_SET_RESOURCES_CONTENT:
1019 {
1020 std::vector<OrthancPluginResourcesContentTags> identifierTags;
1021 std::vector<OrthancPluginResourcesContentTags> mainDicomTags;
1022
1023 identifierTags.reserve(request.set_resources_content().tags().size());
1024 mainDicomTags.reserve(request.set_resources_content().tags().size());
1025
1026 for (int i = 0; i < request.set_resources_content().tags().size(); i++)
1027 {
1028 if (request.set_resources_content().tags(i).group() > 0xffff ||
1029 request.set_resources_content().tags(i).element() > 0xffff)
1030 {
1031 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
1032 }
1033
1034 OrthancPluginResourcesContentTags tag;
1035 tag.resource = request.set_resources_content().tags(i).resource_id();
1036 tag.group = request.set_resources_content().tags(i).group();
1037 tag.element = request.set_resources_content().tags(i).element();
1038 tag.value = request.set_resources_content().tags(i).value().c_str();
1039
1040 if (request.set_resources_content().tags(i).is_identifier())
1041 {
1042 identifierTags.push_back(tag);
1043 }
1044 else
1045 {
1046 mainDicomTags.push_back(tag);
1047 }
1048 }
1049
1050 std::vector<OrthancPluginResourcesContentMetadata> metadata(request.set_resources_content().metadata().size());
1051 for (int i = 0; i < request.set_resources_content().metadata().size(); i++)
1052 {
1053 OrthancPluginResourcesContentMetadata item;
1054 item.resource = request.set_resources_content().metadata(i).resource_id();
1055 item.metadata = request.set_resources_content().metadata(i).metadata();
1056 item.value = request.set_resources_content().metadata(i).value().c_str();
1057 metadata.push_back(item);
1058 }
1059
1060 backend.SetResourcesContent(manager,
1061 identifierTags.size(), (identifierTags.empty() ? NULL : &identifierTags[0]),
1062 mainDicomTags.size(), (mainDicomTags.empty() ? NULL : &mainDicomTags[0]),
1063 metadata.size(), (metadata.empty() ? NULL : &metadata[0]));
1064 break;
1065 }
1066
1067 case Orthanc::DatabasePluginMessages::OPERATION_GET_CHILDREN_METADATA:
1068 {
1069 std::list<std::string> values;
1070 backend.GetChildrenMetadata(values, manager, request.get_children_metadata().id(), request.get_children_metadata().metadata());
1071
1072 for (std::list<std::string>::const_iterator it = values.begin(); it != values.end(); ++it)
1073 {
1074 response.mutable_get_children_metadata()->add_values(*it);
1075 }
1076
1077 break;
1078 }
1079
1080 case Orthanc::DatabasePluginMessages::OPERATION_GET_LAST_CHANGE_INDEX:
1081 {
1082 response.mutable_get_last_change_index()->set_result(backend.GetLastChangeIndex(manager));
1083 break;
1084 }
1085
1086 case Orthanc::DatabasePluginMessages::OPERATION_LOOKUP_RESOURCE_AND_PARENT:
1087 {
1088 int64_t id;
1089 OrthancPluginResourceType type;
1090 std::string parent;
1091
1092 if (backend.LookupResourceAndParent(id, type, parent, manager, request.lookup_resource_and_parent().public_id().c_str()))
1093 {
1094 response.mutable_lookup_resource_and_parent()->set_found(true);
1095 response.mutable_lookup_resource_and_parent()->set_id(id);
1096 response.mutable_lookup_resource_and_parent()->set_type(Convert(type));
1097
1098 if (parent.empty())
1099 {
1100 response.mutable_lookup_resource_and_parent()->set_has_parent(true);
1101 }
1102 else
1103 {
1104 response.mutable_lookup_resource_and_parent()->set_has_parent(false);
1105 response.mutable_lookup_resource_and_parent()->set_parent_public_id(parent);
1106 }
1107 }
1108 else
1109 {
1110 response.mutable_lookup_resource_and_parent()->set_found(false);
1111 }
1112
1113 break;
1114 }
1115
862 default: 1116 default:
863 LOG(ERROR) << "Not implemented transaction operation from protobuf: " << request.operation(); 1117 LOG(ERROR) << "Not implemented transaction operation from protobuf: " << request.operation();
864 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 1118 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
865 } 1119 }
866 } 1120 }