Mercurial > hg > orthanc
comparison OrthancServer/Sources/Database/FindRequest.h @ 5567:f3562c1a150d find-refactoring
FindRequest: group metadata and tag constrains in a single class, allow ordering against metadata
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 23 Apr 2024 16:49:44 +0200 |
parents | def06a42e5ef |
children | b0b5546f1b9f |
comparison
equal
deleted
inserted
replaced
5566:8b507b1514eb | 5567:f3562c1a150d |
---|---|
23 #pragma once | 23 #pragma once |
24 | 24 |
25 #include "../../../OrthancFramework/Sources/DicomFormat/DicomTag.h" | 25 #include "../../../OrthancFramework/Sources/DicomFormat/DicomTag.h" |
26 #include "../ServerEnumerations.h" | 26 #include "../ServerEnumerations.h" |
27 #include "OrthancIdentifiers.h" | 27 #include "OrthancIdentifiers.h" |
28 //#include "../Search/DatabaseConstraint.h" | |
28 | 29 |
29 #include <deque> | 30 #include <deque> |
30 #include <map> | 31 #include <map> |
31 #include <set> | 32 #include <set> |
32 | 33 #include <cassert> |
34 #include <boost/shared_ptr.hpp> | |
33 | 35 |
34 namespace Orthanc | 36 namespace Orthanc |
35 { | 37 { |
36 class FindRequest : public boost::noncopyable | 38 class FindRequest : public boost::noncopyable |
37 { | 39 { |
58 ConstraintType_Range, | 60 ConstraintType_Range, |
59 ConstraintType_Wildcard, | 61 ConstraintType_Wildcard, |
60 ConstraintType_List | 62 ConstraintType_List |
61 }; | 63 }; |
62 | 64 |
63 | 65 enum KeyType // used for ordering and filters |
64 enum Ordering | 66 { |
65 { | 67 KeyType_DicomTag, |
66 Ordering_Ascending, | 68 KeyType_Metadata |
67 Ordering_Descending, | 69 }; |
68 Ordering_None | 70 |
69 }; | 71 enum OrderingDirection |
70 | 72 { |
71 | 73 OrderingDirection_Ascending, |
72 class TagConstraint : public boost::noncopyable | 74 OrderingDirection_Descending |
73 { | 75 }; |
74 private: | 76 |
75 DicomTag tag_; | 77 enum LabelsConstraint |
76 | 78 { |
77 public: | 79 LabelsConstraint_All, |
78 TagConstraint(DicomTag tag) : | 80 LabelsConstraint_Any, |
79 tag_(tag) | 81 LabelsConstraint_None |
80 { | 82 }; |
81 } | 83 |
82 | 84 class Key |
83 virtual ~TagConstraint() | 85 { |
84 { | 86 KeyType type_; |
85 } | 87 boost::shared_ptr<DicomTag> dicomTag_; |
86 | 88 MetadataType metadata_; |
87 virtual DicomTag GetTag() const | 89 public: |
88 { | 90 Key(const DicomTag& dicomTag) : |
89 return tag_; | 91 type_(KeyType_DicomTag), |
92 dicomTag_(new DicomTag(dicomTag)), | |
93 metadata_(MetadataType_EndUser) | |
94 { | |
95 } | |
96 | |
97 Key(MetadataType metadata) : | |
98 type_(KeyType_Metadata), | |
99 metadata_(metadata) | |
100 { | |
101 } | |
102 | |
103 KeyType GetType() const | |
104 { | |
105 return type_; | |
106 } | |
107 | |
108 const DicomTag& GetDicomTag() const | |
109 { | |
110 assert(GetType() == KeyType_DicomTag); | |
111 return *dicomTag_; | |
112 } | |
113 | |
114 MetadataType GetMetadataType() const | |
115 { | |
116 assert(GetType() == KeyType_Metadata); | |
117 return metadata_; | |
118 } | |
119 }; | |
120 | |
121 class Ordering : public boost::noncopyable | |
122 { | |
123 OrderingDirection direction_; | |
124 Key key_; | |
125 | |
126 public: | |
127 Ordering(const Key& key, | |
128 OrderingDirection direction) : | |
129 direction_(direction), | |
130 key_(key) | |
131 { | |
132 } | |
133 | |
134 public: | |
135 KeyType GetKeyType() const | |
136 { | |
137 return key_.GetType(); | |
138 } | |
139 | |
140 OrderingDirection GetDirection() const | |
141 { | |
142 return direction_; | |
143 } | |
144 | |
145 MetadataType GetMetadataType() const | |
146 { | |
147 return key_.GetMetadataType(); | |
148 } | |
149 | |
150 DicomTag GetDicomTag() const | |
151 { | |
152 return key_.GetDicomTag(); | |
153 } | |
154 }; | |
155 | |
156 | |
157 class FilterConstraint : public boost::noncopyable | |
158 { | |
159 Key key_; | |
160 | |
161 protected: | |
162 FilterConstraint(const Key& key) : | |
163 key_(key) | |
164 { | |
165 } | |
166 | |
167 public: | |
168 virtual ~FilterConstraint() | |
169 { | |
90 } | 170 } |
91 | 171 |
92 virtual ConstraintType GetType() const = 0; | 172 virtual ConstraintType GetType() const = 0; |
93 | |
94 virtual bool IsCaseSensitive() const = 0; // Needed for PN VR | 173 virtual bool IsCaseSensitive() const = 0; // Needed for PN VR |
95 }; | 174 }; |
96 | 175 |
97 | 176 |
98 class MandatoryConstraint : public TagConstraint | 177 class MandatoryConstraint : public FilterConstraint |
99 { | 178 { |
100 public: | 179 public: |
101 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 180 virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
102 { | 181 { |
103 return ConstraintType_Mandatory; | 182 return ConstraintType_Mandatory; |
104 } | 183 } |
105 }; | 184 }; |
106 | 185 |
107 | 186 |
108 class StringConstraint : public TagConstraint | 187 class StringConstraint : public FilterConstraint |
109 { | 188 { |
110 private: | 189 private: |
111 bool caseSensitive_; | 190 bool caseSensitive_; |
112 | 191 |
113 public: | 192 public: |
114 StringConstraint(DicomTag tag, | 193 StringConstraint(Key key, |
115 bool caseSensitive) : | 194 bool caseSensitive) : |
116 TagConstraint(tag), | 195 FilterConstraint(key), |
117 caseSensitive_(caseSensitive) | 196 caseSensitive_(caseSensitive) |
118 { | 197 { |
119 } | 198 } |
120 | 199 |
121 bool IsCaseSensitive() const | 200 bool IsCaseSensitive() const |
129 { | 208 { |
130 private: | 209 private: |
131 std::string value_; | 210 std::string value_; |
132 | 211 |
133 public: | 212 public: |
134 explicit EqualityConstraint(DicomTag tag, | 213 explicit EqualityConstraint(Key key, |
135 bool caseSensitive, | 214 bool caseSensitive, |
136 const std::string& value) : | 215 const std::string& value) : |
137 StringConstraint(tag, caseSensitive), | 216 StringConstraint(key, caseSensitive), |
138 value_(value) | 217 value_(value) |
139 { | 218 { |
140 } | 219 } |
141 | 220 |
142 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 221 virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
156 private: | 235 private: |
157 std::string start_; | 236 std::string start_; |
158 std::string end_; // Inclusive | 237 std::string end_; // Inclusive |
159 | 238 |
160 public: | 239 public: |
161 RangeConstraint(DicomTag tag, | 240 RangeConstraint(Key key, |
162 bool caseSensitive, | 241 bool caseSensitive, |
163 const std::string& start, | 242 const std::string& start, |
164 const std::string& end) : | 243 const std::string& end) : |
165 StringConstraint(tag, caseSensitive), | 244 StringConstraint(key, caseSensitive), |
166 start_(start), | 245 start_(start), |
167 end_(end) | 246 end_(end) |
168 { | 247 { |
169 } | 248 } |
170 | 249 |
189 { | 268 { |
190 private: | 269 private: |
191 std::string value_; | 270 std::string value_; |
192 | 271 |
193 public: | 272 public: |
194 explicit WildcardConstraint(DicomTag& tag, | 273 explicit WildcardConstraint(Key& key, |
195 bool caseSensitive, | 274 bool caseSensitive, |
196 const std::string& value) : | 275 const std::string& value) : |
197 StringConstraint(tag, caseSensitive), | 276 StringConstraint(key, caseSensitive), |
198 value_(value) | 277 value_(value) |
199 { | 278 { |
200 } | 279 } |
201 | 280 |
202 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 281 virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
215 { | 294 { |
216 private: | 295 private: |
217 std::set<std::string> values_; | 296 std::set<std::string> values_; |
218 | 297 |
219 public: | 298 public: |
220 ListConstraint(DicomTag tag, | 299 ListConstraint(Key key, |
221 bool caseSensitive) : | 300 bool caseSensitive) : |
222 StringConstraint(tag, caseSensitive) | 301 StringConstraint(key, caseSensitive) |
223 { | 302 { |
224 } | 303 } |
225 | 304 |
226 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 305 virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
227 { | 306 { |
234 } | 313 } |
235 }; | 314 }; |
236 | 315 |
237 | 316 |
238 private: | 317 private: |
239 ResourceType level_; | 318 |
240 ResponseContent responseContent_; | 319 // filter & ordering fields |
241 OrthancIdentifiers orthancIdentifiers_; | 320 ResourceType level_; // The level of the response (the filtering on tags, labels and metadata also happens at this level) |
242 std::deque<TagConstraint*> tagConstraints_; | 321 OrthancIdentifiers orthancIdentifiers_; // The response must belong to this Orthanc resources hierarchy |
322 std::deque<FilterConstraint*> filterConstraints_; // All tags and metadata filters (note: the order is not important) | |
243 bool hasLimits_; | 323 bool hasLimits_; |
244 uint64_t limitsSince_; | 324 uint64_t limitsSince_; |
245 uint64_t limitsCount_; | 325 uint64_t limitsCount_; |
326 std::set<std::string> labels_; | |
327 LabelsConstraint labelsContraint_; | |
328 std::deque<Ordering*> ordering_; // The ordering criteria (note: the order is important !) | |
329 | |
330 // response fields | |
331 ResponseContent responseContent_; | |
332 | |
333 // TODO: check if these 4 options are required. We might just have a retrieveParentTags that could be part of the ResponseContent enum ? | |
246 bool retrievePatientTags_; | 334 bool retrievePatientTags_; |
247 bool retrieveStudyTags_; | 335 bool retrieveStudyTags_; |
248 bool retrieveSeriesTags_; | 336 bool retrieveSeriesTags_; |
249 bool retrieveInstanceTags_; | 337 bool retrieveInstanceTags_; |
250 std::map<DicomTag, Ordering> tagOrdering_; | |
251 std::set<std::string> labels_; | |
252 std::map<MetadataType, std::string> metadataConstraints_; | |
253 | 338 |
254 bool IsCompatibleLevel(ResourceType levelOfInterest) const; | 339 bool IsCompatibleLevel(ResourceType levelOfInterest) const; |
255 | 340 |
256 public: | 341 public: |
257 FindRequest(ResourceType level); | 342 FindRequest(ResourceType level); |
261 ResourceType GetLevel() const | 346 ResourceType GetLevel() const |
262 { | 347 { |
263 return level_; | 348 return level_; |
264 } | 349 } |
265 | 350 |
351 // void GetDatabaseConstraints(std::vector<DatabaseConstraint>& target) const; // conversion to DatabaseConstraint is required to feed to the LookupFormatter | |
352 // void GetOrdering(std::vector<Ordering>& target) const; | |
353 | |
354 | |
266 void SetResponseContent(ResponseContent content) | 355 void SetResponseContent(ResponseContent content) |
267 { | 356 { |
268 responseContent_ = content; | 357 responseContent_ = content; |
269 } | 358 } |
270 | 359 |
306 const OrthancIdentifiers& GetOrthancIdentifiers() const | 395 const OrthancIdentifiers& GetOrthancIdentifiers() const |
307 { | 396 { |
308 return orthancIdentifiers_; | 397 return orthancIdentifiers_; |
309 } | 398 } |
310 | 399 |
311 void AddTagConstraint(TagConstraint* constraint /* takes ownership */); | 400 void AddFilterConstraint(FilterConstraint* constraint /* takes ownership */); |
312 | 401 |
313 size_t GetTagConstraintsCount() const | 402 size_t GetFilterConstraintsCount() const |
314 { | 403 { |
315 return tagConstraints_.size(); | 404 return filterConstraints_.size(); |
316 } | 405 } |
317 | 406 |
318 const TagConstraint& GetTagConstraint(size_t index) const; | 407 const FilterConstraint& GetFilterConstraint(size_t index) const; |
319 | 408 |
320 void SetLimits(uint64_t since, | 409 void SetLimits(uint64_t since, |
321 uint64_t count); | 410 uint64_t count); |
322 | 411 |
323 bool HasLimits() const | 412 bool HasLimits() const |
333 void SetRetrieveTagsAtLevel(ResourceType levelOfInterest, | 422 void SetRetrieveTagsAtLevel(ResourceType levelOfInterest, |
334 bool retrieve); | 423 bool retrieve); |
335 | 424 |
336 bool IsRetrieveTagsAtLevel(ResourceType levelOfInterest) const; | 425 bool IsRetrieveTagsAtLevel(ResourceType levelOfInterest) const; |
337 | 426 |
338 void SetTagOrdering(DicomTag tag, | 427 void AddOrdering(const DicomTag& tag, OrderingDirection direction); |
339 Ordering ordering); | 428 |
340 | 429 void AddOrdering(MetadataType metadataType, OrderingDirection direction); |
341 const std::map<DicomTag, Ordering>& GetTagOrdering() const | 430 |
342 { | 431 const std::deque<Ordering*>& GetOrdering() const |
343 return tagOrdering_; | 432 { |
433 return ordering_; | |
344 } | 434 } |
345 | 435 |
346 void AddLabel(const std::string& label) | 436 void AddLabel(const std::string& label) |
347 { | 437 { |
348 labels_.insert(label); | 438 labels_.insert(label); |
349 } | 439 } |
350 | 440 |
351 const std::set<std::string>& GetLabels() const | 441 const std::set<std::string>& GetLabels() const |
352 { | 442 { |
353 return labels_; | 443 return labels_; |
354 } | |
355 | |
356 void AddMetadataConstraint(MetadataType metadata, | |
357 const std::string& value); | |
358 | |
359 const std::map<MetadataType, std::string>& GetMetadataConstraints() const | |
360 { | |
361 return metadataConstraints_; | |
362 } | 444 } |
363 }; | 445 }; |
364 } | 446 } |