comparison OrthancServer/DatabaseWrapper.cpp @ 759:8cfc6119a5bd dicom-rt

integration mainline -> dicom-rt
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 16 Apr 2014 16:04:55 +0200
parents fd36c80f096f
children a811bdf8b8eb
comparison
equal deleted inserted replaced
605:b82292ba2083 759:8cfc6119a5bd
1 /** 1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store 2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2013 Medical Physics Department, CHU of Liege, 3 * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
4 * Belgium 4 * Belgium
5 * 5 *
6 * This program is free software: you can redistribute it and/or 6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as 7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, either version 3 of the 8 * published by the Free Software Foundation, either version 3 of the
60 return "SignalFileDeleted"; 60 return "SignalFileDeleted";
61 } 61 }
62 62
63 virtual unsigned int GetCardinality() const 63 virtual unsigned int GetCardinality() const
64 { 64 {
65 return 5; 65 return 7;
66 } 66 }
67 67
68 virtual void Compute(SQLite::FunctionContext& context) 68 virtual void Compute(SQLite::FunctionContext& context)
69 { 69 {
70 std::string uncompressedMD5, compressedMD5;
71
72 if (!context.IsNullValue(5))
73 {
74 uncompressedMD5 = context.GetStringValue(5);
75 }
76
77 if (!context.IsNullValue(6))
78 {
79 compressedMD5 = context.GetStringValue(6);
80 }
81
70 FileInfo info(context.GetStringValue(0), 82 FileInfo info(context.GetStringValue(0),
71 static_cast<FileContentType>(context.GetIntValue(1)), 83 static_cast<FileContentType>(context.GetIntValue(1)),
72 static_cast<uint64_t>(context.GetInt64Value(2)), 84 static_cast<uint64_t>(context.GetInt64Value(2)),
85 uncompressedMD5,
73 static_cast<CompressionType>(context.GetIntValue(3)), 86 static_cast<CompressionType>(context.GetIntValue(3)),
74 static_cast<uint64_t>(context.GetInt64Value(4))); 87 static_cast<uint64_t>(context.GetInt64Value(4)),
88 compressedMD5);
75 89
76 listener_.SignalFileDeleted(info); 90 listener_.SignalFileDeleted(info);
77 } 91 }
78 }; 92 };
79 93
83 bool hasRemainingAncestor_; 97 bool hasRemainingAncestor_;
84 std::string remainingPublicId_; 98 std::string remainingPublicId_;
85 ResourceType remainingType_; 99 ResourceType remainingType_;
86 100
87 public: 101 public:
102 SignalRemainingAncestor() :
103 hasRemainingAncestor_(false)
104 {
105 }
106
88 void Reset() 107 void Reset()
89 { 108 {
90 hasRemainingAncestor_ = false; 109 hasRemainingAncestor_ = false;
91 } 110 }
92 111
367 target = s.ColumnString(0); 386 target = s.ColumnString(0);
368 return true; 387 return true;
369 } 388 }
370 } 389 }
371 390
372 bool DatabaseWrapper::ListAvailableMetadata(std::list<MetadataType>& target, 391 void DatabaseWrapper::ListAvailableMetadata(std::list<MetadataType>& target,
373 int64_t id) 392 int64_t id)
374 { 393 {
375 target.clear(); 394 target.clear();
376 395
377 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT type FROM Metadata WHERE id=?"); 396 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT type FROM Metadata WHERE id=?");
379 398
380 while (s.Step()) 399 while (s.Step())
381 { 400 {
382 target.push_back(static_cast<MetadataType>(s.ColumnInt(0))); 401 target.push_back(static_cast<MetadataType>(s.ColumnInt(0)));
383 } 402 }
384
385 return true;
386 } 403 }
387 404
388 405
389 std::string DatabaseWrapper::GetMetadata(int64_t id, 406 std::string DatabaseWrapper::GetMetadata(int64_t id,
390 MetadataType type, 407 MetadataType type,
426 443
427 444
428 void DatabaseWrapper::AddAttachment(int64_t id, 445 void DatabaseWrapper::AddAttachment(int64_t id,
429 const FileInfo& attachment) 446 const FileInfo& attachment)
430 { 447 {
431 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO AttachedFiles VALUES(?, ?, ?, ?, ?, ?)"); 448 SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO AttachedFiles VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
432 s.BindInt64(0, id); 449 s.BindInt64(0, id);
433 s.BindInt(1, attachment.GetContentType()); 450 s.BindInt(1, attachment.GetContentType());
434 s.BindString(2, attachment.GetUuid()); 451 s.BindString(2, attachment.GetUuid());
435 s.BindInt64(3, attachment.GetCompressedSize()); 452 s.BindInt64(3, attachment.GetCompressedSize());
436 s.BindInt64(4, attachment.GetUncompressedSize()); 453 s.BindInt64(4, attachment.GetUncompressedSize());
437 s.BindInt(5, attachment.GetCompressionType()); 454 s.BindInt(5, attachment.GetCompressionType());
455 s.BindString(6, attachment.GetUncompressedMD5());
456 s.BindString(7, attachment.GetCompressedMD5());
438 s.Run(); 457 s.Run();
439 } 458 }
459
460
461 void DatabaseWrapper::DeleteAttachment(int64_t id,
462 FileContentType attachment)
463 {
464 SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM AttachedFiles WHERE id=? AND fileType=?");
465 s.BindInt64(0, id);
466 s.BindInt(1, attachment);
467 s.Run();
468 }
469
470
440 471
441 void DatabaseWrapper::ListAvailableAttachments(std::list<FileContentType>& result, 472 void DatabaseWrapper::ListAvailableAttachments(std::list<FileContentType>& result,
442 int64_t id) 473 int64_t id)
443 { 474 {
444 result.clear(); 475 result.clear();
456 bool DatabaseWrapper::LookupAttachment(FileInfo& attachment, 487 bool DatabaseWrapper::LookupAttachment(FileInfo& attachment,
457 int64_t id, 488 int64_t id,
458 FileContentType contentType) 489 FileContentType contentType)
459 { 490 {
460 SQLite::Statement s(db_, SQLITE_FROM_HERE, 491 SQLite::Statement s(db_, SQLITE_FROM_HERE,
461 "SELECT uuid, uncompressedSize, compressionType, compressedSize FROM AttachedFiles WHERE id=? AND fileType=?"); 492 "SELECT uuid, uncompressedSize, compressionType, compressedSize, uncompressedMD5, compressedMD5 FROM AttachedFiles WHERE id=? AND fileType=?");
462 s.BindInt64(0, id); 493 s.BindInt64(0, id);
463 s.BindInt(1, contentType); 494 s.BindInt(1, contentType);
464 495
465 if (!s.Step()) 496 if (!s.Step())
466 { 497 {
468 } 499 }
469 else 500 else
470 { 501 {
471 attachment = FileInfo(s.ColumnString(0), 502 attachment = FileInfo(s.ColumnString(0),
472 contentType, 503 contentType,
473 s.ColumnInt(1), 504 s.ColumnInt64(1),
505 s.ColumnString(4),
474 static_cast<CompressionType>(s.ColumnInt(2)), 506 static_cast<CompressionType>(s.ColumnInt(2)),
475 s.ColumnInt(3)); 507 s.ColumnInt64(3),
508 s.ColumnString(5));
476 return true; 509 return true;
477 } 510 }
478 } 511 }
479 512
480 void DatabaseWrapper::SetMainDicomTags(int64_t id, 513 void DatabaseWrapper::SetMainDicomTags(int64_t id,
552 585
553 result.clear(); 586 result.clear();
554 587
555 while (s.Step()) 588 while (s.Step())
556 { 589 {
557 result.push_back(s.ColumnInt(0)); 590 result.push_back(s.ColumnInt64(0));
558 } 591 }
559 } 592 }
560 593
561 594
562 void DatabaseWrapper::LogChange(ChangeType changeType, 595 void DatabaseWrapper::LogChange(ChangeType changeType,
581 Json::Value changes = Json::arrayValue; 614 Json::Value changes = Json::arrayValue;
582 int64_t last = since; 615 int64_t last = since;
583 616
584 while (changes.size() < maxResults && s.Step()) 617 while (changes.size() < maxResults && s.Step())
585 { 618 {
586 int64_t seq = s.ColumnInt(0); 619 int64_t seq = s.ColumnInt64(0);
587 ChangeType changeType = static_cast<ChangeType>(s.ColumnInt(1)); 620 ChangeType changeType = static_cast<ChangeType>(s.ColumnInt(1));
588 int64_t internalId = s.ColumnInt(2); 621 int64_t internalId = s.ColumnInt64(2);
589 ResourceType resourceType = static_cast<ResourceType>(s.ColumnInt(3)); 622 ResourceType resourceType = static_cast<ResourceType>(s.ColumnInt(3));
590 const std::string& date = s.ColumnString(4); 623 const std::string& date = s.ColumnString(4);
591 std::string publicId = GetPublicId(internalId); 624 std::string publicId = GetPublicId(internalId);
592 625
593 Json::Value item = Json::objectValue; 626 Json::Value item = Json::objectValue;
649 682
650 s.Run(); 683 s.Run();
651 } 684 }
652 685
653 686
654 void DatabaseWrapper::GetExportedResources(Json::Value& target, 687 void DatabaseWrapper::GetExportedResourcesInternal(Json::Value& target,
655 SQLite::Statement& s, 688 SQLite::Statement& s,
656 int64_t since, 689 int64_t since,
657 unsigned int maxResults) 690 unsigned int maxResults)
658 { 691 {
659 Json::Value changes = Json::arrayValue; 692 Json::Value changes = Json::arrayValue;
660 int64_t last = since; 693 int64_t last = since;
661 694
662 while (changes.size() < maxResults && s.Step()) 695 while (changes.size() < maxResults && s.Step())
663 { 696 {
664 int64_t seq = s.ColumnInt(0); 697 int64_t seq = s.ColumnInt64(0);
665 ResourceType resourceType = static_cast<ResourceType>(s.ColumnInt(1)); 698 ResourceType resourceType = static_cast<ResourceType>(s.ColumnInt(1));
666 std::string publicId = s.ColumnString(2); 699 std::string publicId = s.ColumnString(2);
667 700
668 Json::Value item = Json::objectValue; 701 Json::Value item = Json::objectValue;
669 item["Seq"] = static_cast<int>(seq); 702 item["Seq"] = static_cast<int>(seq);
711 { 744 {
712 SQLite::Statement s(db_, SQLITE_FROM_HERE, 745 SQLite::Statement s(db_, SQLITE_FROM_HERE,
713 "SELECT * FROM ExportedResources WHERE seq>? ORDER BY seq LIMIT ?"); 746 "SELECT * FROM ExportedResources WHERE seq>? ORDER BY seq LIMIT ?");
714 s.BindInt64(0, since); 747 s.BindInt64(0, since);
715 s.BindInt(1, maxResults + 1); 748 s.BindInt(1, maxResults + 1);
716 GetExportedResources(target, s, since, maxResults); 749 GetExportedResourcesInternal(target, s, since, maxResults);
717 } 750 }
718 751
719 752
720 void DatabaseWrapper::GetLastExportedResource(Json::Value& target) 753 void DatabaseWrapper::GetLastExportedResource(Json::Value& target)
721 { 754 {
722 SQLite::Statement s(db_, SQLITE_FROM_HERE, 755 SQLite::Statement s(db_, SQLITE_FROM_HERE,
723 "SELECT * FROM ExportedResources ORDER BY seq DESC LIMIT 1"); 756 "SELECT * FROM ExportedResources ORDER BY seq DESC LIMIT 1");
724 GetExportedResources(target, s, 0, 1); 757 GetExportedResourcesInternal(target, s, 0, 1);
725 } 758 }
726 759
727 760
728 761
729 762
805 std::string query; 838 std::string query;
806 EmbeddedResources::GetFileResource(query, EmbeddedResources::PREPARE_DATABASE); 839 EmbeddedResources::GetFileResource(query, EmbeddedResources::PREPARE_DATABASE);
807 db_.Execute(query); 840 db_.Execute(query);
808 } 841 }
809 842
810 // Sanity check of the version of the database 843 // Check the version of the database
811 std::string version = GetGlobalProperty(GlobalProperty_DatabaseSchemaVersion, "Unknown"); 844 std::string version = GetGlobalProperty(GlobalProperty_DatabaseSchemaVersion, "Unknown");
812 bool ok = false; 845 bool ok = false;
813 try 846 try
814 { 847 {
815 LOG(INFO) << "Version of the Orthanc database: " << version; 848 LOG(INFO) << "Version of the Orthanc database: " << version;
816 unsigned int v = boost::lexical_cast<unsigned int>(version); 849 unsigned int v = boost::lexical_cast<unsigned int>(version);
817 850
818 // This version of Orthanc is only compatible with version 3 of 851 /**
819 // the DB schema (since Orthanc 0.3.2) 852 * History of the database versions:
820 ok = (v == 3); 853 * - Version 3: from Orthanc 0.3.2 to Orthanc 0.7.2 (inclusive)
854 * - Version 4: from Orthanc 0.7.3 (inclusive)
855 **/
856
857 // This version of Orthanc is only compatible with versions 3 of 4 of the DB schema
858 ok = (v == 3 || v == 4);
859
860 if (v == 3)
861 {
862 LOG(WARNING) << "Upgrading database version from 3 to 4";
863 std::string upgrade;
864 EmbeddedResources::GetFileResource(upgrade, EmbeddedResources::UPGRADE_DATABASE_3_TO_4);
865 db_.BeginTransaction();
866 db_.Execute(upgrade);
867 db_.CommitTransaction();
868 }
821 } 869 }
822 catch (boost::bad_lexical_cast&) 870 catch (boost::bad_lexical_cast&)
823 { 871 {
824 } 872 }
825 873
826 if (!ok) 874 if (!ok)
827 { 875 {
876 LOG(ERROR) << "Incompatible version of the Orthanc database: " << version;
828 throw OrthancException(ErrorCode_IncompatibleDatabaseVersion); 877 throw OrthancException(ErrorCode_IncompatibleDatabaseVersion);
829 } 878 }
830 879
831 signalRemainingAncestor_ = new Internals::SignalRemainingAncestor; 880 signalRemainingAncestor_ = new Internals::SignalRemainingAncestor;
832 db_.Register(signalRemainingAncestor_); 881 db_.Register(signalRemainingAncestor_);