Mercurial > hg > orthanc
comparison OrthancServer/Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.cpp @ 4044:d25f4c0fa160 framework
splitting code into OrthancFramework and OrthancServer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 10 Jun 2020 20:30:34 +0200 |
parents | Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.cpp@94f4a18a79cc |
children | cd363608551a |
comparison
equal
deleted
inserted
replaced
4043:6c6239aec462 | 4044:d25f4c0fa160 |
---|---|
1 /** | |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #include "PrecompiledHeadersServer.h" | |
35 #include "DatabaseWrapperBase.h" | |
36 | |
37 #include <stdio.h> | |
38 #include <memory> | |
39 | |
40 namespace Orthanc | |
41 { | |
42 void DatabaseWrapperBase::SetGlobalProperty(GlobalProperty property, | |
43 const std::string& value) | |
44 { | |
45 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT OR REPLACE INTO GlobalProperties VALUES(?, ?)"); | |
46 s.BindInt(0, property); | |
47 s.BindString(1, value); | |
48 s.Run(); | |
49 } | |
50 | |
51 bool DatabaseWrapperBase::LookupGlobalProperty(std::string& target, | |
52 GlobalProperty property) | |
53 { | |
54 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
55 "SELECT value FROM GlobalProperties WHERE property=?"); | |
56 s.BindInt(0, property); | |
57 | |
58 if (!s.Step()) | |
59 { | |
60 return false; | |
61 } | |
62 else | |
63 { | |
64 target = s.ColumnString(0); | |
65 return true; | |
66 } | |
67 } | |
68 | |
69 int64_t DatabaseWrapperBase::CreateResource(const std::string& publicId, | |
70 ResourceType type) | |
71 { | |
72 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO Resources VALUES(NULL, ?, ?, NULL)"); | |
73 s.BindInt(0, type); | |
74 s.BindString(1, publicId); | |
75 s.Run(); | |
76 return db_.GetLastInsertRowId(); | |
77 } | |
78 | |
79 bool DatabaseWrapperBase::LookupResource(int64_t& id, | |
80 ResourceType& type, | |
81 const std::string& publicId) | |
82 { | |
83 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
84 "SELECT internalId, resourceType FROM Resources WHERE publicId=?"); | |
85 s.BindString(0, publicId); | |
86 | |
87 if (!s.Step()) | |
88 { | |
89 return false; | |
90 } | |
91 else | |
92 { | |
93 id = s.ColumnInt(0); | |
94 type = static_cast<ResourceType>(s.ColumnInt(1)); | |
95 | |
96 // Check whether there is a single resource with this public id | |
97 assert(!s.Step()); | |
98 | |
99 return true; | |
100 } | |
101 } | |
102 | |
103 ErrorCode DatabaseWrapperBase::LookupParent(bool& found, | |
104 int64_t& parentId, | |
105 int64_t resourceId) | |
106 { | |
107 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
108 "SELECT parentId FROM Resources WHERE internalId=?"); | |
109 s.BindInt64(0, resourceId); | |
110 | |
111 if (!s.Step()) | |
112 { | |
113 return ErrorCode_UnknownResource; | |
114 } | |
115 | |
116 if (s.ColumnIsNull(0)) | |
117 { | |
118 found = false; | |
119 } | |
120 else | |
121 { | |
122 found = true; | |
123 parentId = s.ColumnInt(0); | |
124 } | |
125 | |
126 return ErrorCode_Success; | |
127 } | |
128 | |
129 bool DatabaseWrapperBase::GetPublicId(std::string& result, | |
130 int64_t resourceId) | |
131 { | |
132 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
133 "SELECT publicId FROM Resources WHERE internalId=?"); | |
134 s.BindInt64(0, resourceId); | |
135 | |
136 if (!s.Step()) | |
137 { | |
138 return false; | |
139 } | |
140 else | |
141 { | |
142 result = s.ColumnString(0); | |
143 return true; | |
144 } | |
145 } | |
146 | |
147 | |
148 ErrorCode DatabaseWrapperBase::GetResourceType(ResourceType& result, | |
149 int64_t resourceId) | |
150 { | |
151 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
152 "SELECT resourceType FROM Resources WHERE internalId=?"); | |
153 s.BindInt64(0, resourceId); | |
154 | |
155 if (s.Step()) | |
156 { | |
157 result = static_cast<ResourceType>(s.ColumnInt(0)); | |
158 return ErrorCode_Success; | |
159 } | |
160 else | |
161 { | |
162 return ErrorCode_UnknownResource; | |
163 } | |
164 } | |
165 | |
166 | |
167 void DatabaseWrapperBase::AttachChild(int64_t parent, | |
168 int64_t child) | |
169 { | |
170 SQLite::Statement s(db_, SQLITE_FROM_HERE, "UPDATE Resources SET parentId = ? WHERE internalId = ?"); | |
171 s.BindInt64(0, parent); | |
172 s.BindInt64(1, child); | |
173 s.Run(); | |
174 } | |
175 | |
176 | |
177 void DatabaseWrapperBase::SetMetadata(int64_t id, | |
178 MetadataType type, | |
179 const std::string& value) | |
180 { | |
181 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT OR REPLACE INTO Metadata VALUES(?, ?, ?)"); | |
182 s.BindInt64(0, id); | |
183 s.BindInt(1, type); | |
184 s.BindString(2, value); | |
185 s.Run(); | |
186 } | |
187 | |
188 void DatabaseWrapperBase::DeleteMetadata(int64_t id, | |
189 MetadataType type) | |
190 { | |
191 SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM Metadata WHERE id=? and type=?"); | |
192 s.BindInt64(0, id); | |
193 s.BindInt(1, type); | |
194 s.Run(); | |
195 } | |
196 | |
197 bool DatabaseWrapperBase::LookupMetadata(std::string& target, | |
198 int64_t id, | |
199 MetadataType type) | |
200 { | |
201 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
202 "SELECT value FROM Metadata WHERE id=? AND type=?"); | |
203 s.BindInt64(0, id); | |
204 s.BindInt(1, type); | |
205 | |
206 if (!s.Step()) | |
207 { | |
208 return false; | |
209 } | |
210 else | |
211 { | |
212 target = s.ColumnString(0); | |
213 return true; | |
214 } | |
215 } | |
216 | |
217 void DatabaseWrapperBase::ListAvailableMetadata(std::list<MetadataType>& target, | |
218 int64_t id) | |
219 { | |
220 target.clear(); | |
221 | |
222 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT type FROM Metadata WHERE id=?"); | |
223 s.BindInt64(0, id); | |
224 | |
225 while (s.Step()) | |
226 { | |
227 target.push_back(static_cast<MetadataType>(s.ColumnInt(0))); | |
228 } | |
229 } | |
230 | |
231 | |
232 void DatabaseWrapperBase::AddAttachment(int64_t id, | |
233 const FileInfo& attachment) | |
234 { | |
235 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO AttachedFiles VALUES(?, ?, ?, ?, ?, ?, ?, ?)"); | |
236 s.BindInt64(0, id); | |
237 s.BindInt(1, attachment.GetContentType()); | |
238 s.BindString(2, attachment.GetUuid()); | |
239 s.BindInt64(3, attachment.GetCompressedSize()); | |
240 s.BindInt64(4, attachment.GetUncompressedSize()); | |
241 s.BindInt(5, attachment.GetCompressionType()); | |
242 s.BindString(6, attachment.GetUncompressedMD5()); | |
243 s.BindString(7, attachment.GetCompressedMD5()); | |
244 s.Run(); | |
245 } | |
246 | |
247 | |
248 void DatabaseWrapperBase::DeleteAttachment(int64_t id, | |
249 FileContentType attachment) | |
250 { | |
251 SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM AttachedFiles WHERE id=? AND fileType=?"); | |
252 s.BindInt64(0, id); | |
253 s.BindInt(1, attachment); | |
254 s.Run(); | |
255 } | |
256 | |
257 | |
258 | |
259 void DatabaseWrapperBase::ListAvailableAttachments(std::list<FileContentType>& target, | |
260 int64_t id) | |
261 { | |
262 target.clear(); | |
263 | |
264 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
265 "SELECT fileType FROM AttachedFiles WHERE id=?"); | |
266 s.BindInt64(0, id); | |
267 | |
268 while (s.Step()) | |
269 { | |
270 target.push_back(static_cast<FileContentType>(s.ColumnInt(0))); | |
271 } | |
272 } | |
273 | |
274 bool DatabaseWrapperBase::LookupAttachment(FileInfo& attachment, | |
275 int64_t id, | |
276 FileContentType contentType) | |
277 { | |
278 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
279 "SELECT uuid, uncompressedSize, compressionType, compressedSize, uncompressedMD5, compressedMD5 FROM AttachedFiles WHERE id=? AND fileType=?"); | |
280 s.BindInt64(0, id); | |
281 s.BindInt(1, contentType); | |
282 | |
283 if (!s.Step()) | |
284 { | |
285 return false; | |
286 } | |
287 else | |
288 { | |
289 attachment = FileInfo(s.ColumnString(0), | |
290 contentType, | |
291 s.ColumnInt64(1), | |
292 s.ColumnString(4), | |
293 static_cast<CompressionType>(s.ColumnInt(2)), | |
294 s.ColumnInt64(3), | |
295 s.ColumnString(5)); | |
296 return true; | |
297 } | |
298 } | |
299 | |
300 | |
301 void DatabaseWrapperBase::ClearMainDicomTags(int64_t id) | |
302 { | |
303 { | |
304 SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM DicomIdentifiers WHERE id=?"); | |
305 s.BindInt64(0, id); | |
306 s.Run(); | |
307 } | |
308 | |
309 { | |
310 SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM MainDicomTags WHERE id=?"); | |
311 s.BindInt64(0, id); | |
312 s.Run(); | |
313 } | |
314 } | |
315 | |
316 | |
317 void DatabaseWrapperBase::SetMainDicomTag(int64_t id, | |
318 const DicomTag& tag, | |
319 const std::string& value) | |
320 { | |
321 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO MainDicomTags VALUES(?, ?, ?, ?)"); | |
322 s.BindInt64(0, id); | |
323 s.BindInt(1, tag.GetGroup()); | |
324 s.BindInt(2, tag.GetElement()); | |
325 s.BindString(3, value); | |
326 s.Run(); | |
327 } | |
328 | |
329 | |
330 void DatabaseWrapperBase::SetIdentifierTag(int64_t id, | |
331 const DicomTag& tag, | |
332 const std::string& value) | |
333 { | |
334 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO DicomIdentifiers VALUES(?, ?, ?, ?)"); | |
335 s.BindInt64(0, id); | |
336 s.BindInt(1, tag.GetGroup()); | |
337 s.BindInt(2, tag.GetElement()); | |
338 s.BindString(3, value); | |
339 s.Run(); | |
340 } | |
341 | |
342 | |
343 void DatabaseWrapperBase::GetMainDicomTags(DicomMap& map, | |
344 int64_t id) | |
345 { | |
346 map.Clear(); | |
347 | |
348 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT * FROM MainDicomTags WHERE id=?"); | |
349 s.BindInt64(0, id); | |
350 while (s.Step()) | |
351 { | |
352 map.SetValue(s.ColumnInt(1), | |
353 s.ColumnInt(2), | |
354 s.ColumnString(3), false); | |
355 } | |
356 } | |
357 | |
358 | |
359 | |
360 void DatabaseWrapperBase::GetChildrenPublicId(std::list<std::string>& target, | |
361 int64_t id) | |
362 { | |
363 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT a.publicId FROM Resources AS a, Resources AS b " | |
364 "WHERE a.parentId = b.internalId AND b.internalId = ?"); | |
365 s.BindInt64(0, id); | |
366 | |
367 target.clear(); | |
368 | |
369 while (s.Step()) | |
370 { | |
371 target.push_back(s.ColumnString(0)); | |
372 } | |
373 } | |
374 | |
375 | |
376 void DatabaseWrapperBase::GetChildrenInternalId(std::list<int64_t>& target, | |
377 int64_t id) | |
378 { | |
379 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT a.internalId FROM Resources AS a, Resources AS b " | |
380 "WHERE a.parentId = b.internalId AND b.internalId = ?"); | |
381 s.BindInt64(0, id); | |
382 | |
383 target.clear(); | |
384 | |
385 while (s.Step()) | |
386 { | |
387 target.push_back(s.ColumnInt64(0)); | |
388 } | |
389 } | |
390 | |
391 | |
392 void DatabaseWrapperBase::LogChange(int64_t internalId, | |
393 const ServerIndexChange& change) | |
394 { | |
395 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO Changes VALUES(NULL, ?, ?, ?, ?)"); | |
396 s.BindInt(0, change.GetChangeType()); | |
397 s.BindInt64(1, internalId); | |
398 s.BindInt(2, change.GetResourceType()); | |
399 s.BindString(3, change.GetDate()); | |
400 s.Run(); | |
401 } | |
402 | |
403 | |
404 ErrorCode DatabaseWrapperBase::GetChangesInternal(std::list<ServerIndexChange>& target, | |
405 bool& done, | |
406 SQLite::Statement& s, | |
407 uint32_t maxResults) | |
408 { | |
409 target.clear(); | |
410 | |
411 while (target.size() < maxResults && s.Step()) | |
412 { | |
413 int64_t seq = s.ColumnInt64(0); | |
414 ChangeType changeType = static_cast<ChangeType>(s.ColumnInt(1)); | |
415 ResourceType resourceType = static_cast<ResourceType>(s.ColumnInt(3)); | |
416 const std::string& date = s.ColumnString(4); | |
417 | |
418 int64_t internalId = s.ColumnInt64(2); | |
419 std::string publicId; | |
420 if (!GetPublicId(publicId, internalId)) | |
421 { | |
422 return ErrorCode_UnknownResource; | |
423 } | |
424 | |
425 target.push_back(ServerIndexChange(seq, changeType, resourceType, publicId, date)); | |
426 } | |
427 | |
428 done = !(target.size() == maxResults && s.Step()); | |
429 return ErrorCode_Success; | |
430 } | |
431 | |
432 | |
433 ErrorCode DatabaseWrapperBase::GetChanges(std::list<ServerIndexChange>& target, | |
434 bool& done, | |
435 int64_t since, | |
436 uint32_t maxResults) | |
437 { | |
438 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT * FROM Changes WHERE seq>? ORDER BY seq LIMIT ?"); | |
439 s.BindInt64(0, since); | |
440 s.BindInt(1, maxResults + 1); | |
441 return GetChangesInternal(target, done, s, maxResults); | |
442 } | |
443 | |
444 ErrorCode DatabaseWrapperBase::GetLastChange(std::list<ServerIndexChange>& target) | |
445 { | |
446 bool done; // Ignored | |
447 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT * FROM Changes ORDER BY seq DESC LIMIT 1"); | |
448 return GetChangesInternal(target, done, s, 1); | |
449 } | |
450 | |
451 | |
452 void DatabaseWrapperBase::LogExportedResource(const ExportedResource& resource) | |
453 { | |
454 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
455 "INSERT INTO ExportedResources VALUES(NULL, ?, ?, ?, ?, ?, ?, ?, ?)"); | |
456 | |
457 s.BindInt(0, resource.GetResourceType()); | |
458 s.BindString(1, resource.GetPublicId()); | |
459 s.BindString(2, resource.GetModality()); | |
460 s.BindString(3, resource.GetPatientId()); | |
461 s.BindString(4, resource.GetStudyInstanceUid()); | |
462 s.BindString(5, resource.GetSeriesInstanceUid()); | |
463 s.BindString(6, resource.GetSopInstanceUid()); | |
464 s.BindString(7, resource.GetDate()); | |
465 s.Run(); | |
466 } | |
467 | |
468 | |
469 void DatabaseWrapperBase::GetExportedResourcesInternal(std::list<ExportedResource>& target, | |
470 bool& done, | |
471 SQLite::Statement& s, | |
472 uint32_t maxResults) | |
473 { | |
474 target.clear(); | |
475 | |
476 while (target.size() < maxResults && s.Step()) | |
477 { | |
478 int64_t seq = s.ColumnInt64(0); | |
479 ResourceType resourceType = static_cast<ResourceType>(s.ColumnInt(1)); | |
480 std::string publicId = s.ColumnString(2); | |
481 | |
482 ExportedResource resource(seq, | |
483 resourceType, | |
484 publicId, | |
485 s.ColumnString(3), // modality | |
486 s.ColumnString(8), // date | |
487 s.ColumnString(4), // patient ID | |
488 s.ColumnString(5), // study instance UID | |
489 s.ColumnString(6), // series instance UID | |
490 s.ColumnString(7)); // sop instance UID | |
491 | |
492 target.push_back(resource); | |
493 } | |
494 | |
495 done = !(target.size() == maxResults && s.Step()); | |
496 } | |
497 | |
498 | |
499 void DatabaseWrapperBase::GetExportedResources(std::list<ExportedResource>& target, | |
500 bool& done, | |
501 int64_t since, | |
502 uint32_t maxResults) | |
503 { | |
504 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
505 "SELECT * FROM ExportedResources WHERE seq>? ORDER BY seq LIMIT ?"); | |
506 s.BindInt64(0, since); | |
507 s.BindInt(1, maxResults + 1); | |
508 GetExportedResourcesInternal(target, done, s, maxResults); | |
509 } | |
510 | |
511 | |
512 void DatabaseWrapperBase::GetLastExportedResource(std::list<ExportedResource>& target) | |
513 { | |
514 bool done; // Ignored | |
515 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
516 "SELECT * FROM ExportedResources ORDER BY seq DESC LIMIT 1"); | |
517 GetExportedResourcesInternal(target, done, s, 1); | |
518 } | |
519 | |
520 | |
521 | |
522 uint64_t DatabaseWrapperBase::GetTotalCompressedSize() | |
523 { | |
524 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT SUM(compressedSize) FROM AttachedFiles"); | |
525 s.Run(); | |
526 return static_cast<uint64_t>(s.ColumnInt64(0)); | |
527 } | |
528 | |
529 | |
530 uint64_t DatabaseWrapperBase::GetTotalUncompressedSize() | |
531 { | |
532 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT SUM(uncompressedSize) FROM AttachedFiles"); | |
533 s.Run(); | |
534 return static_cast<uint64_t>(s.ColumnInt64(0)); | |
535 } | |
536 | |
537 void DatabaseWrapperBase::GetAllInternalIds(std::list<int64_t>& target, | |
538 ResourceType resourceType) | |
539 { | |
540 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT internalId FROM Resources WHERE resourceType=?"); | |
541 s.BindInt(0, resourceType); | |
542 | |
543 target.clear(); | |
544 while (s.Step()) | |
545 { | |
546 target.push_back(s.ColumnInt64(0)); | |
547 } | |
548 } | |
549 | |
550 | |
551 void DatabaseWrapperBase::GetAllPublicIds(std::list<std::string>& target, | |
552 ResourceType resourceType) | |
553 { | |
554 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT publicId FROM Resources WHERE resourceType=?"); | |
555 s.BindInt(0, resourceType); | |
556 | |
557 target.clear(); | |
558 while (s.Step()) | |
559 { | |
560 target.push_back(s.ColumnString(0)); | |
561 } | |
562 } | |
563 | |
564 void DatabaseWrapperBase::GetAllPublicIds(std::list<std::string>& target, | |
565 ResourceType resourceType, | |
566 size_t since, | |
567 size_t limit) | |
568 { | |
569 if (limit == 0) | |
570 { | |
571 target.clear(); | |
572 return; | |
573 } | |
574 | |
575 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT publicId FROM Resources WHERE resourceType=? LIMIT ? OFFSET ?"); | |
576 s.BindInt(0, resourceType); | |
577 s.BindInt64(1, limit); | |
578 s.BindInt64(2, since); | |
579 | |
580 target.clear(); | |
581 while (s.Step()) | |
582 { | |
583 target.push_back(s.ColumnString(0)); | |
584 } | |
585 } | |
586 | |
587 | |
588 uint64_t DatabaseWrapperBase::GetResourceCount(ResourceType resourceType) | |
589 { | |
590 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
591 "SELECT COUNT(*) FROM Resources WHERE resourceType=?"); | |
592 s.BindInt(0, resourceType); | |
593 | |
594 if (!s.Step()) | |
595 { | |
596 return 0; | |
597 } | |
598 else | |
599 { | |
600 int64_t c = s.ColumnInt(0); | |
601 assert(!s.Step()); | |
602 return c; | |
603 } | |
604 } | |
605 | |
606 | |
607 bool DatabaseWrapperBase::SelectPatientToRecycle(int64_t& internalId) | |
608 { | |
609 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
610 "SELECT patientId FROM PatientRecyclingOrder ORDER BY seq ASC LIMIT 1"); | |
611 | |
612 if (!s.Step()) | |
613 { | |
614 // No patient remaining or all the patients are protected | |
615 return false; | |
616 } | |
617 else | |
618 { | |
619 internalId = s.ColumnInt(0); | |
620 return true; | |
621 } | |
622 } | |
623 | |
624 bool DatabaseWrapperBase::SelectPatientToRecycle(int64_t& internalId, | |
625 int64_t patientIdToAvoid) | |
626 { | |
627 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
628 "SELECT patientId FROM PatientRecyclingOrder " | |
629 "WHERE patientId != ? ORDER BY seq ASC LIMIT 1"); | |
630 s.BindInt64(0, patientIdToAvoid); | |
631 | |
632 if (!s.Step()) | |
633 { | |
634 // No patient remaining or all the patients are protected | |
635 return false; | |
636 } | |
637 else | |
638 { | |
639 internalId = s.ColumnInt(0); | |
640 return true; | |
641 } | |
642 } | |
643 | |
644 bool DatabaseWrapperBase::IsProtectedPatient(int64_t internalId) | |
645 { | |
646 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
647 "SELECT * FROM PatientRecyclingOrder WHERE patientId = ?"); | |
648 s.BindInt64(0, internalId); | |
649 return !s.Step(); | |
650 } | |
651 | |
652 void DatabaseWrapperBase::SetProtectedPatient(int64_t internalId, | |
653 bool isProtected) | |
654 { | |
655 if (isProtected) | |
656 { | |
657 SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM PatientRecyclingOrder WHERE patientId=?"); | |
658 s.BindInt64(0, internalId); | |
659 s.Run(); | |
660 } | |
661 else if (IsProtectedPatient(internalId)) | |
662 { | |
663 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO PatientRecyclingOrder VALUES(NULL, ?)"); | |
664 s.BindInt64(0, internalId); | |
665 s.Run(); | |
666 } | |
667 else | |
668 { | |
669 // Nothing to do: The patient is already unprotected | |
670 } | |
671 } | |
672 | |
673 | |
674 | |
675 bool DatabaseWrapperBase::IsExistingResource(int64_t internalId) | |
676 { | |
677 SQLite::Statement s(db_, SQLITE_FROM_HERE, | |
678 "SELECT * FROM Resources WHERE internalId=?"); | |
679 s.BindInt64(0, internalId); | |
680 return s.Step(); | |
681 } | |
682 | |
683 | |
684 | |
685 void DatabaseWrapperBase::LookupIdentifier(std::list<int64_t>& target, | |
686 ResourceType level, | |
687 const DicomTag& tag, | |
688 IdentifierConstraintType type, | |
689 const std::string& value) | |
690 { | |
691 static const char* COMMON = ("SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE " | |
692 "d.id = r.internalId AND r.resourceType=? AND " | |
693 "d.tagGroup=? AND d.tagElement=? AND "); | |
694 | |
695 std::auto_ptr<SQLite::Statement> s; | |
696 | |
697 switch (type) | |
698 { | |
699 case IdentifierConstraintType_GreaterOrEqual: | |
700 s.reset(new SQLite::Statement(db_, std::string(COMMON) + "d.value>=?")); | |
701 break; | |
702 | |
703 case IdentifierConstraintType_SmallerOrEqual: | |
704 s.reset(new SQLite::Statement(db_, std::string(COMMON) + "d.value<=?")); | |
705 break; | |
706 | |
707 case IdentifierConstraintType_Wildcard: | |
708 s.reset(new SQLite::Statement(db_, std::string(COMMON) + "d.value GLOB ?")); | |
709 break; | |
710 | |
711 case IdentifierConstraintType_Equal: | |
712 default: | |
713 s.reset(new SQLite::Statement(db_, std::string(COMMON) + "d.value=?")); | |
714 break; | |
715 } | |
716 | |
717 assert(s.get() != NULL); | |
718 | |
719 s->BindInt(0, level); | |
720 s->BindInt(1, tag.GetGroup()); | |
721 s->BindInt(2, tag.GetElement()); | |
722 s->BindString(3, value); | |
723 | |
724 target.clear(); | |
725 | |
726 while (s->Step()) | |
727 { | |
728 target.push_back(s->ColumnInt64(0)); | |
729 } | |
730 } | |
731 | |
732 | |
733 void DatabaseWrapperBase::LookupIdentifierRange(std::list<int64_t>& target, | |
734 ResourceType level, | |
735 const DicomTag& tag, | |
736 const std::string& start, | |
737 const std::string& end) | |
738 { | |
739 SQLite::Statement statement(db_, SQLITE_FROM_HERE, | |
740 "SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE " | |
741 "d.id = r.internalId AND r.resourceType=? AND " | |
742 "d.tagGroup=? AND d.tagElement=? AND d.value>=? AND d.value<=?"); | |
743 | |
744 statement.BindInt(0, level); | |
745 statement.BindInt(1, tag.GetGroup()); | |
746 statement.BindInt(2, tag.GetElement()); | |
747 statement.BindString(3, start); | |
748 statement.BindString(4, end); | |
749 | |
750 target.clear(); | |
751 | |
752 while (statement.Step()) | |
753 { | |
754 target.push_back(statement.ColumnInt64(0)); | |
755 } | |
756 } | |
757 } |