comparison OrthancServer/Search/LookupResource.cpp @ 1749:99f4a05f39fa db-changes

various types of constraints
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 27 Oct 2015 10:54:51 +0100
parents
children 55d52567bebb
comparison
equal deleted inserted replaced
1748:92203f713205 1749:99f4a05f39fa
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * In addition, as a special exception, the copyright holders of this
12 * program give permission to link the code of its release with the
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it
14 * that use the same license as the "OpenSSL" library), and distribute
15 * the linked executables. You must obey the GNU General Public License
16 * in all respects for all of the code used other than "OpenSSL". If you
17 * modify file(s) with this exception, you may extend this exception to
18 * your version of the file(s), but you are not obligated to do so. If
19 * you do not wish to do so, delete this exception statement from your
20 * version. If you delete this exception statement from all source files
21 * in the program, then also delete it here.
22 *
23 * This program is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 **/
31
32
33 #include "../PrecompiledHeadersServer.h"
34 #include "LookupResource.h"
35
36 #include "../../Core/OrthancException.h"
37
38 namespace Orthanc
39 {
40 LookupResource::Level::Level(ResourceType level)
41 {
42 const DicomTag* tags = NULL;
43 size_t size;
44
45 LookupIdentifierQuery::LoadIdentifiers(tags, size, level);
46
47 for (size_t i = 0; i < size; i++)
48 {
49 identifiers_.insert(tags[i]);
50 }
51
52 DicomMap::LoadMainDicomTags(tags, size, level);
53
54 for (size_t i = 0; i < size; i++)
55 {
56 if (identifiers_.find(tags[i]) == identifiers_.end())
57 {
58 mainTags_.insert(tags[i]);
59 }
60 }
61 }
62
63 LookupResource::Level::~Level()
64 {
65 for (Constraints::iterator it = mainTagsConstraints_.begin();
66 it != mainTagsConstraints_.end(); ++it)
67 {
68 delete *it;
69 }
70
71 for (Constraints::iterator it = identifiersConstraints_.begin();
72 it != identifiersConstraints_.end(); ++it)
73 {
74 delete *it;
75 }
76 }
77
78 bool LookupResource::Level::Add(std::auto_ptr<IFindConstraint>& constraint)
79 {
80 if (identifiers_.find(constraint->GetTag()) != identifiers_.end())
81 {
82 identifiersConstraints_.push_back(constraint.release());
83 return true;
84 }
85 else if (mainTags_.find(constraint->GetTag()) != mainTags_.end())
86 {
87 mainTagsConstraints_.push_back(constraint.release());
88 return true;
89 }
90 else
91 {
92 return false;
93 }
94 }
95
96
97 LookupResource::LookupResource(ResourceType level) : level_(level)
98 {
99 switch (level)
100 {
101 case ResourceType_Patient:
102 levels_[ResourceType_Patient] = new Level(ResourceType_Patient);
103 break;
104
105 case ResourceType_Study:
106 levels_[ResourceType_Study] = new Level(ResourceType_Study);
107 // Do not add "break" here
108
109 case ResourceType_Series:
110 levels_[ResourceType_Series] = new Level(ResourceType_Series);
111 // Do not add "break" here
112
113 case ResourceType_Instance:
114 levels_[ResourceType_Instance] = new Level(ResourceType_Instance);
115 break;
116
117 default:
118 throw OrthancException(ErrorCode_InternalError);
119 }
120 }
121
122
123 LookupResource::~LookupResource()
124 {
125 for (Levels::iterator it = levels_.begin();
126 it != levels_.end(); ++it)
127 {
128 delete it->second;
129 }
130
131 for (Constraints::iterator it = unoptimizedConstraints_.begin();
132 it != unoptimizedConstraints_.end(); ++it)
133 {
134 delete *it;
135 }
136 }
137
138
139
140 bool LookupResource::AddInternal(ResourceType level,
141 std::auto_ptr<IFindConstraint>& constraint)
142 {
143 Levels::iterator it = levels_.find(level);
144 if (it != levels_.end())
145 {
146 if (it->second->Add(constraint))
147 {
148 return true;
149 }
150 }
151
152 return false;
153 }
154
155
156 void LookupResource::Add(IFindConstraint* constraint)
157 {
158 std::auto_ptr<IFindConstraint> c(constraint);
159
160 if (!AddInternal(ResourceType_Patient, c) &&
161 !AddInternal(ResourceType_Study, c) &&
162 !AddInternal(ResourceType_Series, c) &&
163 !AddInternal(ResourceType_Instance, c))
164 {
165 unoptimizedConstraints_.push_back(c.release());
166 }
167 }
168
169
170 static int64_t ChooseOneInstance(IDatabaseWrapper& database,
171 int64_t parent,
172 ResourceType type)
173 {
174 for (;;)
175 {
176 if (type == ResourceType_Instance)
177 {
178 return parent;
179 }
180
181 std::list<int64_t> children;
182 database.GetChildrenInternalId(children, parent);
183
184 if (children.empty())
185 {
186 throw OrthancException(ErrorCode_InternalError);
187 }
188
189 parent = children.front();
190 type = GetChildResourceType(type);
191 }
192 }
193
194 }