comparison OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp @ 5725:95a3802ad133 find-refactoring

initial implementation of protobuf for find
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 19 Jul 2024 14:02:22 +0200
parents 89d559e67b03
children ca06dde85358
comparison
equal deleted inserted replaced
5724:b7bf515864a2 5725:95a3802ad133
133 source.series_instance_uid(), 133 source.series_instance_uid(),
134 source.sop_instance_uid()); 134 source.sop_instance_uid());
135 } 135 }
136 136
137 137
138 static void Convert(DatabasePluginMessages::DatabaseConstraint& target,
139 const DatabaseConstraint& source)
140 {
141 target.set_level(Convert(source.GetLevel()));
142 target.set_tag_group(source.GetTag().GetGroup());
143 target.set_tag_element(source.GetTag().GetElement());
144 target.set_is_identifier_tag(source.IsIdentifier());
145 target.set_is_case_sensitive(source.IsCaseSensitive());
146 target.set_is_mandatory(source.IsMandatory());
147
148 target.mutable_values()->Reserve(source.GetValuesCount());
149 for (size_t j = 0; j < source.GetValuesCount(); j++)
150 {
151 target.add_values(source.GetValue(j));
152 }
153
154 switch (source.GetConstraintType())
155 {
156 case ConstraintType_Equal:
157 target.set_type(DatabasePluginMessages::CONSTRAINT_EQUAL);
158 break;
159
160 case ConstraintType_SmallerOrEqual:
161 target.set_type(DatabasePluginMessages::CONSTRAINT_SMALLER_OR_EQUAL);
162 break;
163
164 case ConstraintType_GreaterOrEqual:
165 target.set_type(DatabasePluginMessages::CONSTRAINT_GREATER_OR_EQUAL);
166 break;
167
168 case ConstraintType_Wildcard:
169 target.set_type(DatabasePluginMessages::CONSTRAINT_WILDCARD);
170 break;
171
172 case ConstraintType_List:
173 target.set_type(DatabasePluginMessages::CONSTRAINT_LIST);
174 break;
175
176 default:
177 throw OrthancException(ErrorCode_ParameterOutOfRange);
178 }
179 }
180
181
182 static DatabasePluginMessages::LabelsConstraintType Convert(LabelsConstraint constraint)
183 {
184 switch (constraint)
185 {
186 case LabelsConstraint_All:
187 return DatabasePluginMessages::LABELS_CONSTRAINT_ALL;
188
189 case LabelsConstraint_Any:
190 return DatabasePluginMessages::LABELS_CONSTRAINT_ANY;
191
192 case LabelsConstraint_None:
193 return DatabasePluginMessages::LABELS_CONSTRAINT_NONE;
194
195 default:
196 throw OrthancException(ErrorCode_ParameterOutOfRange);
197 }
198 }
199
200
201 static void Convert(DatabasePluginMessages::Find_Request_ChildrenSpecification& target,
202 const FindRequest::ChildrenSpecification& source)
203 {
204 target.set_retrieve_identifiers(source.IsRetrieveIdentifiers());
205
206 for (std::set<MetadataType>::const_iterator it = source.GetMetadata().begin(); it != source.GetMetadata().end(); ++it)
207 {
208 target.add_retrieve_metadata(*it);
209 }
210
211 for (std::set<DicomTag>::const_iterator it = source.GetMainDicomTags().begin(); it != source.GetMainDicomTags().end(); ++it)
212 {
213 DatabasePluginMessages::Find_Request_Tag* tag = target.add_retrieve_main_dicom_tags();
214 tag->set_group(it->GetGroup());
215 tag->set_element(it->GetElement());
216 }
217 }
218
219
220 static void Convert(FindResponse::Resource& target,
221 ResourceType level,
222 const DatabasePluginMessages::Find_Response_ResourceContent& source)
223 {
224 for (int i = 0; i < source.main_dicom_tags().size(); i++)
225 {
226 target.AddStringDicomTag(level, source.main_dicom_tags(i).group(),
227 source.main_dicom_tags(i).element(), source.main_dicom_tags(i).value());
228 }
229
230 for (int i = 0; i < source.metadata().size(); i++)
231 {
232 target.AddMetadata(level, static_cast<MetadataType>(source.metadata(i).key()), source.metadata(i).value());
233 }
234 }
235
236
237 static void Convert(FindResponse::Resource& target,
238 ResourceType level,
239 const DatabasePluginMessages::Find_Response_ChildrenContent& source)
240 {
241 for (int i = 0; i < source.identifiers().size(); i++)
242 {
243 target.AddChildIdentifier(level, source.identifiers(i));
244 }
245
246 for (int i = 0; i < source.main_dicom_tags().size(); i++)
247 {
248 const DicomTag tag(source.main_dicom_tags(i).group(), source.main_dicom_tags(i).element());
249
250 for (int j = 0; j < source.main_dicom_tags(i).values().size(); j++)
251 {
252 target.AddChildrenMainDicomTagValue(level, tag, source.main_dicom_tags(i).values(j));
253 }
254 }
255
256 for (int i = 0; i < source.metadata().size(); i++)
257 {
258 MetadataType key = static_cast<MetadataType>(source.metadata(i).key());
259
260 for (int j = 0; j < source.metadata(i).values().size(); j++)
261 {
262 target.AddChildrenMetadataValue(level, key, source.metadata(i).values(j));
263 }
264 }
265 }
266
267
138 static void Execute(DatabasePluginMessages::Response& response, 268 static void Execute(DatabasePluginMessages::Response& response,
139 const OrthancPluginDatabaseV4& database, 269 const OrthancPluginDatabaseV4& database,
140 const DatabasePluginMessages::Request& request) 270 const DatabasePluginMessages::Request& request)
141 { 271 {
142 std::string requestSerialized; 272 std::string requestSerialized;
971 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_IS_DISK_SIZE_ABOVE, request); 1101 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_IS_DISK_SIZE_ABOVE, request);
972 1102
973 return response.is_disk_size_above().result(); 1103 return response.is_disk_size_above().result();
974 } 1104 }
975 1105
976 1106
977 virtual void ApplyLookupResources(std::list<std::string>& resourcesId, 1107 virtual void ApplyLookupResources(std::list<std::string>& resourcesId,
978 std::list<std::string>* instancesId, // Can be NULL if not needed 1108 std::list<std::string>* instancesId, // Can be NULL if not needed
979 const DatabaseConstraints& lookup, 1109 const DatabaseConstraints& lookup,
980 ResourceType queryLevel, 1110 ResourceType queryLevel,
981 const std::set<std::string>& labels, 1111 const std::set<std::string>& labels,
995 1125
996 request.mutable_lookup_resources()->mutable_lookup()->Reserve(lookup.GetSize()); 1126 request.mutable_lookup_resources()->mutable_lookup()->Reserve(lookup.GetSize());
997 1127
998 for (size_t i = 0; i < lookup.GetSize(); i++) 1128 for (size_t i = 0; i < lookup.GetSize(); i++)
999 { 1129 {
1000 const DatabaseConstraint& source = lookup.GetConstraint(i); 1130 Convert(*request.mutable_lookup_resources()->add_lookup(), lookup.GetConstraint(i));
1001
1002 DatabasePluginMessages::DatabaseConstraint* target = request.mutable_lookup_resources()->add_lookup();
1003 target->set_level(Convert(source.GetLevel()));
1004 target->set_tag_group(source.GetTag().GetGroup());
1005 target->set_tag_element(source.GetTag().GetElement());
1006 target->set_is_identifier_tag(source.IsIdentifier());
1007 target->set_is_case_sensitive(source.IsCaseSensitive());
1008 target->set_is_mandatory(source.IsMandatory());
1009
1010 target->mutable_values()->Reserve(source.GetValuesCount());
1011 for (size_t j = 0; j < source.GetValuesCount(); j++)
1012 {
1013 target->add_values(source.GetValue(j));
1014 }
1015
1016 switch (source.GetConstraintType())
1017 {
1018 case ConstraintType_Equal:
1019 target->set_type(DatabasePluginMessages::CONSTRAINT_EQUAL);
1020 break;
1021
1022 case ConstraintType_SmallerOrEqual:
1023 target->set_type(DatabasePluginMessages::CONSTRAINT_SMALLER_OR_EQUAL);
1024 break;
1025
1026 case ConstraintType_GreaterOrEqual:
1027 target->set_type(DatabasePluginMessages::CONSTRAINT_GREATER_OR_EQUAL);
1028 break;
1029
1030 case ConstraintType_Wildcard:
1031 target->set_type(DatabasePluginMessages::CONSTRAINT_WILDCARD);
1032 break;
1033
1034 case ConstraintType_List:
1035 target->set_type(DatabasePluginMessages::CONSTRAINT_LIST);
1036 break;
1037
1038 default:
1039 throw OrthancException(ErrorCode_ParameterOutOfRange);
1040 }
1041 } 1131 }
1042 1132
1043 for (std::set<std::string>::const_iterator it = labels.begin(); it != labels.end(); ++it) 1133 for (std::set<std::string>::const_iterator it = labels.begin(); it != labels.end(); ++it)
1044 { 1134 {
1045 request.mutable_lookup_resources()->add_labels(*it); 1135 request.mutable_lookup_resources()->add_labels(*it);
1046 } 1136 }
1047 1137
1048 switch (labelsConstraint) 1138 request.mutable_lookup_resources()->set_labels_constraint(Convert(labelsConstraint));
1049 {
1050 case LabelsConstraint_All:
1051 request.mutable_lookup_resources()->set_labels_constraint(DatabasePluginMessages::LABELS_CONSTRAINT_ALL);
1052 break;
1053
1054 case LabelsConstraint_Any:
1055 request.mutable_lookup_resources()->set_labels_constraint(DatabasePluginMessages::LABELS_CONSTRAINT_ANY);
1056 break;
1057
1058 case LabelsConstraint_None:
1059 request.mutable_lookup_resources()->set_labels_constraint(DatabasePluginMessages::LABELS_CONSTRAINT_NONE);
1060 break;
1061
1062 default:
1063 throw OrthancException(ErrorCode_ParameterOutOfRange);
1064 }
1065 1139
1066 DatabasePluginMessages::TransactionResponse response; 1140 DatabasePluginMessages::TransactionResponse response;
1067 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCES, request); 1141 ExecuteTransaction(response, DatabasePluginMessages::OPERATION_LOOKUP_RESOURCES, request);
1068 1142
1069 for (int i = 0; i < response.lookup_resources().resources_ids().size(); i++) 1143 for (int i = 0; i < response.lookup_resources().resources_ids().size(); i++)
1283 1357
1284 virtual void ExecuteFind(FindResponse& response, 1358 virtual void ExecuteFind(FindResponse& response,
1285 const FindRequest& request, 1359 const FindRequest& request,
1286 const Capabilities& capabilities) ORTHANC_OVERRIDE 1360 const Capabilities& capabilities) ORTHANC_OVERRIDE
1287 { 1361 {
1288 // TODO-FIND 1362 if (capabilities.HasFindSupport())
1289 throw OrthancException(ErrorCode_NotImplemented); 1363 {
1364 DatabasePluginMessages::TransactionRequest dbRequest;
1365 dbRequest.mutable_find()->set_level(Convert(request.GetLevel()));
1366
1367 if (request.GetOrthancIdentifiers().HasPatientId())
1368 {
1369 dbRequest.mutable_find()->set_orthanc_id_patient(request.GetOrthancIdentifiers().GetPatientId());
1370 }
1371
1372 if (request.GetOrthancIdentifiers().HasStudyId())
1373 {
1374 dbRequest.mutable_find()->set_orthanc_id_study(request.GetOrthancIdentifiers().GetStudyId());
1375 }
1376
1377 if (request.GetOrthancIdentifiers().HasSeriesId())
1378 {
1379 dbRequest.mutable_find()->set_orthanc_id_series(request.GetOrthancIdentifiers().GetSeriesId());
1380 }
1381
1382 if (request.GetOrthancIdentifiers().HasInstanceId())
1383 {
1384 dbRequest.mutable_find()->set_orthanc_id_instance(request.GetOrthancIdentifiers().GetInstanceId());
1385 }
1386
1387 for (size_t i = 0; i < request.GetDicomTagConstraints().GetSize(); i++)
1388 {
1389 Convert(*dbRequest.mutable_find()->add_dicom_tag_constraints(), request.GetDicomTagConstraints().GetConstraint(i));
1390 }
1391
1392 if (request.HasLimits())
1393 {
1394 dbRequest.mutable_find()->mutable_limits()->set_since(request.GetLimitsSince());
1395 dbRequest.mutable_find()->mutable_limits()->set_count(request.GetLimitsCount());
1396 }
1397
1398 for (std::set<std::string>::const_iterator it = request.GetLabels().begin(); it != request.GetLabels().end(); ++it)
1399 {
1400 dbRequest.mutable_find()->add_labels(*it);
1401 }
1402
1403 dbRequest.mutable_find()->set_labels_constraint(Convert(request.GetLabelsConstraint()));
1404
1405 // TODO-FIND: ordering_
1406 // TODO-FIND: metadataConstraints__
1407
1408 dbRequest.mutable_find()->set_retrieve_main_dicom_tags(request.IsRetrieveMainDicomTags());
1409 dbRequest.mutable_find()->set_retrieve_metadata(request.IsRetrieveMetadata());
1410 dbRequest.mutable_find()->set_retrieve_labels(request.IsRetrieveLabels());
1411 dbRequest.mutable_find()->set_retrieve_attachments(request.IsRetrieveAttachments());
1412 dbRequest.mutable_find()->set_retrieve_parent_identifier(request.IsRetrieveParentIdentifier());
1413 dbRequest.mutable_find()->set_retrieve_at_least_one_instance(request.IsRetrieveOneInstanceIdentifier());
1414
1415 if (request.GetLevel() == ResourceType_Study ||
1416 request.GetLevel() == ResourceType_Series ||
1417 request.GetLevel() == ResourceType_Instance)
1418 {
1419 dbRequest.mutable_find()->mutable_parent_patient()->set_retrieve_main_dicom_tags(request.GetParentSpecification(ResourceType_Patient).IsRetrieveMainDicomTags());
1420 dbRequest.mutable_find()->mutable_parent_patient()->set_retrieve_metadata(request.GetParentSpecification(ResourceType_Patient).IsRetrieveMetadata());
1421 }
1422
1423 if (request.GetLevel() == ResourceType_Series ||
1424 request.GetLevel() == ResourceType_Instance)
1425 {
1426 dbRequest.mutable_find()->mutable_parent_study()->set_retrieve_main_dicom_tags(request.GetParentSpecification(ResourceType_Study).IsRetrieveMainDicomTags());
1427 dbRequest.mutable_find()->mutable_parent_study()->set_retrieve_metadata(request.GetParentSpecification(ResourceType_Study).IsRetrieveMetadata());
1428 }
1429
1430 if (request.GetLevel() == ResourceType_Instance)
1431 {
1432 dbRequest.mutable_find()->mutable_parent_series()->set_retrieve_main_dicom_tags(request.GetParentSpecification(ResourceType_Series).IsRetrieveMainDicomTags());
1433 dbRequest.mutable_find()->mutable_parent_series()->set_retrieve_metadata(request.GetParentSpecification(ResourceType_Series).IsRetrieveMetadata());
1434 }
1435
1436 if (request.GetLevel() == ResourceType_Patient)
1437 {
1438 Convert(*dbRequest.mutable_find()->mutable_children_studies(), request.GetChildrenSpecification(ResourceType_Study));
1439 }
1440
1441 if (request.GetLevel() == ResourceType_Patient ||
1442 request.GetLevel() == ResourceType_Study)
1443 {
1444 Convert(*dbRequest.mutable_find()->mutable_children_series(), request.GetChildrenSpecification(ResourceType_Series));
1445 }
1446
1447 if (request.GetLevel() == ResourceType_Patient ||
1448 request.GetLevel() == ResourceType_Study ||
1449 request.GetLevel() == ResourceType_Series)
1450 {
1451 Convert(*dbRequest.mutable_find()->mutable_children_instances(), request.GetChildrenSpecification(ResourceType_Instance));
1452 }
1453
1454 DatabasePluginMessages::TransactionResponse dbResponse;
1455 ExecuteTransaction(dbResponse, DatabasePluginMessages::OPERATION_FIND, dbRequest);
1456
1457 for (int i = 0; i < dbResponse.find().size(); i++)
1458 {
1459 const DatabasePluginMessages::Find_Response& source = dbResponse.find(i);
1460
1461 std::unique_ptr<FindResponse::Resource> target(
1462 new FindResponse::Resource(request.GetLevel(), source.internal_id(), source.public_id()));
1463
1464 if (request.IsRetrieveParentIdentifier())
1465 {
1466 target->SetParentIdentifier(source.parent_public_id());
1467 }
1468
1469 for (int i = 0; i < source.labels().size(); i++)
1470 {
1471 target->AddLabel(source.labels(i));
1472 }
1473
1474 for (int i = 0; i < source.attachments().size(); i++)
1475 {
1476 target->AddAttachment(Convert(source.attachments(i)));
1477 }
1478
1479 Convert(*target, ResourceType_Patient, source.patient_content());
1480
1481 if (request.GetLevel() == ResourceType_Study ||
1482 request.GetLevel() == ResourceType_Series ||
1483 request.GetLevel() == ResourceType_Instance)
1484 {
1485 Convert(*target, ResourceType_Study, source.study_content());
1486 }
1487
1488 if (request.GetLevel() == ResourceType_Series ||
1489 request.GetLevel() == ResourceType_Instance)
1490 {
1491 Convert(*target, ResourceType_Series, source.series_content());
1492 }
1493
1494 if (request.GetLevel() == ResourceType_Instance)
1495 {
1496 Convert(*target, ResourceType_Instance, source.instance_content());
1497 }
1498
1499 if (request.GetLevel() == ResourceType_Patient)
1500 {
1501 Convert(*target, ResourceType_Patient, source.children_studies_content());
1502 }
1503
1504 if (request.GetLevel() == ResourceType_Patient ||
1505 request.GetLevel() == ResourceType_Study)
1506 {
1507 Convert(*target, ResourceType_Study, source.children_series_content());
1508 }
1509
1510 if (request.GetLevel() == ResourceType_Patient ||
1511 request.GetLevel() == ResourceType_Study ||
1512 request.GetLevel() == ResourceType_Series)
1513 {
1514 Convert(*target, ResourceType_Series, source.children_instances_content());
1515 }
1516
1517 response.Add(target.release());
1518 }
1519
1520 throw OrthancException(ErrorCode_NotImplemented);
1521 }
1522 else
1523 {
1524 throw OrthancException(ErrorCode_NotImplemented);
1525 }
1290 } 1526 }
1291 1527
1292 1528
1293 virtual void ExecuteFind(std::list<std::string>& identifiers, 1529 virtual void ExecuteFind(std::list<std::string>& identifiers,
1294 const Capabilities& capabilities, 1530 const Capabilities& capabilities,
1295 const FindRequest& request) ORTHANC_OVERRIDE 1531 const FindRequest& request) ORTHANC_OVERRIDE
1296 { 1532 {
1297 // TODO-FIND 1533 if (capabilities.HasFindSupport())
1298 Compatibility::GenericFind find(*this); 1534 {
1299 find.ExecuteFind(identifiers, capabilities, request); 1535 // The integrated version of "ExecuteFind()" should have been called
1536 throw OrthancException(ErrorCode_BadSequenceOfCalls);
1537 }
1538 else
1539 {
1540 Compatibility::GenericFind find(*this);
1541 find.ExecuteFind(identifiers, capabilities, request);
1542 }
1300 } 1543 }
1301 1544
1302 1545
1303 virtual void ExecuteExpand(FindResponse& response, 1546 virtual void ExecuteExpand(FindResponse& response,
1304 const Capabilities& capabilities, 1547 const Capabilities& capabilities,
1305 const FindRequest& request, 1548 const FindRequest& request,
1306 const std::string& identifier) ORTHANC_OVERRIDE 1549 const std::string& identifier) ORTHANC_OVERRIDE
1307 { 1550 {
1308 // TODO-FIND 1551 if (capabilities.HasFindSupport())
1309 Compatibility::GenericFind find(*this); 1552 {
1310 find.ExecuteExpand(response, capabilities, request, identifier); 1553 // The integrated version of "ExecuteFind()" should have been called
1554 throw OrthancException(ErrorCode_BadSequenceOfCalls);
1555 }
1556 else
1557 {
1558 Compatibility::GenericFind find(*this);
1559 find.ExecuteExpand(response, capabilities, request, identifier);
1560 }
1311 } 1561 }
1312 }; 1562 };
1313 1563
1314 1564
1315 OrthancPluginDatabaseV4::OrthancPluginDatabaseV4(SharedLibrary& library, 1565 OrthancPluginDatabaseV4::OrthancPluginDatabaseV4(SharedLibrary& library,
1395 dbCapabilities_.SetRevisionsSupport(systemInfo.supports_revisions()); 1645 dbCapabilities_.SetRevisionsSupport(systemInfo.supports_revisions());
1396 dbCapabilities_.SetLabelsSupport(systemInfo.supports_labels()); 1646 dbCapabilities_.SetLabelsSupport(systemInfo.supports_labels());
1397 dbCapabilities_.SetAtomicIncrementGlobalProperty(systemInfo.supports_increment_global_property()); 1647 dbCapabilities_.SetAtomicIncrementGlobalProperty(systemInfo.supports_increment_global_property());
1398 dbCapabilities_.SetUpdateAndGetStatistics(systemInfo.has_update_and_get_statistics()); 1648 dbCapabilities_.SetUpdateAndGetStatistics(systemInfo.has_update_and_get_statistics());
1399 dbCapabilities_.SetMeasureLatency(systemInfo.has_measure_latency()); 1649 dbCapabilities_.SetMeasureLatency(systemInfo.has_measure_latency());
1650 dbCapabilities_.SetHasFindSupport(systemInfo.supports_find());
1651
1652 printf(">>> %d\n", dbCapabilities_.HasFindSupport());
1400 } 1653 }
1401 1654
1402 open_ = true; 1655 open_ = true;
1403 } 1656 }
1404 1657
1525 } 1778 }
1526 1779
1527 1780
1528 bool OrthancPluginDatabaseV4::HasIntegratedFind() const 1781 bool OrthancPluginDatabaseV4::HasIntegratedFind() const
1529 { 1782 {
1530 return false; // TODO-FIND 1783 return dbCapabilities_.HasFindSupport();
1531 } 1784 }
1532 } 1785 }