comparison OrthancServer/Sources/ServerIndex.cpp @ 4584:b25941dcdbbe db-changes

ITransactionContext to uncouple ServerIndex from database wrapper
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 09 Mar 2021 16:18:24 +0100
parents 42a846166fa3
children f0bdd99f3d81
comparison
equal deleted inserted replaced
4583:42a846166fa3 4584:b25941dcdbbe
75 pos ++; 75 pos ++;
76 } 76 }
77 } 77 }
78 78
79 79
80 class ServerIndex::Listener : public IDatabaseListener 80 class ServerIndex::Listener : public IDatabaseListener,
81 public ServerIndex::ITransactionContext
81 { 82 {
82 private: 83 private:
83 struct FileToRemove 84 struct FileToRemove
84 { 85 {
85 private: 86 private:
211 const std::string& publicId) ORTHANC_OVERRIDE 212 const std::string& publicId) ORTHANC_OVERRIDE
212 { 213 {
213 SignalChange(ServerIndexChange(ChangeType_Deleted, type, publicId)); 214 SignalChange(ServerIndexChange(ChangeType_Deleted, type, publicId));
214 } 215 }
215 216
216 void SignalChange(const ServerIndexChange& change) 217 virtual void SignalChange(const ServerIndexChange& change) ORTHANC_OVERRIDE
217 { 218 {
218 LOG(TRACE) << "Change related to resource " << change.GetPublicId() << " of type " 219 LOG(TRACE) << "Change related to resource " << change.GetPublicId() << " of type "
219 << EnumerationToString(change.GetResourceType()) << ": " 220 << EnumerationToString(change.GetResourceType()) << ": "
220 << EnumerationToString(change.GetChangeType()); 221 << EnumerationToString(change.GetChangeType());
221 222
227 { 228 {
228 context_.SignalChange(change); 229 context_.SignalChange(change);
229 } 230 }
230 } 231 }
231 232
232 void SignalAttachmentsAdded(uint64_t compressedSize) 233 virtual void SignalAttachmentsAdded(uint64_t compressedSize) ORTHANC_OVERRIDE
233 { 234 {
234 sizeOfAddedAttachments_ += compressedSize; 235 sizeOfAddedAttachments_ += compressedSize;
235 } 236 }
236 237
237 bool HasRemainingLevel() const 238 bool HasRemainingLevel() const
252 } 253 }
253 254
254 uint64_t GetSizeOfAddedAttachments() const 255 uint64_t GetSizeOfAddedAttachments() const
255 { 256 {
256 return sizeOfAddedAttachments_; 257 return sizeOfAddedAttachments_;
258 }
259
260 virtual bool LookupRemainingLevel(std::string& remainingPublicId /* out */,
261 ResourceType& remainingLevel /* out */) ORTHANC_OVERRIDE
262 {
263 if (HasRemainingLevel())
264 {
265 remainingPublicId = GetRemainingPublicId();
266 remainingLevel = GetRemainingType();
267 return true;
268 }
269 else
270 {
271 return false;
272 }
273 };
274
275 virtual void MarkAsUnstable(int64_t id,
276 Orthanc::ResourceType type,
277 const std::string& publicId) ORTHANC_OVERRIDE
278 {
279 context_.GetIndex().MarkAsUnstable(id, type, publicId);
280 }
281
282 virtual bool IsUnstableResource(int64_t id) ORTHANC_OVERRIDE
283 {
284 return context_.GetIndex().IsUnstableResource(id);
257 } 285 }
258 }; 286 };
259 287
260 288
261 class ServerIndex::Transaction 289 class ServerIndex::Transaction
508 if (changeType <= ChangeType_INTERNAL_LastLogged) 536 if (changeType <= ChangeType_INTERNAL_LastLogged)
509 { 537 {
510 db_.LogChange(internalId, change); 538 db_.LogChange(internalId, change);
511 } 539 }
512 540
513 listener_.SignalChange(change); 541 GetTransactionContext().SignalChange(change);
514 } 542 }
515 543
516 544
517 bool ServerIndex::IsUnstableResource(int64_t id) 545 bool ServerIndex::IsUnstableResource(int64_t id)
518 { 546 {
547 boost::mutex::scoped_lock lock(monitoringMutex_);
519 return unstableResources_.Contains(id); 548 return unstableResources_.Contains(id);
520 } 549 }
521 550
522 551
523 ServerIndex::ServerIndex(ServerContext& context, 552 ServerIndex::ServerIndex(ServerContext& context,
1077 * global mutex protecting the database. 1106 * global mutex protecting the database.
1078 **/ 1107 **/
1079 1108
1080 Transaction transaction(*this, TransactionType_ReadOnly); // TODO - Only if not "TransactionType_Implicit" 1109 Transaction transaction(*this, TransactionType_ReadOnly); // TODO - Only if not "TransactionType_Implicit"
1081 { 1110 {
1082 ReadOnlyTransaction t(db_); 1111 ReadOnlyTransaction t(db_, *listener_);
1083 readOperations->Apply(t); 1112 readOperations->Apply(t);
1084 } 1113 }
1085 transaction.Commit(); 1114 transaction.Commit();
1086 } 1115 }
1087 else 1116 else
1151 ResourceType level) 1180 ResourceType level)
1152 { 1181 {
1153 class Operations : public ReadOnlyOperationsT4<bool&, Json::Value&, const std::string&, ResourceType> 1182 class Operations : public ReadOnlyOperationsT4<bool&, Json::Value&, const std::string&, ResourceType>
1154 { 1183 {
1155 private: 1184 private:
1156 ServerIndex& index_; // TODO - REMOVE
1157
1158 static bool LookupStringMetadata(std::string& result, 1185 static bool LookupStringMetadata(std::string& result,
1159 const std::map<MetadataType, std::string>& metadata, 1186 const std::map<MetadataType, std::string>& metadata,
1160 MetadataType type) 1187 MetadataType type)
1161 { 1188 {
1162 std::map<MetadataType, std::string>::const_iterator found = metadata.find(type); 1189 std::map<MetadataType, std::string>::const_iterator found = metadata.find(type);
1194 } 1221 }
1195 } 1222 }
1196 1223
1197 1224
1198 public: 1225 public:
1199 explicit Operations(ServerIndex& index) :
1200 index_(index)
1201 {
1202 }
1203
1204 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 1226 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
1205 const Tuple& tuple) ORTHANC_OVERRIDE 1227 const Tuple& tuple) ORTHANC_OVERRIDE
1206 { 1228 {
1207 // Lookup for the requested resource 1229 // Lookup for the requested resource
1208 int64_t internalId; // unused 1230 int64_t internalId; // unused
1367 1389
1368 if (type == ResourceType_Patient || 1390 if (type == ResourceType_Patient ||
1369 type == ResourceType_Study || 1391 type == ResourceType_Study ||
1370 type == ResourceType_Series) 1392 type == ResourceType_Series)
1371 { 1393 {
1372 target["IsStable"] = !index_.IsUnstableResource(internalId); 1394 target["IsStable"] = !transaction.GetTransactionContext().IsUnstableResource(internalId);
1373 1395
1374 if (LookupStringMetadata(tmp, metadata, MetadataType_LastUpdate)) 1396 if (LookupStringMetadata(tmp, metadata, MetadataType_LastUpdate))
1375 { 1397 {
1376 target["LastUpdate"] = tmp; 1398 target["LastUpdate"] = tmp;
1377 } 1399 }
1381 } 1403 }
1382 } 1404 }
1383 }; 1405 };
1384 1406
1385 bool found; 1407 bool found;
1386 Operations operations(*this); 1408 Operations operations;
1387 operations.Apply(*this, found, target, publicId, level); 1409 operations.Apply(*this, found, target, publicId, level);
1388 return found; 1410 return found;
1389 } 1411 }
1390 1412
1391 1413
2409 else 2431 else
2410 { 2432 {
2411 found_ = true; 2433 found_ = true;
2412 transaction.DeleteResource(id); 2434 transaction.DeleteResource(id);
2413 2435
2414 if (transaction.GetListener().HasRemainingLevel()) 2436 std::string remainingPublicId;
2415 { 2437 ResourceType remainingLevel;
2416 ResourceType remainingType = transaction.GetListener().GetRemainingType(); 2438 if (transaction.GetTransactionContext().LookupRemainingLevel(remainingPublicId, remainingLevel))
2417 const std::string& remainingUuid = transaction.GetListener().GetRemainingPublicId(); 2439 {
2418
2419 target_["RemainingAncestor"] = Json::Value(Json::objectValue); 2440 target_["RemainingAncestor"] = Json::Value(Json::objectValue);
2420 target_["RemainingAncestor"]["Path"] = GetBasePath(remainingType, remainingUuid); 2441 target_["RemainingAncestor"]["Path"] = GetBasePath(remainingLevel, remainingPublicId);
2421 target_["RemainingAncestor"]["Type"] = EnumerationToString(remainingType); 2442 target_["RemainingAncestor"]["Type"] = EnumerationToString(remainingLevel);
2422 target_["RemainingAncestor"]["ID"] = remainingUuid; 2443 target_["RemainingAncestor"]["ID"] = remainingPublicId;
2423 } 2444 }
2424 else 2445 else
2425 { 2446 {
2426 target_["RemainingAncestor"] = Json::nullValue; 2447 target_["RemainingAncestor"] = Json::nullValue;
2427 } 2448 }
3095 class Operations : public IReadWriteOperations 3116 class Operations : public IReadWriteOperations
3096 { 3117 {
3097 private: 3118 private:
3098 StoreStatus storeStatus_; 3119 StoreStatus storeStatus_;
3099 std::map<MetadataType, std::string>& instanceMetadata_; 3120 std::map<MetadataType, std::string>& instanceMetadata_;
3100 ServerIndex& index_;
3101 const DicomMap& dicomSummary_; 3121 const DicomMap& dicomSummary_;
3102 const Attachments& attachments_; 3122 const Attachments& attachments_;
3103 const MetadataMap& metadata_; 3123 const MetadataMap& metadata_;
3104 const DicomInstanceOrigin& origin_; 3124 const DicomInstanceOrigin& origin_;
3105 bool overwrite_; 3125 bool overwrite_;
3184 return false; 3204 return false;
3185 } 3205 }
3186 3206
3187 public: 3207 public:
3188 Operations(std::map<MetadataType, std::string>& instanceMetadata, 3208 Operations(std::map<MetadataType, std::string>& instanceMetadata,
3189 ServerIndex& index,
3190 const DicomMap& dicomSummary, 3209 const DicomMap& dicomSummary,
3191 const Attachments& attachments, 3210 const Attachments& attachments,
3192 const MetadataMap& metadata, 3211 const MetadataMap& metadata,
3193 const DicomInstanceOrigin& origin, 3212 const DicomInstanceOrigin& origin,
3194 bool overwrite, 3213 bool overwrite,
3198 uint64_t pixelDataOffset, 3217 uint64_t pixelDataOffset,
3199 uint64_t maximumStorageSize, 3218 uint64_t maximumStorageSize,
3200 unsigned int maximumPatientCount) : 3219 unsigned int maximumPatientCount) :
3201 storeStatus_(StoreStatus_Failure), 3220 storeStatus_(StoreStatus_Failure),
3202 instanceMetadata_(instanceMetadata), 3221 instanceMetadata_(instanceMetadata),
3203 index_(index),
3204 dicomSummary_(dicomSummary), 3222 dicomSummary_(dicomSummary),
3205 attachments_(attachments), 3223 attachments_(attachments),
3206 metadata_(metadata), 3224 metadata_(metadata),
3207 origin_(origin), 3225 origin_(origin),
3208 overwrite_(overwrite), 3226 overwrite_(overwrite),
3475 transaction.LogChange(status.seriesId_, ChangeType_NewChildInstance, ResourceType_Series, hashSeries_); 3493 transaction.LogChange(status.seriesId_, ChangeType_NewChildInstance, ResourceType_Series, hashSeries_);
3476 transaction.LogChange(status.studyId_, ChangeType_NewChildInstance, ResourceType_Study, hashStudy_); 3494 transaction.LogChange(status.studyId_, ChangeType_NewChildInstance, ResourceType_Study, hashStudy_);
3477 transaction.LogChange(status.patientId_, ChangeType_NewChildInstance, ResourceType_Patient, hashPatient_); 3495 transaction.LogChange(status.patientId_, ChangeType_NewChildInstance, ResourceType_Patient, hashPatient_);
3478 3496
3479 // Mark the parent resources of this instance as unstable 3497 // Mark the parent resources of this instance as unstable
3480 index_.MarkAsUnstable(status.seriesId_, ResourceType_Series, hashSeries_); 3498 transaction.GetTransactionContext().MarkAsUnstable(status.seriesId_, ResourceType_Series, hashSeries_);
3481 index_.MarkAsUnstable(status.studyId_, ResourceType_Study, hashStudy_); 3499 transaction.GetTransactionContext().MarkAsUnstable(status.studyId_, ResourceType_Study, hashStudy_);
3482 index_.MarkAsUnstable(status.patientId_, ResourceType_Patient, hashPatient_); 3500 transaction.GetTransactionContext().MarkAsUnstable(status.patientId_, ResourceType_Patient, hashPatient_);
3483 3501 transaction.GetTransactionContext().SignalAttachmentsAdded(instanceSize);
3484 transaction.GetListener().SignalAttachmentsAdded(instanceSize);
3485 3502
3486 storeStatus_ = StoreStatus_Success; 3503 storeStatus_ = StoreStatus_Success;
3487 } 3504 }
3488 catch (OrthancException& e) 3505 catch (OrthancException& e)
3489 { 3506 {
3501 boost::mutex::scoped_lock lock(monitoringMutex_); 3518 boost::mutex::scoped_lock lock(monitoringMutex_);
3502 maximumStorageSize = maximumStorageSize_; 3519 maximumStorageSize = maximumStorageSize_;
3503 maximumPatients = maximumPatients_; 3520 maximumPatients = maximumPatients_;
3504 } 3521 }
3505 3522
3506 Operations operations(instanceMetadata, *this, dicomSummary, attachments, metadata, origin, 3523 Operations operations(instanceMetadata, dicomSummary, attachments, metadata, origin,
3507 overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset, 3524 overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset,
3508 pixelDataOffset, maximumStorageSize, maximumPatients); 3525 pixelDataOffset, maximumStorageSize, maximumPatients);
3509 Apply(operations); 3526 Apply(operations);
3510 return operations.GetStoreStatus(); 3527 return operations.GetStoreStatus();
3511 } 3528 }
3581 if (IsUserContentType(attachment_.GetContentType())) 3598 if (IsUserContentType(attachment_.GetContentType()))
3582 { 3599 {
3583 transaction.LogChange(resourceId, ChangeType_UpdatedAttachment, resourceType, publicId_); 3600 transaction.LogChange(resourceId, ChangeType_UpdatedAttachment, resourceType, publicId_);
3584 } 3601 }
3585 3602
3586 transaction.GetListener().SignalAttachmentsAdded(attachment_.GetCompressedSize()); 3603 transaction.GetTransactionContext().SignalAttachmentsAdded(attachment_.GetCompressedSize());
3587 3604
3588 status_ = StoreStatus_Success; 3605 status_ = StoreStatus_Success;
3589 } 3606 }
3590 } 3607 }
3591 }; 3608 };