Mercurial > hg > orthanc
comparison OrthancServer/Search/Compatibility/DatabaseLookup.cpp @ 3054:3638de45a08c db-changes
backward compatibility with filtering identifiers
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 21 Dec 2018 12:45:24 +0100 |
parents | 3f986ce336c8 |
children | 71ac4f28176f |
comparison
equal
deleted
inserted
replaced
3053:3f986ce336c8 | 3054:3638de45a08c |
---|---|
32 | 32 |
33 | 33 |
34 #include "../../PrecompiledHeadersServer.h" | 34 #include "../../PrecompiledHeadersServer.h" |
35 #include "DatabaseLookup.h" | 35 #include "DatabaseLookup.h" |
36 | 36 |
37 #include "../../../Core/OrthancException.h" | |
38 #include "../../ServerToolbox.h" | |
37 #include "SetOfResources.h" | 39 #include "SetOfResources.h" |
38 #include "../../../Core/OrthancException.h" | |
39 | 40 |
40 namespace Orthanc | 41 namespace Orthanc |
41 { | 42 { |
42 namespace Compatibility | 43 namespace Compatibility |
43 { | 44 { |
45 static void ApplyIdentifierConstraint(SetOfResources& candidates, | |
46 CompatibilityDatabaseWrapper& database, | |
47 const DatabaseConstraint& constraint, | |
48 ResourceType level) | |
49 { | |
50 std::list<int64_t> matches; | |
51 | |
52 switch (constraint.GetConstraintType()) | |
53 { | |
54 case ConstraintType_Equal: | |
55 database.LookupIdentifier(matches, level, constraint.GetTag(), | |
56 IdentifierConstraintType_Equal, constraint.GetSingleValue()); | |
57 break; | |
58 | |
59 case ConstraintType_SmallerOrEqual: | |
60 database.LookupIdentifier(matches, level, constraint.GetTag(), | |
61 IdentifierConstraintType_SmallerOrEqual, constraint.GetSingleValue()); | |
62 break; | |
63 | |
64 case ConstraintType_GreaterOrEqual: | |
65 database.LookupIdentifier(matches, level, constraint.GetTag(), | |
66 IdentifierConstraintType_GreaterOrEqual, constraint.GetSingleValue()); | |
67 | |
68 break; | |
69 | |
70 case ConstraintType_Wildcard: | |
71 database.LookupIdentifier(matches, level, constraint.GetTag(), | |
72 IdentifierConstraintType_Wildcard, constraint.GetSingleValue()); | |
73 | |
74 break; | |
75 | |
76 case ConstraintType_List: | |
77 { | |
78 for (size_t i = 0; i < constraint.GetValuesCount(); i++) | |
79 { | |
80 std::list<int64_t> tmp; | |
81 database.LookupIdentifier(tmp, level, constraint.GetTag(), | |
82 IdentifierConstraintType_Wildcard, constraint.GetValue(i)); | |
83 matches.splice(matches.end(), tmp); | |
84 } | |
85 | |
86 break; | |
87 } | |
88 | |
89 default: | |
90 throw OrthancException(ErrorCode_InternalError); | |
91 } | |
92 | |
93 candidates.Intersect(matches); | |
94 } | |
95 | |
96 | |
97 static void ApplyIdentifierRange(SetOfResources& candidates, | |
98 CompatibilityDatabaseWrapper& database, | |
99 const DatabaseConstraint& smaller, | |
100 const DatabaseConstraint& greater, | |
101 ResourceType level) | |
102 { | |
103 assert(smaller.GetConstraintType() == ConstraintType_SmallerOrEqual && | |
104 greater.GetConstraintType() == ConstraintType_GreaterOrEqual && | |
105 smaller.GetTag() == greater.GetTag() && | |
106 ServerToolbox::IsIdentifier(smaller.GetTag(), level)); | |
107 | |
108 std::list<int64_t> matches; | |
109 database.LookupIdentifierRange(matches, level, smaller.GetTag(), | |
110 greater.GetSingleValue(), smaller.GetSingleValue()); | |
111 candidates.Intersect(matches); | |
112 } | |
113 | |
114 | |
44 static void ApplyLevel(SetOfResources& candidates, | 115 static void ApplyLevel(SetOfResources& candidates, |
116 CompatibilityDatabaseWrapper& database, | |
45 const std::vector<DatabaseConstraint>& lookup, | 117 const std::vector<DatabaseConstraint>& lookup, |
46 ResourceType level) | 118 ResourceType level) |
47 { | 119 { |
48 std::vector<DatabaseConstraint> identifiers; | 120 typedef std::set<const DatabaseConstraint*> SetOfConstraints; |
121 typedef std::map<DicomTag, SetOfConstraints> Identifiers; | |
122 | |
123 Identifiers identifiers; | |
124 SetOfConstraints mainTags; | |
49 | 125 |
50 for (size_t i = 0; i < lookup.size(); i++) | 126 for (size_t i = 0; i < lookup.size(); i++) |
51 { | 127 { |
52 if (lookup[i].GetLevel() == level && | 128 if (lookup[i].GetLevel() == level) |
53 lookup[i].IsIdentifier()) | 129 { |
54 { | 130 if (lookup[i].IsIdentifier()) |
55 identifiers.push_back(lookup[i]); | 131 { |
56 } | 132 identifiers[lookup[i].GetTag()].insert(&lookup[i]); |
57 } | 133 } |
134 else | |
135 { | |
136 mainTags.insert(&lookup[i]); | |
137 } | |
138 } | |
139 } | |
140 | |
141 for (Identifiers::const_iterator it = identifiers.begin(); | |
142 it != identifiers.end(); ++it) | |
143 { | |
144 const DatabaseConstraint* smaller = NULL; | |
145 const DatabaseConstraint* greater = NULL; | |
146 | |
147 for (SetOfConstraints::const_iterator it2 = it->second.begin(); | |
148 it2 != it->second.end(); ++it2) | |
149 { | |
150 if ((*it2)->GetConstraintType() == ConstraintType_SmallerOrEqual) | |
151 { | |
152 smaller = *it2; | |
153 } | |
154 | |
155 if ((*it2)->GetConstraintType() == ConstraintType_GreaterOrEqual) | |
156 { | |
157 greater = *it2; | |
158 } | |
159 } | |
160 | |
161 if (smaller != NULL && | |
162 greater != NULL) | |
163 { | |
164 ApplyIdentifierRange(candidates, database, *smaller, *greater, level); | |
165 } | |
166 else | |
167 { | |
168 smaller = NULL; | |
169 greater = NULL; | |
170 } | |
171 | |
172 for (SetOfConstraints::const_iterator it2 = it->second.begin(); | |
173 it2 != it->second.end(); ++it2) | |
174 { | |
175 if (*it2 != smaller && | |
176 *it2 != greater) | |
177 { | |
178 ApplyIdentifierConstraint(candidates, database, **it2, level); | |
179 } | |
180 } | |
181 } | |
182 | |
183 | |
184 // TODO - Fiter main DICOM tags | |
58 } | 185 } |
59 | 186 |
60 | 187 |
61 static std::string GetOneInstance(IDatabaseWrapper& database, | 188 static std::string GetOneInstance(IDatabaseWrapper& database, |
62 int64_t resource, | 189 int64_t resource, |
67 assert(database.GetResourceType(resource) == static_cast<ResourceType>(i)); | 194 assert(database.GetResourceType(resource) == static_cast<ResourceType>(i)); |
68 | 195 |
69 std::list<int64_t> children; | 196 std::list<int64_t> children; |
70 database.GetChildrenInternalId(children, resource); | 197 database.GetChildrenInternalId(children, resource); |
71 | 198 |
72 if (children.size() == 0) | 199 if (children.empty()) |
73 { | 200 { |
74 throw OrthancException(ErrorCode_Database); | 201 throw OrthancException(ErrorCode_Database); |
75 } | 202 } |
76 | 203 |
77 resource = children.front(); | 204 resource = children.front(); |
78 } | 205 } |
79 | 206 |
80 return database.GetPublicId(resource); | 207 return database.GetPublicId(resource); |
81 } | 208 } |
82 | 209 |
83 | 210 |
84 void DatabaseLookup::ApplyLookupResources(std::vector<std::string>& resourcesId, | 211 void DatabaseLookup::ApplyLookupResources(std::vector<std::string>& resourcesId, |
117 | 244 |
118 SetOfResources candidates(database_, upperLevel); | 245 SetOfResources candidates(database_, upperLevel); |
119 | 246 |
120 for (int level = upperLevel; level <= lowerLevel; level++) | 247 for (int level = upperLevel; level <= lowerLevel; level++) |
121 { | 248 { |
122 ApplyLevel(candidates, lookup, static_cast<ResourceType>(level)); | 249 ApplyLevel(candidates, database_, lookup, static_cast<ResourceType>(level)); |
123 | 250 |
124 if (level != lowerLevel) | 251 if (level != lowerLevel) |
125 { | 252 { |
126 candidates.GoDown(); | 253 candidates.GoDown(); |
127 } | 254 } |