comparison OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp @ 5224:feba2b0e91bc

Fix a crash in /tools/reconstruct triggered by the Housekeeper plugin when only changing the StorageCompression.
author Alain Mazy <am@osimis.io>
date Mon, 03 Apr 2023 22:19:42 +0200
parents 0ea402b4d901
children 5874e5dd9a38
comparison
equal deleted inserted replaced
5223:a47b24f231d0 5224:feba2b0e91bc
2954 std::map<MetadataType, std::string>& instanceMetadata, 2954 std::map<MetadataType, std::string>& instanceMetadata,
2955 int64_t instance, 2955 int64_t instance,
2956 MetadataType metadata, 2956 MetadataType metadata,
2957 const std::string& value) 2957 const std::string& value)
2958 { 2958 {
2959 if (metadata == 15)
2960 {
2961 LOG(INFO) << "toto";
2962 }
2959 content.AddMetadata(instance, metadata, value); 2963 content.AddMetadata(instance, metadata, value);
2960 instanceMetadata[metadata] = value; 2964 instanceMetadata[metadata] = value;
2961 } 2965 }
2962 2966
2963 static void SetMainDicomSequenceMetadata(ResourcesContent& content, 2967 static void SetMainDicomSequenceMetadata(ResourcesContent& content,
3079 { 3083 {
3080 try 3084 try
3081 { 3085 {
3082 IDatabaseWrapper::CreateInstanceResult status; 3086 IDatabaseWrapper::CreateInstanceResult status;
3083 int64_t instanceId; 3087 int64_t instanceId;
3088
3089 bool isNewInstance = transaction.CreateInstance(status, instanceId, hashPatient_,
3090 hashStudy_, hashSeries_, hashInstance_);
3091
3092 if (isReconstruct_ && isNewInstance)
3093 {
3094 // In case of reconstruct, we just want to modify the attachments and some metadata like the TransferSyntex
3095 // The DicomTags and many metadata have already been updated before we get here in ReconstructInstance
3096 throw OrthancException(ErrorCode_InternalError, "New instance while reconstructing; this should not happen.");
3097 }
3084 3098
3085 // Check whether this instance is already stored 3099 // Check whether this instance is already stored
3086 if (!transaction.CreateInstance(status, instanceId, hashPatient_, 3100 if (!isNewInstance && !isReconstruct_)
3087 hashStudy_, hashSeries_, hashInstance_))
3088 { 3101 {
3089 // The instance already exists 3102 // The instance already exists
3090
3091 if (overwrite_) 3103 if (overwrite_)
3092 { 3104 {
3093 // Overwrite the old instance 3105 // Overwrite the old instance
3094 LOG(INFO) << "Overwriting instance: " << hashInstance_; 3106 LOG(INFO) << "Overwriting instance: " << hashInstance_;
3095 transaction.DeleteResource(instanceId); 3107 transaction.DeleteResource(instanceId);
3096 3108
3097 // Re-create the instance, now that the old one is removed 3109 // Re-create the instance, now that the old one is removed
3098 if (!transaction.CreateInstance(status, instanceId, hashPatient_, 3110 if (!transaction.CreateInstance(status, instanceId, hashPatient_,
3099 hashStudy_, hashSeries_, hashInstance_)) 3111 hashStudy_, hashSeries_, hashInstance_))
3100 { 3112 {
3101 throw OrthancException(ErrorCode_InternalError); 3113 throw OrthancException(ErrorCode_InternalError, "No new instance while overwriting; this should not happen.");
3102 } 3114 }
3103 } 3115 }
3104 else 3116 else
3105 { 3117 {
3106 // Do nothing if the instance already exists and overwriting is disabled 3118 // Do nothing if the instance already exists and overwriting is disabled
3171 3183
3172 // Attach the files to the newly created instance 3184 // Attach the files to the newly created instance
3173 for (Attachments::const_iterator it = attachments_.begin(); 3185 for (Attachments::const_iterator it = attachments_.begin();
3174 it != attachments_.end(); ++it) 3186 it != attachments_.end(); ++it)
3175 { 3187 {
3188 if (isReconstruct_)
3189 {
3190 // we are replacing attachments during a reconstruction
3191 transaction.DeleteAttachment(instanceId, it->GetContentType());
3192 }
3193
3176 transaction.AddAttachment(instanceId, *it, 0 /* this is the first revision */); 3194 transaction.AddAttachment(instanceId, *it, 0 /* this is the first revision */);
3177 } 3195 }
3178 3196
3179 3197 if (!isReconstruct_)
3180 { 3198 {
3181 ResourcesContent content(true /* new resource, metadata can be set */); 3199 ResourcesContent content(true /* new resource, metadata can be set */);
3182
3183 3200
3184 // Attach the user-specified metadata (in case of reconstruction, metadata_ contains all past metadata, including the system ones we want to keep) 3201 // Attach the user-specified metadata (in case of reconstruction, metadata_ contains all past metadata, including the system ones we want to keep)
3185 for (MetadataMap::const_iterator 3202 for (MetadataMap::const_iterator
3186 it = metadata_.begin(); it != metadata_.end(); ++it) 3203 it = metadata_.begin(); it != metadata_.end(); ++it)
3187 { 3204 {
3207 default: 3224 default:
3208 throw OrthancException(ErrorCode_ParameterOutOfRange); 3225 throw OrthancException(ErrorCode_ParameterOutOfRange);
3209 } 3226 }
3210 } 3227 }
3211 3228
3212 // Populate the tags of the newly-created resources 3229 if (!isReconstruct_)
3213 3230 {
3214 content.AddResource(instanceId, ResourceType_Instance, dicomSummary_); 3231 // Populate the tags of the newly-created resources
3215 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0 3232 content.AddResource(instanceId, ResourceType_Instance, dicomSummary_);
3216 SetMainDicomSequenceMetadata(content, instanceId, dicomSummary_, ResourceType_Instance); // new in Orthanc 1.11.1 3233 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0
3217 3234 SetMainDicomSequenceMetadata(content, instanceId, dicomSummary_, ResourceType_Instance); // new in Orthanc 1.11.1
3218 if (status.isNewSeries_) 3235
3219 { 3236 if (status.isNewSeries_)
3220 content.AddResource(status.seriesId_, ResourceType_Series, dicomSummary_);
3221 content.AddMetadata(status.seriesId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0
3222 SetMainDicomSequenceMetadata(content, status.seriesId_, dicomSummary_, ResourceType_Series); // new in Orthanc 1.11.1
3223 }
3224
3225 if (status.isNewStudy_)
3226 {
3227 content.AddResource(status.studyId_, ResourceType_Study, dicomSummary_);
3228 content.AddMetadata(status.studyId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0
3229 SetMainDicomSequenceMetadata(content, status.studyId_, dicomSummary_, ResourceType_Study); // new in Orthanc 1.11.1
3230 }
3231
3232 if (status.isNewPatient_)
3233 {
3234 content.AddResource(status.patientId_, ResourceType_Patient, dicomSummary_);
3235 content.AddMetadata(status.patientId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient)); // New in Orthanc 1.11.0
3236 SetMainDicomSequenceMetadata(content, status.patientId_, dicomSummary_, ResourceType_Patient); // new in Orthanc 1.11.1
3237 }
3238
3239 // Attach the auto-computed metadata for the patient/study/series levels
3240 std::string now = SystemToolbox::GetNowIsoString(true /* use UTC time (not local time) */);
3241 content.AddMetadata(status.seriesId_, MetadataType_LastUpdate, now);
3242 content.AddMetadata(status.studyId_, MetadataType_LastUpdate, now);
3243 content.AddMetadata(status.patientId_, MetadataType_LastUpdate, now);
3244
3245 if (status.isNewSeries_)
3246 {
3247 if (hasExpectedInstances_)
3248 { 3237 {
3249 content.AddMetadata(status.seriesId_, MetadataType_Series_ExpectedNumberOfInstances, 3238 content.AddResource(status.seriesId_, ResourceType_Series, dicomSummary_);
3250 boost::lexical_cast<std::string>(expectedInstances_)); 3239 content.AddMetadata(status.seriesId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0
3240 SetMainDicomSequenceMetadata(content, status.seriesId_, dicomSummary_, ResourceType_Series); // new in Orthanc 1.11.1
3251 } 3241 }
3252 3242
3253 // New in Orthanc 1.9.0 3243 if (status.isNewStudy_)
3254 content.AddMetadata(status.seriesId_, MetadataType_RemoteAet, 3244 {
3255 origin_.GetRemoteAetC()); 3245 content.AddResource(status.studyId_, ResourceType_Study, dicomSummary_);
3256 } 3246 content.AddMetadata(status.studyId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0
3257 3247 SetMainDicomSequenceMetadata(content, status.studyId_, dicomSummary_, ResourceType_Study); // new in Orthanc 1.11.1
3258 if (hasTransferSyntax_) 3248 }
3259 { 3249
3260 // New in Orthanc 1.2.0 3250 if (status.isNewPatient_)
3261 SetInstanceMetadata(content, instanceMetadata_, instanceId, 3251 {
3262 MetadataType_Instance_TransferSyntax, 3252 content.AddResource(status.patientId_, ResourceType_Patient, dicomSummary_);
3263 GetTransferSyntaxUid(transferSyntax_)); 3253 content.AddMetadata(status.patientId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient)); // New in Orthanc 1.11.0
3264 } 3254 SetMainDicomSequenceMetadata(content, status.patientId_, dicomSummary_, ResourceType_Patient); // new in Orthanc 1.11.1
3265 3255 }
3266 if (!isReconstruct_) // don't change origin metadata 3256
3267 { 3257 // Attach the auto-computed metadata for the patient/study/series levels
3258 std::string now = SystemToolbox::GetNowIsoString(true /* use UTC time (not local time) */);
3259 content.AddMetadata(status.seriesId_, MetadataType_LastUpdate, now);
3260 content.AddMetadata(status.studyId_, MetadataType_LastUpdate, now);
3261 content.AddMetadata(status.patientId_, MetadataType_LastUpdate, now);
3262
3263 if (status.isNewSeries_)
3264 {
3265 if (hasExpectedInstances_)
3266 {
3267 content.AddMetadata(status.seriesId_, MetadataType_Series_ExpectedNumberOfInstances,
3268 boost::lexical_cast<std::string>(expectedInstances_));
3269 }
3270
3271 // New in Orthanc 1.9.0
3272 content.AddMetadata(status.seriesId_, MetadataType_RemoteAet,
3273 origin_.GetRemoteAetC());
3274 }
3268 // Attach the auto-computed metadata for the instance level, 3275 // Attach the auto-computed metadata for the instance level,
3269 // reflecting these additions into the input metadata map 3276 // reflecting these additions into the input metadata map
3270 SetInstanceMetadata(content, instanceMetadata_, instanceId, 3277 SetInstanceMetadata(content, instanceMetadata_, instanceId,
3271 MetadataType_Instance_ReceptionDate, now); 3278 MetadataType_Instance_ReceptionDate, now);
3272 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_RemoteAet, 3279 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_RemoteAet,
3294 { 3301 {
3295 // New in Orthanc 1.4.0 3302 // New in Orthanc 1.4.0
3296 SetInstanceMetadata(content, instanceMetadata_, instanceId, 3303 SetInstanceMetadata(content, instanceMetadata_, instanceId,
3297 MetadataType_Instance_HttpUsername, s); 3304 MetadataType_Instance_HttpUsername, s);
3298 } 3305 }
3306 }
3307
3308 // Following metadatas are also updated if reconstructing the instance.
3309 // They might be missing since they have been introduced along Orthanc versions.
3310
3311 if (hasTransferSyntax_)
3312 {
3313 // New in Orthanc 1.2.0
3314 SetInstanceMetadata(content, instanceMetadata_, instanceId,
3315 MetadataType_Instance_TransferSyntax,
3316 GetTransferSyntaxUid(transferSyntax_));
3299 } 3317 }
3300 3318
3301 if (hasPixelDataOffset_) 3319 if (hasPixelDataOffset_)
3302 { 3320 {
3303 // New in Orthanc 1.9.1 3321 // New in Orthanc 1.9.1