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 }