comparison Framework/Plugins/IndexBackend.cpp @ 225:94c9908e6aca

removed DatabaseManager member out of class IndexBackend
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 01 Apr 2021 19:18:19 +0200
parents c8e06b41feec
children a4918d57435c
comparison
equal deleted inserted replaced
224:61c309e06797 225:94c9908e6aca
173 } 173 }
174 174
175 175
176 void IndexBackend::ReadChangesInternal(IDatabaseBackendOutput& output, 176 void IndexBackend::ReadChangesInternal(IDatabaseBackendOutput& output,
177 bool& done, 177 bool& done,
178 DatabaseManager& manager,
178 DatabaseManager::CachedStatement& statement, 179 DatabaseManager::CachedStatement& statement,
179 const Dictionary& args, 180 const Dictionary& args,
180 uint32_t maxResults) 181 uint32_t maxResults)
181 { 182 {
182 statement.Execute(args); 183 statement.Execute(args);
188 { 189 {
189 output.AnswerChange( 190 output.AnswerChange(
190 ReadInteger64(statement, 0), 191 ReadInteger64(statement, 0),
191 ReadInteger32(statement, 1), 192 ReadInteger32(statement, 1),
192 static_cast<OrthancPluginResourceType>(ReadInteger32(statement, 3)), 193 static_cast<OrthancPluginResourceType>(ReadInteger32(statement, 3)),
193 GetPublicId(ReadInteger64(statement, 2)), 194 GetPublicId(manager, ReadInteger64(statement, 2)),
194 ReadString(statement, 4)); 195 ReadString(statement, 4));
195 196
196 statement.Next(); 197 statement.Next();
197 count++; 198 count++;
198 } 199 }
237 done = (count < maxResults || 238 done = (count < maxResults ||
238 statement.IsDone()); 239 statement.IsDone());
239 } 240 }
240 241
241 242
242 void IndexBackend::ClearDeletedFiles() 243 void IndexBackend::ClearDeletedFiles(DatabaseManager& manager)
243 { 244 {
244 DatabaseManager::CachedStatement statement( 245 DatabaseManager::CachedStatement statement(
245 STATEMENT_FROM_HERE, manager_, 246 STATEMENT_FROM_HERE, manager,
246 "DELETE FROM DeletedFiles"); 247 "DELETE FROM DeletedFiles");
247 248
248 statement.Execute(); 249 statement.Execute();
249 } 250 }
250 251
251 252
252 void IndexBackend::ClearDeletedResources() 253 void IndexBackend::ClearDeletedResources(DatabaseManager& manager)
253 { 254 {
254 DatabaseManager::CachedStatement statement( 255 DatabaseManager::CachedStatement statement(
255 STATEMENT_FROM_HERE, manager_, 256 STATEMENT_FROM_HERE, manager,
256 "DELETE FROM DeletedResources"); 257 "DELETE FROM DeletedResources");
257 258
258 statement.Execute(); 259 statement.Execute();
259 } 260 }
260 261
261 262
262 void IndexBackend::SignalDeletedFiles(IDatabaseBackendOutput& output) 263 void IndexBackend::SignalDeletedFiles(IDatabaseBackendOutput& output,
263 { 264 DatabaseManager& manager)
264 DatabaseManager::CachedStatement statement( 265 {
265 STATEMENT_FROM_HERE, manager_, 266 DatabaseManager::CachedStatement statement(
267 STATEMENT_FROM_HERE, manager,
266 "SELECT * FROM DeletedFiles"); 268 "SELECT * FROM DeletedFiles");
267 269
268 statement.SetReadOnly(true); 270 statement.SetReadOnly(true);
269 statement.Execute(); 271 statement.Execute();
270 272
285 statement.Next(); 287 statement.Next();
286 } 288 }
287 } 289 }
288 290
289 291
290 void IndexBackend::SignalDeletedResources(IDatabaseBackendOutput& output) 292 void IndexBackend::SignalDeletedResources(IDatabaseBackendOutput& output,
291 { 293 DatabaseManager& manager)
292 DatabaseManager::CachedStatement statement( 294 {
293 STATEMENT_FROM_HERE, manager_, 295 DatabaseManager::CachedStatement statement(
296 STATEMENT_FROM_HERE, manager,
294 "SELECT * FROM DeletedResources"); 297 "SELECT * FROM DeletedResources");
295 298
296 statement.SetReadOnly(true); 299 statement.SetReadOnly(true);
297 statement.Execute(); 300 statement.Execute();
298 301
305 statement.Next(); 308 statement.Next();
306 } 309 }
307 } 310 }
308 311
309 312
310 IndexBackend::IndexBackend(OrthancPluginContext* context, 313 IndexBackend::IndexBackend(OrthancPluginContext* context) :
311 IDatabaseFactory* factory) : 314 context_(context)
312 context_(context),
313 manager_(factory)
314 { 315 {
315 } 316 }
316 317
317 318
318 void IndexBackend::SetOutputFactory(IDatabaseBackendOutput::IFactory* factory) 319 void IndexBackend::SetOutputFactory(IDatabaseBackendOutput::IFactory* factory)
343 return outputFactory_->CreateOutput(); 344 return outputFactory_->CreateOutput();
344 } 345 }
345 } 346 }
346 347
347 348
348 void IndexBackend::AddAttachment(int64_t id, 349 void IndexBackend::AddAttachment(DatabaseManager& manager,
350 int64_t id,
349 const OrthancPluginAttachment& attachment) 351 const OrthancPluginAttachment& attachment)
350 { 352 {
351 DatabaseManager::CachedStatement statement( 353 DatabaseManager::CachedStatement statement(
352 STATEMENT_FROM_HERE, manager_, 354 STATEMENT_FROM_HERE, manager,
353 "INSERT INTO AttachedFiles VALUES(${id}, ${type}, ${uuid}, " 355 "INSERT INTO AttachedFiles VALUES(${id}, ${type}, ${uuid}, "
354 "${compressed}, ${uncompressed}, ${compression}, ${hash}, ${hash-compressed})"); 356 "${compressed}, ${uncompressed}, ${compression}, ${hash}, ${hash-compressed})");
355 357
356 statement.SetParameterType("id", ValueType_Integer64); 358 statement.SetParameterType("id", ValueType_Integer64);
357 statement.SetParameterType("type", ValueType_Integer64); 359 statement.SetParameterType("type", ValueType_Integer64);
374 376
375 statement.Execute(args); 377 statement.Execute(args);
376 } 378 }
377 379
378 380
379 void IndexBackend::AttachChild(int64_t parent, 381 void IndexBackend::AttachChild(DatabaseManager& manager,
382 int64_t parent,
380 int64_t child) 383 int64_t child)
381 { 384 {
382 DatabaseManager::CachedStatement statement( 385 DatabaseManager::CachedStatement statement(
383 STATEMENT_FROM_HERE, manager_, 386 STATEMENT_FROM_HERE, manager,
384 "UPDATE Resources SET parentId = ${parent} WHERE internalId = ${child}"); 387 "UPDATE Resources SET parentId = ${parent} WHERE internalId = ${child}");
385 388
386 statement.SetParameterType("parent", ValueType_Integer64); 389 statement.SetParameterType("parent", ValueType_Integer64);
387 statement.SetParameterType("child", ValueType_Integer64); 390 statement.SetParameterType("child", ValueType_Integer64);
388 391
392 395
393 statement.Execute(args); 396 statement.Execute(args);
394 } 397 }
395 398
396 399
397 void IndexBackend::ClearChanges() 400 void IndexBackend::ClearChanges(DatabaseManager& manager)
398 { 401 {
399 DatabaseManager::CachedStatement statement( 402 DatabaseManager::CachedStatement statement(
400 STATEMENT_FROM_HERE, manager_, 403 STATEMENT_FROM_HERE, manager,
401 "DELETE FROM Changes"); 404 "DELETE FROM Changes");
402 405
403 statement.Execute(); 406 statement.Execute();
404 } 407 }
405 408
406 409
407 void IndexBackend::ClearExportedResources() 410 void IndexBackend::ClearExportedResources(DatabaseManager& manager)
408 { 411 {
409 DatabaseManager::CachedStatement statement( 412 DatabaseManager::CachedStatement statement(
410 STATEMENT_FROM_HERE, manager_, 413 STATEMENT_FROM_HERE, manager,
411 "DELETE FROM ExportedResources"); 414 "DELETE FROM ExportedResources");
412 415
413 statement.Execute(); 416 statement.Execute();
414 } 417 }
415 418
416 419
417 void IndexBackend::DeleteAttachment(IDatabaseBackendOutput& output, 420 void IndexBackend::DeleteAttachment(IDatabaseBackendOutput& output,
421 DatabaseManager& manager,
418 int64_t id, 422 int64_t id,
419 int32_t attachment) 423 int32_t attachment)
420 { 424 {
421 ClearDeletedFiles(); 425 ClearDeletedFiles(manager);
422 426
423 { 427 {
424 DatabaseManager::CachedStatement statement( 428 DatabaseManager::CachedStatement statement(
425 STATEMENT_FROM_HERE, manager_, 429 STATEMENT_FROM_HERE, manager,
426 "DELETE FROM AttachedFiles WHERE id=${id} AND fileType=${type}"); 430 "DELETE FROM AttachedFiles WHERE id=${id} AND fileType=${type}");
427 431
428 statement.SetParameterType("id", ValueType_Integer64); 432 statement.SetParameterType("id", ValueType_Integer64);
429 statement.SetParameterType("type", ValueType_Integer64); 433 statement.SetParameterType("type", ValueType_Integer64);
430 434
433 args.SetIntegerValue("type", static_cast<int>(attachment)); 437 args.SetIntegerValue("type", static_cast<int>(attachment));
434 438
435 statement.Execute(args); 439 statement.Execute(args);
436 } 440 }
437 441
438 SignalDeletedFiles(output); 442 SignalDeletedFiles(output, manager);
439 } 443 }
440 444
441 445
442 void IndexBackend::DeleteMetadata(int64_t id, 446 void IndexBackend::DeleteMetadata(DatabaseManager& manager,
447 int64_t id,
443 int32_t metadataType) 448 int32_t metadataType)
444 { 449 {
445 DatabaseManager::CachedStatement statement( 450 DatabaseManager::CachedStatement statement(
446 STATEMENT_FROM_HERE, manager_, 451 STATEMENT_FROM_HERE, manager,
447 "DELETE FROM Metadata WHERE id=${id} and type=${type}"); 452 "DELETE FROM Metadata WHERE id=${id} and type=${type}");
448 453
449 statement.SetParameterType("id", ValueType_Integer64); 454 statement.SetParameterType("id", ValueType_Integer64);
450 statement.SetParameterType("type", ValueType_Integer64); 455 statement.SetParameterType("type", ValueType_Integer64);
451 456
456 statement.Execute(args); 461 statement.Execute(args);
457 } 462 }
458 463
459 464
460 void IndexBackend::DeleteResource(IDatabaseBackendOutput& output, 465 void IndexBackend::DeleteResource(IDatabaseBackendOutput& output,
466 DatabaseManager& manager,
461 int64_t id) 467 int64_t id)
462 { 468 {
463 assert(manager_.GetDialect() != Dialect_MySQL); 469 assert(manager.GetDialect() != Dialect_MySQL);
464 470
465 ClearDeletedFiles(); 471 ClearDeletedFiles(manager);
466 ClearDeletedResources(); 472 ClearDeletedResources(manager);
467 473
468 { 474 {
469 DatabaseManager::CachedStatement statement( 475 DatabaseManager::CachedStatement statement(
470 STATEMENT_FROM_HERE, GetManager(), 476 STATEMENT_FROM_HERE, manager,
471 "DELETE FROM RemainingAncestor"); 477 "DELETE FROM RemainingAncestor");
472 478
473 statement.Execute(); 479 statement.Execute();
474 } 480 }
475 481
476 { 482 {
477 DatabaseManager::CachedStatement statement( 483 DatabaseManager::CachedStatement statement(
478 STATEMENT_FROM_HERE, GetManager(), 484 STATEMENT_FROM_HERE, manager,
479 "DELETE FROM Resources WHERE internalId=${id}"); 485 "DELETE FROM Resources WHERE internalId=${id}");
480 486
481 statement.SetParameterType("id", ValueType_Integer64); 487 statement.SetParameterType("id", ValueType_Integer64);
482 488
483 Dictionary args; 489 Dictionary args;
487 } 493 }
488 494
489 495
490 { 496 {
491 DatabaseManager::CachedStatement statement( 497 DatabaseManager::CachedStatement statement(
492 STATEMENT_FROM_HERE, GetManager(), 498 STATEMENT_FROM_HERE, manager,
493 "SELECT * FROM RemainingAncestor"); 499 "SELECT * FROM RemainingAncestor");
494 500
495 statement.Execute(); 501 statement.Execute();
496 502
497 if (!statement.IsDone()) 503 if (!statement.IsDone())
503 // There is at most 1 remaining ancestor 509 // There is at most 1 remaining ancestor
504 assert((statement.Next(), statement.IsDone())); 510 assert((statement.Next(), statement.IsDone()));
505 } 511 }
506 } 512 }
507 513
508 SignalDeletedFiles(output); 514 SignalDeletedFiles(output, manager);
509 SignalDeletedResources(output); 515 SignalDeletedResources(output, manager);
510 } 516 }
511 517
512 518
513 void IndexBackend::GetAllInternalIds(std::list<int64_t>& target, 519 void IndexBackend::GetAllInternalIds(std::list<int64_t>& target,
520 DatabaseManager& manager,
514 OrthancPluginResourceType resourceType) 521 OrthancPluginResourceType resourceType)
515 { 522 {
516 DatabaseManager::CachedStatement statement( 523 DatabaseManager::CachedStatement statement(
517 STATEMENT_FROM_HERE, manager_, 524 STATEMENT_FROM_HERE, manager,
518 "SELECT internalId FROM Resources WHERE resourceType=${type}"); 525 "SELECT internalId FROM Resources WHERE resourceType=${type}");
519 526
520 statement.SetReadOnly(true); 527 statement.SetReadOnly(true);
521 statement.SetParameterType("type", ValueType_Integer64); 528 statement.SetParameterType("type", ValueType_Integer64);
522 529
526 ReadListOfIntegers<int64_t>(target, statement, args); 533 ReadListOfIntegers<int64_t>(target, statement, args);
527 } 534 }
528 535
529 536
530 void IndexBackend::GetAllPublicIds(std::list<std::string>& target, 537 void IndexBackend::GetAllPublicIds(std::list<std::string>& target,
538 DatabaseManager& manager,
531 OrthancPluginResourceType resourceType) 539 OrthancPluginResourceType resourceType)
532 { 540 {
533 DatabaseManager::CachedStatement statement( 541 DatabaseManager::CachedStatement statement(
534 STATEMENT_FROM_HERE, manager_, 542 STATEMENT_FROM_HERE, manager,
535 "SELECT publicId FROM Resources WHERE resourceType=${type}"); 543 "SELECT publicId FROM Resources WHERE resourceType=${type}");
536 544
537 statement.SetReadOnly(true); 545 statement.SetReadOnly(true);
538 statement.SetParameterType("type", ValueType_Integer64); 546 statement.SetParameterType("type", ValueType_Integer64);
539 547
543 ReadListOfStrings(target, statement, args); 551 ReadListOfStrings(target, statement, args);
544 } 552 }
545 553
546 554
547 void IndexBackend::GetAllPublicIds(std::list<std::string>& target, 555 void IndexBackend::GetAllPublicIds(std::list<std::string>& target,
556 DatabaseManager& manager,
548 OrthancPluginResourceType resourceType, 557 OrthancPluginResourceType resourceType,
549 uint64_t since, 558 uint64_t since,
550 uint64_t limit) 559 uint64_t limit)
551 { 560 {
552 DatabaseManager::CachedStatement statement( 561 DatabaseManager::CachedStatement statement(
553 STATEMENT_FROM_HERE, manager_, 562 STATEMENT_FROM_HERE, manager,
554 "SELECT publicId FROM (SELECT publicId FROM Resources " 563 "SELECT publicId FROM (SELECT publicId FROM Resources "
555 "WHERE resourceType=${type}) AS tmp " 564 "WHERE resourceType=${type}) AS tmp "
556 "ORDER BY tmp.publicId LIMIT ${limit} OFFSET ${since}"); 565 "ORDER BY tmp.publicId LIMIT ${limit} OFFSET ${since}");
557 566
558 statement.SetReadOnly(true); 567 statement.SetReadOnly(true);
570 579
571 580
572 /* Use GetOutput().AnswerChange() */ 581 /* Use GetOutput().AnswerChange() */
573 void IndexBackend::GetChanges(IDatabaseBackendOutput& output, 582 void IndexBackend::GetChanges(IDatabaseBackendOutput& output,
574 bool& done /*out*/, 583 bool& done /*out*/,
584 DatabaseManager& manager,
575 int64_t since, 585 int64_t since,
576 uint32_t maxResults) 586 uint32_t maxResults)
577 { 587 {
578 DatabaseManager::CachedStatement statement( 588 DatabaseManager::CachedStatement statement(
579 STATEMENT_FROM_HERE, manager_, 589 STATEMENT_FROM_HERE, manager,
580 "SELECT * FROM Changes WHERE seq>${since} ORDER BY seq LIMIT ${limit}"); 590 "SELECT * FROM Changes WHERE seq>${since} ORDER BY seq LIMIT ${limit}");
581 591
582 statement.SetReadOnly(true); 592 statement.SetReadOnly(true);
583 statement.SetParameterType("limit", ValueType_Integer64); 593 statement.SetParameterType("limit", ValueType_Integer64);
584 statement.SetParameterType("since", ValueType_Integer64); 594 statement.SetParameterType("since", ValueType_Integer64);
585 595
586 Dictionary args; 596 Dictionary args;
587 args.SetIntegerValue("limit", maxResults + 1); 597 args.SetIntegerValue("limit", maxResults + 1);
588 args.SetIntegerValue("since", since); 598 args.SetIntegerValue("since", since);
589 599
590 ReadChangesInternal(output, done, statement, args, maxResults); 600 ReadChangesInternal(output, done, manager, statement, args, maxResults);
591 } 601 }
592 602
593 603
594 void IndexBackend::GetChildrenInternalId(std::list<int64_t>& target /*out*/, 604 void IndexBackend::GetChildrenInternalId(std::list<int64_t>& target /*out*/,
605 DatabaseManager& manager,
595 int64_t id) 606 int64_t id)
596 { 607 {
597 DatabaseManager::CachedStatement statement( 608 DatabaseManager::CachedStatement statement(
598 STATEMENT_FROM_HERE, manager_, 609 STATEMENT_FROM_HERE, manager,
599 "SELECT a.internalId FROM Resources AS a, Resources AS b " 610 "SELECT a.internalId FROM Resources AS a, Resources AS b "
600 "WHERE a.parentId = b.internalId AND b.internalId = ${id}"); 611 "WHERE a.parentId = b.internalId AND b.internalId = ${id}");
601 612
602 statement.SetReadOnly(true); 613 statement.SetReadOnly(true);
603 statement.SetParameterType("id", ValueType_Integer64); 614 statement.SetParameterType("id", ValueType_Integer64);
608 ReadListOfIntegers<int64_t>(target, statement, args); 619 ReadListOfIntegers<int64_t>(target, statement, args);
609 } 620 }
610 621
611 622
612 void IndexBackend::GetChildrenPublicId(std::list<std::string>& target /*out*/, 623 void IndexBackend::GetChildrenPublicId(std::list<std::string>& target /*out*/,
624 DatabaseManager& manager,
613 int64_t id) 625 int64_t id)
614 { 626 {
615 DatabaseManager::CachedStatement statement( 627 DatabaseManager::CachedStatement statement(
616 STATEMENT_FROM_HERE, manager_, 628 STATEMENT_FROM_HERE, manager,
617 "SELECT a.publicId FROM Resources AS a, Resources AS b " 629 "SELECT a.publicId FROM Resources AS a, Resources AS b "
618 "WHERE a.parentId = b.internalId AND b.internalId = ${id}"); 630 "WHERE a.parentId = b.internalId AND b.internalId = ${id}");
619 631
620 statement.SetReadOnly(true); 632 statement.SetReadOnly(true);
621 statement.SetParameterType("id", ValueType_Integer64); 633 statement.SetParameterType("id", ValueType_Integer64);
628 640
629 641
630 /* Use GetOutput().AnswerExportedResource() */ 642 /* Use GetOutput().AnswerExportedResource() */
631 void IndexBackend::GetExportedResources(IDatabaseBackendOutput& output, 643 void IndexBackend::GetExportedResources(IDatabaseBackendOutput& output,
632 bool& done /*out*/, 644 bool& done /*out*/,
645 DatabaseManager& manager,
633 int64_t since, 646 int64_t since,
634 uint32_t maxResults) 647 uint32_t maxResults)
635 { 648 {
636 DatabaseManager::CachedStatement statement( 649 DatabaseManager::CachedStatement statement(
637 STATEMENT_FROM_HERE, manager_, 650 STATEMENT_FROM_HERE, manager,
638 "SELECT * FROM ExportedResources WHERE seq>${since} ORDER BY seq LIMIT ${limit}"); 651 "SELECT * FROM ExportedResources WHERE seq>${since} ORDER BY seq LIMIT ${limit}");
639 652
640 statement.SetReadOnly(true); 653 statement.SetReadOnly(true);
641 statement.SetParameterType("limit", ValueType_Integer64); 654 statement.SetParameterType("limit", ValueType_Integer64);
642 statement.SetParameterType("since", ValueType_Integer64); 655 statement.SetParameterType("since", ValueType_Integer64);
648 ReadExportedResourcesInternal(output, done, statement, args, maxResults); 661 ReadExportedResourcesInternal(output, done, statement, args, maxResults);
649 } 662 }
650 663
651 664
652 /* Use GetOutput().AnswerChange() */ 665 /* Use GetOutput().AnswerChange() */
653 void IndexBackend::GetLastChange(IDatabaseBackendOutput& output) 666 void IndexBackend::GetLastChange(IDatabaseBackendOutput& output,
654 { 667 DatabaseManager& manager)
655 DatabaseManager::CachedStatement statement( 668 {
656 STATEMENT_FROM_HERE, manager_, 669 DatabaseManager::CachedStatement statement(
670 STATEMENT_FROM_HERE, manager,
657 "SELECT * FROM Changes ORDER BY seq DESC LIMIT 1"); 671 "SELECT * FROM Changes ORDER BY seq DESC LIMIT 1");
658 672
659 statement.SetReadOnly(true); 673 statement.SetReadOnly(true);
660 674
661 Dictionary args; 675 Dictionary args;
662 676
663 bool done; // Ignored 677 bool done; // Ignored
664 ReadChangesInternal(output, done, statement, args, 1); 678 ReadChangesInternal(output, done, manager, statement, args, 1);
665 } 679 }
666 680
667 681
668 /* Use GetOutput().AnswerExportedResource() */ 682 /* Use GetOutput().AnswerExportedResource() */
669 void IndexBackend::GetLastExportedResource(IDatabaseBackendOutput& output) 683 void IndexBackend::GetLastExportedResource(IDatabaseBackendOutput& output,
670 { 684 DatabaseManager& manager)
671 DatabaseManager::CachedStatement statement( 685 {
672 STATEMENT_FROM_HERE, manager_, 686 DatabaseManager::CachedStatement statement(
687 STATEMENT_FROM_HERE, manager,
673 "SELECT * FROM ExportedResources ORDER BY seq DESC LIMIT 1"); 688 "SELECT * FROM ExportedResources ORDER BY seq DESC LIMIT 1");
674 689
675 statement.SetReadOnly(true); 690 statement.SetReadOnly(true);
676 691
677 Dictionary args; 692 Dictionary args;
681 } 696 }
682 697
683 698
684 /* Use GetOutput().AnswerDicomTag() */ 699 /* Use GetOutput().AnswerDicomTag() */
685 void IndexBackend::GetMainDicomTags(IDatabaseBackendOutput& output, 700 void IndexBackend::GetMainDicomTags(IDatabaseBackendOutput& output,
701 DatabaseManager& manager,
686 int64_t id) 702 int64_t id)
687 { 703 {
688 DatabaseManager::CachedStatement statement( 704 DatabaseManager::CachedStatement statement(
689 STATEMENT_FROM_HERE, manager_, 705 STATEMENT_FROM_HERE, manager,
690 "SELECT * FROM MainDicomTags WHERE id=${id}"); 706 "SELECT * FROM MainDicomTags WHERE id=${id}");
691 707
692 statement.SetReadOnly(true); 708 statement.SetReadOnly(true);
693 statement.SetParameterType("id", ValueType_Integer64); 709 statement.SetParameterType("id", ValueType_Integer64);
694 710
705 statement.Next(); 721 statement.Next();
706 } 722 }
707 } 723 }
708 724
709 725
710 std::string IndexBackend::GetPublicId(int64_t resourceId) 726 std::string IndexBackend::GetPublicId(DatabaseManager& manager,
711 { 727 int64_t resourceId)
712 DatabaseManager::CachedStatement statement( 728 {
713 STATEMENT_FROM_HERE, manager_, 729 DatabaseManager::CachedStatement statement(
730 STATEMENT_FROM_HERE, manager,
714 "SELECT publicId FROM Resources WHERE internalId=${id}"); 731 "SELECT publicId FROM Resources WHERE internalId=${id}");
715 732
716 statement.SetReadOnly(true); 733 statement.SetReadOnly(true);
717 statement.SetParameterType("id", ValueType_Integer64); 734 statement.SetParameterType("id", ValueType_Integer64);
718 735
730 return ReadString(statement, 0); 747 return ReadString(statement, 0);
731 } 748 }
732 } 749 }
733 750
734 751
735 uint64_t IndexBackend::GetResourcesCount(OrthancPluginResourceType resourceType) 752 uint64_t IndexBackend::GetResourcesCount(DatabaseManager& manager,
753 OrthancPluginResourceType resourceType)
736 { 754 {
737 std::unique_ptr<DatabaseManager::CachedStatement> statement; 755 std::unique_ptr<DatabaseManager::CachedStatement> statement;
738 756
739 switch (manager_.GetDialect()) 757 switch (manager.GetDialect())
740 { 758 {
741 case Dialect_MySQL: 759 case Dialect_MySQL:
742 statement.reset(new DatabaseManager::CachedStatement( 760 statement.reset(new DatabaseManager::CachedStatement(
743 STATEMENT_FROM_HERE, GetManager(), 761 STATEMENT_FROM_HERE, manager,
744 "SELECT CAST(COUNT(*) AS UNSIGNED INT) FROM Resources WHERE resourceType=${type}")); 762 "SELECT CAST(COUNT(*) AS UNSIGNED INT) FROM Resources WHERE resourceType=${type}"));
745 break; 763 break;
746 764
747 case Dialect_PostgreSQL: 765 case Dialect_PostgreSQL:
748 statement.reset(new DatabaseManager::CachedStatement( 766 statement.reset(new DatabaseManager::CachedStatement(
749 STATEMENT_FROM_HERE, GetManager(), 767 STATEMENT_FROM_HERE, manager,
750 "SELECT CAST(COUNT(*) AS BIGINT) FROM Resources WHERE resourceType=${type}")); 768 "SELECT CAST(COUNT(*) AS BIGINT) FROM Resources WHERE resourceType=${type}"));
751 break; 769 break;
752 770
753 case Dialect_SQLite: 771 case Dialect_SQLite:
754 statement.reset(new DatabaseManager::CachedStatement( 772 statement.reset(new DatabaseManager::CachedStatement(
755 STATEMENT_FROM_HERE, GetManager(), 773 STATEMENT_FROM_HERE, manager,
756 "SELECT COUNT(*) FROM Resources WHERE resourceType=${type}")); 774 "SELECT COUNT(*) FROM Resources WHERE resourceType=${type}"));
757 break; 775 break;
758 776
759 default: 777 default:
760 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 778 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
770 788
771 return static_cast<uint64_t>(ReadInteger64(*statement, 0)); 789 return static_cast<uint64_t>(ReadInteger64(*statement, 0));
772 } 790 }
773 791
774 792
775 OrthancPluginResourceType IndexBackend::GetResourceType(int64_t resourceId) 793 OrthancPluginResourceType IndexBackend::GetResourceType(DatabaseManager& manager,
776 { 794 int64_t resourceId)
777 DatabaseManager::CachedStatement statement( 795 {
778 STATEMENT_FROM_HERE, manager_, 796 DatabaseManager::CachedStatement statement(
797 STATEMENT_FROM_HERE, manager,
779 "SELECT resourceType FROM Resources WHERE internalId=${id}"); 798 "SELECT resourceType FROM Resources WHERE internalId=${id}");
780 799
781 statement.SetReadOnly(true); 800 statement.SetReadOnly(true);
782 statement.SetParameterType("id", ValueType_Integer64); 801 statement.SetParameterType("id", ValueType_Integer64);
783 802
795 return static_cast<OrthancPluginResourceType>(ReadInteger32(statement, 0)); 814 return static_cast<OrthancPluginResourceType>(ReadInteger32(statement, 0));
796 } 815 }
797 } 816 }
798 817
799 818
800 uint64_t IndexBackend::GetTotalCompressedSize() 819 uint64_t IndexBackend::GetTotalCompressedSize(DatabaseManager& manager)
801 { 820 {
802 std::unique_ptr<DatabaseManager::CachedStatement> statement; 821 std::unique_ptr<DatabaseManager::CachedStatement> statement;
803 822
804 // NB: "COALESCE" is used to replace "NULL" by "0" if the number of rows is empty 823 // NB: "COALESCE" is used to replace "NULL" by "0" if the number of rows is empty
805 824
806 switch (manager_.GetDialect()) 825 switch (manager.GetDialect())
807 { 826 {
808 case Dialect_MySQL: 827 case Dialect_MySQL:
809 statement.reset(new DatabaseManager::CachedStatement( 828 statement.reset(new DatabaseManager::CachedStatement(
810 STATEMENT_FROM_HERE, GetManager(), 829 STATEMENT_FROM_HERE, manager,
811 "SELECT CAST(COALESCE(SUM(compressedSize), 0) AS UNSIGNED INTEGER) FROM AttachedFiles")); 830 "SELECT CAST(COALESCE(SUM(compressedSize), 0) AS UNSIGNED INTEGER) FROM AttachedFiles"));
812 break; 831 break;
813 832
814 case Dialect_PostgreSQL: 833 case Dialect_PostgreSQL:
815 statement.reset(new DatabaseManager::CachedStatement( 834 statement.reset(new DatabaseManager::CachedStatement(
816 STATEMENT_FROM_HERE, GetManager(), 835 STATEMENT_FROM_HERE, manager,
817 "SELECT CAST(COALESCE(SUM(compressedSize), 0) AS BIGINT) FROM AttachedFiles")); 836 "SELECT CAST(COALESCE(SUM(compressedSize), 0) AS BIGINT) FROM AttachedFiles"));
818 break; 837 break;
819 838
820 case Dialect_SQLite: 839 case Dialect_SQLite:
821 statement.reset(new DatabaseManager::CachedStatement( 840 statement.reset(new DatabaseManager::CachedStatement(
822 STATEMENT_FROM_HERE, GetManager(), 841 STATEMENT_FROM_HERE, manager,
823 "SELECT COALESCE(SUM(compressedSize), 0) FROM AttachedFiles")); 842 "SELECT COALESCE(SUM(compressedSize), 0) FROM AttachedFiles"));
824 break; 843 break;
825 844
826 default: 845 default:
827 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 846 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
832 851
833 return static_cast<uint64_t>(ReadInteger64(*statement, 0)); 852 return static_cast<uint64_t>(ReadInteger64(*statement, 0));
834 } 853 }
835 854
836 855
837 uint64_t IndexBackend::GetTotalUncompressedSize() 856 uint64_t IndexBackend::GetTotalUncompressedSize(DatabaseManager& manager)
838 { 857 {
839 std::unique_ptr<DatabaseManager::CachedStatement> statement; 858 std::unique_ptr<DatabaseManager::CachedStatement> statement;
840 859
841 // NB: "COALESCE" is used to replace "NULL" by "0" if the number of rows is empty 860 // NB: "COALESCE" is used to replace "NULL" by "0" if the number of rows is empty
842 861
843 switch (manager_.GetDialect()) 862 switch (manager.GetDialect())
844 { 863 {
845 case Dialect_MySQL: 864 case Dialect_MySQL:
846 statement.reset(new DatabaseManager::CachedStatement( 865 statement.reset(new DatabaseManager::CachedStatement(
847 STATEMENT_FROM_HERE, GetManager(), 866 STATEMENT_FROM_HERE, manager,
848 "SELECT CAST(COALESCE(SUM(uncompressedSize), 0) AS UNSIGNED INTEGER) FROM AttachedFiles")); 867 "SELECT CAST(COALESCE(SUM(uncompressedSize), 0) AS UNSIGNED INTEGER) FROM AttachedFiles"));
849 break; 868 break;
850 869
851 case Dialect_PostgreSQL: 870 case Dialect_PostgreSQL:
852 statement.reset(new DatabaseManager::CachedStatement( 871 statement.reset(new DatabaseManager::CachedStatement(
853 STATEMENT_FROM_HERE, GetManager(), 872 STATEMENT_FROM_HERE, manager,
854 "SELECT CAST(COALESCE(SUM(uncompressedSize), 0) AS BIGINT) FROM AttachedFiles")); 873 "SELECT CAST(COALESCE(SUM(uncompressedSize), 0) AS BIGINT) FROM AttachedFiles"));
855 break; 874 break;
856 875
857 case Dialect_SQLite: 876 case Dialect_SQLite:
858 statement.reset(new DatabaseManager::CachedStatement( 877 statement.reset(new DatabaseManager::CachedStatement(
859 STATEMENT_FROM_HERE, GetManager(), 878 STATEMENT_FROM_HERE, manager,
860 "SELECT COALESCE(SUM(uncompressedSize), 0) FROM AttachedFiles")); 879 "SELECT COALESCE(SUM(uncompressedSize), 0) FROM AttachedFiles"));
861 break; 880 break;
862 881
863 default: 882 default:
864 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 883 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
869 888
870 return static_cast<uint64_t>(ReadInteger64(*statement, 0)); 889 return static_cast<uint64_t>(ReadInteger64(*statement, 0));
871 } 890 }
872 891
873 892
874 bool IndexBackend::IsExistingResource(int64_t internalId) 893 bool IndexBackend::IsExistingResource(DatabaseManager& manager,
875 { 894 int64_t internalId)
876 DatabaseManager::CachedStatement statement( 895 {
877 STATEMENT_FROM_HERE, manager_, 896 DatabaseManager::CachedStatement statement(
897 STATEMENT_FROM_HERE, manager,
878 "SELECT * FROM Resources WHERE internalId=${id}"); 898 "SELECT * FROM Resources WHERE internalId=${id}");
879 899
880 statement.SetReadOnly(true); 900 statement.SetReadOnly(true);
881 statement.SetParameterType("id", ValueType_Integer64); 901 statement.SetParameterType("id", ValueType_Integer64);
882 902
887 907
888 return !statement.IsDone(); 908 return !statement.IsDone();
889 } 909 }
890 910
891 911
892 bool IndexBackend::IsProtectedPatient(int64_t internalId) 912 bool IndexBackend::IsProtectedPatient(DatabaseManager& manager,
893 { 913 int64_t internalId)
894 DatabaseManager::CachedStatement statement( 914 {
895 STATEMENT_FROM_HERE, manager_, 915 DatabaseManager::CachedStatement statement(
916 STATEMENT_FROM_HERE, manager,
896 "SELECT * FROM PatientRecyclingOrder WHERE patientId = ${id}"); 917 "SELECT * FROM PatientRecyclingOrder WHERE patientId = ${id}");
897 918
898 statement.SetReadOnly(true); 919 statement.SetReadOnly(true);
899 statement.SetParameterType("id", ValueType_Integer64); 920 statement.SetParameterType("id", ValueType_Integer64);
900 921
906 return statement.IsDone(); 927 return statement.IsDone();
907 } 928 }
908 929
909 930
910 void IndexBackend::ListAvailableMetadata(std::list<int32_t>& target /*out*/, 931 void IndexBackend::ListAvailableMetadata(std::list<int32_t>& target /*out*/,
932 DatabaseManager& manager,
911 int64_t id) 933 int64_t id)
912 { 934 {
913 DatabaseManager::CachedStatement statement( 935 DatabaseManager::CachedStatement statement(
914 STATEMENT_FROM_HERE, manager_, 936 STATEMENT_FROM_HERE, manager,
915 "SELECT type FROM Metadata WHERE id=${id}"); 937 "SELECT type FROM Metadata WHERE id=${id}");
916 938
917 statement.SetReadOnly(true); 939 statement.SetReadOnly(true);
918 statement.SetParameterType("id", ValueType_Integer64); 940 statement.SetParameterType("id", ValueType_Integer64);
919 941
923 ReadListOfIntegers<int32_t>(target, statement, args); 945 ReadListOfIntegers<int32_t>(target, statement, args);
924 } 946 }
925 947
926 948
927 void IndexBackend::ListAvailableAttachments(std::list<int32_t>& target /*out*/, 949 void IndexBackend::ListAvailableAttachments(std::list<int32_t>& target /*out*/,
950 DatabaseManager& manager,
928 int64_t id) 951 int64_t id)
929 { 952 {
930 DatabaseManager::CachedStatement statement( 953 DatabaseManager::CachedStatement statement(
931 STATEMENT_FROM_HERE, manager_, 954 STATEMENT_FROM_HERE, manager,
932 "SELECT fileType FROM AttachedFiles WHERE id=${id}"); 955 "SELECT fileType FROM AttachedFiles WHERE id=${id}");
933 956
934 statement.SetReadOnly(true); 957 statement.SetReadOnly(true);
935 statement.SetParameterType("id", ValueType_Integer64); 958 statement.SetParameterType("id", ValueType_Integer64);
936 959
939 962
940 ReadListOfIntegers<int32_t>(target, statement, args); 963 ReadListOfIntegers<int32_t>(target, statement, args);
941 } 964 }
942 965
943 966
944 void IndexBackend::LogChange(int32_t changeType, 967 void IndexBackend::LogChange(DatabaseManager& manager,
968 int32_t changeType,
945 int64_t resourceId, 969 int64_t resourceId,
946 OrthancPluginResourceType resourceType, 970 OrthancPluginResourceType resourceType,
947 const char* date) 971 const char* date)
948 { 972 {
949 DatabaseManager::CachedStatement statement( 973 DatabaseManager::CachedStatement statement(
950 STATEMENT_FROM_HERE, manager_, 974 STATEMENT_FROM_HERE, manager,
951 "INSERT INTO Changes VALUES(${}, ${changeType}, ${id}, ${resourceType}, ${date})"); 975 "INSERT INTO Changes VALUES(${}, ${changeType}, ${id}, ${resourceType}, ${date})");
952 976
953 statement.SetParameterType("changeType", ValueType_Integer64); 977 statement.SetParameterType("changeType", ValueType_Integer64);
954 statement.SetParameterType("id", ValueType_Integer64); 978 statement.SetParameterType("id", ValueType_Integer64);
955 statement.SetParameterType("resourceType", ValueType_Integer64); 979 statement.SetParameterType("resourceType", ValueType_Integer64);
963 987
964 statement.Execute(args); 988 statement.Execute(args);
965 } 989 }
966 990
967 991
968 void IndexBackend::LogExportedResource(const OrthancPluginExportedResource& resource) 992 void IndexBackend::LogExportedResource(DatabaseManager& manager,
969 { 993 const OrthancPluginExportedResource& resource)
970 DatabaseManager::CachedStatement statement( 994 {
971 STATEMENT_FROM_HERE, manager_, 995 DatabaseManager::CachedStatement statement(
996 STATEMENT_FROM_HERE, manager,
972 "INSERT INTO ExportedResources VALUES(${}, ${type}, ${publicId}, " 997 "INSERT INTO ExportedResources VALUES(${}, ${type}, ${publicId}, "
973 "${modality}, ${patient}, ${study}, ${series}, ${instance}, ${date})"); 998 "${modality}, ${patient}, ${study}, ${series}, ${instance}, ${date})");
974 999
975 statement.SetParameterType("type", ValueType_Integer64); 1000 statement.SetParameterType("type", ValueType_Integer64);
976 statement.SetParameterType("publicId", ValueType_Utf8String); 1001 statement.SetParameterType("publicId", ValueType_Utf8String);
995 } 1020 }
996 1021
997 1022
998 /* Use GetOutput().AnswerAttachment() */ 1023 /* Use GetOutput().AnswerAttachment() */
999 bool IndexBackend::LookupAttachment(IDatabaseBackendOutput& output, 1024 bool IndexBackend::LookupAttachment(IDatabaseBackendOutput& output,
1025 DatabaseManager& manager,
1000 int64_t id, 1026 int64_t id,
1001 int32_t contentType) 1027 int32_t contentType)
1002 { 1028 {
1003 DatabaseManager::CachedStatement statement( 1029 DatabaseManager::CachedStatement statement(
1004 STATEMENT_FROM_HERE, manager_, 1030 STATEMENT_FROM_HERE, manager,
1005 "SELECT uuid, uncompressedSize, compressionType, compressedSize, " 1031 "SELECT uuid, uncompressedSize, compressionType, compressedSize, "
1006 "uncompressedHash, compressedHash FROM AttachedFiles WHERE id=${id} AND fileType=${type}"); 1032 "uncompressedHash, compressedHash FROM AttachedFiles WHERE id=${id} AND fileType=${type}");
1007 1033
1008 statement.SetReadOnly(true); 1034 statement.SetReadOnly(true);
1009 statement.SetParameterType("id", ValueType_Integer64); 1035 statement.SetParameterType("id", ValueType_Integer64);
1032 } 1058 }
1033 } 1059 }
1034 1060
1035 1061
1036 bool IndexBackend::LookupGlobalProperty(std::string& target /*out*/, 1062 bool IndexBackend::LookupGlobalProperty(std::string& target /*out*/,
1063 DatabaseManager& manager,
1037 const char* serverIdentifier, 1064 const char* serverIdentifier,
1038 int32_t property) 1065 int32_t property)
1039 { 1066 {
1040 return ::OrthancDatabases::LookupGlobalProperty(target, manager_, serverIdentifier, 1067 return ::OrthancDatabases::LookupGlobalProperty(target, manager, serverIdentifier,
1041 static_cast<Orthanc::GlobalProperty>(property)); 1068 static_cast<Orthanc::GlobalProperty>(property));
1042 } 1069 }
1043 1070
1044 1071
1045 void IndexBackend::LookupIdentifier(std::list<int64_t>& target /*out*/, 1072 void IndexBackend::LookupIdentifier(std::list<int64_t>& target /*out*/,
1073 DatabaseManager& manager,
1046 OrthancPluginResourceType resourceType, 1074 OrthancPluginResourceType resourceType,
1047 uint16_t group, 1075 uint16_t group,
1048 uint16_t element, 1076 uint16_t element,
1049 OrthancPluginIdentifierConstraint constraint, 1077 OrthancPluginIdentifierConstraint constraint,
1050 const char* value) 1078 const char* value)
1059 switch (constraint) 1087 switch (constraint)
1060 { 1088 {
1061 case OrthancPluginIdentifierConstraint_Equal: 1089 case OrthancPluginIdentifierConstraint_Equal:
1062 header += "d.value = ${value}"; 1090 header += "d.value = ${value}";
1063 statement.reset(new DatabaseManager::CachedStatement( 1091 statement.reset(new DatabaseManager::CachedStatement(
1064 STATEMENT_FROM_HERE, manager_, header.c_str())); 1092 STATEMENT_FROM_HERE, manager, header.c_str()));
1065 break; 1093 break;
1066 1094
1067 case OrthancPluginIdentifierConstraint_SmallerOrEqual: 1095 case OrthancPluginIdentifierConstraint_SmallerOrEqual:
1068 header += "d.value <= ${value}"; 1096 header += "d.value <= ${value}";
1069 statement.reset(new DatabaseManager::CachedStatement( 1097 statement.reset(new DatabaseManager::CachedStatement(
1070 STATEMENT_FROM_HERE, manager_, header.c_str())); 1098 STATEMENT_FROM_HERE, manager, header.c_str()));
1071 break; 1099 break;
1072 1100
1073 case OrthancPluginIdentifierConstraint_GreaterOrEqual: 1101 case OrthancPluginIdentifierConstraint_GreaterOrEqual:
1074 header += "d.value >= ${value}"; 1102 header += "d.value >= ${value}";
1075 statement.reset(new DatabaseManager::CachedStatement( 1103 statement.reset(new DatabaseManager::CachedStatement(
1076 STATEMENT_FROM_HERE, manager_, header.c_str())); 1104 STATEMENT_FROM_HERE, manager, header.c_str()));
1077 break; 1105 break;
1078 1106
1079 case OrthancPluginIdentifierConstraint_Wildcard: 1107 case OrthancPluginIdentifierConstraint_Wildcard:
1080 header += "d.value LIKE ${value}"; 1108 header += "d.value LIKE ${value}";
1081 statement.reset(new DatabaseManager::CachedStatement( 1109 statement.reset(new DatabaseManager::CachedStatement(
1082 STATEMENT_FROM_HERE, manager_, header.c_str())); 1110 STATEMENT_FROM_HERE, manager, header.c_str()));
1083 break; 1111 break;
1084 1112
1085 default: 1113 default:
1086 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); 1114 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);
1087 } 1115 }
1116 } 1144 }
1117 } 1145 }
1118 1146
1119 1147
1120 void IndexBackend::LookupIdentifierRange(std::list<int64_t>& target /*out*/, 1148 void IndexBackend::LookupIdentifierRange(std::list<int64_t>& target /*out*/,
1149 DatabaseManager& manager,
1121 OrthancPluginResourceType resourceType, 1150 OrthancPluginResourceType resourceType,
1122 uint16_t group, 1151 uint16_t group,
1123 uint16_t element, 1152 uint16_t element,
1124 const char* start, 1153 const char* start,
1125 const char* end) 1154 const char* end)
1126 { 1155 {
1127 DatabaseManager::CachedStatement statement( 1156 DatabaseManager::CachedStatement statement(
1128 STATEMENT_FROM_HERE, manager_, 1157 STATEMENT_FROM_HERE, manager,
1129 "SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE " 1158 "SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE "
1130 "d.id = r.internalId AND r.resourceType=${type} AND d.tagGroup=${group} " 1159 "d.id = r.internalId AND r.resourceType=${type} AND d.tagGroup=${group} "
1131 "AND d.tagElement=${element} AND d.value>=${start} AND d.value<=${end}"); 1160 "AND d.tagElement=${element} AND d.value>=${start} AND d.value<=${end}");
1132 1161
1133 statement.SetReadOnly(true); 1162 statement.SetReadOnly(true);
1154 } 1183 }
1155 } 1184 }
1156 1185
1157 1186
1158 bool IndexBackend::LookupMetadata(std::string& target /*out*/, 1187 bool IndexBackend::LookupMetadata(std::string& target /*out*/,
1188 DatabaseManager& manager,
1159 int64_t id, 1189 int64_t id,
1160 int32_t metadataType) 1190 int32_t metadataType)
1161 { 1191 {
1162 DatabaseManager::CachedStatement statement( 1192 DatabaseManager::CachedStatement statement(
1163 STATEMENT_FROM_HERE, manager_, 1193 STATEMENT_FROM_HERE, manager,
1164 "SELECT value FROM Metadata WHERE id=${id} and type=${type}"); 1194 "SELECT value FROM Metadata WHERE id=${id} and type=${type}");
1165 1195
1166 statement.SetReadOnly(true); 1196 statement.SetReadOnly(true);
1167 statement.SetParameterType("id", ValueType_Integer64); 1197 statement.SetParameterType("id", ValueType_Integer64);
1168 statement.SetParameterType("type", ValueType_Integer64); 1198 statement.SetParameterType("type", ValueType_Integer64);
1184 } 1214 }
1185 } 1215 }
1186 1216
1187 1217
1188 bool IndexBackend::LookupParent(int64_t& parentId /*out*/, 1218 bool IndexBackend::LookupParent(int64_t& parentId /*out*/,
1219 DatabaseManager& manager,
1189 int64_t resourceId) 1220 int64_t resourceId)
1190 { 1221 {
1191 DatabaseManager::CachedStatement statement( 1222 DatabaseManager::CachedStatement statement(
1192 STATEMENT_FROM_HERE, manager_, 1223 STATEMENT_FROM_HERE, manager,
1193 "SELECT parentId FROM Resources WHERE internalId=${id}"); 1224 "SELECT parentId FROM Resources WHERE internalId=${id}");
1194 1225
1195 statement.SetReadOnly(true); 1226 statement.SetReadOnly(true);
1196 statement.SetParameterType("id", ValueType_Integer64); 1227 statement.SetParameterType("id", ValueType_Integer64);
1197 1228
1213 } 1244 }
1214 1245
1215 1246
1216 bool IndexBackend::LookupResource(int64_t& id /*out*/, 1247 bool IndexBackend::LookupResource(int64_t& id /*out*/,
1217 OrthancPluginResourceType& type /*out*/, 1248 OrthancPluginResourceType& type /*out*/,
1249 DatabaseManager& manager,
1218 const char* publicId) 1250 const char* publicId)
1219 { 1251 {
1220 DatabaseManager::CachedStatement statement( 1252 DatabaseManager::CachedStatement statement(
1221 STATEMENT_FROM_HERE, manager_, 1253 STATEMENT_FROM_HERE, manager,
1222 "SELECT internalId, resourceType FROM Resources WHERE publicId=${id}"); 1254 "SELECT internalId, resourceType FROM Resources WHERE publicId=${id}");
1223 1255
1224 statement.SetReadOnly(true); 1256 statement.SetReadOnly(true);
1225 statement.SetParameterType("id", ValueType_Utf8String); 1257 statement.SetParameterType("id", ValueType_Utf8String);
1226 1258
1240 return true; 1272 return true;
1241 } 1273 }
1242 } 1274 }
1243 1275
1244 1276
1245 bool IndexBackend::SelectPatientToRecycle(int64_t& internalId /*out*/) 1277 bool IndexBackend::SelectPatientToRecycle(int64_t& internalId /*out*/,
1246 { 1278 DatabaseManager& manager)
1247 DatabaseManager::CachedStatement statement( 1279 {
1248 STATEMENT_FROM_HERE, manager_, 1280 DatabaseManager::CachedStatement statement(
1281 STATEMENT_FROM_HERE, manager,
1249 "SELECT patientId FROM PatientRecyclingOrder ORDER BY seq ASC LIMIT 1"); 1282 "SELECT patientId FROM PatientRecyclingOrder ORDER BY seq ASC LIMIT 1");
1250 1283
1251 statement.SetReadOnly(true); 1284 statement.SetReadOnly(true);
1252 statement.Execute(); 1285 statement.Execute();
1253 1286
1262 } 1295 }
1263 } 1296 }
1264 1297
1265 1298
1266 bool IndexBackend::SelectPatientToRecycle(int64_t& internalId /*out*/, 1299 bool IndexBackend::SelectPatientToRecycle(int64_t& internalId /*out*/,
1300 DatabaseManager& manager,
1267 int64_t patientIdToAvoid) 1301 int64_t patientIdToAvoid)
1268 { 1302 {
1269 DatabaseManager::CachedStatement statement( 1303 DatabaseManager::CachedStatement statement(
1270 STATEMENT_FROM_HERE, manager_, 1304 STATEMENT_FROM_HERE, manager,
1271 "SELECT patientId FROM PatientRecyclingOrder " 1305 "SELECT patientId FROM PatientRecyclingOrder "
1272 "WHERE patientId != ${id} ORDER BY seq ASC LIMIT 1"); 1306 "WHERE patientId != ${id} ORDER BY seq ASC LIMIT 1");
1273 1307
1274 statement.SetReadOnly(true); 1308 statement.SetReadOnly(true);
1275 statement.SetParameterType("id", ValueType_Integer64); 1309 statement.SetParameterType("id", ValueType_Integer64);
1289 return true; 1323 return true;
1290 } 1324 }
1291 } 1325 }
1292 1326
1293 1327
1294 void IndexBackend::SetGlobalProperty(const char* serverIdentifier, 1328 void IndexBackend::SetGlobalProperty(DatabaseManager& manager,
1329 const char* serverIdentifier,
1295 int32_t property, 1330 int32_t property,
1296 const char* value) 1331 const char* value)
1297 { 1332 {
1298 return ::OrthancDatabases::SetGlobalProperty( 1333 return ::OrthancDatabases::SetGlobalProperty(
1299 manager_, serverIdentifier, static_cast<Orthanc::GlobalProperty>(property), value); 1334 manager, serverIdentifier, static_cast<Orthanc::GlobalProperty>(property), value);
1300 } 1335 }
1301 1336
1302 1337
1303 static void ExecuteSetTag(DatabaseManager::CachedStatement& statement, 1338 static void ExecuteSetTag(DatabaseManager::CachedStatement& statement,
1304 int64_t id, 1339 int64_t id,
1319 1354
1320 statement.Execute(args); 1355 statement.Execute(args);
1321 } 1356 }
1322 1357
1323 1358
1324 void IndexBackend::SetMainDicomTag(int64_t id, 1359 void IndexBackend::SetMainDicomTag(DatabaseManager& manager,
1360 int64_t id,
1325 uint16_t group, 1361 uint16_t group,
1326 uint16_t element, 1362 uint16_t element,
1327 const char* value) 1363 const char* value)
1328 { 1364 {
1329 DatabaseManager::CachedStatement statement( 1365 DatabaseManager::CachedStatement statement(
1330 STATEMENT_FROM_HERE, manager_, 1366 STATEMENT_FROM_HERE, manager,
1331 "INSERT INTO MainDicomTags VALUES(${id}, ${group}, ${element}, ${value})"); 1367 "INSERT INTO MainDicomTags VALUES(${id}, ${group}, ${element}, ${value})");
1332 1368
1333 ExecuteSetTag(statement, id, group, element, value); 1369 ExecuteSetTag(statement, id, group, element, value);
1334 } 1370 }
1335 1371
1336 1372
1337 void IndexBackend::SetIdentifierTag(int64_t id, 1373 void IndexBackend::SetIdentifierTag(DatabaseManager& manager,
1374 int64_t id,
1338 uint16_t group, 1375 uint16_t group,
1339 uint16_t element, 1376 uint16_t element,
1340 const char* value) 1377 const char* value)
1341 { 1378 {
1342 DatabaseManager::CachedStatement statement( 1379 DatabaseManager::CachedStatement statement(
1343 STATEMENT_FROM_HERE, manager_, 1380 STATEMENT_FROM_HERE, manager,
1344 "INSERT INTO DicomIdentifiers VALUES(${id}, ${group}, ${element}, ${value})"); 1381 "INSERT INTO DicomIdentifiers VALUES(${id}, ${group}, ${element}, ${value})");
1345 1382
1346 ExecuteSetTag(statement, id, group, element, value); 1383 ExecuteSetTag(statement, id, group, element, value);
1347 } 1384 }
1348 1385
1349 1386
1350 void IndexBackend::SetMetadata(int64_t id, 1387 void IndexBackend::SetMetadata(DatabaseManager& manager,
1388 int64_t id,
1351 int32_t metadataType, 1389 int32_t metadataType,
1352 const char* value) 1390 const char* value)
1353 { 1391 {
1354 if (manager_.GetDialect() == Dialect_SQLite) 1392 if (manager.GetDialect() == Dialect_SQLite)
1355 { 1393 {
1356 DatabaseManager::CachedStatement statement( 1394 DatabaseManager::CachedStatement statement(
1357 STATEMENT_FROM_HERE, manager_, 1395 STATEMENT_FROM_HERE, manager,
1358 "INSERT OR REPLACE INTO Metadata VALUES (${id}, ${type}, ${value})"); 1396 "INSERT OR REPLACE INTO Metadata VALUES (${id}, ${type}, ${value})");
1359 1397
1360 statement.SetParameterType("id", ValueType_Integer64); 1398 statement.SetParameterType("id", ValueType_Integer64);
1361 statement.SetParameterType("type", ValueType_Integer64); 1399 statement.SetParameterType("type", ValueType_Integer64);
1362 statement.SetParameterType("value", ValueType_Utf8String); 1400 statement.SetParameterType("value", ValueType_Utf8String);
1370 } 1408 }
1371 else 1409 else
1372 { 1410 {
1373 { 1411 {
1374 DatabaseManager::CachedStatement statement( 1412 DatabaseManager::CachedStatement statement(
1375 STATEMENT_FROM_HERE, manager_, 1413 STATEMENT_FROM_HERE, manager,
1376 "DELETE FROM Metadata WHERE id=${id} AND type=${type}"); 1414 "DELETE FROM Metadata WHERE id=${id} AND type=${type}");
1377 1415
1378 statement.SetParameterType("id", ValueType_Integer64); 1416 statement.SetParameterType("id", ValueType_Integer64);
1379 statement.SetParameterType("type", ValueType_Integer64); 1417 statement.SetParameterType("type", ValueType_Integer64);
1380 1418
1385 statement.Execute(args); 1423 statement.Execute(args);
1386 } 1424 }
1387 1425
1388 { 1426 {
1389 DatabaseManager::CachedStatement statement( 1427 DatabaseManager::CachedStatement statement(
1390 STATEMENT_FROM_HERE, manager_, 1428 STATEMENT_FROM_HERE, manager,
1391 "INSERT INTO Metadata VALUES (${id}, ${type}, ${value})"); 1429 "INSERT INTO Metadata VALUES (${id}, ${type}, ${value})");
1392 1430
1393 statement.SetParameterType("id", ValueType_Integer64); 1431 statement.SetParameterType("id", ValueType_Integer64);
1394 statement.SetParameterType("type", ValueType_Integer64); 1432 statement.SetParameterType("type", ValueType_Integer64);
1395 statement.SetParameterType("value", ValueType_Utf8String); 1433 statement.SetParameterType("value", ValueType_Utf8String);
1403 } 1441 }
1404 } 1442 }
1405 } 1443 }
1406 1444
1407 1445
1408 void IndexBackend::SetProtectedPatient(int64_t internalId, 1446 void IndexBackend::SetProtectedPatient(DatabaseManager& manager,
1447 int64_t internalId,
1409 bool isProtected) 1448 bool isProtected)
1410 { 1449 {
1411 if (isProtected) 1450 if (isProtected)
1412 { 1451 {
1413 DatabaseManager::CachedStatement statement( 1452 DatabaseManager::CachedStatement statement(
1414 STATEMENT_FROM_HERE, manager_, 1453 STATEMENT_FROM_HERE, manager,
1415 "DELETE FROM PatientRecyclingOrder WHERE patientId=${id}"); 1454 "DELETE FROM PatientRecyclingOrder WHERE patientId=${id}");
1416 1455
1417 statement.SetParameterType("id", ValueType_Integer64); 1456 statement.SetParameterType("id", ValueType_Integer64);
1418 1457
1419 Dictionary args; 1458 Dictionary args;
1420 args.SetIntegerValue("id", internalId); 1459 args.SetIntegerValue("id", internalId);
1421 1460
1422 statement.Execute(args); 1461 statement.Execute(args);
1423 } 1462 }
1424 else if (IsProtectedPatient(internalId)) 1463 else if (IsProtectedPatient(manager, internalId))
1425 { 1464 {
1426 DatabaseManager::CachedStatement statement( 1465 DatabaseManager::CachedStatement statement(
1427 STATEMENT_FROM_HERE, manager_, 1466 STATEMENT_FROM_HERE, manager,
1428 "INSERT INTO PatientRecyclingOrder VALUES(${}, ${id})"); 1467 "INSERT INTO PatientRecyclingOrder VALUES(${}, ${id})");
1429 1468
1430 statement.SetParameterType("id", ValueType_Integer64); 1469 statement.SetParameterType("id", ValueType_Integer64);
1431 1470
1432 Dictionary args; 1471 Dictionary args;
1439 // Nothing to do: The patient is already unprotected 1478 // Nothing to do: The patient is already unprotected
1440 } 1479 }
1441 } 1480 }
1442 1481
1443 1482
1444 uint32_t IndexBackend::GetDatabaseVersion() 1483 uint32_t IndexBackend::GetDatabaseVersion(DatabaseManager& manager)
1445 { 1484 {
1446 // Create a read-only, explicit transaction to read the database 1485 // Create a read-only, explicit transaction to read the database
1447 // version (this was a read-write, implicit transaction in 1486 // version (this was a read-write, implicit transaction in
1448 // PostgreSQL plugin <= 3.3 and MySQL plugin <= 3.0) 1487 // PostgreSQL plugin <= 3.3 and MySQL plugin <= 3.0)
1449 DatabaseManager::Transaction transaction(GetManager(), TransactionType_ReadOnly); 1488 DatabaseManager::Transaction transaction(manager, TransactionType_ReadOnly);
1450 1489
1451 std::string version = "unknown"; 1490 std::string version = "unknown";
1452 1491
1453 if (LookupGlobalProperty(version, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion)) 1492 if (LookupGlobalProperty(version, manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion))
1454 { 1493 {
1455 try 1494 try
1456 { 1495 {
1457 return boost::lexical_cast<unsigned int>(version); 1496 return boost::lexical_cast<unsigned int>(version);
1458 } 1497 }
1469 /** 1508 /**
1470 * Upgrade the database to the specified version of the database 1509 * Upgrade the database to the specified version of the database
1471 * schema. The upgrade script is allowed to make calls to 1510 * schema. The upgrade script is allowed to make calls to
1472 * OrthancPluginReconstructMainDicomTags(). 1511 * OrthancPluginReconstructMainDicomTags().
1473 **/ 1512 **/
1474 void IndexBackend::UpgradeDatabase(uint32_t targetVersion, 1513 void IndexBackend::UpgradeDatabase(DatabaseManager& manager,
1514 uint32_t targetVersion,
1475 OrthancPluginStorageArea* storageArea) 1515 OrthancPluginStorageArea* storageArea)
1476 { 1516 {
1477 LOG(ERROR) << "Upgrading database is not implemented by this plugin"; 1517 LOG(ERROR) << "Upgrading database is not implemented by this plugin";
1478 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 1518 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
1479 } 1519 }
1480 1520
1481 1521
1482 void IndexBackend::ClearMainDicomTags(int64_t internalId) 1522 void IndexBackend::ClearMainDicomTags(DatabaseManager& manager,
1523 int64_t internalId)
1483 { 1524 {
1484 { 1525 {
1485 DatabaseManager::CachedStatement statement( 1526 DatabaseManager::CachedStatement statement(
1486 STATEMENT_FROM_HERE, manager_, 1527 STATEMENT_FROM_HERE, manager,
1487 "DELETE FROM MainDicomTags WHERE id=${id}"); 1528 "DELETE FROM MainDicomTags WHERE id=${id}");
1488 1529
1489 statement.SetParameterType("id", ValueType_Integer64); 1530 statement.SetParameterType("id", ValueType_Integer64);
1490 1531
1491 Dictionary args; 1532 Dictionary args;
1494 statement.Execute(args); 1535 statement.Execute(args);
1495 } 1536 }
1496 1537
1497 { 1538 {
1498 DatabaseManager::CachedStatement statement( 1539 DatabaseManager::CachedStatement statement(
1499 STATEMENT_FROM_HERE, manager_, 1540 STATEMENT_FROM_HERE, manager,
1500 "DELETE FROM DicomIdentifiers WHERE id=${id}"); 1541 "DELETE FROM DicomIdentifiers WHERE id=${id}");
1501 1542
1502 statement.SetParameterType("id", ValueType_Integer64); 1543 statement.SetParameterType("id", ValueType_Integer64);
1503 1544
1504 Dictionary args; 1545 Dictionary args;
1508 } 1549 }
1509 } 1550 }
1510 1551
1511 1552
1512 // For unit testing only! 1553 // For unit testing only!
1513 uint64_t IndexBackend::GetAllResourcesCount() 1554 uint64_t IndexBackend::GetAllResourcesCount(DatabaseManager& manager)
1514 { 1555 {
1515 std::unique_ptr<DatabaseManager::CachedStatement> statement; 1556 std::unique_ptr<DatabaseManager::CachedStatement> statement;
1516 1557
1517 switch (manager_.GetDialect()) 1558 switch (manager.GetDialect())
1518 { 1559 {
1519 case Dialect_MySQL: 1560 case Dialect_MySQL:
1520 statement.reset(new DatabaseManager::CachedStatement( 1561 statement.reset(new DatabaseManager::CachedStatement(
1521 STATEMENT_FROM_HERE, GetManager(), 1562 STATEMENT_FROM_HERE, manager,
1522 "SELECT CAST(COUNT(*) AS UNSIGNED INT) FROM Resources")); 1563 "SELECT CAST(COUNT(*) AS UNSIGNED INT) FROM Resources"));
1523 break; 1564 break;
1524 1565
1525 case Dialect_PostgreSQL: 1566 case Dialect_PostgreSQL:
1526 statement.reset(new DatabaseManager::CachedStatement( 1567 statement.reset(new DatabaseManager::CachedStatement(
1527 STATEMENT_FROM_HERE, GetManager(), 1568 STATEMENT_FROM_HERE, manager,
1528 "SELECT CAST(COUNT(*) AS BIGINT) FROM Resources")); 1569 "SELECT CAST(COUNT(*) AS BIGINT) FROM Resources"));
1529 break; 1570 break;
1530 1571
1531 case Dialect_SQLite: 1572 case Dialect_SQLite:
1532 statement.reset(new DatabaseManager::CachedStatement( 1573 statement.reset(new DatabaseManager::CachedStatement(
1533 STATEMENT_FROM_HERE, GetManager(), 1574 STATEMENT_FROM_HERE, manager,
1534 "SELECT COUNT(*) FROM Resources")); 1575 "SELECT COUNT(*) FROM Resources"));
1535 break; 1576 break;
1536 1577
1537 default: 1578 default:
1538 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 1579 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
1544 return static_cast<uint64_t>(ReadInteger64(*statement, 0)); 1585 return static_cast<uint64_t>(ReadInteger64(*statement, 0));
1545 } 1586 }
1546 1587
1547 1588
1548 // For unit testing only! 1589 // For unit testing only!
1549 uint64_t IndexBackend::GetUnprotectedPatientsCount() 1590 uint64_t IndexBackend::GetUnprotectedPatientsCount(DatabaseManager& manager)
1550 { 1591 {
1551 std::unique_ptr<DatabaseManager::CachedStatement> statement; 1592 std::unique_ptr<DatabaseManager::CachedStatement> statement;
1552 1593
1553 switch (manager_.GetDialect()) 1594 switch (manager.GetDialect())
1554 { 1595 {
1555 case Dialect_MySQL: 1596 case Dialect_MySQL:
1556 statement.reset(new DatabaseManager::CachedStatement( 1597 statement.reset(new DatabaseManager::CachedStatement(
1557 STATEMENT_FROM_HERE, GetManager(), 1598 STATEMENT_FROM_HERE, manager,
1558 "SELECT CAST(COUNT(*) AS UNSIGNED INT) FROM PatientRecyclingOrder")); 1599 "SELECT CAST(COUNT(*) AS UNSIGNED INT) FROM PatientRecyclingOrder"));
1559 break; 1600 break;
1560 1601
1561 case Dialect_PostgreSQL: 1602 case Dialect_PostgreSQL:
1562 statement.reset(new DatabaseManager::CachedStatement( 1603 statement.reset(new DatabaseManager::CachedStatement(
1563 STATEMENT_FROM_HERE, GetManager(), 1604 STATEMENT_FROM_HERE, manager,
1564 "SELECT CAST(COUNT(*) AS BIGINT) FROM PatientRecyclingOrder")); 1605 "SELECT CAST(COUNT(*) AS BIGINT) FROM PatientRecyclingOrder"));
1565 break; 1606 break;
1566 1607
1567 case Dialect_SQLite: 1608 case Dialect_SQLite:
1568 statement.reset(new DatabaseManager::CachedStatement( 1609 statement.reset(new DatabaseManager::CachedStatement(
1569 STATEMENT_FROM_HERE, GetManager(), 1610 STATEMENT_FROM_HERE, manager,
1570 "SELECT COUNT(*) FROM PatientRecyclingOrder")); 1611 "SELECT COUNT(*) FROM PatientRecyclingOrder"));
1571 break; 1612 break;
1572 1613
1573 default: 1614 default:
1574 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 1615 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
1581 } 1622 }
1582 1623
1583 1624
1584 // For unit testing only! 1625 // For unit testing only!
1585 bool IndexBackend::GetParentPublicId(std::string& target, 1626 bool IndexBackend::GetParentPublicId(std::string& target,
1627 DatabaseManager& manager,
1586 int64_t id) 1628 int64_t id)
1587 { 1629 {
1588 DatabaseManager::CachedStatement statement( 1630 DatabaseManager::CachedStatement statement(
1589 STATEMENT_FROM_HERE, GetManager(), 1631 STATEMENT_FROM_HERE, manager,
1590 "SELECT a.publicId FROM Resources AS a, Resources AS b " 1632 "SELECT a.publicId FROM Resources AS a, Resources AS b "
1591 "WHERE a.internalId = b.parentId AND b.internalId = ${id}"); 1633 "WHERE a.internalId = b.parentId AND b.internalId = ${id}");
1592 1634
1593 statement.SetReadOnly(true); 1635 statement.SetReadOnly(true);
1594 statement.SetParameterType("id", ValueType_Integer64); 1636 statement.SetParameterType("id", ValueType_Integer64);
1610 } 1652 }
1611 1653
1612 1654
1613 // For unit tests only! 1655 // For unit tests only!
1614 void IndexBackend::GetChildren(std::list<std::string>& childrenPublicIds, 1656 void IndexBackend::GetChildren(std::list<std::string>& childrenPublicIds,
1657 DatabaseManager& manager,
1615 int64_t id) 1658 int64_t id)
1616 { 1659 {
1617 DatabaseManager::CachedStatement statement( 1660 DatabaseManager::CachedStatement statement(
1618 STATEMENT_FROM_HERE, GetManager(), 1661 STATEMENT_FROM_HERE, manager,
1619 "SELECT publicId FROM Resources WHERE parentId=${id}"); 1662 "SELECT publicId FROM Resources WHERE parentId=${id}");
1620 1663
1621 statement.SetReadOnly(true); 1664 statement.SetReadOnly(true);
1622 statement.SetParameterType("id", ValueType_Integer64); 1665 statement.SetParameterType("id", ValueType_Integer64);
1623 1666
1698 1741
1699 1742
1700 #if ORTHANC_PLUGINS_HAS_DATABASE_CONSTRAINT == 1 1743 #if ORTHANC_PLUGINS_HAS_DATABASE_CONSTRAINT == 1
1701 // New primitive since Orthanc 1.5.2 1744 // New primitive since Orthanc 1.5.2
1702 void IndexBackend::LookupResources(IDatabaseBackendOutput& output, 1745 void IndexBackend::LookupResources(IDatabaseBackendOutput& output,
1746 DatabaseManager& manager,
1703 const std::vector<Orthanc::DatabaseConstraint>& lookup, 1747 const std::vector<Orthanc::DatabaseConstraint>& lookup,
1704 OrthancPluginResourceType queryLevel, 1748 OrthancPluginResourceType queryLevel,
1705 uint32_t limit, 1749 uint32_t limit,
1706 bool requestSomeInstance) 1750 bool requestSomeInstance)
1707 { 1751 {
1708 LookupFormatter formatter(manager_.GetDialect()); 1752 LookupFormatter formatter(manager.GetDialect());
1709 1753
1710 std::string sql; 1754 std::string sql;
1711 Orthanc::ISqlLookupFormatter::Apply(sql, formatter, lookup, 1755 Orthanc::ISqlLookupFormatter::Apply(sql, formatter, lookup,
1712 Orthanc::Plugins::Convert(queryLevel), limit); 1756 Orthanc::Plugins::Convert(queryLevel), limit);
1713 1757
1744 default: 1788 default:
1745 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 1789 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
1746 } 1790 }
1747 } 1791 }
1748 1792
1749 DatabaseManager::StandaloneStatement statement(GetManager(), sql); 1793 DatabaseManager::StandaloneStatement statement(manager, sql);
1750 formatter.PrepareStatement(statement); 1794 formatter.PrepareStatement(statement);
1751 1795
1752 statement.Execute(formatter.GetDictionary()); 1796 statement.Execute(formatter.GetDictionary());
1753 1797
1754 while (!statement.IsDone()) 1798 while (!statement.IsDone())
1882 1926
1883 1927
1884 #if ORTHANC_PLUGINS_HAS_DATABASE_CONSTRAINT == 1 1928 #if ORTHANC_PLUGINS_HAS_DATABASE_CONSTRAINT == 1
1885 // New primitive since Orthanc 1.5.2 1929 // New primitive since Orthanc 1.5.2
1886 void IndexBackend::SetResourcesContent( 1930 void IndexBackend::SetResourcesContent(
1931 DatabaseManager& manager,
1887 uint32_t countIdentifierTags, 1932 uint32_t countIdentifierTags,
1888 const OrthancPluginResourcesContentTags* identifierTags, 1933 const OrthancPluginResourcesContentTags* identifierTags,
1889 uint32_t countMainDicomTags, 1934 uint32_t countMainDicomTags,
1890 const OrthancPluginResourcesContentTags* mainDicomTags, 1935 const OrthancPluginResourcesContentTags* mainDicomTags,
1891 uint32_t countMetadata, 1936 uint32_t countMetadata,
1896 * statement, so we execute 3 separate commands (for identifiers, 1941 * statement, so we execute 3 separate commands (for identifiers,
1897 * main tags and metadata). Maybe MySQL does not suffer from the 1942 * main tags and metadata). Maybe MySQL does not suffer from the
1898 * same limitation, to check. 1943 * same limitation, to check.
1899 **/ 1944 **/
1900 1945
1901 ExecuteSetResourcesContentTags(GetManager(), "DicomIdentifiers", "i", 1946 ExecuteSetResourcesContentTags(manager, "DicomIdentifiers", "i",
1902 countIdentifierTags, identifierTags); 1947 countIdentifierTags, identifierTags);
1903 1948
1904 ExecuteSetResourcesContentTags(GetManager(), "MainDicomTags", "t", 1949 ExecuteSetResourcesContentTags(manager, "MainDicomTags", "t",
1905 countMainDicomTags, mainDicomTags); 1950 countMainDicomTags, mainDicomTags);
1906 1951
1907 ExecuteSetResourcesContentMetadata(GetManager(), countMetadata, metadata); 1952 ExecuteSetResourcesContentMetadata(manager, countMetadata, metadata);
1908 } 1953 }
1909 #endif 1954 #endif
1910 1955
1911 1956
1912 // New primitive since Orthanc 1.5.2 1957 // New primitive since Orthanc 1.5.2
1913 void IndexBackend::GetChildrenMetadata(std::list<std::string>& target, 1958 void IndexBackend::GetChildrenMetadata(std::list<std::string>& target,
1959 DatabaseManager& manager,
1914 int64_t resourceId, 1960 int64_t resourceId,
1915 int32_t metadata) 1961 int32_t metadata)
1916 { 1962 {
1917 DatabaseManager::CachedStatement statement( 1963 DatabaseManager::CachedStatement statement(
1918 STATEMENT_FROM_HERE, manager_, 1964 STATEMENT_FROM_HERE, manager,
1919 "SELECT value FROM Metadata WHERE type=${metadata} AND " 1965 "SELECT value FROM Metadata WHERE type=${metadata} AND "
1920 "id IN (SELECT internalId FROM Resources WHERE parentId=${id})"); 1966 "id IN (SELECT internalId FROM Resources WHERE parentId=${id})");
1921 1967
1922 statement.SetReadOnly(true); 1968 statement.SetReadOnly(true);
1923 statement.SetParameterType("id", ValueType_Integer64); 1969 statement.SetParameterType("id", ValueType_Integer64);
1930 ReadListOfStrings(target, statement, args); 1976 ReadListOfStrings(target, statement, args);
1931 } 1977 }
1932 1978
1933 1979
1934 // New primitive since Orthanc 1.5.2 1980 // New primitive since Orthanc 1.5.2
1935 void IndexBackend::TagMostRecentPatient(int64_t patient) 1981 void IndexBackend::TagMostRecentPatient(DatabaseManager& manager,
1982 int64_t patient)
1936 { 1983 {
1937 int64_t seq; 1984 int64_t seq;
1938 1985
1939 { 1986 {
1940 DatabaseManager::CachedStatement statement( 1987 DatabaseManager::CachedStatement statement(
1941 STATEMENT_FROM_HERE, manager_, 1988 STATEMENT_FROM_HERE, manager,
1942 "SELECT * FROM PatientRecyclingOrder WHERE seq >= " 1989 "SELECT * FROM PatientRecyclingOrder WHERE seq >= "
1943 "(SELECT seq FROM PatientRecyclingOrder WHERE patientid=${id}) ORDER BY seq LIMIT 2"); 1990 "(SELECT seq FROM PatientRecyclingOrder WHERE patientid=${id}) ORDER BY seq LIMIT 2");
1944 1991
1945 statement.SetReadOnly(true); 1992 statement.SetReadOnly(true);
1946 statement.SetParameterType("id", ValueType_Integer64); 1993 statement.SetParameterType("id", ValueType_Integer64);
1970 2017
1971 // Delete the old position of the patient in the recycling order 2018 // Delete the old position of the patient in the recycling order
1972 2019
1973 { 2020 {
1974 DatabaseManager::CachedStatement statement( 2021 DatabaseManager::CachedStatement statement(
1975 STATEMENT_FROM_HERE, manager_, 2022 STATEMENT_FROM_HERE, manager,
1976 "DELETE FROM PatientRecyclingOrder WHERE seq=${seq}"); 2023 "DELETE FROM PatientRecyclingOrder WHERE seq=${seq}");
1977 2024
1978 statement.SetParameterType("seq", ValueType_Integer64); 2025 statement.SetParameterType("seq", ValueType_Integer64);
1979 2026
1980 Dictionary args; 2027 Dictionary args;
1985 2032
1986 // Add the patient to the end of the recycling order 2033 // Add the patient to the end of the recycling order
1987 2034
1988 { 2035 {
1989 DatabaseManager::CachedStatement statement( 2036 DatabaseManager::CachedStatement statement(
1990 STATEMENT_FROM_HERE, manager_, 2037 STATEMENT_FROM_HERE, manager,
1991 "INSERT INTO PatientRecyclingOrder VALUES(${}, ${id})"); 2038 "INSERT INTO PatientRecyclingOrder VALUES(${}, ${id})");
1992 2039
1993 statement.SetParameterType("id", ValueType_Integer64); 2040 statement.SetParameterType("id", ValueType_Integer64);
1994 2041
1995 Dictionary args; 2042 Dictionary args;
2004 # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 4) 2051 # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 4)
2005 // New primitive since Orthanc 1.5.4 2052 // New primitive since Orthanc 1.5.4
2006 bool IndexBackend::LookupResourceAndParent(int64_t& id, 2053 bool IndexBackend::LookupResourceAndParent(int64_t& id,
2007 OrthancPluginResourceType& type, 2054 OrthancPluginResourceType& type,
2008 std::string& parentPublicId, 2055 std::string& parentPublicId,
2056 DatabaseManager& manager,
2009 const char* publicId) 2057 const char* publicId)
2010 { 2058 {
2011 DatabaseManager::CachedStatement statement( 2059 DatabaseManager::CachedStatement statement(
2012 STATEMENT_FROM_HERE, manager_, 2060 STATEMENT_FROM_HERE, manager,
2013 "SELECT resource.internalId, resource.resourceType, parent.publicId " 2061 "SELECT resource.internalId, resource.resourceType, parent.publicId "
2014 "FROM Resources AS resource LEFT JOIN Resources parent ON parent.internalId=resource.parentId " 2062 "FROM Resources AS resource LEFT JOIN Resources parent ON parent.internalId=resource.parentId "
2015 "WHERE resource.publicId=${id}"); 2063 "WHERE resource.publicId=${id}");
2016 2064
2017 statement.SetParameterType("id", ValueType_Utf8String); 2065 statement.SetParameterType("id", ValueType_Utf8String);
2065 2113
2066 #if defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE) // Macro introduced in 1.3.1 2114 #if defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE) // Macro introduced in 1.3.1
2067 # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 4) 2115 # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 4)
2068 // New primitive since Orthanc 1.5.4 2116 // New primitive since Orthanc 1.5.4
2069 void IndexBackend::GetAllMetadata(std::map<int32_t, std::string>& result, 2117 void IndexBackend::GetAllMetadata(std::map<int32_t, std::string>& result,
2118 DatabaseManager& manager,
2070 int64_t id) 2119 int64_t id)
2071 { 2120 {
2072 DatabaseManager::CachedStatement statement( 2121 DatabaseManager::CachedStatement statement(
2073 STATEMENT_FROM_HERE, manager_, 2122 STATEMENT_FROM_HERE, manager,
2074 "SELECT type, value FROM Metadata WHERE id=${id}"); 2123 "SELECT type, value FROM Metadata WHERE id=${id}");
2075 2124
2076 statement.SetReadOnly(true); 2125 statement.SetReadOnly(true);
2077 statement.SetParameterType("id", ValueType_Integer64); 2126 statement.SetParameterType("id", ValueType_Integer64);
2078 2127
2103 # endif 2152 # endif
2104 #endif 2153 #endif
2105 2154
2106 2155
2107 void IndexBackend::CreateInstanceGeneric(OrthancPluginCreateInstanceResult& result, 2156 void IndexBackend::CreateInstanceGeneric(OrthancPluginCreateInstanceResult& result,
2157 DatabaseManager& manager,
2108 const char* hashPatient, 2158 const char* hashPatient,
2109 const char* hashStudy, 2159 const char* hashStudy,
2110 const char* hashSeries, 2160 const char* hashSeries,
2111 const char* hashInstance) 2161 const char* hashInstance)
2112 { 2162 {
2114 2164
2115 { 2165 {
2116 OrthancPluginResourceType type; 2166 OrthancPluginResourceType type;
2117 int64_t tmp; 2167 int64_t tmp;
2118 2168
2119 if (LookupResource(tmp, type, hashInstance)) 2169 if (LookupResource(tmp, type, manager, hashInstance))
2120 { 2170 {
2121 // The instance already exists 2171 // The instance already exists
2122 assert(type == OrthancPluginResourceType_Instance); 2172 assert(type == OrthancPluginResourceType_Instance);
2123 result.instanceId = tmp; 2173 result.instanceId = tmp;
2124 result.isNewInstance = false; 2174 result.isNewInstance = false;
2125 return; 2175 return;
2126 } 2176 }
2127 } 2177 }
2128 2178
2129 result.instanceId = CreateResource(hashInstance, OrthancPluginResourceType_Instance); 2179 result.instanceId = CreateResource(manager, hashInstance, OrthancPluginResourceType_Instance);
2130 result.isNewInstance = true; 2180 result.isNewInstance = true;
2131 2181
2132 result.isNewPatient = false; 2182 result.isNewPatient = false;
2133 result.isNewStudy = false; 2183 result.isNewStudy = false;
2134 result.isNewSeries = false; 2184 result.isNewSeries = false;
2140 // hierarchy must be created 2190 // hierarchy must be created
2141 2191
2142 { 2192 {
2143 OrthancPluginResourceType dummy; 2193 OrthancPluginResourceType dummy;
2144 2194
2145 if (LookupResource(result.seriesId, dummy, hashSeries)) 2195 if (LookupResource(result.seriesId, dummy, manager, hashSeries))
2146 { 2196 {
2147 assert(dummy == OrthancPluginResourceType_Series); 2197 assert(dummy == OrthancPluginResourceType_Series);
2148 // The patient, the study and the series already exist 2198 // The patient, the study and the series already exist
2149 2199
2150 bool ok = (LookupResource(result.patientId, dummy, hashPatient) && 2200 bool ok = (LookupResource(result.patientId, dummy, manager, hashPatient) &&
2151 LookupResource(result.studyId, dummy, hashStudy)); 2201 LookupResource(result.studyId, dummy, manager, hashStudy));
2152 (void) ok; // Remove warning about unused variable in release builds 2202 (void) ok; // Remove warning about unused variable in release builds
2153 assert(ok); 2203 assert(ok);
2154 } 2204 }
2155 else if (LookupResource(result.studyId, dummy, hashStudy)) 2205 else if (LookupResource(result.studyId, dummy, manager, hashStudy))
2156 { 2206 {
2157 assert(dummy == OrthancPluginResourceType_Study); 2207 assert(dummy == OrthancPluginResourceType_Study);
2158 2208
2159 // New series: The patient and the study already exist 2209 // New series: The patient and the study already exist
2160 result.isNewSeries = true; 2210 result.isNewSeries = true;
2161 2211
2162 bool ok = LookupResource(result.patientId, dummy, hashPatient); 2212 bool ok = LookupResource(result.patientId, dummy, manager, hashPatient);
2163 (void) ok; // Remove warning about unused variable in release builds 2213 (void) ok; // Remove warning about unused variable in release builds
2164 assert(ok); 2214 assert(ok);
2165 } 2215 }
2166 else if (LookupResource(result.patientId, dummy, hashPatient)) 2216 else if (LookupResource(result.patientId, dummy, manager, hashPatient))
2167 { 2217 {
2168 assert(dummy == OrthancPluginResourceType_Patient); 2218 assert(dummy == OrthancPluginResourceType_Patient);
2169 2219
2170 // New study and series: The patient already exist 2220 // New study and series: The patient already exist
2171 result.isNewStudy = true; 2221 result.isNewStudy = true;
2181 } 2231 }
2182 2232
2183 // Create the series if needed 2233 // Create the series if needed
2184 if (result.isNewSeries) 2234 if (result.isNewSeries)
2185 { 2235 {
2186 result.seriesId = CreateResource(hashSeries, OrthancPluginResourceType_Series); 2236 result.seriesId = CreateResource(manager, hashSeries, OrthancPluginResourceType_Series);
2187 } 2237 }
2188 2238
2189 // Create the study if needed 2239 // Create the study if needed
2190 if (result.isNewStudy) 2240 if (result.isNewStudy)
2191 { 2241 {
2192 result.studyId = CreateResource(hashStudy, OrthancPluginResourceType_Study); 2242 result.studyId = CreateResource(manager, hashStudy, OrthancPluginResourceType_Study);
2193 } 2243 }
2194 2244
2195 // Create the patient if needed 2245 // Create the patient if needed
2196 if (result.isNewPatient) 2246 if (result.isNewPatient)
2197 { 2247 {
2198 result.patientId = CreateResource(hashPatient, OrthancPluginResourceType_Patient); 2248 result.patientId = CreateResource(manager, hashPatient, OrthancPluginResourceType_Patient);
2199 } 2249 }
2200 2250
2201 // Create the parent-to-child links 2251 // Create the parent-to-child links
2202 AttachChild(result.seriesId, result.instanceId); 2252 AttachChild(manager, result.seriesId, result.instanceId);
2203 2253
2204 if (result.isNewSeries) 2254 if (result.isNewSeries)
2205 { 2255 {
2206 AttachChild(result.studyId, result.seriesId); 2256 AttachChild(manager, result.studyId, result.seriesId);
2207 } 2257 }
2208 2258
2209 if (result.isNewStudy) 2259 if (result.isNewStudy)
2210 { 2260 {
2211 AttachChild(result.patientId, result.studyId); 2261 AttachChild(manager, result.patientId, result.studyId);
2212 } 2262 }
2213 2263
2214 TagMostRecentPatient(result.patientId); 2264 TagMostRecentPatient(manager, result.patientId);
2215 2265
2216 // Sanity checks 2266 // Sanity checks
2217 assert(result.patientId != -1); 2267 assert(result.patientId != -1);
2218 assert(result.studyId != -1); 2268 assert(result.studyId != -1);
2219 assert(result.seriesId != -1); 2269 assert(result.seriesId != -1);