Mercurial > hg > orthanc
changeset 4600:c02a04e6161d db-changes
processing of database events in OrthancPluginDatabaseV3
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 18 Mar 2021 12:09:29 +0100 |
parents | 3875dcb65987 |
children | 27c07dbf6b4f |
files | OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h |
diffstat | 2 files changed, 168 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp Thu Mar 18 11:26:53 2021 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp Thu Mar 18 12:09:29 2021 +0100 @@ -62,6 +62,18 @@ } + static FileInfo Convert(const OrthancPluginAttachment& attachment) + { + return FileInfo(attachment.uuid, + static_cast<FileContentType>(attachment.contentType), + attachment.uncompressedSize, + attachment.uncompressedHash, + static_cast<CompressionType>(attachment.compressionType), + attachment.compressedSize, + attachment.compressedHash); + } + + void ReadStringAnswers(std::list<std::string>& target) { uint32_t count; @@ -186,10 +198,68 @@ } + void CheckNoEvent() + { + uint32_t count; + CheckSuccess(that_.backend_.readEventsCount(transaction_, &count)); + if (count != 0) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + } + + + void ProcessEvents(bool isDeletingAttachment) + { + uint32_t count; + CheckSuccess(that_.backend_.readEventsCount(transaction_, &count)); + + for (uint32_t i = 0; i < count; i++) + { + OrthancPluginDatabaseEvent event; + CheckSuccess(that_.backend_.readEvent(transaction_, &event, i)); + + switch (event.type) + { + case OrthancPluginDatabaseEventType_DeletedAttachment: + listener_.SignalAttachmentDeleted(Convert(event.content.attachment)); + break; + + case OrthancPluginDatabaseEventType_DeletedResource: + if (isDeletingAttachment) + { + // This event should only be triggered by "DeleteResource()" + throw OrthancException(ErrorCode_DatabasePlugin); + } + else + { + listener_.SignalResourceDeleted(Plugins::Convert(event.content.resource.level), event.content.resource.publicId); + } + break; + + case OrthancPluginDatabaseEventType_RemainingAncestor: + if (isDeletingAttachment) + { + // This event should only triggered by "DeleteResource()" + throw OrthancException(ErrorCode_DatabasePlugin); + } + else + { + listener_.SignalRemainingAncestor(Plugins::Convert(event.content.resource.level), event.content.resource.publicId); + } + break; + + default: + break; // Unhandled event + } + } + } + + public: Transaction(OrthancPluginDatabaseV3& that, IDatabaseListener& listener, - _OrthancPluginDatabaseTransactionType type) : + OrthancPluginDatabaseTransactionType type) : that_(that), listener_(listener) { @@ -215,12 +285,14 @@ virtual void Rollback() ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.rollback(transaction_)); + CheckNoEvent(); } virtual void Commit(int64_t fileSizeDelta) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.commit(transaction_, fileSizeDelta)); + CheckNoEvent(); } @@ -237,18 +309,21 @@ tmp.compressedHash = attachment.GetCompressedMD5().c_str(); CheckSuccess(that_.backend_.addAttachment(transaction_, id, &tmp)); + CheckNoEvent(); } virtual void ClearChanges() ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.clearChanges(transaction_)); + CheckNoEvent(); } virtual void ClearExportedResources() ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.clearExportedResources(transaction_)); + CheckNoEvent(); } @@ -256,6 +331,7 @@ FileContentType attachment) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.deleteAttachment(transaction_, id, static_cast<int32_t>(attachment))); + ProcessEvents(true); } @@ -263,12 +339,14 @@ MetadataType type) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.deleteMetadata(transaction_, id, static_cast<int32_t>(type))); + CheckNoEvent(); } virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.deleteResource(transaction_, id)); + ProcessEvents(false); } @@ -276,6 +354,7 @@ int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getAllMetadata(transaction_, id)); + CheckNoEvent(); uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -303,6 +382,8 @@ ResourceType resourceType) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getAllPublicIds(transaction_, Plugins::Convert(resourceType))); + CheckNoEvent(); + ReadStringAnswers(target); } @@ -315,6 +396,8 @@ CheckSuccess(that_.backend_.getAllPublicIdsWithLimit( transaction_, Plugins::Convert(resourceType), static_cast<uint64_t>(since), static_cast<uint64_t>(limit))); + CheckNoEvent(); + ReadStringAnswers(target); } @@ -326,6 +409,7 @@ { uint8_t tmpDone = true; CheckSuccess(that_.backend_.getChanges(transaction_, &tmpDone, since, maxResults)); + CheckNoEvent(); done = (tmpDone != 0); @@ -344,6 +428,7 @@ int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getChildrenInternalId(transaction_, id)); + CheckNoEvent(); uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -362,6 +447,8 @@ int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getChildrenPublicId(transaction_, id)); + CheckNoEvent(); + ReadStringAnswers(target); } @@ -373,6 +460,7 @@ { uint8_t tmpDone = true; CheckSuccess(that_.backend_.getExportedResources(transaction_, &tmpDone, since, maxResults)); + CheckNoEvent(); done = (tmpDone != 0); @@ -390,6 +478,7 @@ virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getLastChange(transaction_)); + CheckNoEvent(); uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -409,6 +498,7 @@ virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getLastExportedResource(transaction_)); + CheckNoEvent(); uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -429,6 +519,7 @@ int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getMainDicomTags(transaction_, id)); + CheckNoEvent(); uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -455,6 +546,7 @@ virtual std::string GetPublicId(int64_t resourceId) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getPublicId(transaction_, resourceId)); + CheckNoEvent(); std::string s; if (ReadSingleStringAnswer(s)) @@ -472,6 +564,7 @@ { uint64_t value; CheckSuccess(that_.backend_.getResourcesCount(transaction_, &value, Plugins::Convert(resourceType))); + CheckNoEvent(); return value; } @@ -480,6 +573,7 @@ { OrthancPluginResourceType type; CheckSuccess(that_.backend_.getResourceType(transaction_, &type, resourceId)); + CheckNoEvent(); return Plugins::Convert(type); } @@ -488,6 +582,7 @@ { uint64_t s; CheckSuccess(that_.backend_.getTotalCompressedSize(transaction_, &s)); + CheckNoEvent(); return s; } @@ -496,6 +591,7 @@ { uint64_t s; CheckSuccess(that_.backend_.getTotalUncompressedSize(transaction_, &s)); + CheckNoEvent(); return s; } @@ -504,6 +600,7 @@ { uint8_t b; CheckSuccess(that_.backend_.isExistingResource(transaction_, &b, internalId)); + CheckNoEvent(); return (b != 0); } @@ -512,6 +609,7 @@ { uint8_t b; CheckSuccess(that_.backend_.isProtectedPatient(transaction_, &b, internalId)); + CheckNoEvent(); return (b != 0); } @@ -520,6 +618,7 @@ int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.listAvailableAttachments(transaction_, id)); + CheckNoEvent(); uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -540,6 +639,7 @@ CheckSuccess(that_.backend_.logChange(transaction_, static_cast<int32_t>(change.GetChangeType()), internalId, Plugins::Convert(change.GetResourceType()), change.GetDate().c_str())); + CheckNoEvent(); } @@ -553,6 +653,7 @@ resource.GetStudyInstanceUid().c_str(), resource.GetSeriesInstanceUid().c_str(), resource.GetSopInstanceUid().c_str())); + CheckNoEvent(); } @@ -561,6 +662,7 @@ FileContentType contentType) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.lookupAttachment(transaction_, id, static_cast<int32_t>(contentType))); + CheckNoEvent(); uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -573,14 +675,7 @@ { OrthancPluginAttachment tmp; CheckSuccess(that_.backend_.readAnswerAttachment(transaction_, &tmp, 0)); - - attachment = FileInfo(tmp.uuid, - static_cast<FileContentType>(tmp.contentType), - tmp.uncompressedSize, - tmp.uncompressedHash, - static_cast<CompressionType>(tmp.compressionType), - tmp.compressedSize, - tmp.compressedHash); + attachment = Convert(tmp); return true; } else @@ -594,6 +689,7 @@ GlobalProperty property) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.lookupGlobalProperty(transaction_, static_cast<int32_t>(property))); + CheckNoEvent(); return ReadSingleStringAnswer(target); } @@ -603,6 +699,7 @@ MetadataType type) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.lookupMetadata(transaction_, id, static_cast<int32_t>(type))); + CheckNoEvent(); return ReadSingleStringAnswer(target); } @@ -611,6 +708,7 @@ int64_t resourceId) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.lookupParent(transaction_, resourceId)); + CheckNoEvent(); return ReadSingleInt64Answer(parentId); } @@ -620,6 +718,7 @@ const std::string& publicId) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.lookupResource(transaction_, Plugins::Convert(type), publicId.c_str())); + CheckNoEvent(); return ReadSingleInt64Answer(id); } @@ -627,6 +726,7 @@ virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.selectPatientToRecycle(transaction_)); + CheckNoEvent(); return ReadSingleInt64Answer(internalId); } @@ -635,6 +735,7 @@ int64_t patientIdToAvoid) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.selectPatientToRecycle2(transaction_, patientIdToAvoid)); + CheckNoEvent(); return ReadSingleInt64Answer(internalId); } @@ -643,12 +744,14 @@ const std::string& value) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.setGlobalProperty(transaction_, static_cast<int32_t>(property), value.c_str())); + CheckNoEvent(); } virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.clearMainDicomTags(transaction_, id)); + CheckNoEvent(); } @@ -657,6 +760,7 @@ const std::string& value) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.setMetadata(transaction_, id, static_cast<int32_t>(type), value.c_str())); + CheckNoEvent(); } @@ -664,6 +768,7 @@ bool isProtected) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.setProtectedPatient(transaction_, internalId, (isProtected ? 1 : 0))); + CheckNoEvent(); } @@ -671,6 +776,7 @@ { uint8_t tmp; CheckSuccess(that_.backend_.isDiskSizeAbove(transaction_, &tmp, threshold)); + CheckNoEvent(); return (tmp != 0); } @@ -696,6 +802,7 @@ (lookup.empty() ? NULL : &constraints[0]), Plugins::Convert(queryLevel), limit, (instancesId == NULL ? 0 : 1))); + CheckNoEvent(); uint32_t count; CheckSuccess(that_.backend_.readAnswersCount(transaction_, &count)); @@ -746,6 +853,7 @@ CheckSuccess(that_.backend_.createInstance(transaction_, &output, patient.c_str(), study.c_str(), series.c_str(), instance.c_str())); + CheckNoEvent(); instanceId = output.instanceId; @@ -816,6 +924,7 @@ (mainDicomTags.empty() ? NULL : &mainDicomTags[0]), metadata.size(), (metadata.empty() ? NULL : &metadata[0]))); + CheckNoEvent(); } @@ -824,6 +933,7 @@ MetadataType metadata) ORTHANC_OVERRIDE { CheckSuccess(that_.backend_.getChildrenMetadata(transaction_, resourceId, static_cast<int32_t>(metadata))); + CheckNoEvent(); ReadStringAnswers(target); } @@ -832,6 +942,7 @@ { int64_t tmp; CheckSuccess(that_.backend_.getLastChangeIndex(transaction_, &tmp)); + CheckNoEvent(); return tmp; } @@ -844,6 +955,7 @@ uint8_t isExisting; OrthancPluginResourceType tmpType; CheckSuccess(that_.backend_.lookupResourceAndParent(transaction_, &isExisting, &id, &tmpType, publicId.c_str())); + CheckNoEvent(); if (isExisting) { @@ -967,10 +1079,10 @@ switch (type) { case TransactionType_ReadOnly: - return new Transaction(*this, listener, _OrthancPluginDatabaseTransactionType_ReadOnly); + return new Transaction(*this, listener, OrthancPluginDatabaseTransactionType_ReadOnly); case TransactionType_ReadWrite: - return new Transaction(*this, listener, _OrthancPluginDatabaseTransactionType_ReadWrite); + return new Transaction(*this, listener, OrthancPluginDatabaseTransactionType_ReadWrite); default: throw OrthancException(ErrorCode_InternalError); @@ -993,7 +1105,7 @@ if (backend_.upgradeDatabase != NULL) { - Transaction transaction(*this, listener, _OrthancPluginDatabaseTransactionType_ReadWrite); + Transaction transaction(*this, listener, OrthancPluginDatabaseTransactionType_ReadWrite); OrthancPluginErrorCode code = backend_.upgradeDatabase( database_, reinterpret_cast<OrthancPluginStorageArea*>(&storageArea),
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h Thu Mar 18 11:26:53 2021 +0100 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h Thu Mar 18 12:09:29 2021 +0100 @@ -982,13 +982,44 @@ /*<! @cond Doxygen_Suppress */ typedef enum { - _OrthancPluginDatabaseTransactionType_ReadOnly = 1, - _OrthancPluginDatabaseTransactionType_ReadWrite = 2, - _OrthancPluginDatabaseTransactionType_INTERNAL = 0x7fffffff - } _OrthancPluginDatabaseTransactionType; + OrthancPluginDatabaseTransactionType_ReadOnly = 1, + OrthancPluginDatabaseTransactionType_ReadWrite = 2, + OrthancPluginDatabaseTransactionType_INTERNAL = 0x7fffffff + } OrthancPluginDatabaseTransactionType; + + + typedef enum + { + OrthancPluginDatabaseEventType_DeletedAttachment = 1, + OrthancPluginDatabaseEventType_DeletedResource = 2, + OrthancPluginDatabaseEventType_RemainingAncestor = 3, + OrthancPluginDatabaseEventType_INTERNAL = 0x7fffffff + } OrthancPluginDatabaseEventType; + typedef struct { + OrthancPluginDatabaseEventType type; + + union + { + struct + { + /* For ""DeletedResource" and "RemainingAncestor" */ + OrthancPluginResourceType level; + const char* publicId; + } resource; + + /* For "DeletedAttachment" */ + OrthancPluginAttachment attachment; + + } content; + + } OrthancPluginDatabaseEvent; + + + typedef struct + { /** * Functions to read the answers inside a transaction **/ @@ -1034,7 +1065,15 @@ OrthancPluginErrorCode (*readAnswerString) (OrthancPluginDatabaseTransaction* transaction, const char** target /* out */, uint32_t index); + + OrthancPluginErrorCode (*readEventsCount) (OrthancPluginDatabaseTransaction* transaction, + uint32_t* target /* out */); + OrthancPluginErrorCode (*readEvent) (OrthancPluginDatabaseTransaction* transaction, + OrthancPluginDatabaseEvent* event /* out */, + uint32_t index); + + /** * Functions to access the global database object @@ -1056,7 +1095,7 @@ OrthancPluginErrorCode (*startTransaction) (OrthancPluginDatabaseContext* database, OrthancPluginDatabaseTransaction** target /* out */, - _OrthancPluginDatabaseTransactionType type); + OrthancPluginDatabaseTransactionType type); OrthancPluginErrorCode (*destructTransaction) (OrthancPluginDatabaseTransaction* transaction);