Mercurial > hg > orthanc
comparison OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp @ 5614:4640b7ae9a11 find-refactoring
moving normalization of constraints into FindRequest
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 09 May 2024 11:59:56 +0200 |
parents | 3f24eb4013d8 |
children | 824a5fb0774e |
comparison
equal
deleted
inserted
replaced
5613:f1ce8dd361b7 | 5614:4640b7ae9a11 |
---|---|
297 pos ++; | 297 pos ++; |
298 } | 298 } |
299 } | 299 } |
300 | 300 |
301 | 301 |
302 class StatelessDatabaseOperations::MainDicomTagsRegistry : public boost::noncopyable | |
303 { | |
304 private: | |
305 class TagInfo | |
306 { | |
307 private: | |
308 ResourceType level_; | |
309 DicomTagType type_; | |
310 | |
311 public: | |
312 TagInfo() | |
313 { | |
314 } | |
315 | |
316 TagInfo(ResourceType level, | |
317 DicomTagType type) : | |
318 level_(level), | |
319 type_(type) | |
320 { | |
321 } | |
322 | |
323 ResourceType GetLevel() const | |
324 { | |
325 return level_; | |
326 } | |
327 | |
328 DicomTagType GetType() const | |
329 { | |
330 return type_; | |
331 } | |
332 }; | |
333 | |
334 typedef std::map<DicomTag, TagInfo> Registry; | |
335 | |
336 | |
337 Registry registry_; | |
338 | |
339 void LoadTags(ResourceType level) | |
340 { | |
341 { | |
342 const DicomTag* tags = NULL; | |
343 size_t size; | |
344 | |
345 ServerToolbox::LoadIdentifiers(tags, size, level); | |
346 | |
347 for (size_t i = 0; i < size; i++) | |
348 { | |
349 if (registry_.find(tags[i]) == registry_.end()) | |
350 { | |
351 registry_[tags[i]] = TagInfo(level, DicomTagType_Identifier); | |
352 } | |
353 else | |
354 { | |
355 // These patient-level tags are copied in the study level | |
356 assert(level == ResourceType_Study && | |
357 (tags[i] == DICOM_TAG_PATIENT_ID || | |
358 tags[i] == DICOM_TAG_PATIENT_NAME || | |
359 tags[i] == DICOM_TAG_PATIENT_BIRTH_DATE)); | |
360 } | |
361 } | |
362 } | |
363 | |
364 { | |
365 std::set<DicomTag> tags; | |
366 DicomMap::GetMainDicomTags(tags, level); | |
367 | |
368 for (std::set<DicomTag>::const_iterator | |
369 tag = tags.begin(); tag != tags.end(); ++tag) | |
370 { | |
371 if (registry_.find(*tag) == registry_.end()) | |
372 { | |
373 registry_[*tag] = TagInfo(level, DicomTagType_Main); | |
374 } | |
375 } | |
376 } | |
377 } | |
378 | |
379 public: | |
380 MainDicomTagsRegistry() | |
381 { | |
382 LoadTags(ResourceType_Patient); | |
383 LoadTags(ResourceType_Study); | |
384 LoadTags(ResourceType_Series); | |
385 LoadTags(ResourceType_Instance); | |
386 } | |
387 | |
388 void LookupTag(ResourceType& level, | |
389 DicomTagType& type, | |
390 const DicomTag& tag) const | |
391 { | |
392 Registry::const_iterator it = registry_.find(tag); | |
393 | |
394 if (it == registry_.end()) | |
395 { | |
396 // Default values | |
397 level = ResourceType_Instance; | |
398 type = DicomTagType_Generic; | |
399 } | |
400 else | |
401 { | |
402 level = it->second.GetLevel(); | |
403 type = it->second.GetType(); | |
404 } | |
405 } | |
406 }; | |
407 | |
408 | |
409 void StatelessDatabaseOperations::ReadWriteTransaction::LogChange(int64_t internalId, | 302 void StatelessDatabaseOperations::ReadWriteTransaction::LogChange(int64_t internalId, |
410 ChangeType changeType, | 303 ChangeType changeType, |
411 ResourceType resourceType, | 304 ResourceType resourceType, |
412 const std::string& publicId) | 305 const std::string& publicId) |
413 { | 306 { |
497 } | 390 } |
498 | 391 |
499 target.push_back(source.GetConstraint(i).ConvertToDatabaseConstraint(level, type)); | 392 target.push_back(source.GetConstraint(i).ConvertToDatabaseConstraint(level, type)); |
500 } | 393 } |
501 } | 394 } |
502 } | |
503 | |
504 void StatelessDatabaseOperations::NormalizeLookup(std::vector<DatabaseConstraint>& target, | |
505 const FindRequest& findRequest) const | |
506 { | |
507 assert(mainDicomTagsRegistry_.get() != NULL); | |
508 | |
509 target.clear(); | |
510 target.reserve(findRequest.GetDicomTagConstraintsCount()); | |
511 | |
512 for (size_t i = 0; i < findRequest.GetDicomTagConstraintsCount(); i++) | |
513 { | |
514 ResourceType level; | |
515 DicomTagType type; | |
516 | |
517 mainDicomTagsRegistry_->LookupTag(level, type, findRequest.GetDicomTagConstraint(i).GetTag()); | |
518 | |
519 if (type == DicomTagType_Identifier || | |
520 type == DicomTagType_Main) | |
521 { | |
522 // Use the fact that patient-level tags are copied at the study level | |
523 if (level == ResourceType_Patient && | |
524 findRequest.GetLevel() != ResourceType_Patient) | |
525 { | |
526 level = ResourceType_Study; | |
527 } | |
528 | |
529 target.push_back(findRequest.GetDicomTagConstraint(i).ConvertToDatabaseConstraint(level, type)); | |
530 } | |
531 } | |
532 | |
533 // TODO-FIND: add metadata constraints | |
534 } | 395 } |
535 | 396 |
536 | 397 |
537 class StatelessDatabaseOperations::Transaction : public boost::noncopyable | 398 class StatelessDatabaseOperations::Transaction : public boost::noncopyable |
538 { | 399 { |
3842 | 3703 |
3843 | 3704 |
3844 void StatelessDatabaseOperations::ExecuteFind(FindResponse& response, | 3705 void StatelessDatabaseOperations::ExecuteFind(FindResponse& response, |
3845 const FindRequest& request) | 3706 const FindRequest& request) |
3846 { | 3707 { |
3847 class IntegratedFind : public ReadOnlyOperationsT3<FindResponse&, const FindRequest&, const std::vector<DatabaseConstraint>&> | 3708 class IntegratedFind : public ReadOnlyOperationsT2<FindResponse&, const FindRequest&> |
3848 { | 3709 { |
3849 public: | 3710 public: |
3850 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | 3711 virtual void ApplyTuple(ReadOnlyTransaction& transaction, |
3851 const Tuple& tuple) ORTHANC_OVERRIDE | 3712 const Tuple& tuple) ORTHANC_OVERRIDE |
3852 { | 3713 { |
3853 transaction.ExecuteFind(tuple.get<0>(), tuple.get<1>(), tuple.get<2>()); | 3714 transaction.ExecuteFind(tuple.get<0>(), tuple.get<1>()); |
3854 } | 3715 } |
3855 }; | 3716 }; |
3856 | 3717 |
3857 class FindStage : public ReadOnlyOperationsT3<std::list<std::string>&, const FindRequest&, const std::vector<DatabaseConstraint>&> | 3718 class FindStage : public ReadOnlyOperationsT2<std::list<std::string>&, const FindRequest&> |
3858 { | 3719 { |
3859 public: | 3720 public: |
3860 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | 3721 virtual void ApplyTuple(ReadOnlyTransaction& transaction, |
3861 const Tuple& tuple) ORTHANC_OVERRIDE | 3722 const Tuple& tuple) ORTHANC_OVERRIDE |
3862 { | 3723 { |
3863 transaction.ExecuteFind(tuple.get<0>(), tuple.get<1>(), tuple.get<2>()); | 3724 transaction.ExecuteFind(tuple.get<0>(), tuple.get<1>()); |
3864 } | 3725 } |
3865 }; | 3726 }; |
3866 | 3727 |
3867 class ExpandStage : public ReadOnlyOperationsT3<FindResponse&, const FindRequest&, const std::string&> | 3728 class ExpandStage : public ReadOnlyOperationsT3<FindResponse&, const FindRequest&, const std::string&> |
3868 { | 3729 { |
3871 const Tuple& tuple) ORTHANC_OVERRIDE | 3732 const Tuple& tuple) ORTHANC_OVERRIDE |
3872 { | 3733 { |
3873 transaction.ExecuteExpand(tuple.get<0>(), tuple.get<1>(), tuple.get<2>()); | 3734 transaction.ExecuteExpand(tuple.get<0>(), tuple.get<1>(), tuple.get<2>()); |
3874 } | 3735 } |
3875 }; | 3736 }; |
3876 | |
3877 std::vector<DatabaseConstraint> normalized; | |
3878 NormalizeLookup(normalized, request); | |
3879 | 3737 |
3880 if (db_.HasIntegratedFind()) | 3738 if (db_.HasIntegratedFind()) |
3881 { | 3739 { |
3882 /** | 3740 /** |
3883 * In this flavor, the "find" and the "expand" phases are | 3741 * In this flavor, the "find" and the "expand" phases are |
3884 * executed in one single transaction. | 3742 * executed in one single transaction. |
3885 **/ | 3743 **/ |
3886 IntegratedFind operations; | 3744 IntegratedFind operations; |
3887 operations.Apply(*this, response, request, normalized); | 3745 operations.Apply(*this, response, request); |
3888 } | 3746 } |
3889 else | 3747 else |
3890 { | 3748 { |
3891 /** | 3749 /** |
3892 * In this flavor, the "find" and the "expand" phases for each | 3750 * In this flavor, the "find" and the "expand" phases for each |
3894 * the compatibility mode equivalent to Orthanc <= 1.12.3. | 3752 * the compatibility mode equivalent to Orthanc <= 1.12.3. |
3895 **/ | 3753 **/ |
3896 std::list<std::string> identifiers; | 3754 std::list<std::string> identifiers; |
3897 | 3755 |
3898 FindStage find; | 3756 FindStage find; |
3899 find.Apply(*this, identifiers, request, normalized); | 3757 find.Apply(*this, identifiers, request); |
3900 | 3758 |
3901 ExpandStage expand; | 3759 ExpandStage expand; |
3902 | 3760 |
3903 for (std::list<std::string>::const_iterator it = identifiers.begin(); it != identifiers.end(); ++it) | 3761 for (std::list<std::string>::const_iterator it = identifiers.begin(); it != identifiers.end(); ++it) |
3904 { | 3762 { |