Mercurial > hg > orthanc
comparison OrthancServer/Sources/Database/FindRequest.h @ 5568:b0b5546f1b9f find-refactoring
find refactor: re-use existing code. /studies?expand is almost fully implemented with new code
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Thu, 25 Apr 2024 09:22:07 +0200 |
parents | f3562c1a150d |
children | 5a13483d12c5 |
comparison
equal
deleted
inserted
replaced
5567:f3562c1a150d | 5568:b0b5546f1b9f |
---|---|
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 #include "../Search/DicomTagConstraint.h" |
29 #include "../Search/LabelsConstraint.h" | |
30 #include "../Search/DatabaseConstraint.h" | |
29 | 31 |
30 #include <deque> | 32 #include <deque> |
31 #include <map> | 33 #include <map> |
32 #include <set> | 34 #include <set> |
33 #include <cassert> | 35 #include <cassert> |
72 { | 74 { |
73 OrderingDirection_Ascending, | 75 OrderingDirection_Ascending, |
74 OrderingDirection_Descending | 76 OrderingDirection_Descending |
75 }; | 77 }; |
76 | 78 |
77 enum LabelsConstraint | |
78 { | |
79 LabelsConstraint_All, | |
80 LabelsConstraint_Any, | |
81 LabelsConstraint_None | |
82 }; | |
83 | 79 |
84 class Key | 80 class Key |
85 { | 81 { |
86 KeyType type_; | 82 KeyType type_; |
87 boost::shared_ptr<DicomTag> dicomTag_; | 83 boost::shared_ptr<DicomTag> dicomTag_; |
88 MetadataType metadata_; | 84 MetadataType metadata_; |
85 | |
86 // TODO-FIND: to execute the query, we actually need: | |
87 // ResourceType level_; | |
88 // DicomTagType dicomTagType_; | |
89 // these are however only populated in StatelessDatabaseOperations -> we had to add the normalized lookup arg to ExecuteFind | |
90 | |
89 public: | 91 public: |
90 Key(const DicomTag& dicomTag) : | 92 Key(const DicomTag& dicomTag) : |
91 type_(KeyType_DicomTag), | 93 type_(KeyType_DicomTag), |
92 dicomTag_(new DicomTag(dicomTag)), | 94 dicomTag_(new DicomTag(dicomTag)), |
93 metadata_(MetadataType_EndUser) | 95 metadata_(MetadataType_EndUser) |
151 { | 153 { |
152 return key_.GetDicomTag(); | 154 return key_.GetDicomTag(); |
153 } | 155 } |
154 }; | 156 }; |
155 | 157 |
156 | 158 // TODO-FIND: this class hierarchy actually adds complexity and is very redundant with DicomTagConstraint. |
157 class FilterConstraint : public boost::noncopyable | 159 // e.g, in this class hierarchy, it is difficult to implement an equivalent to DicomTagConstraint::ConvertToDatabaseConstraint |
158 { | 160 // I have the feeling we can just have a MetadataConstraint in the same way as DicomTagConstraint |
159 Key key_; | 161 // and both convert to a DatabaseConstraint in StatelessDatabaseOperations |
162 // class FilterConstraint : public boost::noncopyable | |
163 // { | |
164 // Key key_; | |
160 | 165 |
161 protected: | 166 // protected: |
162 FilterConstraint(const Key& key) : | 167 // FilterConstraint(const Key& key) : |
163 key_(key) | 168 // key_(key) |
164 { | 169 // { |
165 } | 170 // } |
166 | 171 |
167 public: | 172 // public: |
168 virtual ~FilterConstraint() | 173 // virtual ~FilterConstraint() |
169 { | 174 // { |
170 } | 175 // } |
171 | 176 |
172 virtual ConstraintType GetType() const = 0; | 177 // const Key& GetKey() const |
173 virtual bool IsCaseSensitive() const = 0; // Needed for PN VR | 178 // { |
174 }; | 179 // return key_; |
175 | 180 // } |
176 | 181 |
177 class MandatoryConstraint : public FilterConstraint | 182 // virtual ConstraintType GetType() const = 0; |
178 { | 183 // virtual bool IsCaseSensitive() const = 0; // Needed for PN VR |
179 public: | 184 |
180 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 185 |
181 { | 186 // }; |
182 return ConstraintType_Mandatory; | 187 |
183 } | 188 |
184 }; | 189 // class MandatoryConstraint : public FilterConstraint |
185 | 190 // { |
186 | 191 // public: |
187 class StringConstraint : public FilterConstraint | 192 // virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
188 { | 193 // { |
189 private: | 194 // return ConstraintType_Mandatory; |
190 bool caseSensitive_; | 195 // } |
191 | 196 // }; |
192 public: | 197 |
193 StringConstraint(Key key, | 198 |
194 bool caseSensitive) : | 199 // class StringConstraint : public FilterConstraint |
195 FilterConstraint(key), | 200 // { |
196 caseSensitive_(caseSensitive) | 201 // private: |
197 { | 202 // bool caseSensitive_; |
198 } | 203 |
199 | 204 // public: |
200 bool IsCaseSensitive() const | 205 // StringConstraint(Key key, |
201 { | 206 // bool caseSensitive) : |
202 return caseSensitive_; | 207 // FilterConstraint(key), |
203 } | 208 // caseSensitive_(caseSensitive) |
204 }; | 209 // { |
205 | 210 // } |
206 | 211 |
207 class EqualityConstraint : public StringConstraint | 212 // bool IsCaseSensitive() const |
208 { | 213 // { |
209 private: | 214 // return caseSensitive_; |
210 std::string value_; | 215 // } |
211 | 216 // }; |
212 public: | 217 |
213 explicit EqualityConstraint(Key key, | 218 |
214 bool caseSensitive, | 219 // class EqualityConstraint : public StringConstraint |
215 const std::string& value) : | 220 // { |
216 StringConstraint(key, caseSensitive), | 221 // private: |
217 value_(value) | 222 // std::string value_; |
218 { | 223 |
219 } | 224 // public: |
220 | 225 // explicit EqualityConstraint(Key key, |
221 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 226 // bool caseSensitive, |
222 { | 227 // const std::string& value) : |
223 return ConstraintType_Equality; | 228 // StringConstraint(key, caseSensitive), |
224 } | 229 // value_(value) |
225 | 230 // { |
226 const std::string& GetValue() const | 231 // } |
227 { | 232 |
228 return value_; | 233 // virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
229 } | 234 // { |
230 }; | 235 // return ConstraintType_Equality; |
231 | 236 // } |
232 | 237 |
233 class RangeConstraint : public StringConstraint | 238 // const std::string& GetValue() const |
234 { | 239 // { |
235 private: | 240 // return value_; |
236 std::string start_; | 241 // } |
237 std::string end_; // Inclusive | 242 // }; |
238 | 243 |
239 public: | 244 |
240 RangeConstraint(Key key, | 245 // class RangeConstraint : public StringConstraint |
241 bool caseSensitive, | 246 // { |
242 const std::string& start, | 247 // private: |
243 const std::string& end) : | 248 // std::string start_; |
244 StringConstraint(key, caseSensitive), | 249 // std::string end_; // Inclusive |
245 start_(start), | 250 |
246 end_(end) | 251 // public: |
247 { | 252 // RangeConstraint(Key key, |
248 } | 253 // bool caseSensitive, |
249 | 254 // const std::string& start, |
250 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 255 // const std::string& end) : |
251 { | 256 // StringConstraint(key, caseSensitive), |
252 return ConstraintType_Range; | 257 // start_(start), |
253 } | 258 // end_(end) |
254 | 259 // { |
255 const std::string& GetStart() const | 260 // } |
256 { | 261 |
257 return start_; | 262 // virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
258 } | 263 // { |
259 | 264 // return ConstraintType_Range; |
260 const std::string& GetEnd() const | 265 // } |
261 { | 266 |
262 return end_; | 267 // const std::string& GetStart() const |
263 } | 268 // { |
264 }; | 269 // return start_; |
265 | 270 // } |
266 | 271 |
267 class WildcardConstraint : public StringConstraint | 272 // const std::string& GetEnd() const |
268 { | 273 // { |
269 private: | 274 // return end_; |
270 std::string value_; | 275 // } |
271 | 276 // }; |
272 public: | 277 |
273 explicit WildcardConstraint(Key& key, | 278 |
274 bool caseSensitive, | 279 // class WildcardConstraint : public StringConstraint |
275 const std::string& value) : | 280 // { |
276 StringConstraint(key, caseSensitive), | 281 // private: |
277 value_(value) | 282 // std::string value_; |
278 { | 283 |
279 } | 284 // public: |
280 | 285 // explicit WildcardConstraint(Key& key, |
281 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 286 // bool caseSensitive, |
282 { | 287 // const std::string& value) : |
283 return ConstraintType_Wildcard; | 288 // StringConstraint(key, caseSensitive), |
284 } | 289 // value_(value) |
285 | 290 // { |
286 const std::string& GetValue() const | 291 // } |
287 { | 292 |
288 return value_; | 293 // virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
289 } | 294 // { |
290 }; | 295 // return ConstraintType_Wildcard; |
291 | 296 // } |
292 | 297 |
293 class ListConstraint : public StringConstraint | 298 // const std::string& GetValue() const |
294 { | 299 // { |
295 private: | 300 // return value_; |
296 std::set<std::string> values_; | 301 // } |
297 | 302 // }; |
298 public: | 303 |
299 ListConstraint(Key key, | 304 |
300 bool caseSensitive) : | 305 // class ListConstraint : public StringConstraint |
301 StringConstraint(key, caseSensitive) | 306 // { |
302 { | 307 // private: |
303 } | 308 // std::set<std::string> values_; |
304 | 309 |
305 virtual ConstraintType GetType() const ORTHANC_OVERRIDE | 310 // public: |
306 { | 311 // ListConstraint(Key key, |
307 return ConstraintType_List; | 312 // bool caseSensitive) : |
308 } | 313 // StringConstraint(key, caseSensitive) |
309 | 314 // { |
310 const std::set<std::string>& GetValues() const | 315 // } |
311 { | 316 |
312 return values_; | 317 // virtual ConstraintType GetType() const ORTHANC_OVERRIDE |
313 } | 318 // { |
314 }; | 319 // return ConstraintType_List; |
320 // } | |
321 | |
322 // const std::set<std::string>& GetValues() const | |
323 // { | |
324 // return values_; | |
325 // } | |
326 // }; | |
315 | 327 |
316 | 328 |
317 private: | 329 private: |
318 | 330 |
319 // filter & ordering fields | 331 // filter & ordering fields |
320 ResourceType level_; // The level of the response (the filtering on tags, labels and metadata also happens at this level) | 332 ResourceType level_; // The level of the response (the filtering on tags, labels and metadata also happens at this level) |
321 OrthancIdentifiers orthancIdentifiers_; // The response must belong to this Orthanc resources hierarchy | 333 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) | 334 // std::deque<FilterConstraint*> filterConstraints_; // All tags and metadata filters (note: the order is not important) |
335 std::vector<DicomTagConstraint> dicomTagConstraints_; // All tags filters (note: the order is not important) | |
336 std::deque<void*> /* TODO-FIND */ metadataConstraints_; // All metadata filters (note: the order is not important) | |
323 bool hasLimits_; | 337 bool hasLimits_; |
324 uint64_t limitsSince_; | 338 uint64_t limitsSince_; |
325 uint64_t limitsCount_; | 339 uint64_t limitsCount_; |
326 std::set<std::string> labels_; | 340 std::set<std::string> labels_; |
327 LabelsConstraint labelsContraint_; | 341 LabelsConstraint labelsContraint_; |
346 ResourceType GetLevel() const | 360 ResourceType GetLevel() const |
347 { | 361 { |
348 return level_; | 362 return level_; |
349 } | 363 } |
350 | 364 |
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 | 365 |
355 void SetResponseContent(ResponseContent content) | 366 void SetResponseContent(ResponseContent content) |
356 { | 367 { |
357 responseContent_ = content; | 368 responseContent_ = content; |
358 } | 369 } |
370 bool HasResponseContent(ResponseContent content) const | 381 bool HasResponseContent(ResponseContent content) const |
371 { | 382 { |
372 return (responseContent_ & content) == content; | 383 return (responseContent_ & content) == content; |
373 } | 384 } |
374 | 385 |
386 bool IsResponseIdentifiersOnly() const | |
387 { | |
388 return responseContent_ == ResponseContent_IdentifiersOnly; | |
389 } | |
390 | |
375 void SetOrthancPatientId(const std::string& id) | 391 void SetOrthancPatientId(const std::string& id) |
376 { | 392 { |
377 orthancIdentifiers_.SetPatientId(id); | 393 orthancIdentifiers_.SetPatientId(id); |
378 } | 394 } |
379 | 395 |
395 const OrthancIdentifiers& GetOrthancIdentifiers() const | 411 const OrthancIdentifiers& GetOrthancIdentifiers() const |
396 { | 412 { |
397 return orthancIdentifiers_; | 413 return orthancIdentifiers_; |
398 } | 414 } |
399 | 415 |
400 void AddFilterConstraint(FilterConstraint* constraint /* takes ownership */); | 416 |
401 | 417 void AddDicomTagConstraint(const DicomTagConstraint& constraint); |
402 size_t GetFilterConstraintsCount() const | 418 |
403 { | 419 size_t GetDicomTagConstraintsCount() const |
404 return filterConstraints_.size(); | 420 { |
405 } | 421 return dicomTagConstraints_.size(); |
406 | 422 } |
407 const FilterConstraint& GetFilterConstraint(size_t index) const; | 423 |
424 size_t GetMetadataConstraintsCount() const | |
425 { | |
426 return metadataConstraints_.size(); | |
427 } | |
428 | |
429 const DicomTagConstraint& GetDicomTagConstraint(size_t index) const; | |
408 | 430 |
409 void SetLimits(uint64_t since, | 431 void SetLimits(uint64_t since, |
410 uint64_t count); | 432 uint64_t count); |
411 | 433 |
412 bool HasLimits() const | 434 bool HasLimits() const |
440 | 462 |
441 const std::set<std::string>& GetLabels() const | 463 const std::set<std::string>& GetLabels() const |
442 { | 464 { |
443 return labels_; | 465 return labels_; |
444 } | 466 } |
467 | |
468 LabelsConstraint GetLabelsConstraint() const | |
469 { | |
470 return labelsContraint_; | |
471 } | |
445 }; | 472 }; |
446 } | 473 } |