Mercurial > hg > orthanc
comparison OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp @ 4591:ff8170d17d90 db-changes
moving all accesses to databases from IDatabaseWrapper to ITransaction
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 15 Mar 2021 15:30:42 +0100 |
parents | bec74e29f86b |
children | 36bbf3169a27 |
comparison
equal
deleted
inserted
replaced
4590:4a0bf1019335 | 4591:ff8170d17d90 |
---|---|
39 #endif | 39 #endif |
40 | 40 |
41 | 41 |
42 #include "../../../OrthancFramework/Sources/Logging.h" | 42 #include "../../../OrthancFramework/Sources/Logging.h" |
43 #include "../../../OrthancFramework/Sources/OrthancException.h" | 43 #include "../../../OrthancFramework/Sources/OrthancException.h" |
44 #include "../../Sources/Database/VoidDatabaseListener.h" | |
44 #include "PluginsEnumerations.h" | 45 #include "PluginsEnumerations.h" |
45 | 46 |
46 #include <cassert> | 47 #include <cassert> |
47 | 48 |
48 namespace Orthanc | 49 namespace Orthanc |
49 { | 50 { |
50 class OrthancPluginDatabase::Transaction : public IDatabaseWrapper::ITransaction | 51 class OrthancPluginDatabase::Transaction : |
52 public IDatabaseWrapper::ITransaction, | |
53 public Compatibility::ICreateInstance, | |
54 public Compatibility::IGetChildrenMetadata, | |
55 public Compatibility::ILookupResources, | |
56 public Compatibility::ILookupResourceAndParent, | |
57 public Compatibility::ISetResourcesContent | |
51 { | 58 { |
52 private: | 59 private: |
53 OrthancPluginDatabase& that_; | 60 OrthancPluginDatabase& that_; |
54 | 61 |
55 void CheckSuccess(OrthancPluginErrorCode code) const | 62 void CheckSuccess(OrthancPluginErrorCode code) const |
99 throw OrthancException(ErrorCode_DatabasePlugin); | 106 throw OrthancException(ErrorCode_DatabasePlugin); |
100 } | 107 } |
101 | 108 |
102 uint64_t newDiskSize = (that_.currentDiskSize_ + diskSizeDelta); | 109 uint64_t newDiskSize = (that_.currentDiskSize_ + diskSizeDelta); |
103 | 110 |
104 assert(newDiskSize == that_.GetTotalCompressedSize()); | 111 assert(newDiskSize == GetTotalCompressedSize()); |
105 | 112 |
106 CheckSuccess(that_.backend_.commitTransaction(that_.payload_)); | 113 CheckSuccess(that_.backend_.commitTransaction(that_.payload_)); |
107 | 114 |
108 // The transaction has succeeded, we can commit the new disk size | 115 // The transaction has succeeded, we can commit the new disk size |
109 that_.currentDiskSize_ = newDiskSize; | 116 that_.currentDiskSize_ = newDiskSize; |
110 } | 117 } |
111 } | 118 } |
119 | |
120 | |
121 // From the "ILookupResources" interface | |
122 void GetAllInternalIds(std::list<int64_t>& target, | |
123 ResourceType resourceType) ORTHANC_OVERRIDE | |
124 { | |
125 if (that_.extensions_.getAllInternalIds == NULL) | |
126 { | |
127 throw OrthancException(ErrorCode_DatabasePlugin, | |
128 "The database plugin does not implement the mandatory GetAllInternalIds() extension"); | |
129 } | |
130 | |
131 that_.ResetAnswers(); | |
132 CheckSuccess(that_.extensions_.getAllInternalIds(that_.GetContext(), that_.payload_, Plugins::Convert(resourceType))); | |
133 that_.ForwardAnswers(target); | |
134 } | |
135 | |
136 | |
137 | |
138 // From the "ILookupResources" interface | |
139 void LookupIdentifier(std::list<int64_t>& result, | |
140 ResourceType level, | |
141 const DicomTag& tag, | |
142 Compatibility::IdentifierConstraintType type, | |
143 const std::string& value) ORTHANC_OVERRIDE | |
144 { | |
145 if (that_.extensions_.lookupIdentifier3 == NULL) | |
146 { | |
147 throw OrthancException(ErrorCode_DatabasePlugin, | |
148 "The database plugin does not implement the mandatory LookupIdentifier3() extension"); | |
149 } | |
150 | |
151 OrthancPluginDicomTag tmp; | |
152 tmp.group = tag.GetGroup(); | |
153 tmp.element = tag.GetElement(); | |
154 tmp.value = value.c_str(); | |
155 | |
156 that_.ResetAnswers(); | |
157 CheckSuccess(that_.extensions_.lookupIdentifier3(that_.GetContext(), that_.payload_, Plugins::Convert(level), | |
158 &tmp, Compatibility::Convert(type))); | |
159 that_.ForwardAnswers(result); | |
160 } | |
161 | |
162 | |
163 | |
164 /** | |
165 * Implementation of "ITransaction" | |
166 **/ | |
167 | |
168 virtual void ApplyLookupResources(std::list<std::string>& resourcesId, | |
169 std::list<std::string>* instancesId, | |
170 const std::vector<DatabaseConstraint>& lookup, | |
171 ResourceType queryLevel, | |
172 size_t limit) ORTHANC_OVERRIDE | |
173 { | |
174 if (that_.extensions_.lookupResources == NULL) | |
175 { | |
176 // Fallback to compatibility mode | |
177 ILookupResources::Apply | |
178 (*this, *this, resourcesId, instancesId, lookup, queryLevel, limit); | |
179 } | |
180 else | |
181 { | |
182 std::vector<OrthancPluginDatabaseConstraint> constraints; | |
183 std::vector< std::vector<const char*> > constraintsValues; | |
184 | |
185 constraints.resize(lookup.size()); | |
186 constraintsValues.resize(lookup.size()); | |
187 | |
188 for (size_t i = 0; i < lookup.size(); i++) | |
189 { | |
190 lookup[i].EncodeForPlugins(constraints[i], constraintsValues[i]); | |
191 } | |
192 | |
193 that_.ResetAnswers(); | |
194 that_.answerMatchingResources_ = &resourcesId; | |
195 that_.answerMatchingInstances_ = instancesId; | |
196 | |
197 CheckSuccess(that_.extensions_.lookupResources(that_.GetContext(), that_.payload_, lookup.size(), | |
198 (lookup.empty() ? NULL : &constraints[0]), | |
199 Plugins::Convert(queryLevel), | |
200 limit, (instancesId == NULL ? 0 : 1))); | |
201 } | |
202 } | |
203 | |
204 | |
205 bool CreateInstance(IDatabaseWrapper::CreateInstanceResult& result, | |
206 int64_t& instanceId, | |
207 const std::string& patient, | |
208 const std::string& study, | |
209 const std::string& series, | |
210 const std::string& instance) ORTHANC_OVERRIDE | |
211 { | |
212 if (that_.extensions_.createInstance == NULL) | |
213 { | |
214 // Fallback to compatibility mode | |
215 return ICreateInstance::Apply | |
216 (*this, result, instanceId, patient, study, series, instance); | |
217 } | |
218 else | |
219 { | |
220 OrthancPluginCreateInstanceResult output; | |
221 memset(&output, 0, sizeof(output)); | |
222 | |
223 CheckSuccess(that_.extensions_.createInstance(&output, that_.payload_, patient.c_str(), | |
224 study.c_str(), series.c_str(), instance.c_str())); | |
225 | |
226 instanceId = output.instanceId; | |
227 | |
228 if (output.isNewInstance) | |
229 { | |
230 result.isNewPatient_ = output.isNewPatient; | |
231 result.isNewStudy_ = output.isNewStudy; | |
232 result.isNewSeries_ = output.isNewSeries; | |
233 result.patientId_ = output.patientId; | |
234 result.studyId_ = output.studyId; | |
235 result.seriesId_ = output.seriesId; | |
236 return true; | |
237 } | |
238 else | |
239 { | |
240 return false; | |
241 } | |
242 } | |
243 } | |
244 | |
245 | |
246 virtual int64_t CreateResource(const std::string& publicId, | |
247 ResourceType type) ORTHANC_OVERRIDE | |
248 { | |
249 int64_t id; | |
250 CheckSuccess(that_.backend_.createResource(&id, that_.payload_, publicId.c_str(), Plugins::Convert(type))); | |
251 return id; | |
252 } | |
253 | |
254 | |
255 virtual void AddAttachment(int64_t id, | |
256 const FileInfo& attachment) ORTHANC_OVERRIDE | |
257 { | |
258 OrthancPluginAttachment tmp; | |
259 tmp.uuid = attachment.GetUuid().c_str(); | |
260 tmp.contentType = static_cast<int32_t>(attachment.GetContentType()); | |
261 tmp.uncompressedSize = attachment.GetUncompressedSize(); | |
262 tmp.uncompressedHash = attachment.GetUncompressedMD5().c_str(); | |
263 tmp.compressionType = static_cast<int32_t>(attachment.GetCompressionType()); | |
264 tmp.compressedSize = attachment.GetCompressedSize(); | |
265 tmp.compressedHash = attachment.GetCompressedMD5().c_str(); | |
266 | |
267 CheckSuccess(that_.backend_.addAttachment(that_.payload_, id, &tmp)); | |
268 } | |
269 | |
270 | |
271 virtual void AttachChild(int64_t parent, | |
272 int64_t child) ORTHANC_OVERRIDE | |
273 { | |
274 CheckSuccess(that_.backend_.attachChild(that_.payload_, parent, child)); | |
275 } | |
276 | |
277 | |
278 virtual void ClearChanges() ORTHANC_OVERRIDE | |
279 { | |
280 CheckSuccess(that_.backend_.clearChanges(that_.payload_)); | |
281 } | |
282 | |
283 | |
284 virtual void ClearExportedResources() ORTHANC_OVERRIDE | |
285 { | |
286 CheckSuccess(that_.backend_.clearExportedResources(that_.payload_)); | |
287 } | |
288 | |
289 | |
290 virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE | |
291 { | |
292 if (that_.extensions_.clearMainDicomTags == NULL) | |
293 { | |
294 throw OrthancException(ErrorCode_DatabasePlugin, | |
295 "Your custom index plugin does not implement the mandatory ClearMainDicomTags() extension"); | |
296 } | |
297 | |
298 CheckSuccess(that_.extensions_.clearMainDicomTags(that_.payload_, id)); | |
299 } | |
300 | |
301 | |
302 virtual void DeleteAttachment(int64_t id, | |
303 FileContentType attachment) ORTHANC_OVERRIDE | |
304 { | |
305 CheckSuccess(that_.backend_.deleteAttachment(that_.payload_, id, static_cast<int32_t>(attachment))); | |
306 } | |
307 | |
308 | |
309 virtual void DeleteMetadata(int64_t id, | |
310 MetadataType type) ORTHANC_OVERRIDE | |
311 { | |
312 CheckSuccess(that_.backend_.deleteMetadata(that_.payload_, id, static_cast<int32_t>(type))); | |
313 } | |
314 | |
315 | |
316 virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE | |
317 { | |
318 CheckSuccess(that_.backend_.deleteResource(that_.payload_, id)); | |
319 } | |
320 | |
321 | |
322 virtual void GetAllMetadata(std::map<MetadataType, std::string>& target, | |
323 int64_t id) ORTHANC_OVERRIDE | |
324 { | |
325 if (that_.extensions_.getAllMetadata == NULL) | |
326 { | |
327 // Fallback implementation if extension is missing | |
328 target.clear(); | |
329 | |
330 that_.ResetAnswers(); | |
331 CheckSuccess(that_.backend_.listAvailableMetadata(that_.GetContext(), that_.payload_, id)); | |
332 | |
333 if (that_.type_ != _OrthancPluginDatabaseAnswerType_None && | |
334 that_.type_ != _OrthancPluginDatabaseAnswerType_Int32) | |
335 { | |
336 throw OrthancException(ErrorCode_DatabasePlugin); | |
337 } | |
338 | |
339 target.clear(); | |
340 | |
341 if (that_.type_ == _OrthancPluginDatabaseAnswerType_Int32) | |
342 { | |
343 for (std::list<int32_t>::const_iterator | |
344 it = that_.answerInt32_.begin(); it != that_.answerInt32_.end(); ++it) | |
345 { | |
346 MetadataType type = static_cast<MetadataType>(*it); | |
347 | |
348 std::string value; | |
349 if (LookupMetadata(value, id, type)) | |
350 { | |
351 target[type] = value; | |
352 } | |
353 } | |
354 } | |
355 } | |
356 else | |
357 { | |
358 that_.ResetAnswers(); | |
359 | |
360 that_.answerMetadata_ = ⌖ | |
361 target.clear(); | |
362 | |
363 CheckSuccess(that_.extensions_.getAllMetadata(that_.GetContext(), that_.payload_, id)); | |
364 | |
365 if (that_.type_ != _OrthancPluginDatabaseAnswerType_None && | |
366 that_.type_ != _OrthancPluginDatabaseAnswerType_Metadata) | |
367 { | |
368 throw OrthancException(ErrorCode_DatabasePlugin); | |
369 } | |
370 } | |
371 } | |
372 | |
373 | |
374 virtual void GetAllPublicIds(std::list<std::string>& target, | |
375 ResourceType resourceType) ORTHANC_OVERRIDE | |
376 { | |
377 that_.ResetAnswers(); | |
378 CheckSuccess(that_.backend_.getAllPublicIds(that_.GetContext(), that_.payload_, Plugins::Convert(resourceType))); | |
379 that_.ForwardAnswers(target); | |
380 } | |
381 | |
382 | |
383 virtual void GetAllPublicIds(std::list<std::string>& target, | |
384 ResourceType resourceType, | |
385 size_t since, | |
386 size_t limit) ORTHANC_OVERRIDE | |
387 { | |
388 if (that_.extensions_.getAllPublicIdsWithLimit != NULL) | |
389 { | |
390 // This extension is available since Orthanc 0.9.4 | |
391 that_.ResetAnswers(); | |
392 CheckSuccess(that_.extensions_.getAllPublicIdsWithLimit | |
393 (that_.GetContext(), that_.payload_, Plugins::Convert(resourceType), since, limit)); | |
394 that_.ForwardAnswers(target); | |
395 } | |
396 else | |
397 { | |
398 // The extension is not available in the database plugin, use a | |
399 // fallback implementation | |
400 target.clear(); | |
401 | |
402 if (limit == 0) | |
403 { | |
404 return; | |
405 } | |
406 | |
407 std::list<std::string> tmp; | |
408 GetAllPublicIds(tmp, resourceType); | |
409 | |
410 if (tmp.size() <= since) | |
411 { | |
412 // Not enough results => empty answer | |
413 return; | |
414 } | |
415 | |
416 std::list<std::string>::iterator current = tmp.begin(); | |
417 std::advance(current, since); | |
418 | |
419 while (limit > 0 && current != tmp.end()) | |
420 { | |
421 target.push_back(*current); | |
422 --limit; | |
423 ++current; | |
424 } | |
425 } | |
426 } | |
427 | |
428 | |
429 virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/, | |
430 bool& done /*out*/, | |
431 int64_t since, | |
432 uint32_t maxResults) ORTHANC_OVERRIDE | |
433 { | |
434 that_.ResetAnswers(); | |
435 that_.answerChanges_ = ⌖ | |
436 that_.answerDone_ = &done; | |
437 done = false; | |
438 | |
439 CheckSuccess(that_.backend_.getChanges(that_.GetContext(), that_.payload_, since, maxResults)); | |
440 } | |
441 | |
442 | |
443 virtual void GetChildrenInternalId(std::list<int64_t>& target, | |
444 int64_t id) ORTHANC_OVERRIDE | |
445 { | |
446 that_.ResetAnswers(); | |
447 CheckSuccess(that_.backend_.getChildrenInternalId(that_.GetContext(), that_.payload_, id)); | |
448 that_.ForwardAnswers(target); | |
449 } | |
450 | |
451 | |
452 virtual void GetChildrenMetadata(std::list<std::string>& target, | |
453 int64_t resourceId, | |
454 MetadataType metadata) ORTHANC_OVERRIDE | |
455 { | |
456 if (that_.extensions_.getChildrenMetadata == NULL) | |
457 { | |
458 IGetChildrenMetadata::Apply(*this, target, resourceId, metadata); | |
459 } | |
460 else | |
461 { | |
462 that_.ResetAnswers(); | |
463 CheckSuccess(that_.extensions_.getChildrenMetadata | |
464 (that_.GetContext(), that_.payload_, resourceId, static_cast<int32_t>(metadata))); | |
465 that_.ForwardAnswers(target); | |
466 } | |
467 } | |
468 | |
469 | |
470 virtual void GetChildrenPublicId(std::list<std::string>& target, | |
471 int64_t id) ORTHANC_OVERRIDE | |
472 { | |
473 that_.ResetAnswers(); | |
474 CheckSuccess(that_.backend_.getChildrenPublicId(that_.GetContext(), that_.payload_, id)); | |
475 that_.ForwardAnswers(target); | |
476 } | |
477 | |
478 | |
479 virtual void GetExportedResources(std::list<ExportedResource>& target /*out*/, | |
480 bool& done /*out*/, | |
481 int64_t since, | |
482 uint32_t maxResults) ORTHANC_OVERRIDE | |
483 { | |
484 that_.ResetAnswers(); | |
485 that_.answerExportedResources_ = ⌖ | |
486 that_.answerDone_ = &done; | |
487 done = false; | |
488 | |
489 CheckSuccess(that_.backend_.getExportedResources(that_.GetContext(), that_.payload_, since, maxResults)); | |
490 } | |
491 | |
492 | |
493 virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/) ORTHANC_OVERRIDE | |
494 { | |
495 that_.answerDoneIgnored_ = false; | |
496 | |
497 that_.ResetAnswers(); | |
498 that_.answerChanges_ = ⌖ | |
499 that_.answerDone_ = &that_.answerDoneIgnored_; | |
500 | |
501 CheckSuccess(that_.backend_.getLastChange(that_.GetContext(), that_.payload_)); | |
502 } | |
503 | |
504 | |
505 int64_t GetLastChangeIndex() ORTHANC_OVERRIDE | |
506 { | |
507 if (that_.extensions_.getLastChangeIndex == NULL) | |
508 { | |
509 // This was the default behavior in Orthanc <= 1.5.1 | |
510 // https://groups.google.com/d/msg/orthanc-users/QhzB6vxYeZ0/YxabgqpfBAAJ | |
511 return 0; | |
512 } | |
513 else | |
514 { | |
515 int64_t result = 0; | |
516 CheckSuccess(that_.extensions_.getLastChangeIndex(&result, that_.payload_)); | |
517 return result; | |
518 } | |
519 } | |
520 | |
521 | |
522 virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/) ORTHANC_OVERRIDE | |
523 { | |
524 that_.answerDoneIgnored_ = false; | |
525 | |
526 that_.ResetAnswers(); | |
527 that_.answerExportedResources_ = ⌖ | |
528 that_.answerDone_ = &that_.answerDoneIgnored_; | |
529 | |
530 CheckSuccess(that_.backend_.getLastExportedResource(that_.GetContext(), that_.payload_)); | |
531 } | |
532 | |
533 | |
534 virtual void GetMainDicomTags(DicomMap& map, | |
535 int64_t id) ORTHANC_OVERRIDE | |
536 { | |
537 that_.ResetAnswers(); | |
538 that_.answerDicomMap_ = ↦ | |
539 | |
540 CheckSuccess(that_.backend_.getMainDicomTags(that_.GetContext(), that_.payload_, id)); | |
541 } | |
542 | |
543 | |
544 virtual std::string GetPublicId(int64_t resourceId) ORTHANC_OVERRIDE | |
545 { | |
546 that_.ResetAnswers(); | |
547 std::string s; | |
548 | |
549 CheckSuccess(that_.backend_.getPublicId(that_.GetContext(), that_.payload_, resourceId)); | |
550 | |
551 if (!that_.ForwardSingleAnswer(s)) | |
552 { | |
553 throw OrthancException(ErrorCode_DatabasePlugin); | |
554 } | |
555 | |
556 return s; | |
557 } | |
558 | |
559 | |
560 virtual uint64_t GetResourceCount(ResourceType resourceType) ORTHANC_OVERRIDE | |
561 { | |
562 uint64_t count; | |
563 CheckSuccess(that_.backend_.getResourceCount(&count, that_.payload_, Plugins::Convert(resourceType))); | |
564 return count; | |
565 } | |
566 | |
567 | |
568 virtual ResourceType GetResourceType(int64_t resourceId) ORTHANC_OVERRIDE | |
569 { | |
570 OrthancPluginResourceType type; | |
571 CheckSuccess(that_.backend_.getResourceType(&type, that_.payload_, resourceId)); | |
572 return Plugins::Convert(type); | |
573 } | |
574 | |
575 | |
576 virtual uint64_t GetTotalCompressedSize() ORTHANC_OVERRIDE | |
577 { | |
578 uint64_t size; | |
579 CheckSuccess(that_.backend_.getTotalCompressedSize(&size, that_.payload_)); | |
580 return size; | |
581 } | |
582 | |
583 | |
584 virtual uint64_t GetTotalUncompressedSize() ORTHANC_OVERRIDE | |
585 { | |
586 uint64_t size; | |
587 CheckSuccess(that_.backend_.getTotalUncompressedSize(&size, that_.payload_)); | |
588 return size; | |
589 } | |
590 | |
591 | |
592 virtual bool IsDiskSizeAbove(uint64_t threshold) ORTHANC_OVERRIDE | |
593 { | |
594 if (that_.fastGetTotalSize_) | |
595 { | |
596 return GetTotalCompressedSize() > threshold; | |
597 } | |
598 else | |
599 { | |
600 assert(GetTotalCompressedSize() == that_.currentDiskSize_); | |
601 return that_.currentDiskSize_ > threshold; | |
602 } | |
603 } | |
604 | |
605 | |
606 virtual bool IsExistingResource(int64_t internalId) ORTHANC_OVERRIDE | |
607 { | |
608 int32_t existing; | |
609 CheckSuccess(that_.backend_.isExistingResource(&existing, that_.payload_, internalId)); | |
610 return (existing != 0); | |
611 } | |
612 | |
613 | |
614 virtual bool IsProtectedPatient(int64_t internalId) ORTHANC_OVERRIDE | |
615 { | |
616 int32_t isProtected; | |
617 CheckSuccess(that_.backend_.isProtectedPatient(&isProtected, that_.payload_, internalId)); | |
618 return (isProtected != 0); | |
619 } | |
620 | |
621 | |
622 virtual void ListAvailableAttachments(std::set<FileContentType>& target, | |
623 int64_t id) ORTHANC_OVERRIDE | |
624 { | |
625 that_.ResetAnswers(); | |
626 | |
627 CheckSuccess(that_.backend_.listAvailableAttachments(that_.GetContext(), that_.payload_, id)); | |
628 | |
629 if (that_.type_ != _OrthancPluginDatabaseAnswerType_None && | |
630 that_.type_ != _OrthancPluginDatabaseAnswerType_Int32) | |
631 { | |
632 throw OrthancException(ErrorCode_DatabasePlugin); | |
633 } | |
634 | |
635 target.clear(); | |
636 | |
637 if (that_.type_ == _OrthancPluginDatabaseAnswerType_Int32) | |
638 { | |
639 for (std::list<int32_t>::const_iterator | |
640 it = that_.answerInt32_.begin(); it != that_.answerInt32_.end(); ++it) | |
641 { | |
642 target.insert(static_cast<FileContentType>(*it)); | |
643 } | |
644 } | |
645 } | |
646 | |
647 | |
648 virtual void LogChange(int64_t internalId, | |
649 const ServerIndexChange& change) ORTHANC_OVERRIDE | |
650 { | |
651 OrthancPluginChange tmp; | |
652 tmp.seq = change.GetSeq(); | |
653 tmp.changeType = static_cast<int32_t>(change.GetChangeType()); | |
654 tmp.resourceType = Plugins::Convert(change.GetResourceType()); | |
655 tmp.publicId = change.GetPublicId().c_str(); | |
656 tmp.date = change.GetDate().c_str(); | |
657 | |
658 CheckSuccess(that_.backend_.logChange(that_.payload_, &tmp)); | |
659 } | |
660 | |
661 | |
662 virtual void LogExportedResource(const ExportedResource& resource) ORTHANC_OVERRIDE | |
663 { | |
664 OrthancPluginExportedResource tmp; | |
665 tmp.seq = resource.GetSeq(); | |
666 tmp.resourceType = Plugins::Convert(resource.GetResourceType()); | |
667 tmp.publicId = resource.GetPublicId().c_str(); | |
668 tmp.modality = resource.GetModality().c_str(); | |
669 tmp.date = resource.GetDate().c_str(); | |
670 tmp.patientId = resource.GetPatientId().c_str(); | |
671 tmp.studyInstanceUid = resource.GetStudyInstanceUid().c_str(); | |
672 tmp.seriesInstanceUid = resource.GetSeriesInstanceUid().c_str(); | |
673 tmp.sopInstanceUid = resource.GetSopInstanceUid().c_str(); | |
674 | |
675 CheckSuccess(that_.backend_.logExportedResource(that_.payload_, &tmp)); | |
676 } | |
677 | |
678 | |
679 virtual bool LookupAttachment(FileInfo& attachment, | |
680 int64_t id, | |
681 FileContentType contentType) ORTHANC_OVERRIDE | |
682 { | |
683 that_.ResetAnswers(); | |
684 | |
685 CheckSuccess(that_.backend_.lookupAttachment | |
686 (that_.GetContext(), that_.payload_, id, static_cast<int32_t>(contentType))); | |
687 | |
688 if (that_.type_ == _OrthancPluginDatabaseAnswerType_None) | |
689 { | |
690 return false; | |
691 } | |
692 else if (that_.type_ == _OrthancPluginDatabaseAnswerType_Attachment && | |
693 that_.answerAttachments_.size() == 1) | |
694 { | |
695 attachment = that_.answerAttachments_.front(); | |
696 return true; | |
697 } | |
698 else | |
699 { | |
700 throw OrthancException(ErrorCode_DatabasePlugin); | |
701 } | |
702 } | |
703 | |
704 | |
705 virtual bool LookupGlobalProperty(std::string& target, | |
706 GlobalProperty property) ORTHANC_OVERRIDE | |
707 { | |
708 that_.ResetAnswers(); | |
709 | |
710 CheckSuccess(that_.backend_.lookupGlobalProperty | |
711 (that_.GetContext(), that_.payload_, static_cast<int32_t>(property))); | |
712 | |
713 return that_.ForwardSingleAnswer(target); | |
714 } | |
715 | |
716 | |
717 virtual void LookupIdentifierRange(std::list<int64_t>& result, | |
718 ResourceType level, | |
719 const DicomTag& tag, | |
720 const std::string& start, | |
721 const std::string& end) ORTHANC_OVERRIDE | |
722 { | |
723 if (that_.extensions_.lookupIdentifierRange == NULL) | |
724 { | |
725 // Default implementation, for plugins using Orthanc SDK <= 1.3.2 | |
726 | |
727 LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_GreaterOrEqual, start); | |
728 | |
729 std::list<int64_t> b; | |
730 LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_SmallerOrEqual, end); | |
731 | |
732 result.splice(result.end(), b); | |
733 } | |
734 else | |
735 { | |
736 that_.ResetAnswers(); | |
737 CheckSuccess(that_.extensions_.lookupIdentifierRange(that_.GetContext(), that_.payload_, Plugins::Convert(level), | |
738 tag.GetGroup(), tag.GetElement(), | |
739 start.c_str(), end.c_str())); | |
740 that_.ForwardAnswers(result); | |
741 } | |
742 } | |
743 | |
744 | |
745 virtual bool LookupMetadata(std::string& target, | |
746 int64_t id, | |
747 MetadataType type) ORTHANC_OVERRIDE | |
748 { | |
749 that_.ResetAnswers(); | |
750 CheckSuccess(that_.backend_.lookupMetadata(that_.GetContext(), that_.payload_, id, static_cast<int32_t>(type))); | |
751 return that_.ForwardSingleAnswer(target); | |
752 } | |
753 | |
754 | |
755 virtual bool LookupParent(int64_t& parentId, | |
756 int64_t resourceId) ORTHANC_OVERRIDE | |
757 { | |
758 that_.ResetAnswers(); | |
759 CheckSuccess(that_.backend_.lookupParent(that_.GetContext(), that_.payload_, resourceId)); | |
760 return that_.ForwardSingleAnswer(parentId); | |
761 } | |
762 | |
763 | |
764 virtual bool LookupResource(int64_t& id, | |
765 ResourceType& type, | |
766 const std::string& publicId) ORTHANC_OVERRIDE | |
767 { | |
768 that_.ResetAnswers(); | |
769 | |
770 CheckSuccess(that_.backend_.lookupResource(that_.GetContext(), that_.payload_, publicId.c_str())); | |
771 | |
772 if (that_.type_ == _OrthancPluginDatabaseAnswerType_None) | |
773 { | |
774 return false; | |
775 } | |
776 else if (that_.type_ == _OrthancPluginDatabaseAnswerType_Resource && | |
777 that_.answerResources_.size() == 1) | |
778 { | |
779 id = that_.answerResources_.front().first; | |
780 type = that_.answerResources_.front().second; | |
781 return true; | |
782 } | |
783 else | |
784 { | |
785 throw OrthancException(ErrorCode_DatabasePlugin); | |
786 } | |
787 } | |
788 | |
789 | |
790 virtual bool LookupResourceAndParent(int64_t& id, | |
791 ResourceType& type, | |
792 std::string& parentPublicId, | |
793 const std::string& publicId) ORTHANC_OVERRIDE | |
794 { | |
795 if (that_.extensions_.lookupResourceAndParent == NULL) | |
796 { | |
797 return ILookupResourceAndParent::Apply(*this, id, type, parentPublicId, publicId); | |
798 } | |
799 else | |
800 { | |
801 std::list<std::string> parent; | |
802 | |
803 uint8_t isExisting; | |
804 OrthancPluginResourceType pluginType = OrthancPluginResourceType_Patient; | |
805 | |
806 that_.ResetAnswers(); | |
807 CheckSuccess(that_.extensions_.lookupResourceAndParent | |
808 (that_.GetContext(), &isExisting, &id, &pluginType, that_.payload_, publicId.c_str())); | |
809 that_.ForwardAnswers(parent); | |
810 | |
811 if (isExisting) | |
812 { | |
813 type = Plugins::Convert(pluginType); | |
814 | |
815 if (parent.empty()) | |
816 { | |
817 if (type != ResourceType_Patient) | |
818 { | |
819 throw OrthancException(ErrorCode_DatabasePlugin); | |
820 } | |
821 } | |
822 else if (parent.size() == 1) | |
823 { | |
824 if ((type != ResourceType_Study && | |
825 type != ResourceType_Series && | |
826 type != ResourceType_Instance) || | |
827 parent.front().empty()) | |
828 { | |
829 throw OrthancException(ErrorCode_DatabasePlugin); | |
830 } | |
831 | |
832 parentPublicId = parent.front(); | |
833 } | |
834 else | |
835 { | |
836 throw OrthancException(ErrorCode_DatabasePlugin); | |
837 } | |
838 | |
839 return true; | |
840 } | |
841 else | |
842 { | |
843 return false; | |
844 } | |
845 } | |
846 } | |
847 | |
848 | |
849 virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE | |
850 { | |
851 that_.ResetAnswers(); | |
852 CheckSuccess(that_.backend_.selectPatientToRecycle(that_.GetContext(), that_.payload_)); | |
853 return that_.ForwardSingleAnswer(internalId); | |
854 } | |
855 | |
856 | |
857 virtual bool SelectPatientToRecycle(int64_t& internalId, | |
858 int64_t patientIdToAvoid) ORTHANC_OVERRIDE | |
859 { | |
860 that_.ResetAnswers(); | |
861 CheckSuccess(that_.backend_.selectPatientToRecycle2(that_.GetContext(), that_.payload_, patientIdToAvoid)); | |
862 return that_.ForwardSingleAnswer(internalId); | |
863 } | |
864 | |
865 | |
866 virtual void SetGlobalProperty(GlobalProperty property, | |
867 const std::string& value) ORTHANC_OVERRIDE | |
868 { | |
869 CheckSuccess(that_.backend_.setGlobalProperty | |
870 (that_.payload_, static_cast<int32_t>(property), value.c_str())); | |
871 } | |
872 | |
873 | |
874 virtual void SetIdentifierTag(int64_t id, | |
875 const DicomTag& tag, | |
876 const std::string& value) ORTHANC_OVERRIDE | |
877 { | |
878 OrthancPluginDicomTag tmp; | |
879 tmp.group = tag.GetGroup(); | |
880 tmp.element = tag.GetElement(); | |
881 tmp.value = value.c_str(); | |
882 | |
883 CheckSuccess(that_.backend_.setIdentifierTag(that_.payload_, id, &tmp)); | |
884 } | |
885 | |
886 | |
887 virtual void SetMainDicomTag(int64_t id, | |
888 const DicomTag& tag, | |
889 const std::string& value) ORTHANC_OVERRIDE | |
890 { | |
891 OrthancPluginDicomTag tmp; | |
892 tmp.group = tag.GetGroup(); | |
893 tmp.element = tag.GetElement(); | |
894 tmp.value = value.c_str(); | |
895 | |
896 CheckSuccess(that_.backend_.setMainDicomTag(that_.payload_, id, &tmp)); | |
897 } | |
898 | |
899 | |
900 virtual void SetMetadata(int64_t id, | |
901 MetadataType type, | |
902 const std::string& value) ORTHANC_OVERRIDE | |
903 { | |
904 CheckSuccess(that_.backend_.setMetadata | |
905 (that_.payload_, id, static_cast<int32_t>(type), value.c_str())); | |
906 } | |
907 | |
908 | |
909 virtual void SetProtectedPatient(int64_t internalId, | |
910 bool isProtected) ORTHANC_OVERRIDE | |
911 { | |
912 CheckSuccess(that_.backend_.setProtectedPatient(that_.payload_, internalId, isProtected)); | |
913 } | |
914 | |
915 | |
916 virtual void SetResourcesContent(const Orthanc::ResourcesContent& content) ORTHANC_OVERRIDE | |
917 { | |
918 if (that_.extensions_.setResourcesContent == NULL) | |
919 { | |
920 ISetResourcesContent::Apply(*this, content); | |
921 } | |
922 else | |
923 { | |
924 std::vector<OrthancPluginResourcesContentTags> identifierTags; | |
925 std::vector<OrthancPluginResourcesContentTags> mainDicomTags; | |
926 std::vector<OrthancPluginResourcesContentMetadata> metadata; | |
927 | |
928 identifierTags.reserve(content.GetListTags().size()); | |
929 mainDicomTags.reserve(content.GetListTags().size()); | |
930 metadata.reserve(content.GetListMetadata().size()); | |
931 | |
932 for (ResourcesContent::ListTags::const_iterator | |
933 it = content.GetListTags().begin(); it != content.GetListTags().end(); ++it) | |
934 { | |
935 OrthancPluginResourcesContentTags tmp; | |
936 tmp.resource = it->resourceId_; | |
937 tmp.group = it->tag_.GetGroup(); | |
938 tmp.element = it->tag_.GetElement(); | |
939 tmp.value = it->value_.c_str(); | |
940 | |
941 if (it->isIdentifier_) | |
942 { | |
943 identifierTags.push_back(tmp); | |
944 } | |
945 else | |
946 { | |
947 mainDicomTags.push_back(tmp); | |
948 } | |
949 } | |
950 | |
951 for (ResourcesContent::ListMetadata::const_iterator | |
952 it = content.GetListMetadata().begin(); it != content.GetListMetadata().end(); ++it) | |
953 { | |
954 OrthancPluginResourcesContentMetadata tmp; | |
955 tmp.resource = it->resourceId_; | |
956 tmp.metadata = it->metadata_; | |
957 tmp.value = it->value_.c_str(); | |
958 metadata.push_back(tmp); | |
959 } | |
960 | |
961 assert(identifierTags.size() + mainDicomTags.size() == content.GetListTags().size() && | |
962 metadata.size() == content.GetListMetadata().size()); | |
963 | |
964 CheckSuccess(that_.extensions_.setResourcesContent( | |
965 that_.payload_, | |
966 identifierTags.size(), | |
967 (identifierTags.empty() ? NULL : &identifierTags[0]), | |
968 mainDicomTags.size(), | |
969 (mainDicomTags.empty() ? NULL : &mainDicomTags[0]), | |
970 metadata.size(), | |
971 (metadata.empty() ? NULL : &metadata[0]))); | |
972 } | |
973 } | |
974 | |
975 | |
976 virtual void TagMostRecentPatient(int64_t patient) ORTHANC_OVERRIDE | |
977 { | |
978 if (that_.extensions_.tagMostRecentPatient != NULL) | |
979 { | |
980 CheckSuccess(that_.extensions_.tagMostRecentPatient(that_.payload_, patient)); | |
981 } | |
982 } | |
983 | |
112 }; | 984 }; |
113 | 985 |
114 | 986 |
115 static FileInfo Convert(const OrthancPluginAttachment& attachment) | 987 static FileInfo Convert(const OrthancPluginAttachment& attachment) |
116 { | 988 { |
317 << "(affected by issue 58)"; | 1189 << "(affected by issue 58)"; |
318 } | 1190 } |
319 } | 1191 } |
320 | 1192 |
321 | 1193 |
322 namespace | |
323 { | |
324 class VoidListener : public IDatabaseListener | |
325 { | |
326 public: | |
327 virtual void SignalRemainingAncestor(ResourceType parentType, | |
328 const std::string& publicId) | |
329 { | |
330 throw OrthancException(ErrorCode_InternalError); // Should be read-only transaction | |
331 } | |
332 | |
333 virtual void SignalAttachmentDeleted(const FileInfo& info) | |
334 { | |
335 throw OrthancException(ErrorCode_InternalError); // Should be read-only transaction | |
336 } | |
337 | |
338 virtual void SignalResourceDeleted(ResourceType type, | |
339 const std::string& publicId) | |
340 { | |
341 throw OrthancException(ErrorCode_InternalError); // Should be read-only transaction | |
342 } | |
343 }; | |
344 } | |
345 | |
346 | |
347 void OrthancPluginDatabase::Open() | 1194 void OrthancPluginDatabase::Open() |
348 { | 1195 { |
349 CheckSuccess(backend_.open(payload_)); | 1196 CheckSuccess(backend_.open(payload_)); |
350 | 1197 |
351 VoidListener listener; | 1198 VoidDatabaseListener listener; |
352 | 1199 |
353 { | 1200 { |
354 Transaction transaction(*this, listener); | 1201 Transaction transaction(*this, listener); |
355 transaction.Begin(); | 1202 transaction.Begin(); |
356 | 1203 |
357 std::string tmp; | 1204 std::string tmp; |
358 fastGetTotalSize_ = | 1205 fastGetTotalSize_ = |
359 (LookupGlobalProperty(tmp, GlobalProperty_GetTotalSizeIsFast) && | 1206 (transaction.LookupGlobalProperty(tmp, GlobalProperty_GetTotalSizeIsFast) && |
360 tmp == "1"); | 1207 tmp == "1"); |
361 | 1208 |
362 if (fastGetTotalSize_) | 1209 if (fastGetTotalSize_) |
363 { | 1210 { |
364 currentDiskSize_ = 0; // Unused | 1211 currentDiskSize_ = 0; // Unused |
365 } | 1212 } |
366 else | 1213 else |
367 { | 1214 { |
368 // This is the case of database plugins using Orthanc SDK <= 1.5.2 | 1215 // This is the case of database plugins using Orthanc SDK <= 1.5.2 |
369 LOG(WARNING) << "Your database index plugin is not compatible with multiple Orthanc writers"; | 1216 LOG(WARNING) << "Your database index plugin is not compatible with multiple Orthanc writers"; |
370 currentDiskSize_ = GetTotalCompressedSize(); | 1217 currentDiskSize_ = transaction.GetTotalCompressedSize(); |
371 } | 1218 } |
372 | 1219 |
373 transaction.Commit(0); | 1220 transaction.Commit(0); |
374 } | 1221 } |
375 } | |
376 | |
377 | |
378 void OrthancPluginDatabase::AddAttachment(int64_t id, | |
379 const FileInfo& attachment) | |
380 { | |
381 OrthancPluginAttachment tmp; | |
382 tmp.uuid = attachment.GetUuid().c_str(); | |
383 tmp.contentType = static_cast<int32_t>(attachment.GetContentType()); | |
384 tmp.uncompressedSize = attachment.GetUncompressedSize(); | |
385 tmp.uncompressedHash = attachment.GetUncompressedMD5().c_str(); | |
386 tmp.compressionType = static_cast<int32_t>(attachment.GetCompressionType()); | |
387 tmp.compressedSize = attachment.GetCompressedSize(); | |
388 tmp.compressedHash = attachment.GetCompressedMD5().c_str(); | |
389 | |
390 CheckSuccess(backend_.addAttachment(payload_, id, &tmp)); | |
391 } | |
392 | |
393 | |
394 void OrthancPluginDatabase::AttachChild(int64_t parent, | |
395 int64_t child) | |
396 { | |
397 CheckSuccess(backend_.attachChild(payload_, parent, child)); | |
398 } | |
399 | |
400 | |
401 void OrthancPluginDatabase::ClearChanges() | |
402 { | |
403 CheckSuccess(backend_.clearChanges(payload_)); | |
404 } | |
405 | |
406 | |
407 void OrthancPluginDatabase::ClearExportedResources() | |
408 { | |
409 CheckSuccess(backend_.clearExportedResources(payload_)); | |
410 } | |
411 | |
412 | |
413 int64_t OrthancPluginDatabase::CreateResource(const std::string& publicId, | |
414 ResourceType type) | |
415 { | |
416 int64_t id; | |
417 CheckSuccess(backend_.createResource(&id, payload_, publicId.c_str(), Plugins::Convert(type))); | |
418 return id; | |
419 } | |
420 | |
421 | |
422 void OrthancPluginDatabase::DeleteAttachment(int64_t id, | |
423 FileContentType attachment) | |
424 { | |
425 CheckSuccess(backend_.deleteAttachment(payload_, id, static_cast<int32_t>(attachment))); | |
426 } | |
427 | |
428 | |
429 void OrthancPluginDatabase::DeleteMetadata(int64_t id, | |
430 MetadataType type) | |
431 { | |
432 CheckSuccess(backend_.deleteMetadata(payload_, id, static_cast<int32_t>(type))); | |
433 } | |
434 | |
435 | |
436 void OrthancPluginDatabase::DeleteResource(int64_t id) | |
437 { | |
438 CheckSuccess(backend_.deleteResource(payload_, id)); | |
439 } | |
440 | |
441 | |
442 void OrthancPluginDatabase::GetAllMetadata(std::map<MetadataType, std::string>& target, | |
443 int64_t id) | |
444 { | |
445 if (extensions_.getAllMetadata == NULL) | |
446 { | |
447 // Fallback implementation if extension is missing | |
448 target.clear(); | |
449 | |
450 ResetAnswers(); | |
451 CheckSuccess(backend_.listAvailableMetadata(GetContext(), payload_, id)); | |
452 | |
453 if (type_ != _OrthancPluginDatabaseAnswerType_None && | |
454 type_ != _OrthancPluginDatabaseAnswerType_Int32) | |
455 { | |
456 throw OrthancException(ErrorCode_DatabasePlugin); | |
457 } | |
458 | |
459 target.clear(); | |
460 | |
461 if (type_ == _OrthancPluginDatabaseAnswerType_Int32) | |
462 { | |
463 for (std::list<int32_t>::const_iterator | |
464 it = answerInt32_.begin(); it != answerInt32_.end(); ++it) | |
465 { | |
466 MetadataType type = static_cast<MetadataType>(*it); | |
467 | |
468 std::string value; | |
469 if (LookupMetadata(value, id, type)) | |
470 { | |
471 target[type] = value; | |
472 } | |
473 } | |
474 } | |
475 } | |
476 else | |
477 { | |
478 ResetAnswers(); | |
479 | |
480 answerMetadata_ = ⌖ | |
481 target.clear(); | |
482 | |
483 CheckSuccess(extensions_.getAllMetadata(GetContext(), payload_, id)); | |
484 | |
485 if (type_ != _OrthancPluginDatabaseAnswerType_None && | |
486 type_ != _OrthancPluginDatabaseAnswerType_Metadata) | |
487 { | |
488 throw OrthancException(ErrorCode_DatabasePlugin); | |
489 } | |
490 } | |
491 } | |
492 | |
493 | |
494 void OrthancPluginDatabase::GetAllInternalIds(std::list<int64_t>& target, | |
495 ResourceType resourceType) | |
496 { | |
497 if (extensions_.getAllInternalIds == NULL) | |
498 { | |
499 throw OrthancException(ErrorCode_DatabasePlugin, | |
500 "The database plugin does not implement the mandatory GetAllInternalIds() extension"); | |
501 } | |
502 | |
503 ResetAnswers(); | |
504 CheckSuccess(extensions_.getAllInternalIds(GetContext(), payload_, Plugins::Convert(resourceType))); | |
505 ForwardAnswers(target); | |
506 } | |
507 | |
508 | |
509 void OrthancPluginDatabase::GetAllPublicIds(std::list<std::string>& target, | |
510 ResourceType resourceType) | |
511 { | |
512 ResetAnswers(); | |
513 CheckSuccess(backend_.getAllPublicIds(GetContext(), payload_, Plugins::Convert(resourceType))); | |
514 ForwardAnswers(target); | |
515 } | |
516 | |
517 | |
518 void OrthancPluginDatabase::GetAllPublicIds(std::list<std::string>& target, | |
519 ResourceType resourceType, | |
520 size_t since, | |
521 size_t limit) | |
522 { | |
523 if (extensions_.getAllPublicIdsWithLimit != NULL) | |
524 { | |
525 // This extension is available since Orthanc 0.9.4 | |
526 ResetAnswers(); | |
527 CheckSuccess(extensions_.getAllPublicIdsWithLimit | |
528 (GetContext(), payload_, Plugins::Convert(resourceType), since, limit)); | |
529 ForwardAnswers(target); | |
530 } | |
531 else | |
532 { | |
533 // The extension is not available in the database plugin, use a | |
534 // fallback implementation | |
535 target.clear(); | |
536 | |
537 if (limit == 0) | |
538 { | |
539 return; | |
540 } | |
541 | |
542 std::list<std::string> tmp; | |
543 GetAllPublicIds(tmp, resourceType); | |
544 | |
545 if (tmp.size() <= since) | |
546 { | |
547 // Not enough results => empty answer | |
548 return; | |
549 } | |
550 | |
551 std::list<std::string>::iterator current = tmp.begin(); | |
552 std::advance(current, since); | |
553 | |
554 while (limit > 0 && current != tmp.end()) | |
555 { | |
556 target.push_back(*current); | |
557 --limit; | |
558 ++current; | |
559 } | |
560 } | |
561 } | |
562 | |
563 | |
564 | |
565 void OrthancPluginDatabase::GetChanges(std::list<ServerIndexChange>& target /*out*/, | |
566 bool& done /*out*/, | |
567 int64_t since, | |
568 uint32_t maxResults) | |
569 { | |
570 ResetAnswers(); | |
571 answerChanges_ = ⌖ | |
572 answerDone_ = &done; | |
573 done = false; | |
574 | |
575 CheckSuccess(backend_.getChanges(GetContext(), payload_, since, maxResults)); | |
576 } | |
577 | |
578 | |
579 void OrthancPluginDatabase::GetChildrenInternalId(std::list<int64_t>& target, | |
580 int64_t id) | |
581 { | |
582 ResetAnswers(); | |
583 CheckSuccess(backend_.getChildrenInternalId(GetContext(), payload_, id)); | |
584 ForwardAnswers(target); | |
585 } | |
586 | |
587 | |
588 void OrthancPluginDatabase::GetChildrenPublicId(std::list<std::string>& target, | |
589 int64_t id) | |
590 { | |
591 ResetAnswers(); | |
592 CheckSuccess(backend_.getChildrenPublicId(GetContext(), payload_, id)); | |
593 ForwardAnswers(target); | |
594 } | |
595 | |
596 | |
597 void OrthancPluginDatabase::GetExportedResources(std::list<ExportedResource>& target /*out*/, | |
598 bool& done /*out*/, | |
599 int64_t since, | |
600 uint32_t maxResults) | |
601 { | |
602 ResetAnswers(); | |
603 answerExportedResources_ = ⌖ | |
604 answerDone_ = &done; | |
605 done = false; | |
606 | |
607 CheckSuccess(backend_.getExportedResources(GetContext(), payload_, since, maxResults)); | |
608 } | |
609 | |
610 | |
611 void OrthancPluginDatabase::GetLastChange(std::list<ServerIndexChange>& target /*out*/) | |
612 { | |
613 answerDoneIgnored_ = false; | |
614 | |
615 ResetAnswers(); | |
616 answerChanges_ = ⌖ | |
617 answerDone_ = &answerDoneIgnored_; | |
618 | |
619 CheckSuccess(backend_.getLastChange(GetContext(), payload_)); | |
620 } | |
621 | |
622 | |
623 void OrthancPluginDatabase::GetLastExportedResource(std::list<ExportedResource>& target /*out*/) | |
624 { | |
625 answerDoneIgnored_ = false; | |
626 | |
627 ResetAnswers(); | |
628 answerExportedResources_ = ⌖ | |
629 answerDone_ = &answerDoneIgnored_; | |
630 | |
631 CheckSuccess(backend_.getLastExportedResource(GetContext(), payload_)); | |
632 } | |
633 | |
634 | |
635 void OrthancPluginDatabase::GetMainDicomTags(DicomMap& map, | |
636 int64_t id) | |
637 { | |
638 ResetAnswers(); | |
639 answerDicomMap_ = ↦ | |
640 | |
641 CheckSuccess(backend_.getMainDicomTags(GetContext(), payload_, id)); | |
642 } | |
643 | |
644 | |
645 std::string OrthancPluginDatabase::GetPublicId(int64_t resourceId) | |
646 { | |
647 ResetAnswers(); | |
648 std::string s; | |
649 | |
650 CheckSuccess(backend_.getPublicId(GetContext(), payload_, resourceId)); | |
651 | |
652 if (!ForwardSingleAnswer(s)) | |
653 { | |
654 throw OrthancException(ErrorCode_DatabasePlugin); | |
655 } | |
656 | |
657 return s; | |
658 } | |
659 | |
660 | |
661 uint64_t OrthancPluginDatabase::GetResourceCount(ResourceType resourceType) | |
662 { | |
663 uint64_t count; | |
664 CheckSuccess(backend_.getResourceCount(&count, payload_, Plugins::Convert(resourceType))); | |
665 return count; | |
666 } | |
667 | |
668 | |
669 ResourceType OrthancPluginDatabase::GetResourceType(int64_t resourceId) | |
670 { | |
671 OrthancPluginResourceType type; | |
672 CheckSuccess(backend_.getResourceType(&type, payload_, resourceId)); | |
673 return Plugins::Convert(type); | |
674 } | |
675 | |
676 | |
677 uint64_t OrthancPluginDatabase::GetTotalCompressedSize() | |
678 { | |
679 uint64_t size; | |
680 CheckSuccess(backend_.getTotalCompressedSize(&size, payload_)); | |
681 return size; | |
682 } | |
683 | |
684 | |
685 uint64_t OrthancPluginDatabase::GetTotalUncompressedSize() | |
686 { | |
687 uint64_t size; | |
688 CheckSuccess(backend_.getTotalUncompressedSize(&size, payload_)); | |
689 return size; | |
690 } | |
691 | |
692 | |
693 bool OrthancPluginDatabase::IsExistingResource(int64_t internalId) | |
694 { | |
695 int32_t existing; | |
696 CheckSuccess(backend_.isExistingResource(&existing, payload_, internalId)); | |
697 return (existing != 0); | |
698 } | |
699 | |
700 | |
701 bool OrthancPluginDatabase::IsProtectedPatient(int64_t internalId) | |
702 { | |
703 int32_t isProtected; | |
704 CheckSuccess(backend_.isProtectedPatient(&isProtected, payload_, internalId)); | |
705 return (isProtected != 0); | |
706 } | |
707 | |
708 | |
709 void OrthancPluginDatabase::ListAvailableAttachments(std::set<FileContentType>& target, | |
710 int64_t id) | |
711 { | |
712 ResetAnswers(); | |
713 | |
714 CheckSuccess(backend_.listAvailableAttachments(GetContext(), payload_, id)); | |
715 | |
716 if (type_ != _OrthancPluginDatabaseAnswerType_None && | |
717 type_ != _OrthancPluginDatabaseAnswerType_Int32) | |
718 { | |
719 throw OrthancException(ErrorCode_DatabasePlugin); | |
720 } | |
721 | |
722 target.clear(); | |
723 | |
724 if (type_ == _OrthancPluginDatabaseAnswerType_Int32) | |
725 { | |
726 for (std::list<int32_t>::const_iterator | |
727 it = answerInt32_.begin(); it != answerInt32_.end(); ++it) | |
728 { | |
729 target.insert(static_cast<FileContentType>(*it)); | |
730 } | |
731 } | |
732 } | |
733 | |
734 | |
735 void OrthancPluginDatabase::LogChange(int64_t internalId, | |
736 const ServerIndexChange& change) | |
737 { | |
738 OrthancPluginChange tmp; | |
739 tmp.seq = change.GetSeq(); | |
740 tmp.changeType = static_cast<int32_t>(change.GetChangeType()); | |
741 tmp.resourceType = Plugins::Convert(change.GetResourceType()); | |
742 tmp.publicId = change.GetPublicId().c_str(); | |
743 tmp.date = change.GetDate().c_str(); | |
744 | |
745 CheckSuccess(backend_.logChange(payload_, &tmp)); | |
746 } | |
747 | |
748 | |
749 void OrthancPluginDatabase::LogExportedResource(const ExportedResource& resource) | |
750 { | |
751 OrthancPluginExportedResource tmp; | |
752 tmp.seq = resource.GetSeq(); | |
753 tmp.resourceType = Plugins::Convert(resource.GetResourceType()); | |
754 tmp.publicId = resource.GetPublicId().c_str(); | |
755 tmp.modality = resource.GetModality().c_str(); | |
756 tmp.date = resource.GetDate().c_str(); | |
757 tmp.patientId = resource.GetPatientId().c_str(); | |
758 tmp.studyInstanceUid = resource.GetStudyInstanceUid().c_str(); | |
759 tmp.seriesInstanceUid = resource.GetSeriesInstanceUid().c_str(); | |
760 tmp.sopInstanceUid = resource.GetSopInstanceUid().c_str(); | |
761 | |
762 CheckSuccess(backend_.logExportedResource(payload_, &tmp)); | |
763 } | |
764 | |
765 | |
766 bool OrthancPluginDatabase::LookupAttachment(FileInfo& attachment, | |
767 int64_t id, | |
768 FileContentType contentType) | |
769 { | |
770 ResetAnswers(); | |
771 | |
772 CheckSuccess(backend_.lookupAttachment | |
773 (GetContext(), payload_, id, static_cast<int32_t>(contentType))); | |
774 | |
775 if (type_ == _OrthancPluginDatabaseAnswerType_None) | |
776 { | |
777 return false; | |
778 } | |
779 else if (type_ == _OrthancPluginDatabaseAnswerType_Attachment && | |
780 answerAttachments_.size() == 1) | |
781 { | |
782 attachment = answerAttachments_.front(); | |
783 return true; | |
784 } | |
785 else | |
786 { | |
787 throw OrthancException(ErrorCode_DatabasePlugin); | |
788 } | |
789 } | |
790 | |
791 | |
792 bool OrthancPluginDatabase::LookupGlobalProperty(std::string& target, | |
793 GlobalProperty property) | |
794 { | |
795 ResetAnswers(); | |
796 | |
797 CheckSuccess(backend_.lookupGlobalProperty | |
798 (GetContext(), payload_, static_cast<int32_t>(property))); | |
799 | |
800 return ForwardSingleAnswer(target); | |
801 } | |
802 | |
803 | |
804 bool OrthancPluginDatabase::LookupMetadata(std::string& target, | |
805 int64_t id, | |
806 MetadataType type) | |
807 { | |
808 ResetAnswers(); | |
809 CheckSuccess(backend_.lookupMetadata(GetContext(), payload_, id, static_cast<int32_t>(type))); | |
810 return ForwardSingleAnswer(target); | |
811 } | |
812 | |
813 | |
814 bool OrthancPluginDatabase::LookupParent(int64_t& parentId, | |
815 int64_t resourceId) | |
816 { | |
817 ResetAnswers(); | |
818 CheckSuccess(backend_.lookupParent(GetContext(), payload_, resourceId)); | |
819 return ForwardSingleAnswer(parentId); | |
820 } | |
821 | |
822 | |
823 bool OrthancPluginDatabase::LookupResource(int64_t& id, | |
824 ResourceType& type, | |
825 const std::string& publicId) | |
826 { | |
827 ResetAnswers(); | |
828 | |
829 CheckSuccess(backend_.lookupResource(GetContext(), payload_, publicId.c_str())); | |
830 | |
831 if (type_ == _OrthancPluginDatabaseAnswerType_None) | |
832 { | |
833 return false; | |
834 } | |
835 else if (type_ == _OrthancPluginDatabaseAnswerType_Resource && | |
836 answerResources_.size() == 1) | |
837 { | |
838 id = answerResources_.front().first; | |
839 type = answerResources_.front().second; | |
840 return true; | |
841 } | |
842 else | |
843 { | |
844 throw OrthancException(ErrorCode_DatabasePlugin); | |
845 } | |
846 } | |
847 | |
848 | |
849 bool OrthancPluginDatabase::SelectPatientToRecycle(int64_t& internalId) | |
850 { | |
851 ResetAnswers(); | |
852 CheckSuccess(backend_.selectPatientToRecycle(GetContext(), payload_)); | |
853 return ForwardSingleAnswer(internalId); | |
854 } | |
855 | |
856 | |
857 bool OrthancPluginDatabase::SelectPatientToRecycle(int64_t& internalId, | |
858 int64_t patientIdToAvoid) | |
859 { | |
860 ResetAnswers(); | |
861 CheckSuccess(backend_.selectPatientToRecycle2(GetContext(), payload_, patientIdToAvoid)); | |
862 return ForwardSingleAnswer(internalId); | |
863 } | |
864 | |
865 | |
866 void OrthancPluginDatabase::SetGlobalProperty(GlobalProperty property, | |
867 const std::string& value) | |
868 { | |
869 CheckSuccess(backend_.setGlobalProperty | |
870 (payload_, static_cast<int32_t>(property), value.c_str())); | |
871 } | |
872 | |
873 | |
874 void OrthancPluginDatabase::ClearMainDicomTags(int64_t id) | |
875 { | |
876 if (extensions_.clearMainDicomTags == NULL) | |
877 { | |
878 throw OrthancException(ErrorCode_DatabasePlugin, | |
879 "Your custom index plugin does not implement the mandatory ClearMainDicomTags() extension"); | |
880 } | |
881 | |
882 CheckSuccess(extensions_.clearMainDicomTags(payload_, id)); | |
883 } | |
884 | |
885 | |
886 void OrthancPluginDatabase::SetMainDicomTag(int64_t id, | |
887 const DicomTag& tag, | |
888 const std::string& value) | |
889 { | |
890 OrthancPluginDicomTag tmp; | |
891 tmp.group = tag.GetGroup(); | |
892 tmp.element = tag.GetElement(); | |
893 tmp.value = value.c_str(); | |
894 | |
895 CheckSuccess(backend_.setMainDicomTag(payload_, id, &tmp)); | |
896 } | |
897 | |
898 | |
899 void OrthancPluginDatabase::SetIdentifierTag(int64_t id, | |
900 const DicomTag& tag, | |
901 const std::string& value) | |
902 { | |
903 OrthancPluginDicomTag tmp; | |
904 tmp.group = tag.GetGroup(); | |
905 tmp.element = tag.GetElement(); | |
906 tmp.value = value.c_str(); | |
907 | |
908 CheckSuccess(backend_.setIdentifierTag(payload_, id, &tmp)); | |
909 } | |
910 | |
911 | |
912 void OrthancPluginDatabase::SetMetadata(int64_t id, | |
913 MetadataType type, | |
914 const std::string& value) | |
915 { | |
916 CheckSuccess(backend_.setMetadata | |
917 (payload_, id, static_cast<int32_t>(type), value.c_str())); | |
918 } | |
919 | |
920 | |
921 void OrthancPluginDatabase::SetProtectedPatient(int64_t internalId, | |
922 bool isProtected) | |
923 { | |
924 CheckSuccess(backend_.setProtectedPatient(payload_, internalId, isProtected)); | |
925 } | 1222 } |
926 | 1223 |
927 | 1224 |
928 IDatabaseWrapper::ITransaction* OrthancPluginDatabase::StartTransaction(TransactionType type, | 1225 IDatabaseWrapper::ITransaction* OrthancPluginDatabase::StartTransaction(TransactionType type, |
929 IDatabaseListener& listener) | 1226 IDatabaseListener& listener) |
988 | 1285 |
989 | 1286 |
990 void OrthancPluginDatabase::Upgrade(unsigned int targetVersion, | 1287 void OrthancPluginDatabase::Upgrade(unsigned int targetVersion, |
991 IStorageArea& storageArea) | 1288 IStorageArea& storageArea) |
992 { | 1289 { |
993 VoidListener listener; | 1290 VoidDatabaseListener listener; |
994 | 1291 |
995 if (extensions_.upgradeDatabase != NULL) | 1292 if (extensions_.upgradeDatabase != NULL) |
996 { | 1293 { |
997 Transaction transaction(*this, listener); | 1294 Transaction transaction(*this, listener); |
998 transaction.Begin(); | 1295 transaction.Begin(); |
1265 throw OrthancException(ErrorCode_DatabasePlugin, | 1562 throw OrthancException(ErrorCode_DatabasePlugin, |
1266 "Unhandled type of answer for custom index plugin: " + | 1563 "Unhandled type of answer for custom index plugin: " + |
1267 boost::lexical_cast<std::string>(answer.type)); | 1564 boost::lexical_cast<std::string>(answer.type)); |
1268 } | 1565 } |
1269 } | 1566 } |
1270 | |
1271 | |
1272 bool OrthancPluginDatabase::IsDiskSizeAbove(uint64_t threshold) | |
1273 { | |
1274 if (fastGetTotalSize_) | |
1275 { | |
1276 return GetTotalCompressedSize() > threshold; | |
1277 } | |
1278 else | |
1279 { | |
1280 assert(GetTotalCompressedSize() == currentDiskSize_); | |
1281 return currentDiskSize_ > threshold; | |
1282 } | |
1283 } | |
1284 | |
1285 | |
1286 void OrthancPluginDatabase::ApplyLookupResources(std::list<std::string>& resourcesId, | |
1287 std::list<std::string>* instancesId, | |
1288 const std::vector<DatabaseConstraint>& lookup, | |
1289 ResourceType queryLevel, | |
1290 size_t limit) | |
1291 { | |
1292 if (extensions_.lookupResources == NULL) | |
1293 { | |
1294 // Fallback to compatibility mode | |
1295 ILookupResources::Apply | |
1296 (*this, *this, resourcesId, instancesId, lookup, queryLevel, limit); | |
1297 } | |
1298 else | |
1299 { | |
1300 std::vector<OrthancPluginDatabaseConstraint> constraints; | |
1301 std::vector< std::vector<const char*> > constraintsValues; | |
1302 | |
1303 constraints.resize(lookup.size()); | |
1304 constraintsValues.resize(lookup.size()); | |
1305 | |
1306 for (size_t i = 0; i < lookup.size(); i++) | |
1307 { | |
1308 lookup[i].EncodeForPlugins(constraints[i], constraintsValues[i]); | |
1309 } | |
1310 | |
1311 ResetAnswers(); | |
1312 answerMatchingResources_ = &resourcesId; | |
1313 answerMatchingInstances_ = instancesId; | |
1314 | |
1315 CheckSuccess(extensions_.lookupResources(GetContext(), payload_, lookup.size(), | |
1316 (lookup.empty() ? NULL : &constraints[0]), | |
1317 Plugins::Convert(queryLevel), | |
1318 limit, (instancesId == NULL ? 0 : 1))); | |
1319 } | |
1320 } | |
1321 | |
1322 | |
1323 bool OrthancPluginDatabase::CreateInstance( | |
1324 IDatabaseWrapper::CreateInstanceResult& result, | |
1325 int64_t& instanceId, | |
1326 const std::string& patient, | |
1327 const std::string& study, | |
1328 const std::string& series, | |
1329 const std::string& instance) | |
1330 { | |
1331 if (extensions_.createInstance == NULL) | |
1332 { | |
1333 // Fallback to compatibility mode | |
1334 return ICreateInstance::Apply | |
1335 (*this, result, instanceId, patient, study, series, instance); | |
1336 } | |
1337 else | |
1338 { | |
1339 OrthancPluginCreateInstanceResult output; | |
1340 memset(&output, 0, sizeof(output)); | |
1341 | |
1342 CheckSuccess(extensions_.createInstance(&output, payload_, patient.c_str(), | |
1343 study.c_str(), series.c_str(), instance.c_str())); | |
1344 | |
1345 instanceId = output.instanceId; | |
1346 | |
1347 if (output.isNewInstance) | |
1348 { | |
1349 result.isNewPatient_ = output.isNewPatient; | |
1350 result.isNewStudy_ = output.isNewStudy; | |
1351 result.isNewSeries_ = output.isNewSeries; | |
1352 result.patientId_ = output.patientId; | |
1353 result.studyId_ = output.studyId; | |
1354 result.seriesId_ = output.seriesId; | |
1355 return true; | |
1356 } | |
1357 else | |
1358 { | |
1359 return false; | |
1360 } | |
1361 } | |
1362 } | |
1363 | |
1364 | |
1365 void OrthancPluginDatabase::LookupIdentifier(std::list<int64_t>& result, | |
1366 ResourceType level, | |
1367 const DicomTag& tag, | |
1368 Compatibility::IdentifierConstraintType type, | |
1369 const std::string& value) | |
1370 { | |
1371 if (extensions_.lookupIdentifier3 == NULL) | |
1372 { | |
1373 throw OrthancException(ErrorCode_DatabasePlugin, | |
1374 "The database plugin does not implement the mandatory LookupIdentifier3() extension"); | |
1375 } | |
1376 | |
1377 OrthancPluginDicomTag tmp; | |
1378 tmp.group = tag.GetGroup(); | |
1379 tmp.element = tag.GetElement(); | |
1380 tmp.value = value.c_str(); | |
1381 | |
1382 ResetAnswers(); | |
1383 CheckSuccess(extensions_.lookupIdentifier3(GetContext(), payload_, Plugins::Convert(level), | |
1384 &tmp, Compatibility::Convert(type))); | |
1385 ForwardAnswers(result); | |
1386 } | |
1387 | |
1388 | |
1389 void OrthancPluginDatabase::LookupIdentifierRange(std::list<int64_t>& result, | |
1390 ResourceType level, | |
1391 const DicomTag& tag, | |
1392 const std::string& start, | |
1393 const std::string& end) | |
1394 { | |
1395 if (extensions_.lookupIdentifierRange == NULL) | |
1396 { | |
1397 // Default implementation, for plugins using Orthanc SDK <= 1.3.2 | |
1398 | |
1399 LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_GreaterOrEqual, start); | |
1400 | |
1401 std::list<int64_t> b; | |
1402 LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_SmallerOrEqual, end); | |
1403 | |
1404 result.splice(result.end(), b); | |
1405 } | |
1406 else | |
1407 { | |
1408 ResetAnswers(); | |
1409 CheckSuccess(extensions_.lookupIdentifierRange(GetContext(), payload_, Plugins::Convert(level), | |
1410 tag.GetGroup(), tag.GetElement(), | |
1411 start.c_str(), end.c_str())); | |
1412 ForwardAnswers(result); | |
1413 } | |
1414 } | |
1415 | |
1416 | |
1417 void OrthancPluginDatabase::SetResourcesContent(const Orthanc::ResourcesContent& content) | |
1418 { | |
1419 if (extensions_.setResourcesContent == NULL) | |
1420 { | |
1421 ISetResourcesContent::Apply(*this, content); | |
1422 } | |
1423 else | |
1424 { | |
1425 std::vector<OrthancPluginResourcesContentTags> identifierTags; | |
1426 std::vector<OrthancPluginResourcesContentTags> mainDicomTags; | |
1427 std::vector<OrthancPluginResourcesContentMetadata> metadata; | |
1428 | |
1429 identifierTags.reserve(content.GetListTags().size()); | |
1430 mainDicomTags.reserve(content.GetListTags().size()); | |
1431 metadata.reserve(content.GetListMetadata().size()); | |
1432 | |
1433 for (ResourcesContent::ListTags::const_iterator | |
1434 it = content.GetListTags().begin(); it != content.GetListTags().end(); ++it) | |
1435 { | |
1436 OrthancPluginResourcesContentTags tmp; | |
1437 tmp.resource = it->resourceId_; | |
1438 tmp.group = it->tag_.GetGroup(); | |
1439 tmp.element = it->tag_.GetElement(); | |
1440 tmp.value = it->value_.c_str(); | |
1441 | |
1442 if (it->isIdentifier_) | |
1443 { | |
1444 identifierTags.push_back(tmp); | |
1445 } | |
1446 else | |
1447 { | |
1448 mainDicomTags.push_back(tmp); | |
1449 } | |
1450 } | |
1451 | |
1452 for (ResourcesContent::ListMetadata::const_iterator | |
1453 it = content.GetListMetadata().begin(); it != content.GetListMetadata().end(); ++it) | |
1454 { | |
1455 OrthancPluginResourcesContentMetadata tmp; | |
1456 tmp.resource = it->resourceId_; | |
1457 tmp.metadata = it->metadata_; | |
1458 tmp.value = it->value_.c_str(); | |
1459 metadata.push_back(tmp); | |
1460 } | |
1461 | |
1462 assert(identifierTags.size() + mainDicomTags.size() == content.GetListTags().size() && | |
1463 metadata.size() == content.GetListMetadata().size()); | |
1464 | |
1465 CheckSuccess(extensions_.setResourcesContent( | |
1466 payload_, | |
1467 identifierTags.size(), | |
1468 (identifierTags.empty() ? NULL : &identifierTags[0]), | |
1469 mainDicomTags.size(), | |
1470 (mainDicomTags.empty() ? NULL : &mainDicomTags[0]), | |
1471 metadata.size(), | |
1472 (metadata.empty() ? NULL : &metadata[0]))); | |
1473 } | |
1474 } | |
1475 | |
1476 | |
1477 | |
1478 void OrthancPluginDatabase::GetChildrenMetadata(std::list<std::string>& target, | |
1479 int64_t resourceId, | |
1480 MetadataType metadata) | |
1481 { | |
1482 if (extensions_.getChildrenMetadata == NULL) | |
1483 { | |
1484 IGetChildrenMetadata::Apply(*this, target, resourceId, metadata); | |
1485 } | |
1486 else | |
1487 { | |
1488 ResetAnswers(); | |
1489 CheckSuccess(extensions_.getChildrenMetadata | |
1490 (GetContext(), payload_, resourceId, static_cast<int32_t>(metadata))); | |
1491 ForwardAnswers(target); | |
1492 } | |
1493 } | |
1494 | |
1495 | |
1496 int64_t OrthancPluginDatabase::GetLastChangeIndex() | |
1497 { | |
1498 if (extensions_.getLastChangeIndex == NULL) | |
1499 { | |
1500 // This was the default behavior in Orthanc <= 1.5.1 | |
1501 // https://groups.google.com/d/msg/orthanc-users/QhzB6vxYeZ0/YxabgqpfBAAJ | |
1502 return 0; | |
1503 } | |
1504 else | |
1505 { | |
1506 int64_t result = 0; | |
1507 CheckSuccess(extensions_.getLastChangeIndex(&result, payload_)); | |
1508 return result; | |
1509 } | |
1510 } | |
1511 | |
1512 | |
1513 void OrthancPluginDatabase::TagMostRecentPatient(int64_t patient) | |
1514 { | |
1515 if (extensions_.tagMostRecentPatient != NULL) | |
1516 { | |
1517 CheckSuccess(extensions_.tagMostRecentPatient(payload_, patient)); | |
1518 } | |
1519 } | |
1520 | |
1521 | |
1522 bool OrthancPluginDatabase::LookupResourceAndParent(int64_t& id, | |
1523 ResourceType& type, | |
1524 std::string& parentPublicId, | |
1525 const std::string& publicId) | |
1526 { | |
1527 if (extensions_.lookupResourceAndParent == NULL) | |
1528 { | |
1529 return ILookupResourceAndParent::Apply(*this, id, type, parentPublicId, publicId); | |
1530 } | |
1531 else | |
1532 { | |
1533 std::list<std::string> parent; | |
1534 | |
1535 uint8_t isExisting; | |
1536 OrthancPluginResourceType pluginType = OrthancPluginResourceType_Patient; | |
1537 | |
1538 ResetAnswers(); | |
1539 CheckSuccess(extensions_.lookupResourceAndParent | |
1540 (GetContext(), &isExisting, &id, &pluginType, payload_, publicId.c_str())); | |
1541 ForwardAnswers(parent); | |
1542 | |
1543 if (isExisting) | |
1544 { | |
1545 type = Plugins::Convert(pluginType); | |
1546 | |
1547 if (parent.empty()) | |
1548 { | |
1549 if (type != ResourceType_Patient) | |
1550 { | |
1551 throw OrthancException(ErrorCode_DatabasePlugin); | |
1552 } | |
1553 } | |
1554 else if (parent.size() == 1) | |
1555 { | |
1556 if ((type != ResourceType_Study && | |
1557 type != ResourceType_Series && | |
1558 type != ResourceType_Instance) || | |
1559 parent.front().empty()) | |
1560 { | |
1561 throw OrthancException(ErrorCode_DatabasePlugin); | |
1562 } | |
1563 | |
1564 parentPublicId = parent.front(); | |
1565 } | |
1566 else | |
1567 { | |
1568 throw OrthancException(ErrorCode_DatabasePlugin); | |
1569 } | |
1570 | |
1571 return true; | |
1572 } | |
1573 else | |
1574 { | |
1575 return false; | |
1576 } | |
1577 } | |
1578 } | |
1579 } | 1567 } |