Mercurial > hg > orthanc
comparison OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp @ 5211:27e6ec2811e3 db-protobuf
completed first implementation of OrthancPluginDatabaseV4
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 03 Apr 2023 10:29:45 +0200 |
parents | 6a7a244c777d |
children | 055428d92772 |
comparison
equal
deleted
inserted
replaced
5210:6a7a244c777d | 5211:27e6ec2811e3 |
---|---|
27 # error The plugin support is disabled | 27 # error The plugin support is disabled |
28 #endif | 28 #endif |
29 | 29 |
30 #include "../../../OrthancFramework/Sources/Logging.h" | 30 #include "../../../OrthancFramework/Sources/Logging.h" |
31 #include "../../../OrthancFramework/Sources/OrthancException.h" | 31 #include "../../../OrthancFramework/Sources/OrthancException.h" |
32 #include "../../Sources/Database/ResourcesContent.h" | |
32 #include "PluginsEnumerations.h" | 33 #include "PluginsEnumerations.h" |
33 | 34 |
34 #include "OrthancDatabasePlugin.pb.h" | 35 #include "OrthancDatabasePlugin.pb.h" // Auto-generated file |
35 | 36 |
36 #include <cassert> | 37 #include <cassert> |
37 | 38 |
38 | 39 |
39 namespace Orthanc | 40 namespace Orthanc |
657 virtual bool LookupAttachment(FileInfo& attachment, | 658 virtual bool LookupAttachment(FileInfo& attachment, |
658 int64_t& revision, | 659 int64_t& revision, |
659 int64_t id, | 660 int64_t id, |
660 FileContentType contentType) ORTHANC_OVERRIDE | 661 FileContentType contentType) ORTHANC_OVERRIDE |
661 { | 662 { |
663 DatabasePluginMessages::TransactionRequest request; | |
664 request.mutable_lookup_attachment()->set_id(id); | |
665 request.mutable_lookup_attachment()->set_content_type(contentType); | |
666 | |
667 DatabasePluginMessages::TransactionResponse response; | |
668 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_ATTACHMENT, request); | |
669 | |
670 if (response.lookup_attachment().found()) | |
671 { | |
672 attachment = Convert(response.lookup_attachment().attachment()); | |
673 revision = response.lookup_attachment().revision(); | |
674 return true; | |
675 } | |
676 else | |
677 { | |
678 return false; | |
679 } | |
662 } | 680 } |
663 | 681 |
664 | 682 |
665 virtual bool LookupGlobalProperty(std::string& target, | 683 virtual bool LookupGlobalProperty(std::string& target, |
666 GlobalProperty property, | 684 GlobalProperty property, |
667 bool shared) ORTHANC_OVERRIDE | 685 bool shared) ORTHANC_OVERRIDE |
668 { | 686 { |
687 DatabasePluginMessages::TransactionRequest request; | |
688 request.mutable_lookup_global_property()->set_server_id(shared ? "" : database_.GetServerIdentifier()); | |
689 request.mutable_lookup_global_property()->set_property(property); | |
690 | |
691 DatabasePluginMessages::TransactionResponse response; | |
692 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_GLOBAL_PROPERTY, request); | |
693 | |
694 if (response.lookup_global_property().found()) | |
695 { | |
696 target = response.lookup_global_property().value(); | |
697 return true; | |
698 } | |
699 else | |
700 { | |
701 return false; | |
702 } | |
669 } | 703 } |
670 | 704 |
671 | 705 |
672 virtual bool LookupMetadata(std::string& target, | 706 virtual bool LookupMetadata(std::string& target, |
673 int64_t& revision, | 707 int64_t& revision, |
674 int64_t id, | 708 int64_t id, |
675 MetadataType type) ORTHANC_OVERRIDE | 709 MetadataType type) ORTHANC_OVERRIDE |
676 { | 710 { |
711 DatabasePluginMessages::TransactionRequest request; | |
712 request.mutable_lookup_metadata()->set_id(id); | |
713 request.mutable_lookup_metadata()->set_metadata_type(type); | |
714 | |
715 DatabasePluginMessages::TransactionResponse response; | |
716 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_METADATA, request); | |
717 | |
718 if (response.lookup_metadata().found()) | |
719 { | |
720 target = response.lookup_metadata().value(); | |
721 revision = response.lookup_metadata().revision(); | |
722 return true; | |
723 } | |
724 else | |
725 { | |
726 return false; | |
727 } | |
677 } | 728 } |
678 | 729 |
679 | 730 |
680 virtual bool LookupParent(int64_t& parentId, | 731 virtual bool LookupParent(int64_t& parentId, |
681 int64_t resourceId) ORTHANC_OVERRIDE | 732 int64_t resourceId) ORTHANC_OVERRIDE |
682 { | 733 { |
734 DatabasePluginMessages::TransactionRequest request; | |
735 request.mutable_lookup_parent()->set_id(resourceId); | |
736 | |
737 DatabasePluginMessages::TransactionResponse response; | |
738 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_PARENT, request); | |
739 | |
740 if (response.lookup_parent().found()) | |
741 { | |
742 parentId = response.lookup_parent().parent(); | |
743 return true; | |
744 } | |
745 else | |
746 { | |
747 return false; | |
748 } | |
683 } | 749 } |
684 | 750 |
685 | 751 |
686 virtual bool LookupResource(int64_t& id, | 752 virtual bool LookupResource(int64_t& id, |
687 ResourceType& type, | 753 ResourceType& type, |
688 const std::string& publicId) ORTHANC_OVERRIDE | 754 const std::string& publicId) ORTHANC_OVERRIDE |
689 { | 755 { |
756 DatabasePluginMessages::TransactionRequest request; | |
757 request.mutable_lookup_resource()->set_public_id(publicId); | |
758 | |
759 DatabasePluginMessages::TransactionResponse response; | |
760 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCE, request); | |
761 | |
762 if (response.lookup_resource().found()) | |
763 { | |
764 id = response.lookup_resource().internal_id(); | |
765 type = Convert(response.lookup_resource().type()); | |
766 return true; | |
767 } | |
768 else | |
769 { | |
770 return false; | |
771 } | |
690 } | 772 } |
691 | 773 |
692 | 774 |
693 virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE | 775 virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE |
694 { | 776 { |
777 DatabasePluginMessages::TransactionResponse response; | |
778 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_SELECT_PATIENT_TO_RECYCLE); | |
779 | |
780 if (response.select_patient_to_recycle().found()) | |
781 { | |
782 internalId = response.select_patient_to_recycle().patient_id(); | |
783 return true; | |
784 } | |
785 else | |
786 { | |
787 return false; | |
788 } | |
695 } | 789 } |
696 | 790 |
697 | 791 |
698 virtual bool SelectPatientToRecycle(int64_t& internalId, | 792 virtual bool SelectPatientToRecycle(int64_t& internalId, |
699 int64_t patientIdToAvoid) ORTHANC_OVERRIDE | 793 int64_t patientIdToAvoid) ORTHANC_OVERRIDE |
700 { | 794 { |
795 DatabasePluginMessages::TransactionRequest request; | |
796 request.mutable_select_patient_to_recycle_with_avoid()->set_patient_id_to_avoid(patientIdToAvoid); | |
797 | |
798 DatabasePluginMessages::TransactionResponse response; | |
799 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_SELECT_PATIENT_TO_RECYCLE_WITH_AVOID, request); | |
800 | |
801 if (response.select_patient_to_recycle_with_avoid().found()) | |
802 { | |
803 internalId = response.select_patient_to_recycle_with_avoid().patient_id(); | |
804 return true; | |
805 } | |
806 else | |
807 { | |
808 return false; | |
809 } | |
701 } | 810 } |
702 | 811 |
703 | 812 |
704 virtual void SetGlobalProperty(GlobalProperty property, | 813 virtual void SetGlobalProperty(GlobalProperty property, |
705 bool shared, | 814 bool shared, |
706 const std::string& value) ORTHANC_OVERRIDE | 815 const std::string& value) ORTHANC_OVERRIDE |
707 { | 816 { |
817 DatabasePluginMessages::TransactionRequest request; | |
818 request.mutable_set_global_property()->set_server_id(shared ? "" : database_.GetServerIdentifier()); | |
819 request.mutable_set_global_property()->set_property(property); | |
820 request.mutable_set_global_property()->set_value(value); | |
821 | |
822 ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_GLOBAL_PROPERTY, request); | |
708 } | 823 } |
709 | 824 |
710 | 825 |
711 virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE | 826 virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE |
712 { | 827 { |
828 DatabasePluginMessages::TransactionRequest request; | |
829 request.mutable_clear_main_dicom_tags()->set_id(id); | |
830 | |
831 ExecuteTransaction(DatabasePluginMessages::OPERATION_CLEAR_MAIN_DICOM_TAGS, request); | |
713 } | 832 } |
714 | 833 |
715 | 834 |
716 virtual void SetMetadata(int64_t id, | 835 virtual void SetMetadata(int64_t id, |
717 MetadataType type, | 836 MetadataType type, |
718 const std::string& value, | 837 const std::string& value, |
719 int64_t revision) ORTHANC_OVERRIDE | 838 int64_t revision) ORTHANC_OVERRIDE |
720 { | 839 { |
840 DatabasePluginMessages::TransactionRequest request; | |
841 request.mutable_set_metadata()->set_id(id); | |
842 request.mutable_set_metadata()->set_metadata_type(type); | |
843 request.mutable_set_metadata()->set_value(value); | |
844 request.mutable_set_metadata()->set_revision(revision); | |
845 | |
846 ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_METADATA, request); | |
721 } | 847 } |
722 | 848 |
723 | 849 |
724 virtual void SetProtectedPatient(int64_t internalId, | 850 virtual void SetProtectedPatient(int64_t internalId, |
725 bool isProtected) ORTHANC_OVERRIDE | 851 bool isProtected) ORTHANC_OVERRIDE |
726 { | 852 { |
853 DatabasePluginMessages::TransactionRequest request; | |
854 request.mutable_set_protected_patient()->set_patient_id(internalId); | |
855 request.mutable_set_protected_patient()->set_protected_patient(isProtected); | |
856 | |
857 ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_PROTECTED_PATIENT, request); | |
727 } | 858 } |
728 | 859 |
729 | 860 |
730 virtual bool IsDiskSizeAbove(uint64_t threshold) ORTHANC_OVERRIDE | 861 virtual bool IsDiskSizeAbove(uint64_t threshold) ORTHANC_OVERRIDE |
731 { | 862 { |
863 DatabasePluginMessages::TransactionRequest request; | |
864 request.mutable_is_disk_size_above()->set_threshold(threshold); | |
865 | |
866 DatabasePluginMessages::TransactionResponse response; | |
867 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_IS_DISK_SIZE_ABOVE, request); | |
868 | |
869 return response.is_disk_size_above().result(); | |
732 } | 870 } |
733 | 871 |
734 | 872 |
735 virtual void ApplyLookupResources(std::list<std::string>& resourcesId, | 873 virtual void ApplyLookupResources(std::list<std::string>& resourcesId, |
736 std::list<std::string>* instancesId, // Can be NULL if not needed | 874 std::list<std::string>* instancesId, // Can be NULL if not needed |
737 const std::vector<DatabaseConstraint>& lookup, | 875 const std::vector<DatabaseConstraint>& lookup, |
738 ResourceType queryLevel, | 876 ResourceType queryLevel, |
739 size_t limit) ORTHANC_OVERRIDE | 877 size_t limit) ORTHANC_OVERRIDE |
740 { | 878 { |
879 // TODO => "size_t limit" : uint32_t | |
880 | |
881 DatabasePluginMessages::TransactionRequest request; | |
882 request.mutable_lookup_resources()->set_query_level(Convert(queryLevel)); | |
883 request.mutable_lookup_resources()->set_limit(limit); | |
884 request.mutable_lookup_resources()->set_retrieve_instances_ids(instancesId != NULL); | |
885 | |
886 request.mutable_lookup_resources()->mutable_lookup()->Reserve(lookup.size()); | |
887 | |
888 for (size_t i = 0; i < lookup.size(); i++) | |
889 { | |
890 DatabasePluginMessages::DatabaseConstraint* constraint = request.mutable_lookup_resources()->add_lookup(); | |
891 constraint->set_level(Convert(lookup[i].GetLevel())); | |
892 constraint->set_tag_group(lookup[i].GetTag().GetGroup()); | |
893 constraint->set_tag_element(lookup[i].GetTag().GetElement()); | |
894 constraint->set_is_identifier_tag(lookup[i].IsIdentifier()); | |
895 constraint->set_is_case_sensitive(lookup[i].IsCaseSensitive()); | |
896 constraint->set_is_mandatory(lookup[i].IsMandatory()); | |
897 | |
898 constraint->mutable_values()->Reserve(lookup[i].GetValuesCount()); | |
899 for (size_t j = 0; j < lookup[i].GetValuesCount(); j++) | |
900 { | |
901 constraint->add_values(lookup[i].GetValue(j)); | |
902 } | |
903 | |
904 switch (lookup[i].GetConstraintType()) | |
905 { | |
906 case ConstraintType_Equal: | |
907 constraint->set_type(DatabasePluginMessages::CONSTRAINT_EQUAL); | |
908 break; | |
909 | |
910 case ConstraintType_SmallerOrEqual: | |
911 constraint->set_type(DatabasePluginMessages::CONSTRAINT_SMALLER_OR_EQUAL); | |
912 break; | |
913 | |
914 case ConstraintType_GreaterOrEqual: | |
915 constraint->set_type(DatabasePluginMessages::CONSTRAINT_GREATER_OR_EQUAL); | |
916 break; | |
917 | |
918 case ConstraintType_Wildcard: | |
919 constraint->set_type(DatabasePluginMessages::CONSTRAINT_WILDCARD); | |
920 break; | |
921 | |
922 case ConstraintType_List: | |
923 constraint->set_type(DatabasePluginMessages::CONSTRAINT_LIST); | |
924 break; | |
925 | |
926 default: | |
927 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
928 } | |
929 } | |
930 | |
931 DatabasePluginMessages::TransactionResponse response; | |
932 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCES, request); | |
933 | |
934 for (int i = 0; i < response.lookup_resources().resources_ids().size(); i++) | |
935 { | |
936 resourcesId.push_back(response.lookup_resources().resources_ids(i)); | |
937 } | |
938 | |
939 if (instancesId != NULL) | |
940 { | |
941 if (response.lookup_resources().resources_ids().size() != response.lookup_resources().instances_ids().size()) | |
942 { | |
943 throw OrthancException(ErrorCode_DatabasePlugin); | |
944 } | |
945 else | |
946 { | |
947 for (int i = 0; i < response.lookup_resources().instances_ids().size(); i++) | |
948 { | |
949 instancesId->push_back(response.lookup_resources().instances_ids(i)); | |
950 } | |
951 } | |
952 } | |
741 } | 953 } |
742 | 954 |
743 | 955 |
744 virtual bool CreateInstance(CreateInstanceResult& result, /* out */ | 956 virtual bool CreateInstance(CreateInstanceResult& result, /* out */ |
745 int64_t& instanceId, /* out */ | 957 int64_t& instanceId, /* out */ |
746 const std::string& patient, | 958 const std::string& patient, |
747 const std::string& study, | 959 const std::string& study, |
748 const std::string& series, | 960 const std::string& series, |
749 const std::string& instance) ORTHANC_OVERRIDE | 961 const std::string& instance) ORTHANC_OVERRIDE |
750 { | 962 { |
963 // TODO: "CreateInstanceResult" => constructor and getters | |
964 | |
965 DatabasePluginMessages::TransactionRequest request; | |
966 request.mutable_create_instance()->set_patient(patient); | |
967 request.mutable_create_instance()->set_study(study); | |
968 request.mutable_create_instance()->set_series(series); | |
969 request.mutable_create_instance()->set_instance(instance); | |
970 | |
971 DatabasePluginMessages::TransactionResponse response; | |
972 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_CREATE_INSTANCE, request); | |
973 | |
974 instanceId = response.create_instance().instance_id(); | |
975 | |
976 if (response.create_instance().is_new_instance()) | |
977 { | |
978 result.isNewPatient_ = response.create_instance().is_new_patient(); | |
979 result.isNewStudy_ = response.create_instance().is_new_study(); | |
980 result.isNewSeries_ = response.create_instance().is_new_series(); | |
981 result.patientId_ = response.create_instance().patient_id(); | |
982 result.studyId_ = response.create_instance().study_id(); | |
983 result.seriesId_ = response.create_instance().series_id(); | |
984 return true; | |
985 } | |
986 else | |
987 { | |
988 return false; | |
989 } | |
751 } | 990 } |
752 | 991 |
753 | 992 |
754 virtual void SetResourcesContent(const ResourcesContent& content) ORTHANC_OVERRIDE | 993 virtual void SetResourcesContent(const ResourcesContent& content) ORTHANC_OVERRIDE |
755 { | 994 { |
995 // TODO: "ResourcesContent" => getters | |
996 | |
997 DatabasePluginMessages::TransactionRequest request; | |
998 | |
999 request.mutable_set_resources_content()->mutable_tags()->Reserve(content.GetListTags().size()); | |
1000 for (ResourcesContent::ListTags::const_iterator it = content.GetListTags().begin(); it != content.GetListTags().end(); ++it) | |
1001 { | |
1002 DatabasePluginMessages::SetResourcesContent_Request_Tag* tag = request.mutable_set_resources_content()->add_tags(); | |
1003 tag->set_resource_id(it->resourceId_); | |
1004 tag->set_is_identifier(it->isIdentifier_); | |
1005 tag->set_group(it->tag_.GetGroup()); | |
1006 tag->set_element(it->tag_.GetElement()); | |
1007 tag->set_value(it->value_); | |
1008 } | |
1009 | |
1010 request.mutable_set_resources_content()->mutable_metadata()->Reserve(content.GetListMetadata().size()); | |
1011 for (ResourcesContent::ListMetadata::const_iterator it = content.GetListMetadata().begin(); it != content.GetListMetadata().end(); ++it) | |
1012 { | |
1013 DatabasePluginMessages::SetResourcesContent_Request_Metadata* metadata = request.mutable_set_resources_content()->add_metadata(); | |
1014 metadata->set_resource_id(it->resourceId_); | |
1015 metadata->set_metadata(it->metadata_); | |
1016 metadata->set_value(it->value_); | |
1017 } | |
1018 | |
1019 ExecuteTransaction(DatabasePluginMessages::OPERATION_SET_RESOURCES_CONTENT, request); | |
756 } | 1020 } |
757 | 1021 |
758 | 1022 |
759 virtual void GetChildrenMetadata(std::list<std::string>& target, | 1023 virtual void GetChildrenMetadata(std::list<std::string>& target, |
760 int64_t resourceId, | 1024 int64_t resourceId, |
761 MetadataType metadata) ORTHANC_OVERRIDE | 1025 MetadataType metadata) ORTHANC_OVERRIDE |
762 { | 1026 { |
1027 DatabasePluginMessages::TransactionRequest request; | |
1028 request.mutable_get_children_metadata()->set_id(resourceId); | |
1029 request.mutable_get_children_metadata()->set_metadata(metadata); | |
1030 | |
1031 DatabasePluginMessages::TransactionResponse response; | |
1032 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_CHILDREN_METADATA, request); | |
1033 | |
1034 for (int i = 0; i < response.get_children_metadata().values().size(); i++) | |
1035 { | |
1036 target.push_back(response.get_children_metadata().values(i)); | |
1037 } | |
763 } | 1038 } |
764 | 1039 |
765 | 1040 |
766 virtual int64_t GetLastChangeIndex() ORTHANC_OVERRIDE | 1041 virtual int64_t GetLastChangeIndex() ORTHANC_OVERRIDE |
767 { | 1042 { |
1043 DatabasePluginMessages::TransactionResponse response; | |
1044 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_GET_LAST_CHANGE_INDEX); | |
1045 return response.get_last_change_index().result(); | |
768 } | 1046 } |
769 | 1047 |
770 | 1048 |
771 virtual bool LookupResourceAndParent(int64_t& id, | 1049 virtual bool LookupResourceAndParent(int64_t& id, |
772 ResourceType& type, | 1050 ResourceType& type, |
773 std::string& parentPublicId, | 1051 std::string& parentPublicId, |
774 const std::string& publicId) ORTHANC_OVERRIDE | 1052 const std::string& publicId) ORTHANC_OVERRIDE |
775 { | 1053 { |
1054 DatabasePluginMessages::TransactionRequest request; | |
1055 request.mutable_lookup_resource_and_parent()->set_public_id(publicId); | |
1056 | |
1057 DatabasePluginMessages::TransactionResponse response; | |
1058 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCE_AND_PARENT, request); | |
1059 | |
1060 if (response.lookup_resource_and_parent().found()) | |
1061 { | |
1062 id = response.lookup_resource_and_parent().id(); | |
1063 type = Convert(response.lookup_resource_and_parent().type()); | |
1064 | |
1065 switch (type) | |
1066 { | |
1067 case ResourceType_Patient: | |
1068 if (!response.lookup_resource_and_parent().parent_public_id().empty()) | |
1069 { | |
1070 throw OrthancException(ErrorCode_DatabasePlugin); | |
1071 } | |
1072 break; | |
1073 | |
1074 case ResourceType_Study: | |
1075 case ResourceType_Series: | |
1076 case ResourceType_Instance: | |
1077 if (response.lookup_resource_and_parent().parent_public_id().empty()) | |
1078 { | |
1079 throw OrthancException(ErrorCode_DatabasePlugin); | |
1080 } | |
1081 else | |
1082 { | |
1083 parentPublicId = response.lookup_resource_and_parent().parent_public_id(); | |
1084 } | |
1085 break; | |
1086 | |
1087 default: | |
1088 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1089 } | |
1090 | |
1091 return true; | |
1092 } | |
1093 else | |
1094 { | |
1095 return false; | |
1096 } | |
776 } | 1097 } |
777 }; | 1098 }; |
778 | 1099 |
779 | 1100 |
780 OrthancPluginDatabaseV4::OrthancPluginDatabaseV4(SharedLibrary& library, | 1101 OrthancPluginDatabaseV4::OrthancPluginDatabaseV4(SharedLibrary& library, |