comparison OrthancServer/ServerIndex.cpp @ 187:8e673a65564d

refactoring of storing new instances
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 12 Nov 2012 17:29:11 +0100
parents f68c039b0571
children 090cefdab1d1
comparison
equal deleted inserted replaced
186:f68c039b0571 187:8e673a65564d
237 void ServerIndex::CreateInstance(DicomInstanceHasher& hasher, 237 void ServerIndex::CreateInstance(DicomInstanceHasher& hasher,
238 const DicomMap& dicomSummary, 238 const DicomMap& dicomSummary,
239 const std::string& fileUuid, 239 const std::string& fileUuid,
240 uint64_t fileSize, 240 uint64_t fileSize,
241 const std::string& jsonUuid, 241 const std::string& jsonUuid,
242 const std::string& distantAet) 242 const std::string& remoteAet)
243 { 243 {
244 SQLite::Statement s2(db_, SQLITE_FROM_HERE, "INSERT INTO Resources VALUES(?, ?)"); 244 SQLite::Statement s2(db_, SQLITE_FROM_HERE, "INSERT INTO Resources VALUES(?, ?)");
245 s2.BindString(0, hasher.HashInstance()); 245 s2.BindString(0, hasher.HashInstance());
246 s2.BindInt(1, ResourceType_Instance); 246 s2.BindInt(1, ResourceType_Instance);
247 s2.Run(); 247 s2.Run();
251 s.BindString(1, hasher.HashSeries()); 251 s.BindString(1, hasher.HashSeries());
252 s.BindString(2, hasher.GetInstanceUid()); 252 s.BindString(2, hasher.GetInstanceUid());
253 s.BindString(3, fileUuid); 253 s.BindString(3, fileUuid);
254 s.BindInt64(4, fileSize); 254 s.BindInt64(4, fileSize);
255 s.BindString(5, jsonUuid); 255 s.BindString(5, jsonUuid);
256 s.BindString(6, distantAet); 256 s.BindString(6, remoteAet);
257 257
258 const DicomValue* indexInSeries; 258 const DicomValue* indexInSeries;
259 if ((indexInSeries = dicomSummary.TestAndGetValue(DICOM_TAG_INSTANCE_NUMBER)) != NULL || 259 if ((indexInSeries = dicomSummary.TestAndGetValue(DICOM_TAG_INSTANCE_NUMBER)) != NULL ||
260 (indexInSeries = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGE_INDEX)) != NULL) 260 (indexInSeries = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGE_INDEX)) != NULL)
261 { 261 {
509 db_.Execute(query); 509 db_.Execute(query);
510 } 510 }
511 } 511 }
512 512
513 513
514 StoreStatus ServerIndex::Store(std::string& instanceUuid, 514 StoreStatus ServerIndex::Store2(const DicomMap& dicomSummary,
515 const DicomMap& dicomSummary, 515 const std::string& fileUuid,
516 uint64_t uncompressedFileSize,
517 const std::string& jsonUuid,
518 const std::string& remoteAet)
519 {
520 boost::mutex::scoped_lock scoped_lock(mutex_);
521
522 DicomInstanceHasher hasher(dicomSummary);
523
524 try
525 {
526 std::auto_ptr<SQLite::Transaction> t(db2_->StartTransaction());
527 t->Begin();
528
529 int64_t patient, study, series, instance;
530 ResourceType type;
531 bool isNewSeries = false;
532
533 // Do nothing if the instance already exists
534 if (db2_->FindResource(hasher.HashInstance(), patient, type))
535 {
536 assert(type == ResourceType_Patient);
537 return StoreStatus_AlreadyStored;
538 }
539
540 // Create the patient/study/series/instance hierarchy
541 instance = db2_->CreateResource(hasher.HashInstance(), ResourceType_Instance);
542
543 if (!db2_->FindResource(hasher.HashSeries(), series, type))
544 {
545 // This is a new series
546 isNewSeries = true;
547 series = db2_->CreateResource(hasher.HashSeries(), ResourceType_Series);
548 db2_->AttachChild(series, instance);
549
550 if (!db2_->FindResource(hasher.HashStudy(), study, type))
551 {
552 // This is a new study
553 study = db2_->CreateResource(hasher.HashStudy(), ResourceType_Study);
554 db2_->AttachChild(study, series);
555
556 if (!db2_->FindResource(hasher.HashPatient(), patient, type))
557 {
558 // This is a new patient
559 patient = db2_->CreateResource(hasher.HashPatient(), ResourceType_Patient);
560 db2_->AttachChild(patient, study);
561 }
562 else
563 {
564 assert(type == ResourceType_Patient);
565 }
566 }
567 else
568 {
569 assert(type == ResourceType_Study);
570 }
571 }
572 else
573 {
574 assert(type == ResourceType_Series);
575 }
576
577 // Attach the files to the newly created instance
578 db2_->AttachFile(instance, "_dicom", fileUuid, uncompressedFileSize);
579 db2_->AttachFile(instance, "_json", jsonUuid, 0); // TODO "0"
580
581 // Attach the metadata
582 db2_->SetMetadata(instance, MetadataType_Instance_ReceptionDate, Toolbox::GetNowIsoString());
583 db2_->SetMetadata(instance, MetadataType_Instance_RemoteAet, remoteAet);
584
585 const DicomValue* value;
586 if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_INSTANCE_NUMBER)) != NULL ||
587 (value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGE_INDEX)) != NULL)
588 {
589 db2_->SetMetadata(instance, MetadataType_Instance_IndexInSeries, value->AsString());
590 }
591
592 if (isNewSeries)
593 {
594 if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_SLICES)) != NULL ||
595 (value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGES_IN_ACQUISITION)) != NULL)
596 {
597 db2_->SetMetadata(series, MetadataType_Series_ExpectedNumberOfInstances, value->AsString());
598 }
599 }
600
601 t->Commit();
602 }
603 catch (OrthancException& e)
604 {
605 LOG(ERROR) << "EXCEPTION2 [" << e.What() << "]" << " " << db_.GetErrorMessage();
606 }
607
608 return StoreStatus_Failure;
609 }
610
611
612 StoreStatus ServerIndex::Store(const DicomMap& dicomSummary,
516 const std::string& fileUuid, 613 const std::string& fileUuid,
517 uint64_t uncompressedFileSize, 614 uint64_t uncompressedFileSize,
518 const std::string& jsonUuid, 615 const std::string& jsonUuid,
519 const std::string& distantAet) 616 const std::string& remoteAet)
520 { 617 {
618 Store2(dicomSummary, fileUuid, uncompressedFileSize, jsonUuid, remoteAet);
619
521 boost::mutex::scoped_lock scoped_lock(mutex_); 620 boost::mutex::scoped_lock scoped_lock(mutex_);
522 621
523 DicomInstanceHasher hasher(dicomSummary); 622 DicomInstanceHasher hasher(dicomSummary);
524 623
525 try 624 try
559 { 658 {
560 CreateSeries(hasher, dicomSummary); 659 CreateSeries(hasher, dicomSummary);
561 } 660 }
562 661
563 CreateInstance(hasher, dicomSummary, fileUuid, 662 CreateInstance(hasher, dicomSummary, fileUuid,
564 uncompressedFileSize, jsonUuid, distantAet); 663 uncompressedFileSize, jsonUuid, remoteAet);
565 664
566 t.Commit(); 665 t.Commit();
567 return StoreStatus_Success; 666 return StoreStatus_Success;
568 //t.Rollback(); 667 //t.Rollback();
569 } 668 }
574 673
575 return StoreStatus_Failure; 674 return StoreStatus_Failure;
576 } 675 }
577 676
578 677
579 StoreStatus ServerIndex::Store(std::string& instanceUuid, 678 StoreStatus ServerIndex::Store(FileStorage& storage,
580 FileStorage& storage,
581 const char* dicomFile, 679 const char* dicomFile,
582 size_t dicomSize, 680 size_t dicomSize,
583 const DicomMap& dicomSummary, 681 const DicomMap& dicomSummary,
584 const Json::Value& dicomJson, 682 const Json::Value& dicomJson,
585 const std::string& distantAet) 683 const std::string& remoteAet)
586 { 684 {
587 std::string fileUuid = storage.Create(dicomFile, dicomSize); 685 std::string fileUuid = storage.Create(dicomFile, dicomSize);
588 std::string jsonUuid = storage.Create(dicomJson.toStyledString()); 686 std::string jsonUuid = storage.Create(dicomJson.toStyledString());
589 StoreStatus status = Store(instanceUuid, dicomSummary, fileUuid, 687 StoreStatus status = Store(dicomSummary, fileUuid, dicomSize, jsonUuid, remoteAet);
590 dicomSize, jsonUuid, distantAet);
591 688
592 if (status != StoreStatus_Success) 689 if (status != StoreStatus_Success)
593 { 690 {
594 storage.Remove(fileUuid); 691 storage.Remove(fileUuid);
595 storage.Remove(jsonUuid); 692 storage.Remove(jsonUuid);
596 } 693 }
597 694
598 switch (status) 695 switch (status)
599 { 696 {
600 case StoreStatus_Success: 697 case StoreStatus_Success:
601 LOG(WARNING) << "New instance stored: " << GetTotalSize() << " bytes"; 698 LOG(WARNING) << "New instance stored";
602 break; 699 break;
603 700
604 case StoreStatus_AlreadyStored: 701 case StoreStatus_AlreadyStored:
605 LOG(WARNING) << "Already stored"; 702 LOG(WARNING) << "Already stored";
606 break; 703 break;
611 } 708 }
612 709
613 return status; 710 return status;
614 } 711 }
615 712
616 uint64_t ServerIndex::GetTotalSize() 713 uint64_t ServerIndex::GetTotalCompressedSize()
617 { 714 {
618 boost::mutex::scoped_lock scoped_lock(mutex_); 715 boost::mutex::scoped_lock scoped_lock(mutex_);
619 SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT SUM(fileSize) FROM Instances"); 716 return db2_->GetTotalCompressedSize();
620 s.Run(); 717 }
621 return s.ColumnInt64(0); 718
622 } 719 uint64_t ServerIndex::GetTotalUncompressedSize()
720 {
721 boost::mutex::scoped_lock scoped_lock(mutex_);
722 return db2_->GetTotalUncompressedSize();
723 }
724
725
623 726
624 727
625 SeriesStatus ServerIndex::GetSeriesStatus(const std::string& seriesUuid) 728 SeriesStatus ServerIndex::GetSeriesStatus(const std::string& seriesUuid)
626 { 729 {
627 SQLite::Statement s1(db_, SQLITE_FROM_HERE, "SELECT expectedNumberOfInstances FROM Series WHERE uuid=?"); 730 SQLite::Statement s1(db_, SQLITE_FROM_HERE, "SELECT expectedNumberOfInstances FROM Series WHERE uuid=?");