Mercurial > hg > orthanc
annotate OrthancServer/ServerIndex.cpp @ 231:8098448bd827
export log
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 30 Nov 2012 12:18:44 +0100 |
parents | 8a26a8e85edf |
children | 5368bbe813cf |
rev | line source |
---|---|
0 | 1 /** |
62 | 2 * Orthanc - A Lightweight, RESTful DICOM Store |
0 | 3 * Copyright (C) 2012 Medical Physics Department, CHU of Liege, |
4 * 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. | |
136 | 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. | |
0 | 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 "ServerIndex.h" | |
34 | |
6 | 35 #ifndef NOMINMAX |
2 | 36 #define NOMINMAX |
6 | 37 #endif |
38 | |
8 | 39 #include "EmbeddedResources.h" |
0 | 40 #include "../Core/Toolbox.h" |
41 #include "../Core/Uuid.h" | |
42 #include "../Core/DicomFormat/DicomArray.h" | |
43 #include "../Core/SQLite/Transaction.h" | |
44 #include "FromDcmtkBridge.h" | |
226
8a26a8e85edf
refactoring to read files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
224
diff
changeset
|
45 #include "ServerContext.h" |
0 | 46 |
47 #include <boost/lexical_cast.hpp> | |
48 #include <stdio.h> | |
108 | 49 #include <glog/logging.h> |
0 | 50 |
62 | 51 namespace Orthanc |
0 | 52 { |
53 namespace Internals | |
54 { | |
202 | 55 class ServerIndexListener : public IServerIndexListener |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
56 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
57 private: |
226
8a26a8e85edf
refactoring to read files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
224
diff
changeset
|
58 ServerContext& context_; |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
59 bool hasRemainingLevel_; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
60 ResourceType remainingType_; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
61 std::string remainingPublicId_; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
62 |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
63 public: |
226
8a26a8e85edf
refactoring to read files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
224
diff
changeset
|
64 ServerIndexListener(ServerContext& context) : |
8a26a8e85edf
refactoring to read files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
224
diff
changeset
|
65 context_(context), |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
66 hasRemainingLevel_(false) |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
67 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
68 assert(ResourceType_Patient < ResourceType_Study && |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
69 ResourceType_Study < ResourceType_Series && |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
70 ResourceType_Series < ResourceType_Instance); |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
71 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
72 |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
73 void Reset() |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
74 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
75 hasRemainingLevel_ = false; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
76 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
77 |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
78 virtual void SignalRemainingAncestor(ResourceType parentType, |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
79 const std::string& publicId) |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
80 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
81 LOG(INFO) << "Remaining ancestor \"" << publicId << "\" (" << parentType << ")"; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
82 |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
83 if (hasRemainingLevel_) |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
84 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
85 if (parentType < remainingType_) |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
86 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
87 remainingType_ = parentType; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
88 remainingPublicId_ = publicId; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
89 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
90 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
91 else |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
92 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
93 hasRemainingLevel_ = true; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
94 remainingType_ = parentType; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
95 remainingPublicId_ = publicId; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
96 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
97 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
98 |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
99 virtual void SignalFileDeleted(const std::string& fileUuid) |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
100 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
101 assert(Toolbox::IsUuid(fileUuid)); |
226
8a26a8e85edf
refactoring to read files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
224
diff
changeset
|
102 context_.RemoveFile(fileUuid); |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
103 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
104 |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
105 bool HasRemainingLevel() const |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
106 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
107 return hasRemainingLevel_; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
108 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
109 |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
110 ResourceType GetRemainingType() const |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
111 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
112 assert(HasRemainingLevel()); |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
113 return remainingType_; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
114 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
115 |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
116 const std::string& GetRemainingPublicId() const |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
117 { |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
118 assert(HasRemainingLevel()); |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
119 return remainingPublicId_; |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
120 } |
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
121 }; |
0 | 122 } |
123 | |
124 | |
212 | 125 bool ServerIndex::DeleteResource(Json::Value& target, |
0 | 126 const std::string& uuid, |
202 | 127 ResourceType expectedType) |
0 | 128 { |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
129 boost::mutex::scoped_lock lock(mutex_); |
0 | 130 |
202 | 131 listener_->Reset(); |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
132 |
202 | 133 std::auto_ptr<SQLite::Transaction> t(db_->StartTransaction()); |
134 t->Begin(); | |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
135 |
202 | 136 int64_t id; |
137 ResourceType type; | |
138 if (!db_->LookupResource(uuid, id, type) || | |
139 expectedType != type) | |
0 | 140 { |
141 return false; | |
142 } | |
202 | 143 |
144 db_->DeleteResource(id); | |
0 | 145 |
202 | 146 if (listener_->HasRemainingLevel()) |
0 | 147 { |
202 | 148 ResourceType type = listener_->GetRemainingType(); |
149 const std::string& uuid = listener_->GetRemainingPublicId(); | |
0 | 150 |
151 target["RemainingAncestor"] = Json::Value(Json::objectValue); | |
204 | 152 target["RemainingAncestor"]["Path"] = GetBasePath(type, uuid); |
202 | 153 target["RemainingAncestor"]["Type"] = ToString(type); |
0 | 154 target["RemainingAncestor"]["ID"] = uuid; |
155 } | |
156 else | |
157 { | |
158 target["RemainingAncestor"] = Json::nullValue; | |
159 } | |
160 | |
202 | 161 t->Commit(); |
162 | |
0 | 163 return true; |
164 } | |
165 | |
166 | |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
167 static void FlushThread(DatabaseWrapper* db, |
220 | 168 boost::mutex* mutex, |
169 unsigned int sleep) | |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
170 { |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
171 LOG(INFO) << "Starting the database flushing thread (sleep = " << sleep << ")"; |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
172 |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
173 while (1) |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
174 { |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
175 boost::this_thread::sleep(boost::posix_time::seconds(sleep)); |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
176 boost::mutex::scoped_lock lock(*mutex); |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
177 db->FlushToDisk(); |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
178 } |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
179 } |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
180 |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
181 |
226
8a26a8e85edf
refactoring to read files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
224
diff
changeset
|
182 ServerIndex::ServerIndex(ServerContext& context, |
220 | 183 const std::string& dbPath) : mutex_() |
186
f68c039b0571
preparing refactoring of ServerIndex
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
180
diff
changeset
|
184 { |
226
8a26a8e85edf
refactoring to read files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
224
diff
changeset
|
185 listener_.reset(new Internals::ServerIndexListener(context)); |
186
f68c039b0571
preparing refactoring of ServerIndex
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
180
diff
changeset
|
186 |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
187 if (dbPath == ":memory:") |
180
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
188 { |
202 | 189 db_.reset(new DatabaseWrapper(*listener_)); |
180
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
190 } |
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
191 else |
0 | 192 { |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
193 boost::filesystem::path p = dbPath; |
180
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
194 |
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
195 try |
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
196 { |
201
bee20e978835
refactoring of delete
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
200
diff
changeset
|
197 boost::filesystem::create_directories(p); |
180
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
198 } |
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
199 catch (boost::filesystem::filesystem_error) |
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
200 { |
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
201 } |
626777d01dc4
use of hashes to index dicom objects
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
179
diff
changeset
|
202 |
202 | 203 db_.reset(new DatabaseWrapper(p.string() + "/index", *listener_)); |
0 | 204 } |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
205 |
220 | 206 unsigned int sleep; |
207 try | |
208 { | |
209 std::string sleepString = db_->GetGlobalProperty(GlobalProperty_FlushSleep); | |
210 sleep = boost::lexical_cast<unsigned int>(sleepString); | |
211 } | |
212 catch (boost::bad_lexical_cast&) | |
213 { | |
214 // By default, wait for 10 seconds before flushing | |
215 sleep = 10; | |
216 } | |
217 | |
218 flushThread_ = boost::thread(FlushThread, db_.get(), &mutex_, sleep); | |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
219 } |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
220 |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
221 |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
222 ServerIndex::~ServerIndex() |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
223 { |
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
224 LOG(INFO) << "Stopping the database flushing thread"; |
220 | 225 /*flushThread_.terminate(); |
226 flushThread_.join();*/ | |
0 | 227 } |
228 | |
229 | |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
230 StoreStatus ServerIndex::Store(const DicomMap& dicomSummary, |
0 | 231 const std::string& fileUuid, |
232 uint64_t uncompressedFileSize, | |
233 const std::string& jsonUuid, | |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
234 const std::string& remoteAet) |
0 | 235 { |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
236 boost::mutex::scoped_lock lock(mutex_); |
0 | 237 |
178 | 238 DicomInstanceHasher hasher(dicomSummary); |
0 | 239 |
240 try | |
241 { | |
202 | 242 std::auto_ptr<SQLite::Transaction> t(db_->StartTransaction()); |
243 t->Begin(); | |
0 | 244 |
202 | 245 int64_t patient, study, series, instance; |
246 ResourceType type; | |
247 bool isNewSeries = false; | |
248 | |
249 // Do nothing if the instance already exists | |
250 if (db_->LookupResource(hasher.HashInstance(), patient, type)) | |
0 | 251 { |
202 | 252 assert(type == ResourceType_Instance); |
0 | 253 return StoreStatus_AlreadyStored; |
254 } | |
255 | |
202 | 256 // Create the instance |
257 instance = db_->CreateResource(hasher.HashInstance(), ResourceType_Instance); | |
258 | |
259 DicomMap dicom; | |
260 dicomSummary.ExtractInstanceInformation(dicom); | |
261 db_->SetMainDicomTags(instance, dicom); | |
262 | |
263 // Create the patient/study/series/instance hierarchy | |
264 if (!db_->LookupResource(hasher.HashSeries(), series, type)) | |
0 | 265 { |
202 | 266 // This is a new series |
267 isNewSeries = true; | |
268 series = db_->CreateResource(hasher.HashSeries(), ResourceType_Series); | |
269 dicomSummary.ExtractSeriesInformation(dicom); | |
270 db_->SetMainDicomTags(series, dicom); | |
271 db_->AttachChild(series, instance); | |
272 | |
273 if (!db_->LookupResource(hasher.HashStudy(), study, type)) | |
274 { | |
275 // This is a new study | |
276 study = db_->CreateResource(hasher.HashStudy(), ResourceType_Study); | |
277 dicomSummary.ExtractStudyInformation(dicom); | |
278 db_->SetMainDicomTags(study, dicom); | |
279 db_->AttachChild(study, series); | |
280 | |
281 if (!db_->LookupResource(hasher.HashPatient(), patient, type)) | |
282 { | |
283 // This is a new patient | |
284 patient = db_->CreateResource(hasher.HashPatient(), ResourceType_Patient); | |
285 dicomSummary.ExtractPatientInformation(dicom); | |
286 db_->SetMainDicomTags(patient, dicom); | |
287 db_->AttachChild(patient, study); | |
288 } | |
289 else | |
290 { | |
291 assert(type == ResourceType_Patient); | |
292 db_->AttachChild(patient, study); | |
293 } | |
294 } | |
295 else | |
296 { | |
297 assert(type == ResourceType_Study); | |
298 db_->AttachChild(study, series); | |
299 } | |
0 | 300 } |
301 else | |
302 { | |
202 | 303 assert(type == ResourceType_Series); |
304 db_->AttachChild(series, instance); | |
0 | 305 } |
306 | |
202 | 307 // Attach the files to the newly created instance |
308 db_->AttachFile(instance, AttachedFileType_Dicom, fileUuid, uncompressedFileSize); | |
309 db_->AttachFile(instance, AttachedFileType_Json, jsonUuid, 0); // TODO "0" | |
310 | |
311 // Attach the metadata | |
312 db_->SetMetadata(instance, MetadataType_Instance_ReceptionDate, Toolbox::GetNowIsoString()); | |
313 db_->SetMetadata(instance, MetadataType_Instance_RemoteAet, remoteAet); | |
314 | |
315 const DicomValue* value; | |
316 if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_INSTANCE_NUMBER)) != NULL || | |
317 (value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGE_INDEX)) != NULL) | |
0 | 318 { |
202 | 319 db_->SetMetadata(instance, MetadataType_Instance_IndexInSeries, value->AsString()); |
0 | 320 } |
321 | |
202 | 322 if (isNewSeries) |
323 { | |
324 if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_SLICES)) != NULL || | |
325 (value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGES_IN_ACQUISITION)) != NULL || | |
326 (value = dicomSummary.TestAndGetValue(DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES)) != NULL) | |
327 { | |
328 db_->SetMetadata(series, MetadataType_Series_ExpectedNumberOfInstances, value->AsString()); | |
329 } | |
330 } | |
331 | |
205
6ab754744446
logging of completed series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
204
diff
changeset
|
332 // Check whether the series of this new instance is now completed |
6ab754744446
logging of completed series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
204
diff
changeset
|
333 SeriesStatus seriesStatus = GetSeriesStatus(series); |
6ab754744446
logging of completed series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
204
diff
changeset
|
334 if (seriesStatus == SeriesStatus_Complete) |
6ab754744446
logging of completed series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
204
diff
changeset
|
335 { |
6ab754744446
logging of completed series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
204
diff
changeset
|
336 db_->LogChange(ChangeType_CompletedSeries, series, ResourceType_Series); |
6ab754744446
logging of completed series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
204
diff
changeset
|
337 } |
6ab754744446
logging of completed series
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
204
diff
changeset
|
338 |
202 | 339 t->Commit(); |
340 | |
0 | 341 return StoreStatus_Success; |
342 } | |
62 | 343 catch (OrthancException& e) |
0 | 344 { |
202 | 345 LOG(ERROR) << "EXCEPTION2 [" << e.What() << "]" << " " << db_->GetErrorMessage(); |
0 | 346 } |
347 | |
348 return StoreStatus_Failure; | |
349 } | |
350 | |
351 | |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
352 uint64_t ServerIndex::GetTotalCompressedSize() |
0 | 353 { |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
354 boost::mutex::scoped_lock lock(mutex_); |
202 | 355 return db_->GetTotalCompressedSize(); |
0 | 356 } |
357 | |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
358 uint64_t ServerIndex::GetTotalUncompressedSize() |
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
359 { |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
360 boost::mutex::scoped_lock lock(mutex_); |
202 | 361 return db_->GetTotalUncompressedSize(); |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
362 } |
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
363 |
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
186
diff
changeset
|
364 |
199 | 365 SeriesStatus ServerIndex::GetSeriesStatus(int id) |
366 { | |
367 // Get the expected number of instances in this series (from the metadata) | |
202 | 368 std::string s = db_->GetMetadata(id, MetadataType_Series_ExpectedNumberOfInstances); |
199 | 369 |
370 size_t expected; | |
371 try | |
372 { | |
373 expected = boost::lexical_cast<size_t>(s); | |
374 if (expected < 0) | |
375 { | |
376 return SeriesStatus_Unknown; | |
377 } | |
378 } | |
379 catch (boost::bad_lexical_cast&) | |
380 { | |
381 return SeriesStatus_Unknown; | |
382 } | |
383 | |
384 // Loop over the instances of this series | |
385 std::list<int64_t> children; | |
202 | 386 db_->GetChildrenInternalId(children, id); |
199 | 387 |
388 std::set<size_t> instances; | |
389 for (std::list<int64_t>::const_iterator | |
390 it = children.begin(); it != children.end(); it++) | |
391 { | |
392 // Get the index of this instance in the series | |
202 | 393 s = db_->GetMetadata(*it, MetadataType_Instance_IndexInSeries); |
199 | 394 size_t index; |
395 try | |
396 { | |
397 index = boost::lexical_cast<size_t>(s); | |
398 } | |
399 catch (boost::bad_lexical_cast&) | |
400 { | |
401 return SeriesStatus_Unknown; | |
402 } | |
403 | |
404 if (index <= 0 || index > expected) | |
405 { | |
406 // Out-of-range instance index | |
407 return SeriesStatus_Inconsistent; | |
408 } | |
409 | |
410 if (instances.find(index) != instances.end()) | |
411 { | |
412 // Twice the same instance index | |
413 return SeriesStatus_Inconsistent; | |
414 } | |
415 | |
416 instances.insert(index); | |
417 } | |
418 | |
419 if (instances.size() == expected) | |
420 { | |
421 return SeriesStatus_Complete; | |
422 } | |
423 else | |
424 { | |
425 return SeriesStatus_Missing; | |
426 } | |
427 } | |
428 | |
429 | |
430 | |
202 | 431 void ServerIndex::MainDicomTagsToJson(Json::Value& target, |
432 int64_t resourceId) | |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
433 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
434 DicomMap tags; |
202 | 435 db_->GetMainDicomTags(tags, resourceId); |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
436 target["MainDicomTags"] = Json::objectValue; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
437 FromDcmtkBridge::ToJson(target["MainDicomTags"], tags); |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
438 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
439 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
440 bool ServerIndex::LookupResource(Json::Value& result, |
199 | 441 const std::string& publicId, |
442 ResourceType expectedType) | |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
443 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
444 result = Json::objectValue; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
445 |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
446 boost::mutex::scoped_lock lock(mutex_); |
199 | 447 |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
448 // Lookup for the requested resource |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
449 int64_t id; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
450 ResourceType type; |
202 | 451 if (!db_->LookupResource(publicId, id, type) || |
199 | 452 type != expectedType) |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
453 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
454 return false; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
455 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
456 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
457 // Find the parent resource (if it exists) |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
458 if (type != ResourceType_Patient) |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
459 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
460 int64_t parentId; |
202 | 461 if (!db_->LookupParent(parentId, id)) |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
462 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
463 throw OrthancException(ErrorCode_InternalError); |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
464 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
465 |
202 | 466 std::string parent = db_->GetPublicId(parentId); |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
467 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
468 switch (type) |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
469 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
470 case ResourceType_Study: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
471 result["ParentPatient"] = parent; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
472 break; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
473 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
474 case ResourceType_Series: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
475 result["ParentStudy"] = parent; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
476 break; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
477 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
478 case ResourceType_Instance: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
479 result["ParentSeries"] = parent; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
480 break; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
481 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
482 default: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
483 throw OrthancException(ErrorCode_InternalError); |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
484 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
485 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
486 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
487 // List the children resources |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
488 std::list<std::string> children; |
202 | 489 db_->GetChildrenPublicId(children, id); |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
490 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
491 if (type != ResourceType_Instance) |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
492 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
493 Json::Value c = Json::arrayValue; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
494 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
495 for (std::list<std::string>::const_iterator |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
496 it = children.begin(); it != children.end(); it++) |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
497 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
498 c.append(*it); |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
499 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
500 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
501 switch (type) |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
502 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
503 case ResourceType_Patient: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
504 result["Studies"] = c; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
505 break; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
506 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
507 case ResourceType_Study: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
508 result["Series"] = c; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
509 break; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
510 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
511 case ResourceType_Series: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
512 result["Instances"] = c; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
513 break; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
514 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
515 default: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
516 throw OrthancException(ErrorCode_InternalError); |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
517 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
518 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
519 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
520 // Set the resource type |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
521 switch (type) |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
522 { |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
523 case ResourceType_Patient: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
524 result["Type"] = "Patient"; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
525 break; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
526 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
527 case ResourceType_Study: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
528 result["Type"] = "Study"; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
529 break; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
530 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
531 case ResourceType_Series: |
199 | 532 { |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
533 result["Type"] = "Series"; |
199 | 534 result["Status"] = ToString(GetSeriesStatus(id)); |
535 | |
200
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
536 int i; |
202 | 537 if (db_->GetMetadataAsInteger(i, id, MetadataType_Series_ExpectedNumberOfInstances)) |
200
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
538 result["ExpectedNumberOfInstances"] = i; |
202 | 539 else |
199 | 540 result["ExpectedNumberOfInstances"] = Json::nullValue; |
200
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
541 |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
542 break; |
199 | 543 } |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
544 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
545 case ResourceType_Instance: |
200
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
546 { |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
547 result["Type"] = "Instance"; |
200
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
548 |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
549 std::string fileUuid; |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
550 uint64_t uncompressedSize; |
202 | 551 if (!db_->LookupFile(id, AttachedFileType_Dicom, fileUuid, uncompressedSize)) |
200
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
552 { |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
553 throw OrthancException(ErrorCode_InternalError); |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
554 } |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
555 |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
556 result["FileSize"] = static_cast<unsigned int>(uncompressedSize); |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
557 result["FileUuid"] = fileUuid; |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
558 |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
559 int i; |
202 | 560 if (db_->GetMetadataAsInteger(i, id, MetadataType_Instance_IndexInSeries)) |
200
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
561 result["IndexInSeries"] = i; |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
562 else |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
563 result["IndexInSeries"] = Json::nullValue; |
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
564 |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
565 break; |
200
9c58b2b03cf0
refactoring of read operations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
199
diff
changeset
|
566 } |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
567 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
568 default: |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
569 throw OrthancException(ErrorCode_InternalError); |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
570 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
571 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
572 // Record the remaining information |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
573 result["ID"] = publicId; |
202 | 574 MainDicomTagsToJson(result, id); |
198
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
575 |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
576 return true; |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
577 } |
663cc6c46d0a
before refactoring of ServerIndex::GetXXX
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
197
diff
changeset
|
578 |
0 | 579 |
193
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
580 bool ServerIndex::GetFile(std::string& fileUuid, |
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
581 CompressionType& compressionType, |
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
582 const std::string& instanceUuid, |
197
530a25320461
removal of text as ids in sqlite db
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
194
diff
changeset
|
583 AttachedFileType contentType) |
0 | 584 { |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
585 boost::mutex::scoped_lock lock(mutex_); |
0 | 586 |
193
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
587 int64_t id; |
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
588 ResourceType type; |
202 | 589 if (!db_->LookupResource(instanceUuid, id, type) || |
193
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
590 type != ResourceType_Instance) |
192
c56dc32266e0
refactoring getfile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
591 { |
c56dc32266e0
refactoring getfile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
592 throw OrthancException(ErrorCode_InternalError); |
c56dc32266e0
refactoring getfile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
593 } |
193
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
594 |
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
595 uint64_t compressedSize, uncompressedSize; |
a1b9d1e1497b
failed attempt to compile with linux standard base
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
596 |
202 | 597 return db_->LookupFile(id, contentType, fileUuid, compressedSize, uncompressedSize, compressionType); |
192
c56dc32266e0
refactoring getfile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
598 } |
c56dc32266e0
refactoring getfile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
599 |
c56dc32266e0
refactoring getfile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
600 |
c56dc32266e0
refactoring getfile
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
601 |
0 | 602 void ServerIndex::GetAllUuids(Json::Value& target, |
190 | 603 ResourceType resourceType) |
0 | 604 { |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
605 boost::mutex::scoped_lock lock(mutex_); |
202 | 606 db_->GetAllPublicIds(target, resourceType); |
0 | 607 } |
608 | |
609 | |
610 bool ServerIndex::GetChanges(Json::Value& target, | |
204 | 611 int64_t since, |
0 | 612 unsigned int maxResults) |
613 { | |
206
4453a010d0db
flush to disk thread
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
205
diff
changeset
|
614 boost::mutex::scoped_lock lock(mutex_); |
0 | 615 |
204 | 616 db_->GetChanges(target, since, maxResults); |
0 | 617 |
204 | 618 return true; |
0 | 619 } |
231 | 620 |
621 void ServerIndex::LogExportedResource(const std::string& publicId, | |
622 const std::string& remoteModality) | |
623 { | |
624 boost::mutex::scoped_lock lock(mutex_); | |
625 | |
626 int64_t id; | |
627 ResourceType type; | |
628 if (!db_->LookupResource(publicId, id, type)) | |
629 { | |
630 throw OrthancException(ErrorCode_InternalError); | |
631 } | |
632 | |
633 std::string patientId; | |
634 std::string studyInstanceUid; | |
635 std::string seriesInstanceUid; | |
636 std::string sopInstanceUid; | |
637 | |
638 int64_t currentId = id; | |
639 ResourceType currentType = type; | |
640 | |
641 // Iteratively go up inside the patient/study/series/instance hierarchy | |
642 bool done = false; | |
643 while (!done) | |
644 { | |
645 DicomMap map; | |
646 db_->GetMainDicomTags(map, currentId); | |
647 | |
648 switch (currentType) | |
649 { | |
650 case ResourceType_Patient: | |
651 patientId = map.GetValue(DICOM_TAG_PATIENT_ID).AsString(); | |
652 done = true; | |
653 break; | |
654 | |
655 case ResourceType_Study: | |
656 studyInstanceUid = map.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString(); | |
657 currentType = ResourceType_Patient; | |
658 break; | |
659 | |
660 case ResourceType_Series: | |
661 seriesInstanceUid = map.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).AsString(); | |
662 currentType = ResourceType_Study; | |
663 break; | |
664 | |
665 case ResourceType_Instance: | |
666 sopInstanceUid = map.GetValue(DICOM_TAG_SOP_INSTANCE_UID).AsString(); | |
667 currentType = ResourceType_Series; | |
668 break; | |
669 | |
670 default: | |
671 throw OrthancException(ErrorCode_InternalError); | |
672 } | |
673 | |
674 // If we have not reached the Patient level, find the parent of | |
675 // the current resource | |
676 if (!done) | |
677 { | |
678 assert(db_->LookupParent(currentId, currentId)); | |
679 } | |
680 } | |
681 | |
682 // No need for a SQLite::Transaction here, as we only insert 1 record | |
683 db_->LogExportedResource(type, | |
684 publicId, | |
685 remoteModality, | |
686 patientId, | |
687 studyInstanceUid, | |
688 seriesInstanceUid, | |
689 sopInstanceUid); | |
690 } | |
691 | |
692 | |
693 bool ServerIndex::GetExportedResources(Json::Value& target, | |
694 int64_t since, | |
695 unsigned int maxResults) | |
696 { | |
697 boost::mutex::scoped_lock lock(mutex_); | |
698 db_->GetExportedResources(target, since, maxResults); | |
699 return true; | |
700 } | |
0 | 701 } |