Mercurial > hg > orthanc
diff OrthancServer/ServerIndex.cpp @ 3080:1a75595d8e44 db-changes
started refactoring of ServerIndex::Store()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 03 Jan 2019 18:21:22 +0100 |
parents | ead8576a02ef |
children | 847a0ed92654 |
line wrap: on
line diff
--- a/OrthancServer/ServerIndex.cpp Thu Jan 03 14:03:39 2019 +0100 +++ b/OrthancServer/ServerIndex.cpp Thu Jan 03 18:21:22 2019 +0100 @@ -612,44 +612,6 @@ - int64_t ServerIndex::CreateResource(const std::string& publicId, - ResourceType type) - { - int64_t id = db_.CreateResource(publicId, type); - - ChangeType changeType; - switch (type) - { - case ResourceType_Patient: - changeType = ChangeType_NewPatient; - break; - - case ResourceType_Study: - changeType = ChangeType_NewStudy; - break; - - case ResourceType_Series: - changeType = ChangeType_NewSeries; - break; - - case ResourceType_Instance: - changeType = ChangeType_NewInstance; - break; - - default: - throw OrthancException(ErrorCode_InternalError); - } - - ServerIndexChange change(changeType, type, publicId); - db_.LogChange(id, change); - - assert(listener_.get() != NULL); - listener_->SignalChange(change); - - return id; - } - - ServerIndex::ServerIndex(ServerContext& context, IDatabaseWrapper& db, unsigned int threadSleep) : @@ -720,7 +682,19 @@ } - + void ServerIndex::SignalNewResource(ChangeType changeType, + ResourceType level, + const std::string& publicId, + int64_t internalId) + { + ServerIndexChange change(changeType, level, publicId); + db_.LogChange(internalId, change); + + assert(listener_.get() != NULL); + listener_->SignalChange(change); + } + + StoreStatus ServerIndex::Store(std::map<MetadataType, std::string>& instanceMetadata, DicomInstanceToStore& instanceToStore, const Attachments& attachments) @@ -732,33 +706,47 @@ instanceMetadata.clear(); + const std::string hashPatient = instanceToStore.GetHasher().HashPatient(); + const std::string hashStudy = instanceToStore.GetHasher().HashStudy(); + const std::string hashSeries = instanceToStore.GetHasher().HashSeries(); + const std::string hashInstance = instanceToStore.GetHasher().HashInstance(); + try { Transaction t(*this); + IDatabaseWrapper::CreateInstanceResult status; + int64_t instanceId; + // Check whether this instance is already stored + if (!db_.CreateInstance(status, instanceId, hashPatient, + hashStudy, hashSeries, hashInstance, overwrite_)) { - ResourceType type; - int64_t tmp; - if (db_.LookupResource(tmp, type, instanceToStore.GetHasher().HashInstance())) - { - assert(type == ResourceType_Instance); - - if (overwrite_) - { - // Overwrite the old instance - LOG(INFO) << "Overwriting instance: " << instanceToStore.GetHasher().HashInstance(); - db_.DeleteResource(tmp); - } - else - { - // Do nothing if the instance already exists - db_.GetAllMetadata(instanceMetadata, tmp); - return StoreStatus_AlreadyStored; - } - } + // Do nothing if the instance already exists and overwriting is disabled + db_.GetAllMetadata(instanceMetadata, instanceId); + return StoreStatus_AlreadyStored; + } + + + // Warn about the creation of new resources. The order must be from instance to patient. + SignalNewResource(ChangeType_NewInstance, ResourceType_Instance, hashInstance, instanceId); + + if (status.isNewSeries_) + { + SignalNewResource(ChangeType_NewSeries, ResourceType_Series, hashSeries, status.seriesId_); } - + + if (status.isNewStudy_) + { + SignalNewResource(ChangeType_NewStudy, ResourceType_Study, hashStudy, status.studyId_); + } + + if (status.isNewPatient_) + { + SignalNewResource(ChangeType_NewPatient, ResourceType_Patient, hashPatient, status.patientId_); + } + + // Ensure there is enough room in the storage for the new instance uint64_t instanceSize = 0; for (Attachments::const_iterator it = attachments.begin(); @@ -767,125 +755,59 @@ instanceSize += it->GetCompressedSize(); } - Recycle(instanceSize, instanceToStore.GetHasher().HashPatient()); - - // Create the instance - int64_t instance = CreateResource(instanceToStore.GetHasher().HashInstance(), ResourceType_Instance); - ServerToolbox::StoreMainDicomTags(db_, instance, ResourceType_Instance, dicomSummary); - - // Detect up to which level the patient/study/series/instance - // hierarchy must be created - int64_t patient = -1, study = -1, series = -1; - bool isNewPatient = false; - bool isNewStudy = false; - bool isNewSeries = false; - + Recycle(instanceSize, hashPatient /* don't consider the current patient for recycling */); + + + // Populate the newly-created resources + // TODO - GROUP THIS + + ServerToolbox::StoreMainDicomTags(db_, instanceId, ResourceType_Instance, dicomSummary); + + if (status.isNewSeries_) { - ResourceType dummy; - - if (db_.LookupResource(series, dummy, instanceToStore.GetHasher().HashSeries())) - { - assert(dummy == ResourceType_Series); - // The patient, the study and the series already exist - - bool ok = (db_.LookupResource(patient, dummy, instanceToStore.GetHasher().HashPatient()) && - db_.LookupResource(study, dummy, instanceToStore.GetHasher().HashStudy())); - assert(ok); - } - else if (db_.LookupResource(study, dummy, instanceToStore.GetHasher().HashStudy())) - { - assert(dummy == ResourceType_Study); - - // New series: The patient and the study already exist - isNewSeries = true; - - bool ok = db_.LookupResource(patient, dummy, instanceToStore.GetHasher().HashPatient()); - assert(ok); - } - else if (db_.LookupResource(patient, dummy, instanceToStore.GetHasher().HashPatient())) - { - assert(dummy == ResourceType_Patient); - - // New study and series: The patient already exist - isNewStudy = true; - isNewSeries = true; - } - else - { - // New patient, study and series: Nothing exists - isNewPatient = true; - isNewStudy = true; - isNewSeries = true; - } + ServerToolbox::StoreMainDicomTags(db_, status.seriesId_, ResourceType_Series, dicomSummary); + } + + if (status.isNewStudy_) + { + ServerToolbox::StoreMainDicomTags(db_, status.studyId_, ResourceType_Study, dicomSummary); } - // Create the series if needed - if (isNewSeries) - { - series = CreateResource(instanceToStore.GetHasher().HashSeries(), ResourceType_Series); - ServerToolbox::StoreMainDicomTags(db_, series, ResourceType_Series, dicomSummary); - } - - // Create the study if needed - if (isNewStudy) + if (status.isNewPatient_) { - study = CreateResource(instanceToStore.GetHasher().HashStudy(), ResourceType_Study); - ServerToolbox::StoreMainDicomTags(db_, study, ResourceType_Study, dicomSummary); - } - - // Create the patient if needed - if (isNewPatient) - { - patient = CreateResource(instanceToStore.GetHasher().HashPatient(), ResourceType_Patient); - ServerToolbox::StoreMainDicomTags(db_, patient, ResourceType_Patient, dicomSummary); + ServerToolbox::StoreMainDicomTags(db_, status.patientId_, ResourceType_Patient, dicomSummary); } - // Create the parent-to-child links - db_.AttachChild(series, instance); - - if (isNewSeries) - { - db_.AttachChild(study, series); - } - - if (isNewStudy) - { - db_.AttachChild(patient, study); - } - - // Sanity checks - assert(patient != -1); - assert(study != -1); - assert(series != -1); - assert(instance != -1); - + // Attach the files to the newly created instance for (Attachments::const_iterator it = attachments.begin(); it != attachments.end(); ++it) { - db_.AddAttachment(instance, *it); + db_.AddAttachment(instanceId, *it); } + // Attach the user-specified metadata + // TODO - GROUP THIS for (MetadataMap::const_iterator it = metadata.begin(); it != metadata.end(); ++it) { switch (it->first.first) { case ResourceType_Patient: - db_.SetMetadata(patient, it->first.second, it->second); + db_.SetMetadata(status.patientId_, it->first.second, it->second); break; case ResourceType_Study: - db_.SetMetadata(study, it->first.second, it->second); + db_.SetMetadata(status.studyId_, it->first.second, it->second); break; case ResourceType_Series: - db_.SetMetadata(series, it->first.second, it->second); + db_.SetMetadata(status.seriesId_, it->first.second, it->second); break; case ResourceType_Instance: - SetInstanceMetadata(instanceMetadata, instance, it->first.second, it->second); + SetInstanceMetadata(instanceMetadata, instanceId, it->first.second, it->second); break; default: @@ -895,16 +817,16 @@ // Attach the auto-computed metadata for the patient/study/series levels std::string now = SystemToolbox::GetNowIsoString(true /* use UTC time (not local time) */); - db_.SetMetadata(series, MetadataType_LastUpdate, now); - db_.SetMetadata(study, MetadataType_LastUpdate, now); - db_.SetMetadata(patient, MetadataType_LastUpdate, now); + db_.SetMetadata(status.seriesId_, MetadataType_LastUpdate, now); + db_.SetMetadata(status.studyId_, MetadataType_LastUpdate, now); + db_.SetMetadata(status.patientId_, MetadataType_LastUpdate, now); // Attach the auto-computed metadata for the instance level, // reflecting these additions into the input metadata map - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_ReceptionDate, now); - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_RemoteAet, + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_ReceptionDate, now); + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_RemoteAet, instanceToStore.GetOrigin().GetRemoteAetC()); - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_Origin, + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_Origin, EnumerationToString(instanceToStore.GetOrigin().GetRequestOrigin())); { @@ -913,25 +835,25 @@ if (instanceToStore.LookupTransferSyntax(s)) { // New in Orthanc 1.2.0 - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_TransferSyntax, s); + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_TransferSyntax, s); } if (instanceToStore.GetOrigin().LookupRemoteIp(s)) { // New in Orthanc 1.4.0 - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_RemoteIp, s); + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_RemoteIp, s); } if (instanceToStore.GetOrigin().LookupCalledAet(s)) { // New in Orthanc 1.4.0 - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_CalledAet, s); + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_CalledAet, s); } if (instanceToStore.GetOrigin().LookupHttpUsername(s)) { // New in Orthanc 1.4.0 - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_HttpUsername, s); + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_HttpUsername, s); } } @@ -940,7 +862,7 @@ !value->IsNull() && !value->IsBinary()) { - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_SopClassUid, value->GetContent()); + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_SopClassUid, value->GetContent()); } if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_INSTANCE_NUMBER)) != NULL || @@ -949,26 +871,26 @@ if (!value->IsNull() && !value->IsBinary()) { - SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_IndexInSeries, value->GetContent()); + SetInstanceMetadata(instanceMetadata, instanceId, MetadataType_Instance_IndexInSeries, value->GetContent()); } } // Check whether the series of this new instance is now completed - if (isNewSeries) + if (status.isNewSeries_) { - ComputeExpectedNumberOfInstances(db_, series, dicomSummary); + ComputeExpectedNumberOfInstances(db_, status.seriesId_, dicomSummary); } - SeriesStatus seriesStatus = GetSeriesStatus(series); + SeriesStatus seriesStatus = GetSeriesStatus(status.seriesId_); if (seriesStatus == SeriesStatus_Complete) { - LogChange(series, ChangeType_CompletedSeries, ResourceType_Series, instanceToStore.GetHasher().HashSeries()); + LogChange(status.seriesId_, ChangeType_CompletedSeries, ResourceType_Series, hashSeries); } // Mark the parent resources of this instance as unstable - MarkAsUnstable(series, ResourceType_Series, instanceToStore.GetHasher().HashSeries()); - MarkAsUnstable(study, ResourceType_Study, instanceToStore.GetHasher().HashStudy()); - MarkAsUnstable(patient, ResourceType_Patient, instanceToStore.GetHasher().HashPatient()); + MarkAsUnstable(status.seriesId_, ResourceType_Series, hashSeries); + MarkAsUnstable(status.studyId_, ResourceType_Study, hashStudy); + MarkAsUnstable(status.patientId_, ResourceType_Patient, hashPatient); t.Commit(instanceSize);