comparison SQLite/Plugins/IndexPlugin.cpp @ 210:a0c095a4ba7d

all the integration tests pass on SQLite
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 22 Mar 2021 19:36:43 +0100
parents 13a3863df7fa
children d74a92ac00ea
comparison
equal deleted inserted replaced
209:13a3863df7fa 210:a0c095a4ba7d
97 public: 97 public:
98 Output() : 98 Output() :
99 answerType_(_OrthancPluginDatabaseAnswerType_None) 99 answerType_(_OrthancPluginDatabaseAnswerType_None)
100 { 100 {
101 } 101 }
102 102
103
104 void Clear() 103 void Clear()
105 { 104 {
106 // We don't systematically clear all the vectors, in order to 105 // We don't systematically clear all the vectors, in order to
107 // avoid spending unnecessary time 106 // avoid spending unnecessary time
108 107
151 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 150 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
152 } 151 }
153 152
154 answerType_ = _OrthancPluginDatabaseAnswerType_None; 153 answerType_ = _OrthancPluginDatabaseAnswerType_None;
155 stringsStore_.clear(); 154 stringsStore_.clear();
155 events_.clear();
156 156
157 assert(attachments_.empty()); 157 assert(attachments_.empty());
158 assert(changes_.empty()); 158 assert(changes_.empty());
159 assert(tags_.empty()); 159 assert(tags_.empty());
160 assert(exported_.empty()); 160 assert(exported_.empty());
165 assert(metadata_.empty()); 165 assert(metadata_.empty());
166 assert(stringAnswers_.empty()); 166 assert(stringAnswers_.empty());
167 } 167 }
168 168
169 169
170 static OrthancPluginErrorCode ReadAnswersCount(OrthancPluginDatabaseTransaction* transaction, 170 OrthancPluginErrorCode ReadAnswersCount(uint32_t& target) const
171 uint32_t* target /* out */) 171 {
172 { 172 switch (answerType_)
173 const Output& that = *reinterpret_cast<const Output*>(transaction);
174
175 size_t size;
176
177 switch (that.answerType_)
178 { 173 {
179 case _OrthancPluginDatabaseAnswerType_None: 174 case _OrthancPluginDatabaseAnswerType_None:
180 size = 0; 175 target = static_cast<uint32_t>(0);
181 break; 176 break;
182 177
183 case _OrthancPluginDatabaseAnswerType_Attachment: 178 case _OrthancPluginDatabaseAnswerType_Attachment:
184 size = that.attachments_.size(); 179 target = static_cast<uint32_t>(attachments_.size());
185 break; 180 break;
186 181
187 case _OrthancPluginDatabaseAnswerType_Change: 182 case _OrthancPluginDatabaseAnswerType_Change:
188 size = that.changes_.size(); 183 target = static_cast<uint32_t>(changes_.size());
189 break; 184 break;
190 185
191 case _OrthancPluginDatabaseAnswerType_DicomTag: 186 case _OrthancPluginDatabaseAnswerType_DicomTag:
192 size = that.tags_.size(); 187 target = static_cast<uint32_t>(tags_.size());
193 break; 188 break;
194 189
195 case _OrthancPluginDatabaseAnswerType_ExportedResource: 190 case _OrthancPluginDatabaseAnswerType_ExportedResource:
196 size = that.exported_.size(); 191 target = static_cast<uint32_t>(exported_.size());
197 break; 192 break;
198 193
199 case _OrthancPluginDatabaseAnswerType_Int32: 194 case _OrthancPluginDatabaseAnswerType_Int32:
200 size = that.integers32_.size(); 195 target = static_cast<uint32_t>(integers32_.size());
201 break; 196 break;
202 197
203 case _OrthancPluginDatabaseAnswerType_Int64: 198 case _OrthancPluginDatabaseAnswerType_Int64:
204 size = that.integers64_.size(); 199 target = static_cast<uint32_t>(integers64_.size());
205 break; 200 break;
206 201
207 case _OrthancPluginDatabaseAnswerType_MatchingResource: 202 case _OrthancPluginDatabaseAnswerType_MatchingResource:
208 size = that.matches_.size(); 203 target = static_cast<uint32_t>(matches_.size());
209 break; 204 break;
210 205
211 case _OrthancPluginDatabaseAnswerType_Metadata: 206 case _OrthancPluginDatabaseAnswerType_Metadata:
212 size = that.metadata_.size(); 207 target = static_cast<uint32_t>(metadata_.size());
213 break; 208 break;
214 209
215 case _OrthancPluginDatabaseAnswerType_String: 210 case _OrthancPluginDatabaseAnswerType_String:
216 size = that.stringAnswers_.size(); 211 target = static_cast<uint32_t>(stringAnswers_.size());
217 break; 212 break;
218 213
219 default: 214 default:
220 return OrthancPluginErrorCode_InternalError; 215 return OrthancPluginErrorCode_InternalError;
221 } 216 }
222 217
223 *target = static_cast<uint32_t>(size); 218 return OrthancPluginErrorCode_Success;
224 return OrthancPluginErrorCode_Success; 219 }
225 } 220
226 221
227 222 OrthancPluginErrorCode ReadAnswerAttachment(OrthancPluginAttachment& target /* out */,
228 static OrthancPluginErrorCode ReadAnswerAttachment(OrthancPluginDatabaseTransaction* transaction, 223 uint32_t index) const
229 OrthancPluginAttachment* target /* out */, 224 {
230 uint32_t index) 225 if (index < attachments_.size())
231 { 226 {
232 const Output& that = *reinterpret_cast<const Output*>(transaction); 227 target = attachments_[index];
233 228 return OrthancPluginErrorCode_Success;
234 if (index < that.attachments_.size()) 229 }
235 { 230 else
236 *target = that.attachments_[index]; 231 {
232 return OrthancPluginErrorCode_ParameterOutOfRange;
233 }
234 }
235
236
237 OrthancPluginErrorCode ReadAnswerChange(OrthancPluginChange& target /* out */,
238 uint32_t index) const
239 {
240 if (index < changes_.size())
241 {
242 target = changes_[index];
237 return OrthancPluginErrorCode_Success; 243 return OrthancPluginErrorCode_Success;
238 } 244 }
239 else 245 else
240 { 246 {
241 return OrthancPluginErrorCode_ParameterOutOfRange; 247 return OrthancPluginErrorCode_ParameterOutOfRange;
242 } 248 }
243 } 249 }
244 250
245 251
246 static OrthancPluginErrorCode ReadAnswerChange(OrthancPluginDatabaseTransaction* transaction, 252 OrthancPluginErrorCode ReadAnswerDicomTag(uint16_t& group,
247 OrthancPluginChange* target /* out */, 253 uint16_t& element,
248 uint32_t index) 254 const char*& value,
249 { 255 uint32_t index) const
250 const Output& that = *reinterpret_cast<const Output*>(transaction); 256 {
251 257 if (index < tags_.size())
252 if (index < that.changes_.size()) 258 {
253 { 259 const OrthancPluginDicomTag& tag = tags_[index];
254 *target = that.changes_[index]; 260 group = tag.group;
261 element = tag.element;
262 value = tag.value;
255 return OrthancPluginErrorCode_Success; 263 return OrthancPluginErrorCode_Success;
256 } 264 }
257 else 265 else
258 { 266 {
259 return OrthancPluginErrorCode_ParameterOutOfRange; 267 return OrthancPluginErrorCode_ParameterOutOfRange;
260 } 268 }
261 } 269 }
262 270
263 271
264 static OrthancPluginErrorCode ReadAnswerDicomTag(OrthancPluginDatabaseTransaction* transaction, 272 OrthancPluginErrorCode ReadAnswerExportedResource(OrthancPluginExportedResource& target /* out */,
265 uint16_t* group, 273 uint32_t index) const
266 uint16_t* element, 274 {
267 const char** value, 275 if (index < exported_.size())
268 uint32_t index) 276 {
269 { 277 target = exported_[index];
270 const Output& that = *reinterpret_cast<const Output*>(transaction);
271
272 if (index < that.tags_.size())
273 {
274 const OrthancPluginDicomTag& tag = that.tags_[index];
275 *group = tag.group;
276 *element = tag.element;
277 *value = tag.value;
278 return OrthancPluginErrorCode_Success; 278 return OrthancPluginErrorCode_Success;
279 } 279 }
280 else 280 else
281 { 281 {
282 return OrthancPluginErrorCode_ParameterOutOfRange; 282 return OrthancPluginErrorCode_ParameterOutOfRange;
283 } 283 }
284 } 284 }
285 285
286 286
287 static OrthancPluginErrorCode ReadAnswerExportedResource(OrthancPluginDatabaseTransaction* transaction, 287 OrthancPluginErrorCode ReadAnswerInt32(int32_t& target,
288 OrthancPluginExportedResource* target /* out */, 288 uint32_t index) const
289 uint32_t index) 289 {
290 { 290 if (index < integers32_.size())
291 const Output& that = *reinterpret_cast<const Output*>(transaction); 291 {
292 292 target = integers32_[index];
293 if (index < that.exported_.size())
294 {
295 *target = that.exported_[index];
296 return OrthancPluginErrorCode_Success; 293 return OrthancPluginErrorCode_Success;
297 } 294 }
298 else 295 else
299 { 296 {
300 return OrthancPluginErrorCode_ParameterOutOfRange; 297 return OrthancPluginErrorCode_ParameterOutOfRange;
301 } 298 }
302 } 299 }
303 300
304 301
305 static OrthancPluginErrorCode ReadAnswerInt32(OrthancPluginDatabaseTransaction* transaction, 302 OrthancPluginErrorCode ReadAnswerInt64(int64_t& target,
306 int32_t* target, 303 uint32_t index) const
307 uint32_t index) 304 {
308 { 305 if (index < integers64_.size())
309 const Output& that = *reinterpret_cast<const Output*>(transaction); 306 {
310 307 target = integers64_[index];
311 if (index < that.integers32_.size())
312 {
313 *target = that.integers32_[index];
314 return OrthancPluginErrorCode_Success; 308 return OrthancPluginErrorCode_Success;
315 } 309 }
316 else 310 else
317 { 311 {
318 return OrthancPluginErrorCode_ParameterOutOfRange; 312 return OrthancPluginErrorCode_ParameterOutOfRange;
319 } 313 }
320 } 314 }
321 315
322 316
323 static OrthancPluginErrorCode ReadAnswerInt64(OrthancPluginDatabaseTransaction* transaction, 317 OrthancPluginErrorCode ReadAnswerMatchingResource(OrthancPluginMatchingResource& target,
324 int64_t* target, 318 uint32_t index) const
325 uint32_t index) 319 {
326 { 320 if (index < matches_.size())
327 const Output& that = *reinterpret_cast<const Output*>(transaction); 321 {
328 322 target = matches_[index];
329 if (index < that.integers64_.size())
330 {
331 *target = that.integers64_[index];
332 return OrthancPluginErrorCode_Success; 323 return OrthancPluginErrorCode_Success;
333 } 324 }
334 else 325 else
335 { 326 {
336 return OrthancPluginErrorCode_ParameterOutOfRange; 327 return OrthancPluginErrorCode_ParameterOutOfRange;
337 } 328 }
338 } 329 }
339 330
340 331
341 static OrthancPluginErrorCode ReadAnswerMatchingResource(OrthancPluginDatabaseTransaction* transaction, 332 OrthancPluginErrorCode ReadAnswerMetadata(int32_t& metadata,
342 OrthancPluginMatchingResource* target, 333 const char*& value,
343 uint32_t index) 334 uint32_t index) const
344 { 335 {
345 const Output& that = *reinterpret_cast<const Output*>(transaction); 336 if (index < metadata_.size())
346 337 {
347 if (index < that.matches_.size()) 338 const Metadata& tmp = metadata_[index];
348 { 339 metadata = tmp.metadata;
349 *target = that.matches_[index]; 340 value = tmp.value;
350 return OrthancPluginErrorCode_Success; 341 return OrthancPluginErrorCode_Success;
351 } 342 }
352 else 343 else
353 { 344 {
354 return OrthancPluginErrorCode_ParameterOutOfRange; 345 return OrthancPluginErrorCode_ParameterOutOfRange;
355 } 346 }
356 } 347 }
357 348
358 349
359 static OrthancPluginErrorCode ReadAnswerMetadata(OrthancPluginDatabaseTransaction* transaction, 350 OrthancPluginErrorCode ReadAnswerString(const char*& target,
360 int32_t* metadata, 351 uint32_t index) const
361 const char** value, 352 {
362 uint32_t index) 353 if (index < stringAnswers_.size())
363 { 354 {
364 const Output& that = *reinterpret_cast<const Output*>(transaction); 355 target = stringAnswers_[index].c_str();
365
366 if (index < that.metadata_.size())
367 {
368 const Metadata& tmp = that.metadata_[index];
369 *metadata = tmp.metadata;
370 *value = tmp.value;
371 return OrthancPluginErrorCode_Success; 356 return OrthancPluginErrorCode_Success;
372 } 357 }
373 else 358 else
374 { 359 {
375 return OrthancPluginErrorCode_ParameterOutOfRange; 360 return OrthancPluginErrorCode_ParameterOutOfRange;
376 } 361 }
377 } 362 }
378 363
379 364
380 static OrthancPluginErrorCode ReadAnswerString(OrthancPluginDatabaseTransaction* transaction, 365 OrthancPluginErrorCode ReadEventsCount(uint32_t& target /* out */) const
381 const char** target, 366 {
382 uint32_t index) 367 target = static_cast<uint32_t>(events_.size());
383 { 368 return OrthancPluginErrorCode_Success;
384 const Output& that = *reinterpret_cast<const Output*>(transaction); 369 }
385 370
386 if (index < that.stringAnswers_.size()) 371
387 { 372 OrthancPluginErrorCode ReadEvent(OrthancPluginDatabaseEvent& event /* out */,
388 *target = that.stringAnswers_[index].c_str(); 373 uint32_t index) const
389 return OrthancPluginErrorCode_Success; 374 {
375 if (index < events_.size())
376 {
377 event = events_[index];
378 return OrthancPluginErrorCode_Success;
390 } 379 }
391 else 380 else
392 { 381 {
393 return OrthancPluginErrorCode_ParameterOutOfRange;
394 }
395 }
396
397
398 static OrthancPluginErrorCode ReadEventsCount(OrthancPluginDatabaseTransaction* transaction,
399 uint32_t* target /* out */)
400 {
401 const Output& that = *reinterpret_cast<const Output*>(transaction);
402 *target = static_cast<uint32_t>(that.events_.size());
403 return OrthancPluginErrorCode_Success;
404 }
405
406
407 static OrthancPluginErrorCode ReadEvent(OrthancPluginDatabaseTransaction* transaction,
408 OrthancPluginDatabaseEvent* event /* out */,
409 uint32_t index)
410 {
411 const Output& that = *reinterpret_cast<const Output*>(transaction);
412
413 if (index < that.events_.size())
414 {
415 *event = that.events_[index];
416 return OrthancPluginErrorCode_Success;
417 }
418 else
419 {
420 return OrthancPluginErrorCode_ParameterOutOfRange; 382 return OrthancPluginErrorCode_ParameterOutOfRange;
421 } 383 }
422 } 384 }
423 385
424 386
425 virtual void SignalDeletedAttachment(const std::string& uuid, 387 virtual void SignalDeletedAttachment(const std::string& uuid,
426 int32_t contentType, 388 int32_t contentType,
427 uint64_t uncompressedSize, 389 uint64_t uncompressedSize,
428 const std::string& uncompressedHash, 390 const std::string& uncompressedHash,
429 int32_t compressionType, 391 int32_t compressionType,
593 integers64_.reserve(values.size()); 555 integers64_.reserve(values.size());
594 std::copy(std::begin(values), std::end(values), std::back_inserter(integers64_)); 556 std::copy(std::begin(values), std::end(values), std::back_inserter(integers64_));
595 } 557 }
596 558
597 559
560 void AnswerInteger64(int64_t value)
561 {
562 SetupAnswerType(_OrthancPluginDatabaseAnswerType_Int64);
563
564 integers64_.resize(1);
565 integers64_[0] = value;
566 }
567
568
598 void AnswerMetadata(int32_t metadata, 569 void AnswerMetadata(int32_t metadata,
599 const std::string& value) 570 const std::string& value)
600 { 571 {
601 SetupAnswerType(_OrthancPluginDatabaseAnswerType_Metadata); 572 SetupAnswerType(_OrthancPluginDatabaseAnswerType_Metadata);
602 573
649 620
650 class Transaction : public boost::noncopyable 621 class Transaction : public boost::noncopyable
651 { 622 {
652 private: 623 private:
653 boost::mutex::scoped_lock lock_; // TODO - REMOVE 624 boost::mutex::scoped_lock lock_; // TODO - REMOVE
654 IDatabaseBackend& backend_; 625 IndexBackend& backend_;
655 std::unique_ptr<Output> output_; 626 std::unique_ptr<Output> output_;
656 627
657 static boost::mutex& GetMutex() // TODO - REMOVE 628 static boost::mutex& GetMutex() // TODO - REMOVE
658 { 629 {
659 static boost::mutex mutex_; 630 static boost::mutex mutex_;
660 return mutex_; 631 return mutex_;
661 } 632 }
662 633
663 public: 634 public:
664 Transaction(IDatabaseBackend& backend) : 635 Transaction(IndexBackend& backend) :
665 lock_(GetMutex()), 636 lock_(GetMutex()),
666 backend_(backend), 637 backend_(backend),
667 output_(new Output) 638 output_(new Output)
668 { 639 {
669 } 640 }
670 641
671 IDatabaseBackend& GetBackend() const 642 ~Transaction()
643 {
644 }
645
646 IndexBackend& GetBackend() const
672 { 647 {
673 return backend_; 648 return backend_;
674 } 649 }
675 650
676 Output& GetOutput() const 651 Output& GetOutput() const
683 return backend_.GetContext(); 658 return backend_.GetContext();
684 } 659 }
685 }; 660 };
686 661
687 662
663 static OrthancPluginErrorCode ReadAnswersCount(OrthancPluginDatabaseTransaction* transaction,
664 uint32_t* target /* out */)
665 {
666 assert(target != NULL);
667 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
668 return that.GetOutput().ReadAnswersCount(*target);
669 }
670
671
672 static OrthancPluginErrorCode ReadAnswerAttachment(OrthancPluginDatabaseTransaction* transaction,
673 OrthancPluginAttachment* target /* out */,
674 uint32_t index)
675 {
676 assert(target != NULL);
677 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
678 return that.GetOutput().ReadAnswerAttachment(*target, index);
679 }
680
681
682 static OrthancPluginErrorCode ReadAnswerChange(OrthancPluginDatabaseTransaction* transaction,
683 OrthancPluginChange* target /* out */,
684 uint32_t index)
685 {
686 assert(target != NULL);
687 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
688 return that.GetOutput().ReadAnswerChange(*target, index);
689 }
690
691
692 static OrthancPluginErrorCode ReadAnswerDicomTag(OrthancPluginDatabaseTransaction* transaction,
693 uint16_t* group,
694 uint16_t* element,
695 const char** value,
696 uint32_t index)
697 {
698 assert(group != NULL);
699 assert(element != NULL);
700 assert(value != NULL);
701 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
702 return that.GetOutput().ReadAnswerDicomTag(*group, *element, *value, index);
703 }
704
705
706 static OrthancPluginErrorCode ReadAnswerExportedResource(OrthancPluginDatabaseTransaction* transaction,
707 OrthancPluginExportedResource* target /* out */,
708 uint32_t index)
709 {
710 assert(target != NULL);
711 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
712 return that.GetOutput().ReadAnswerExportedResource(*target, index);
713 }
714
715
716 static OrthancPluginErrorCode ReadAnswerInt32(OrthancPluginDatabaseTransaction* transaction,
717 int32_t* target,
718 uint32_t index)
719 {
720 assert(target != NULL);
721 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
722 return that.GetOutput().ReadAnswerInt32(*target, index);
723 }
724
725
726 static OrthancPluginErrorCode ReadAnswerInt64(OrthancPluginDatabaseTransaction* transaction,
727 int64_t* target,
728 uint32_t index)
729 {
730 assert(target != NULL);
731 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
732 return that.GetOutput().ReadAnswerInt64(*target, index);
733 }
734
735
736 static OrthancPluginErrorCode ReadAnswerMatchingResource(OrthancPluginDatabaseTransaction* transaction,
737 OrthancPluginMatchingResource* target,
738 uint32_t index)
739 {
740 assert(target != NULL);
741 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
742 return that.GetOutput().ReadAnswerMatchingResource(*target, index);
743 }
744
745
746 static OrthancPluginErrorCode ReadAnswerMetadata(OrthancPluginDatabaseTransaction* transaction,
747 int32_t* metadata,
748 const char** value,
749 uint32_t index)
750 {
751 assert(metadata != NULL);
752 assert(value != NULL);
753 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
754 return that.GetOutput().ReadAnswerMetadata(*metadata, *value, index);
755 }
756
757
758 static OrthancPluginErrorCode ReadAnswerString(OrthancPluginDatabaseTransaction* transaction,
759 const char** target,
760 uint32_t index)
761 {
762 assert(target != NULL);
763 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
764 return that.GetOutput().ReadAnswerString(*target, index);
765 }
766
767
768 static OrthancPluginErrorCode ReadEventsCount(OrthancPluginDatabaseTransaction* transaction,
769 uint32_t* target /* out */)
770 {
771 assert(target != NULL);
772 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
773 return that.GetOutput().ReadEventsCount(*target);
774 }
775
776
777 static OrthancPluginErrorCode ReadEvent(OrthancPluginDatabaseTransaction* transaction,
778 OrthancPluginDatabaseEvent* event /* out */,
779 uint32_t index)
780 {
781 assert(event != NULL);
782 const Transaction& that = *reinterpret_cast<const Transaction*>(transaction);
783 return that.GetOutput().ReadEvent(*event, index);
784 }
785
786
688 static OrthancPluginErrorCode Open(void* database) 787 static OrthancPluginErrorCode Open(void* database)
689 { 788 {
690 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(database); 789 IndexBackend* backend = reinterpret_cast<IndexBackend*>(database);
691 790
692 try 791 try
693 { 792 {
694 backend->Open(); 793 backend->Open();
695 return OrthancPluginErrorCode_Success; 794 return OrthancPluginErrorCode_Success;
698 } 797 }
699 798
700 799
701 static OrthancPluginErrorCode Close(void* database) 800 static OrthancPluginErrorCode Close(void* database)
702 { 801 {
703 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(database); 802 IndexBackend* backend = reinterpret_cast<IndexBackend*>(database);
704 803
705 try 804 try
706 { 805 {
707 backend->Close(); 806 backend->Close();
708 return OrthancPluginErrorCode_Success; 807 return OrthancPluginErrorCode_Success;
726 825
727 826
728 static OrthancPluginErrorCode GetDatabaseVersion(void* database, 827 static OrthancPluginErrorCode GetDatabaseVersion(void* database,
729 uint32_t* version) 828 uint32_t* version)
730 { 829 {
731 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(database); 830 IndexBackend* backend = reinterpret_cast<IndexBackend*>(database);
732 831
733 try 832 try
734 { 833 {
735 *version = backend->GetDatabaseVersion(); 834 *version = backend->GetDatabaseVersion();
736 return OrthancPluginErrorCode_Success; 835 return OrthancPluginErrorCode_Success;
741 840
742 static OrthancPluginErrorCode UpgradeDatabase(void* database, 841 static OrthancPluginErrorCode UpgradeDatabase(void* database,
743 OrthancPluginStorageArea* storageArea, 842 OrthancPluginStorageArea* storageArea,
744 uint32_t targetVersion) 843 uint32_t targetVersion)
745 { 844 {
746 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(database); 845 IndexBackend* backend = reinterpret_cast<IndexBackend*>(database);
747 846
748 try 847 try
749 { 848 {
750 backend->UpgradeDatabase(targetVersion, storageArea); 849 backend->UpgradeDatabase(targetVersion, storageArea);
751 return OrthancPluginErrorCode_Success; 850 return OrthancPluginErrorCode_Success;
756 855
757 static OrthancPluginErrorCode StartTransaction(void* database, 856 static OrthancPluginErrorCode StartTransaction(void* database,
758 OrthancPluginDatabaseTransaction** target /* out */, 857 OrthancPluginDatabaseTransaction** target /* out */,
759 OrthancPluginDatabaseTransactionType type) 858 OrthancPluginDatabaseTransactionType type)
760 { 859 {
761 IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(database); 860 IndexBackend* backend = reinterpret_cast<IndexBackend*>(database);
762 861
763 try 862 try
764 { 863 {
765 std::unique_ptr<Transaction> transaction(new Transaction(*backend)); 864 std::unique_ptr<Transaction> transaction(new Transaction(*backend));
766 865
792 { 891 {
793 return OrthancPluginErrorCode_NullPointer; 892 return OrthancPluginErrorCode_NullPointer;
794 } 893 }
795 else 894 else
796 { 895 {
797 delete reinterpret_cast<Output*>(transaction); 896 delete reinterpret_cast<Transaction*>(transaction);
798 return OrthancPluginErrorCode_Success; 897 return OrthancPluginErrorCode_Success;
799 } 898 }
800 } 899 }
801 900
802 901
804 { 903 {
805 Transaction* t = reinterpret_cast<Transaction*>(transaction); 904 Transaction* t = reinterpret_cast<Transaction*>(transaction);
806 905
807 try 906 try
808 { 907 {
908 t->GetOutput().Clear();
809 t->GetBackend().RollbackTransaction(); 909 t->GetBackend().RollbackTransaction();
810 return OrthancPluginErrorCode_Success; 910 return OrthancPluginErrorCode_Success;
811 } 911 }
812 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext()); 912 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
813 } 913 }
818 { 918 {
819 Transaction* t = reinterpret_cast<Transaction*>(transaction); 919 Transaction* t = reinterpret_cast<Transaction*>(transaction);
820 920
821 try 921 try
822 { 922 {
923 t->GetOutput().Clear();
823 t->GetBackend().CommitTransaction(); 924 t->GetBackend().CommitTransaction();
824 return OrthancPluginErrorCode_Success; 925 return OrthancPluginErrorCode_Success;
825 } 926 }
826 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext()); 927 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
827 } 928 }
896 Transaction* t = reinterpret_cast<Transaction*>(transaction); 997 Transaction* t = reinterpret_cast<Transaction*>(transaction);
897 998
898 try 999 try
899 { 1000 {
900 t->GetOutput().Clear(); 1001 t->GetOutput().Clear();
901 t->GetBackend().CreateInstance(*target, hashPatient, hashStudy, hashSeries, hashInstance); 1002
1003 if (t->GetBackend().HasCreateInstance())
1004 {
1005 t->GetBackend().CreateInstance(*target, hashPatient, hashStudy, hashSeries, hashInstance);
1006 }
1007 else
1008 {
1009 t->GetBackend().CreateInstanceGeneric(*target, hashPatient, hashStudy, hashSeries, hashInstance);
1010 }
1011
902 return OrthancPluginErrorCode_Success; 1012 return OrthancPluginErrorCode_Success;
903 } 1013 }
904 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext()); 1014 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
905 } 1015 }
906 1016
1427 } 1537 }
1428 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext()); 1538 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1429 } 1539 }
1430 1540
1431 1541
1432 static void RegisterV3(IDatabaseBackend& database) 1542 static OrthancPluginErrorCode LookupParent(OrthancPluginDatabaseTransaction* transaction,
1543 int64_t id)
1544 {
1545 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1546
1547 try
1548 {
1549 t->GetOutput().Clear();
1550
1551 int64_t parentId;
1552 if (t->GetBackend().LookupParent(parentId, id))
1553 {
1554 t->GetOutput().AnswerInteger64(parentId);
1555 }
1556
1557 return OrthancPluginErrorCode_Success;
1558 }
1559 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1560 }
1561
1562
1563 static OrthancPluginErrorCode LookupResource(OrthancPluginDatabaseTransaction* transaction,
1564 uint8_t* isExisting /* out */,
1565 int64_t* id /* out */,
1566 OrthancPluginResourceType* type /* out */,
1567 const char* publicId)
1568 {
1569 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1570
1571 try
1572 {
1573 t->GetOutput().Clear();
1574
1575 if (t->GetBackend().LookupResource(*id, *type, publicId))
1576 {
1577 *isExisting = 1;
1578 }
1579 else
1580 {
1581 *isExisting = 0;
1582 }
1583
1584 return OrthancPluginErrorCode_Success;
1585 }
1586 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1587 }
1588
1589
1590 static OrthancPluginErrorCode LookupResources(OrthancPluginDatabaseTransaction* transaction,
1591 uint32_t constraintsCount,
1592 const OrthancPluginDatabaseConstraint* constraints,
1593 OrthancPluginResourceType queryLevel,
1594 uint32_t limit,
1595 uint8_t requestSomeInstanceId)
1596 {
1597 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1598
1599 try
1600 {
1601 t->GetOutput().Clear();
1602
1603 std::vector<Orthanc::DatabaseConstraint> lookup;
1604 lookup.reserve(constraintsCount);
1605
1606 for (uint32_t i = 0; i < constraintsCount; i++)
1607 {
1608 lookup.push_back(Orthanc::DatabaseConstraint(constraints[i]));
1609 }
1610
1611 t->GetBackend().LookupResources(t->GetOutput(), lookup, queryLevel, limit, (requestSomeInstanceId != 0));
1612 return OrthancPluginErrorCode_Success;
1613 }
1614 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1615 }
1616
1617
1618 static OrthancPluginErrorCode LookupResourceAndParent(OrthancPluginDatabaseTransaction* transaction,
1619 uint8_t* isExisting /* out */,
1620 int64_t* id /* out */,
1621 OrthancPluginResourceType* type /* out */,
1622 const char* publicId)
1623 {
1624 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1625
1626 try
1627 {
1628 t->GetOutput().Clear();
1629
1630 std::string parent;
1631 if (t->GetBackend().LookupResourceAndParent(*id, *type, parent, publicId))
1632 {
1633 *isExisting = 1;
1634
1635 if (!parent.empty())
1636 {
1637 t->GetOutput().AnswerString(parent);
1638 }
1639 }
1640 else
1641 {
1642 *isExisting = 0;
1643 }
1644
1645 return OrthancPluginErrorCode_Success;
1646 }
1647 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1648 }
1649
1650
1651 static OrthancPluginErrorCode SelectPatientToRecycle(OrthancPluginDatabaseTransaction* transaction)
1652 {
1653 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1654
1655 try
1656 {
1657 t->GetOutput().Clear();
1658
1659 int64_t id;
1660 if (t->GetBackend().SelectPatientToRecycle(id))
1661 {
1662 t->GetOutput().AnswerInteger64(id);
1663 }
1664
1665 return OrthancPluginErrorCode_Success;
1666 }
1667 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1668 }
1669
1670
1671 static OrthancPluginErrorCode SelectPatientToRecycle2(OrthancPluginDatabaseTransaction* transaction,
1672 int64_t patientIdToAvoid)
1673 {
1674 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1675
1676 try
1677 {
1678 t->GetOutput().Clear();
1679
1680 int64_t id;
1681 if (t->GetBackend().SelectPatientToRecycle(id, patientIdToAvoid))
1682 {
1683 t->GetOutput().AnswerInteger64(id);
1684 }
1685
1686 return OrthancPluginErrorCode_Success;
1687 }
1688 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1689 }
1690
1691
1692 static OrthancPluginErrorCode SetGlobalProperty(OrthancPluginDatabaseTransaction* transaction,
1693 int32_t property,
1694 const char* value)
1695 {
1696 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1697
1698 try
1699 {
1700 t->GetOutput().Clear();
1701 t->GetBackend().SetGlobalProperty(property, value);
1702 return OrthancPluginErrorCode_Success;
1703 }
1704 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1705 }
1706
1707
1708 static OrthancPluginErrorCode SetMetadata(OrthancPluginDatabaseTransaction* transaction,
1709 int64_t id,
1710 int32_t metadata,
1711 const char* value)
1712 {
1713 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1714
1715 try
1716 {
1717 t->GetOutput().Clear();
1718 t->GetBackend().SetMetadata(id, metadata, value);
1719 return OrthancPluginErrorCode_Success;
1720 }
1721 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1722 }
1723
1724
1725 static OrthancPluginErrorCode SetProtectedPatient(OrthancPluginDatabaseTransaction* transaction,
1726 int64_t id,
1727 uint8_t isProtected)
1728 {
1729 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1730
1731 try
1732 {
1733 t->GetOutput().Clear();
1734 t->GetBackend().SetProtectedPatient(id, (isProtected != 0));
1735 return OrthancPluginErrorCode_Success;
1736 }
1737 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1738 }
1739
1740
1741 static OrthancPluginErrorCode SetResourcesContent(OrthancPluginDatabaseTransaction* transaction,
1742 uint32_t countIdentifierTags,
1743 const OrthancPluginResourcesContentTags* identifierTags,
1744 uint32_t countMainDicomTags,
1745 const OrthancPluginResourcesContentTags* mainDicomTags,
1746 uint32_t countMetadata,
1747 const OrthancPluginResourcesContentMetadata* metadata)
1748 {
1749 Transaction* t = reinterpret_cast<Transaction*>(transaction);
1750
1751 try
1752 {
1753 t->GetOutput().Clear();
1754 t->GetBackend().SetResourcesContent(countIdentifierTags, identifierTags,
1755 countMainDicomTags, mainDicomTags,
1756 countMetadata, metadata);
1757 return OrthancPluginErrorCode_Success;
1758 }
1759 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetContext());
1760 }
1761
1762
1763 static void RegisterV3(IndexBackend& database)
1433 { 1764 {
1434 OrthancPluginDatabaseBackendV3 params; 1765 OrthancPluginDatabaseBackendV3 params;
1435 memset(&params, 0, sizeof(params)); 1766 memset(&params, 0, sizeof(params));
1436 1767
1437 params.readAnswersCount = Output::ReadAnswersCount; 1768 params.readAnswersCount = ReadAnswersCount;
1438 params.readAnswerAttachment = Output::ReadAnswerAttachment; 1769 params.readAnswerAttachment = ReadAnswerAttachment;
1439 params.readAnswerChange = Output::ReadAnswerChange; 1770 params.readAnswerChange = ReadAnswerChange;
1440 params.readAnswerDicomTag = Output::ReadAnswerDicomTag; 1771 params.readAnswerDicomTag = ReadAnswerDicomTag;
1441 params.readAnswerExportedResource = Output::ReadAnswerExportedResource; 1772 params.readAnswerExportedResource = ReadAnswerExportedResource;
1442 params.readAnswerInt32 = Output::ReadAnswerInt32; 1773 params.readAnswerInt32 = ReadAnswerInt32;
1443 params.readAnswerInt64 = Output::ReadAnswerInt64; 1774 params.readAnswerInt64 = ReadAnswerInt64;
1444 params.readAnswerMatchingResource = Output::ReadAnswerMatchingResource; 1775 params.readAnswerMatchingResource = ReadAnswerMatchingResource;
1445 params.readAnswerMetadata = Output::ReadAnswerMetadata; 1776 params.readAnswerMetadata = ReadAnswerMetadata;
1446 params.readAnswerString = Output::ReadAnswerString; 1777 params.readAnswerString = ReadAnswerString;
1447 1778
1448 params.readEventsCount = Output::ReadEventsCount; 1779 params.readEventsCount = ReadEventsCount;
1449 params.readEvent = Output::ReadEvent; 1780 params.readEvent = ReadEvent;
1450 1781
1451 params.open = Open; 1782 params.open = Open;
1452 params.close = Close; 1783 params.close = Close;
1453 params.destructDatabase = DestructDatabase; 1784 params.destructDatabase = DestructDatabase;
1454 params.getDatabaseVersion = GetDatabaseVersion; 1785 params.getDatabaseVersion = GetDatabaseVersion;
1490 params.logChange = LogChange; 1821 params.logChange = LogChange;
1491 params.logExportedResource = LogExportedResource; 1822 params.logExportedResource = LogExportedResource;
1492 params.lookupAttachment = LookupAttachment; 1823 params.lookupAttachment = LookupAttachment;
1493 params.lookupGlobalProperty = LookupGlobalProperty; 1824 params.lookupGlobalProperty = LookupGlobalProperty;
1494 params.lookupMetadata = LookupMetadata; 1825 params.lookupMetadata = LookupMetadata;
1826 params.lookupParent = LookupParent;
1827 params.lookupResource = LookupResource;
1828 params.lookupResources = LookupResources;
1829 params.lookupResourceAndParent = LookupResourceAndParent;
1830 params.selectPatientToRecycle = SelectPatientToRecycle;
1831 params.selectPatientToRecycle2 = SelectPatientToRecycle2;
1832 params.setGlobalProperty = SetGlobalProperty;
1833 params.setMetadata = SetMetadata;
1834 params.setProtectedPatient = SetProtectedPatient;
1835 params.setResourcesContent = SetResourcesContent;
1495 1836
1496 OrthancPluginContext* context = database.GetContext(); 1837 OrthancPluginContext* context = database.GetContext();
1497 1838
1498 if (OrthancPluginRegisterDatabaseBackendV3(context, &params, sizeof(params), &database) != OrthancPluginErrorCode_Success) 1839 if (OrthancPluginRegisterDatabaseBackendV3(context, &params, sizeof(params), &database) != OrthancPluginErrorCode_Success)
1499 { 1840 {