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 }