Mercurial > hg > orthanc
diff OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp @ 4591:ff8170d17d90 db-changes
moving all accesses to databases from IDatabaseWrapper to ITransaction
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 15 Mar 2021 15:30:42 +0100 |
parents | bec74e29f86b |
children | 36bbf3169a27 |
line wrap: on
line diff
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp Fri Mar 12 16:04:09 2021 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp Mon Mar 15 15:30:42 2021 +0100 @@ -41,13 +41,20 @@ #include "../../../OrthancFramework/Sources/Logging.h" #include "../../../OrthancFramework/Sources/OrthancException.h" +#include "../../Sources/Database/VoidDatabaseListener.h" #include "PluginsEnumerations.h" #include <cassert> namespace Orthanc { - class OrthancPluginDatabase::Transaction : public IDatabaseWrapper::ITransaction + class OrthancPluginDatabase::Transaction : + public IDatabaseWrapper::ITransaction, + public Compatibility::ICreateInstance, + public Compatibility::IGetChildrenMetadata, + public Compatibility::ILookupResources, + public Compatibility::ILookupResourceAndParent, + public Compatibility::ISetResourcesContent { private: OrthancPluginDatabase& that_; @@ -101,7 +108,7 @@ uint64_t newDiskSize = (that_.currentDiskSize_ + diskSizeDelta); - assert(newDiskSize == that_.GetTotalCompressedSize()); + assert(newDiskSize == GetTotalCompressedSize()); CheckSuccess(that_.backend_.commitTransaction(that_.payload_)); @@ -109,6 +116,871 @@ that_.currentDiskSize_ = newDiskSize; } } + + + // From the "ILookupResources" interface + void GetAllInternalIds(std::list<int64_t>& target, + ResourceType resourceType) ORTHANC_OVERRIDE + { + if (that_.extensions_.getAllInternalIds == NULL) + { + throw OrthancException(ErrorCode_DatabasePlugin, + "The database plugin does not implement the mandatory GetAllInternalIds() extension"); + } + + that_.ResetAnswers(); + CheckSuccess(that_.extensions_.getAllInternalIds(that_.GetContext(), that_.payload_, Plugins::Convert(resourceType))); + that_.ForwardAnswers(target); + } + + + + // From the "ILookupResources" interface + void LookupIdentifier(std::list<int64_t>& result, + ResourceType level, + const DicomTag& tag, + Compatibility::IdentifierConstraintType type, + const std::string& value) ORTHANC_OVERRIDE + { + if (that_.extensions_.lookupIdentifier3 == NULL) + { + throw OrthancException(ErrorCode_DatabasePlugin, + "The database plugin does not implement the mandatory LookupIdentifier3() extension"); + } + + OrthancPluginDicomTag tmp; + tmp.group = tag.GetGroup(); + tmp.element = tag.GetElement(); + tmp.value = value.c_str(); + + that_.ResetAnswers(); + CheckSuccess(that_.extensions_.lookupIdentifier3(that_.GetContext(), that_.payload_, Plugins::Convert(level), + &tmp, Compatibility::Convert(type))); + that_.ForwardAnswers(result); + } + + + + /** + * Implementation of "ITransaction" + **/ + + virtual void ApplyLookupResources(std::list<std::string>& resourcesId, + std::list<std::string>* instancesId, + const std::vector<DatabaseConstraint>& lookup, + ResourceType queryLevel, + size_t limit) ORTHANC_OVERRIDE + { + if (that_.extensions_.lookupResources == NULL) + { + // Fallback to compatibility mode + ILookupResources::Apply + (*this, *this, resourcesId, instancesId, lookup, queryLevel, limit); + } + else + { + std::vector<OrthancPluginDatabaseConstraint> constraints; + std::vector< std::vector<const char*> > constraintsValues; + + constraints.resize(lookup.size()); + constraintsValues.resize(lookup.size()); + + for (size_t i = 0; i < lookup.size(); i++) + { + lookup[i].EncodeForPlugins(constraints[i], constraintsValues[i]); + } + + that_.ResetAnswers(); + that_.answerMatchingResources_ = &resourcesId; + that_.answerMatchingInstances_ = instancesId; + + CheckSuccess(that_.extensions_.lookupResources(that_.GetContext(), that_.payload_, lookup.size(), + (lookup.empty() ? NULL : &constraints[0]), + Plugins::Convert(queryLevel), + limit, (instancesId == NULL ? 0 : 1))); + } + } + + + bool CreateInstance(IDatabaseWrapper::CreateInstanceResult& result, + int64_t& instanceId, + const std::string& patient, + const std::string& study, + const std::string& series, + const std::string& instance) ORTHANC_OVERRIDE + { + if (that_.extensions_.createInstance == NULL) + { + // Fallback to compatibility mode + return ICreateInstance::Apply + (*this, result, instanceId, patient, study, series, instance); + } + else + { + OrthancPluginCreateInstanceResult output; + memset(&output, 0, sizeof(output)); + + CheckSuccess(that_.extensions_.createInstance(&output, that_.payload_, patient.c_str(), + study.c_str(), series.c_str(), instance.c_str())); + + instanceId = output.instanceId; + + if (output.isNewInstance) + { + result.isNewPatient_ = output.isNewPatient; + result.isNewStudy_ = output.isNewStudy; + result.isNewSeries_ = output.isNewSeries; + result.patientId_ = output.patientId; + result.studyId_ = output.studyId; + result.seriesId_ = output.seriesId; + return true; + } + else + { + return false; + } + } + } + + + virtual int64_t CreateResource(const std::string& publicId, + ResourceType type) ORTHANC_OVERRIDE + { + int64_t id; + CheckSuccess(that_.backend_.createResource(&id, that_.payload_, publicId.c_str(), Plugins::Convert(type))); + return id; + } + + + virtual void AddAttachment(int64_t id, + const FileInfo& attachment) ORTHANC_OVERRIDE + { + OrthancPluginAttachment tmp; + tmp.uuid = attachment.GetUuid().c_str(); + tmp.contentType = static_cast<int32_t>(attachment.GetContentType()); + tmp.uncompressedSize = attachment.GetUncompressedSize(); + tmp.uncompressedHash = attachment.GetUncompressedMD5().c_str(); + tmp.compressionType = static_cast<int32_t>(attachment.GetCompressionType()); + tmp.compressedSize = attachment.GetCompressedSize(); + tmp.compressedHash = attachment.GetCompressedMD5().c_str(); + + CheckSuccess(that_.backend_.addAttachment(that_.payload_, id, &tmp)); + } + + + virtual void AttachChild(int64_t parent, + int64_t child) ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.attachChild(that_.payload_, parent, child)); + } + + + virtual void ClearChanges() ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.clearChanges(that_.payload_)); + } + + + virtual void ClearExportedResources() ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.clearExportedResources(that_.payload_)); + } + + + virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE + { + if (that_.extensions_.clearMainDicomTags == NULL) + { + throw OrthancException(ErrorCode_DatabasePlugin, + "Your custom index plugin does not implement the mandatory ClearMainDicomTags() extension"); + } + + CheckSuccess(that_.extensions_.clearMainDicomTags(that_.payload_, id)); + } + + + virtual void DeleteAttachment(int64_t id, + FileContentType attachment) ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.deleteAttachment(that_.payload_, id, static_cast<int32_t>(attachment))); + } + + + virtual void DeleteMetadata(int64_t id, + MetadataType type) ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.deleteMetadata(that_.payload_, id, static_cast<int32_t>(type))); + } + + + virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.deleteResource(that_.payload_, id)); + } + + + virtual void GetAllMetadata(std::map<MetadataType, std::string>& target, + int64_t id) ORTHANC_OVERRIDE + { + if (that_.extensions_.getAllMetadata == NULL) + { + // Fallback implementation if extension is missing + target.clear(); + + that_.ResetAnswers(); + CheckSuccess(that_.backend_.listAvailableMetadata(that_.GetContext(), that_.payload_, id)); + + if (that_.type_ != _OrthancPluginDatabaseAnswerType_None && + that_.type_ != _OrthancPluginDatabaseAnswerType_Int32) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + + target.clear(); + + if (that_.type_ == _OrthancPluginDatabaseAnswerType_Int32) + { + for (std::list<int32_t>::const_iterator + it = that_.answerInt32_.begin(); it != that_.answerInt32_.end(); ++it) + { + MetadataType type = static_cast<MetadataType>(*it); + + std::string value; + if (LookupMetadata(value, id, type)) + { + target[type] = value; + } + } + } + } + else + { + that_.ResetAnswers(); + + that_.answerMetadata_ = ⌖ + target.clear(); + + CheckSuccess(that_.extensions_.getAllMetadata(that_.GetContext(), that_.payload_, id)); + + if (that_.type_ != _OrthancPluginDatabaseAnswerType_None && + that_.type_ != _OrthancPluginDatabaseAnswerType_Metadata) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + } + } + + + virtual void GetAllPublicIds(std::list<std::string>& target, + ResourceType resourceType) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + CheckSuccess(that_.backend_.getAllPublicIds(that_.GetContext(), that_.payload_, Plugins::Convert(resourceType))); + that_.ForwardAnswers(target); + } + + + virtual void GetAllPublicIds(std::list<std::string>& target, + ResourceType resourceType, + size_t since, + size_t limit) ORTHANC_OVERRIDE + { + if (that_.extensions_.getAllPublicIdsWithLimit != NULL) + { + // This extension is available since Orthanc 0.9.4 + that_.ResetAnswers(); + CheckSuccess(that_.extensions_.getAllPublicIdsWithLimit + (that_.GetContext(), that_.payload_, Plugins::Convert(resourceType), since, limit)); + that_.ForwardAnswers(target); + } + else + { + // The extension is not available in the database plugin, use a + // fallback implementation + target.clear(); + + if (limit == 0) + { + return; + } + + std::list<std::string> tmp; + GetAllPublicIds(tmp, resourceType); + + if (tmp.size() <= since) + { + // Not enough results => empty answer + return; + } + + std::list<std::string>::iterator current = tmp.begin(); + std::advance(current, since); + + while (limit > 0 && current != tmp.end()) + { + target.push_back(*current); + --limit; + ++current; + } + } + } + + + virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/, + bool& done /*out*/, + int64_t since, + uint32_t maxResults) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + that_.answerChanges_ = ⌖ + that_.answerDone_ = &done; + done = false; + + CheckSuccess(that_.backend_.getChanges(that_.GetContext(), that_.payload_, since, maxResults)); + } + + + virtual void GetChildrenInternalId(std::list<int64_t>& target, + int64_t id) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + CheckSuccess(that_.backend_.getChildrenInternalId(that_.GetContext(), that_.payload_, id)); + that_.ForwardAnswers(target); + } + + + virtual void GetChildrenMetadata(std::list<std::string>& target, + int64_t resourceId, + MetadataType metadata) ORTHANC_OVERRIDE + { + if (that_.extensions_.getChildrenMetadata == NULL) + { + IGetChildrenMetadata::Apply(*this, target, resourceId, metadata); + } + else + { + that_.ResetAnswers(); + CheckSuccess(that_.extensions_.getChildrenMetadata + (that_.GetContext(), that_.payload_, resourceId, static_cast<int32_t>(metadata))); + that_.ForwardAnswers(target); + } + } + + + virtual void GetChildrenPublicId(std::list<std::string>& target, + int64_t id) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + CheckSuccess(that_.backend_.getChildrenPublicId(that_.GetContext(), that_.payload_, id)); + that_.ForwardAnswers(target); + } + + + virtual void GetExportedResources(std::list<ExportedResource>& target /*out*/, + bool& done /*out*/, + int64_t since, + uint32_t maxResults) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + that_.answerExportedResources_ = ⌖ + that_.answerDone_ = &done; + done = false; + + CheckSuccess(that_.backend_.getExportedResources(that_.GetContext(), that_.payload_, since, maxResults)); + } + + + virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/) ORTHANC_OVERRIDE + { + that_.answerDoneIgnored_ = false; + + that_.ResetAnswers(); + that_.answerChanges_ = ⌖ + that_.answerDone_ = &that_.answerDoneIgnored_; + + CheckSuccess(that_.backend_.getLastChange(that_.GetContext(), that_.payload_)); + } + + + int64_t GetLastChangeIndex() ORTHANC_OVERRIDE + { + if (that_.extensions_.getLastChangeIndex == NULL) + { + // This was the default behavior in Orthanc <= 1.5.1 + // https://groups.google.com/d/msg/orthanc-users/QhzB6vxYeZ0/YxabgqpfBAAJ + return 0; + } + else + { + int64_t result = 0; + CheckSuccess(that_.extensions_.getLastChangeIndex(&result, that_.payload_)); + return result; + } + } + + + virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/) ORTHANC_OVERRIDE + { + that_.answerDoneIgnored_ = false; + + that_.ResetAnswers(); + that_.answerExportedResources_ = ⌖ + that_.answerDone_ = &that_.answerDoneIgnored_; + + CheckSuccess(that_.backend_.getLastExportedResource(that_.GetContext(), that_.payload_)); + } + + + virtual void GetMainDicomTags(DicomMap& map, + int64_t id) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + that_.answerDicomMap_ = ↦ + + CheckSuccess(that_.backend_.getMainDicomTags(that_.GetContext(), that_.payload_, id)); + } + + + virtual std::string GetPublicId(int64_t resourceId) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + std::string s; + + CheckSuccess(that_.backend_.getPublicId(that_.GetContext(), that_.payload_, resourceId)); + + if (!that_.ForwardSingleAnswer(s)) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + + return s; + } + + + virtual uint64_t GetResourceCount(ResourceType resourceType) ORTHANC_OVERRIDE + { + uint64_t count; + CheckSuccess(that_.backend_.getResourceCount(&count, that_.payload_, Plugins::Convert(resourceType))); + return count; + } + + + virtual ResourceType GetResourceType(int64_t resourceId) ORTHANC_OVERRIDE + { + OrthancPluginResourceType type; + CheckSuccess(that_.backend_.getResourceType(&type, that_.payload_, resourceId)); + return Plugins::Convert(type); + } + + + virtual uint64_t GetTotalCompressedSize() ORTHANC_OVERRIDE + { + uint64_t size; + CheckSuccess(that_.backend_.getTotalCompressedSize(&size, that_.payload_)); + return size; + } + + + virtual uint64_t GetTotalUncompressedSize() ORTHANC_OVERRIDE + { + uint64_t size; + CheckSuccess(that_.backend_.getTotalUncompressedSize(&size, that_.payload_)); + return size; + } + + + virtual bool IsDiskSizeAbove(uint64_t threshold) ORTHANC_OVERRIDE + { + if (that_.fastGetTotalSize_) + { + return GetTotalCompressedSize() > threshold; + } + else + { + assert(GetTotalCompressedSize() == that_.currentDiskSize_); + return that_.currentDiskSize_ > threshold; + } + } + + + virtual bool IsExistingResource(int64_t internalId) ORTHANC_OVERRIDE + { + int32_t existing; + CheckSuccess(that_.backend_.isExistingResource(&existing, that_.payload_, internalId)); + return (existing != 0); + } + + + virtual bool IsProtectedPatient(int64_t internalId) ORTHANC_OVERRIDE + { + int32_t isProtected; + CheckSuccess(that_.backend_.isProtectedPatient(&isProtected, that_.payload_, internalId)); + return (isProtected != 0); + } + + + virtual void ListAvailableAttachments(std::set<FileContentType>& target, + int64_t id) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + + CheckSuccess(that_.backend_.listAvailableAttachments(that_.GetContext(), that_.payload_, id)); + + if (that_.type_ != _OrthancPluginDatabaseAnswerType_None && + that_.type_ != _OrthancPluginDatabaseAnswerType_Int32) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + + target.clear(); + + if (that_.type_ == _OrthancPluginDatabaseAnswerType_Int32) + { + for (std::list<int32_t>::const_iterator + it = that_.answerInt32_.begin(); it != that_.answerInt32_.end(); ++it) + { + target.insert(static_cast<FileContentType>(*it)); + } + } + } + + + virtual void LogChange(int64_t internalId, + const ServerIndexChange& change) ORTHANC_OVERRIDE + { + OrthancPluginChange tmp; + tmp.seq = change.GetSeq(); + tmp.changeType = static_cast<int32_t>(change.GetChangeType()); + tmp.resourceType = Plugins::Convert(change.GetResourceType()); + tmp.publicId = change.GetPublicId().c_str(); + tmp.date = change.GetDate().c_str(); + + CheckSuccess(that_.backend_.logChange(that_.payload_, &tmp)); + } + + + virtual void LogExportedResource(const ExportedResource& resource) ORTHANC_OVERRIDE + { + OrthancPluginExportedResource tmp; + tmp.seq = resource.GetSeq(); + tmp.resourceType = Plugins::Convert(resource.GetResourceType()); + tmp.publicId = resource.GetPublicId().c_str(); + tmp.modality = resource.GetModality().c_str(); + tmp.date = resource.GetDate().c_str(); + tmp.patientId = resource.GetPatientId().c_str(); + tmp.studyInstanceUid = resource.GetStudyInstanceUid().c_str(); + tmp.seriesInstanceUid = resource.GetSeriesInstanceUid().c_str(); + tmp.sopInstanceUid = resource.GetSopInstanceUid().c_str(); + + CheckSuccess(that_.backend_.logExportedResource(that_.payload_, &tmp)); + } + + + virtual bool LookupAttachment(FileInfo& attachment, + int64_t id, + FileContentType contentType) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + + CheckSuccess(that_.backend_.lookupAttachment + (that_.GetContext(), that_.payload_, id, static_cast<int32_t>(contentType))); + + if (that_.type_ == _OrthancPluginDatabaseAnswerType_None) + { + return false; + } + else if (that_.type_ == _OrthancPluginDatabaseAnswerType_Attachment && + that_.answerAttachments_.size() == 1) + { + attachment = that_.answerAttachments_.front(); + return true; + } + else + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + } + + + virtual bool LookupGlobalProperty(std::string& target, + GlobalProperty property) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + + CheckSuccess(that_.backend_.lookupGlobalProperty + (that_.GetContext(), that_.payload_, static_cast<int32_t>(property))); + + return that_.ForwardSingleAnswer(target); + } + + + virtual void LookupIdentifierRange(std::list<int64_t>& result, + ResourceType level, + const DicomTag& tag, + const std::string& start, + const std::string& end) ORTHANC_OVERRIDE + { + if (that_.extensions_.lookupIdentifierRange == NULL) + { + // Default implementation, for plugins using Orthanc SDK <= 1.3.2 + + LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_GreaterOrEqual, start); + + std::list<int64_t> b; + LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_SmallerOrEqual, end); + + result.splice(result.end(), b); + } + else + { + that_.ResetAnswers(); + CheckSuccess(that_.extensions_.lookupIdentifierRange(that_.GetContext(), that_.payload_, Plugins::Convert(level), + tag.GetGroup(), tag.GetElement(), + start.c_str(), end.c_str())); + that_.ForwardAnswers(result); + } + } + + + virtual bool LookupMetadata(std::string& target, + int64_t id, + MetadataType type) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + CheckSuccess(that_.backend_.lookupMetadata(that_.GetContext(), that_.payload_, id, static_cast<int32_t>(type))); + return that_.ForwardSingleAnswer(target); + } + + + virtual bool LookupParent(int64_t& parentId, + int64_t resourceId) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + CheckSuccess(that_.backend_.lookupParent(that_.GetContext(), that_.payload_, resourceId)); + return that_.ForwardSingleAnswer(parentId); + } + + + virtual bool LookupResource(int64_t& id, + ResourceType& type, + const std::string& publicId) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + + CheckSuccess(that_.backend_.lookupResource(that_.GetContext(), that_.payload_, publicId.c_str())); + + if (that_.type_ == _OrthancPluginDatabaseAnswerType_None) + { + return false; + } + else if (that_.type_ == _OrthancPluginDatabaseAnswerType_Resource && + that_.answerResources_.size() == 1) + { + id = that_.answerResources_.front().first; + type = that_.answerResources_.front().second; + return true; + } + else + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + } + + + virtual bool LookupResourceAndParent(int64_t& id, + ResourceType& type, + std::string& parentPublicId, + const std::string& publicId) ORTHANC_OVERRIDE + { + if (that_.extensions_.lookupResourceAndParent == NULL) + { + return ILookupResourceAndParent::Apply(*this, id, type, parentPublicId, publicId); + } + else + { + std::list<std::string> parent; + + uint8_t isExisting; + OrthancPluginResourceType pluginType = OrthancPluginResourceType_Patient; + + that_.ResetAnswers(); + CheckSuccess(that_.extensions_.lookupResourceAndParent + (that_.GetContext(), &isExisting, &id, &pluginType, that_.payload_, publicId.c_str())); + that_.ForwardAnswers(parent); + + if (isExisting) + { + type = Plugins::Convert(pluginType); + + if (parent.empty()) + { + if (type != ResourceType_Patient) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + } + else if (parent.size() == 1) + { + if ((type != ResourceType_Study && + type != ResourceType_Series && + type != ResourceType_Instance) || + parent.front().empty()) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + + parentPublicId = parent.front(); + } + else + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + + return true; + } + else + { + return false; + } + } + } + + + virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + CheckSuccess(that_.backend_.selectPatientToRecycle(that_.GetContext(), that_.payload_)); + return that_.ForwardSingleAnswer(internalId); + } + + + virtual bool SelectPatientToRecycle(int64_t& internalId, + int64_t patientIdToAvoid) ORTHANC_OVERRIDE + { + that_.ResetAnswers(); + CheckSuccess(that_.backend_.selectPatientToRecycle2(that_.GetContext(), that_.payload_, patientIdToAvoid)); + return that_.ForwardSingleAnswer(internalId); + } + + + virtual void SetGlobalProperty(GlobalProperty property, + const std::string& value) ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.setGlobalProperty + (that_.payload_, static_cast<int32_t>(property), value.c_str())); + } + + + virtual void SetIdentifierTag(int64_t id, + const DicomTag& tag, + const std::string& value) ORTHANC_OVERRIDE + { + OrthancPluginDicomTag tmp; + tmp.group = tag.GetGroup(); + tmp.element = tag.GetElement(); + tmp.value = value.c_str(); + + CheckSuccess(that_.backend_.setIdentifierTag(that_.payload_, id, &tmp)); + } + + + virtual void SetMainDicomTag(int64_t id, + const DicomTag& tag, + const std::string& value) ORTHANC_OVERRIDE + { + OrthancPluginDicomTag tmp; + tmp.group = tag.GetGroup(); + tmp.element = tag.GetElement(); + tmp.value = value.c_str(); + + CheckSuccess(that_.backend_.setMainDicomTag(that_.payload_, id, &tmp)); + } + + + virtual void SetMetadata(int64_t id, + MetadataType type, + const std::string& value) ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.setMetadata + (that_.payload_, id, static_cast<int32_t>(type), value.c_str())); + } + + + virtual void SetProtectedPatient(int64_t internalId, + bool isProtected) ORTHANC_OVERRIDE + { + CheckSuccess(that_.backend_.setProtectedPatient(that_.payload_, internalId, isProtected)); + } + + + virtual void SetResourcesContent(const Orthanc::ResourcesContent& content) ORTHANC_OVERRIDE + { + if (that_.extensions_.setResourcesContent == NULL) + { + ISetResourcesContent::Apply(*this, content); + } + else + { + std::vector<OrthancPluginResourcesContentTags> identifierTags; + std::vector<OrthancPluginResourcesContentTags> mainDicomTags; + std::vector<OrthancPluginResourcesContentMetadata> metadata; + + identifierTags.reserve(content.GetListTags().size()); + mainDicomTags.reserve(content.GetListTags().size()); + metadata.reserve(content.GetListMetadata().size()); + + for (ResourcesContent::ListTags::const_iterator + it = content.GetListTags().begin(); it != content.GetListTags().end(); ++it) + { + OrthancPluginResourcesContentTags tmp; + tmp.resource = it->resourceId_; + tmp.group = it->tag_.GetGroup(); + tmp.element = it->tag_.GetElement(); + tmp.value = it->value_.c_str(); + + if (it->isIdentifier_) + { + identifierTags.push_back(tmp); + } + else + { + mainDicomTags.push_back(tmp); + } + } + + for (ResourcesContent::ListMetadata::const_iterator + it = content.GetListMetadata().begin(); it != content.GetListMetadata().end(); ++it) + { + OrthancPluginResourcesContentMetadata tmp; + tmp.resource = it->resourceId_; + tmp.metadata = it->metadata_; + tmp.value = it->value_.c_str(); + metadata.push_back(tmp); + } + + assert(identifierTags.size() + mainDicomTags.size() == content.GetListTags().size() && + metadata.size() == content.GetListMetadata().size()); + + CheckSuccess(that_.extensions_.setResourcesContent( + that_.payload_, + identifierTags.size(), + (identifierTags.empty() ? NULL : &identifierTags[0]), + mainDicomTags.size(), + (mainDicomTags.empty() ? NULL : &mainDicomTags[0]), + metadata.size(), + (metadata.empty() ? NULL : &metadata[0]))); + } + } + + + virtual void TagMostRecentPatient(int64_t patient) ORTHANC_OVERRIDE + { + if (that_.extensions_.tagMostRecentPatient != NULL) + { + CheckSuccess(that_.extensions_.tagMostRecentPatient(that_.payload_, patient)); + } + } + }; @@ -319,36 +1191,11 @@ } - namespace - { - class VoidListener : public IDatabaseListener - { - public: - virtual void SignalRemainingAncestor(ResourceType parentType, - const std::string& publicId) - { - throw OrthancException(ErrorCode_InternalError); // Should be read-only transaction - } - - virtual void SignalAttachmentDeleted(const FileInfo& info) - { - throw OrthancException(ErrorCode_InternalError); // Should be read-only transaction - } - - virtual void SignalResourceDeleted(ResourceType type, - const std::string& publicId) - { - throw OrthancException(ErrorCode_InternalError); // Should be read-only transaction - } - }; - } - - void OrthancPluginDatabase::Open() { CheckSuccess(backend_.open(payload_)); - VoidListener listener; + VoidDatabaseListener listener; { Transaction transaction(*this, listener); @@ -356,7 +1203,7 @@ std::string tmp; fastGetTotalSize_ = - (LookupGlobalProperty(tmp, GlobalProperty_GetTotalSizeIsFast) && + (transaction.LookupGlobalProperty(tmp, GlobalProperty_GetTotalSizeIsFast) && tmp == "1"); if (fastGetTotalSize_) @@ -367,7 +1214,7 @@ { // This is the case of database plugins using Orthanc SDK <= 1.5.2 LOG(WARNING) << "Your database index plugin is not compatible with multiple Orthanc writers"; - currentDiskSize_ = GetTotalCompressedSize(); + currentDiskSize_ = transaction.GetTotalCompressedSize(); } transaction.Commit(0); @@ -375,556 +1222,6 @@ } - void OrthancPluginDatabase::AddAttachment(int64_t id, - const FileInfo& attachment) - { - OrthancPluginAttachment tmp; - tmp.uuid = attachment.GetUuid().c_str(); - tmp.contentType = static_cast<int32_t>(attachment.GetContentType()); - tmp.uncompressedSize = attachment.GetUncompressedSize(); - tmp.uncompressedHash = attachment.GetUncompressedMD5().c_str(); - tmp.compressionType = static_cast<int32_t>(attachment.GetCompressionType()); - tmp.compressedSize = attachment.GetCompressedSize(); - tmp.compressedHash = attachment.GetCompressedMD5().c_str(); - - CheckSuccess(backend_.addAttachment(payload_, id, &tmp)); - } - - - void OrthancPluginDatabase::AttachChild(int64_t parent, - int64_t child) - { - CheckSuccess(backend_.attachChild(payload_, parent, child)); - } - - - void OrthancPluginDatabase::ClearChanges() - { - CheckSuccess(backend_.clearChanges(payload_)); - } - - - void OrthancPluginDatabase::ClearExportedResources() - { - CheckSuccess(backend_.clearExportedResources(payload_)); - } - - - int64_t OrthancPluginDatabase::CreateResource(const std::string& publicId, - ResourceType type) - { - int64_t id; - CheckSuccess(backend_.createResource(&id, payload_, publicId.c_str(), Plugins::Convert(type))); - return id; - } - - - void OrthancPluginDatabase::DeleteAttachment(int64_t id, - FileContentType attachment) - { - CheckSuccess(backend_.deleteAttachment(payload_, id, static_cast<int32_t>(attachment))); - } - - - void OrthancPluginDatabase::DeleteMetadata(int64_t id, - MetadataType type) - { - CheckSuccess(backend_.deleteMetadata(payload_, id, static_cast<int32_t>(type))); - } - - - void OrthancPluginDatabase::DeleteResource(int64_t id) - { - CheckSuccess(backend_.deleteResource(payload_, id)); - } - - - void OrthancPluginDatabase::GetAllMetadata(std::map<MetadataType, std::string>& target, - int64_t id) - { - if (extensions_.getAllMetadata == NULL) - { - // Fallback implementation if extension is missing - target.clear(); - - ResetAnswers(); - CheckSuccess(backend_.listAvailableMetadata(GetContext(), payload_, id)); - - if (type_ != _OrthancPluginDatabaseAnswerType_None && - type_ != _OrthancPluginDatabaseAnswerType_Int32) - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - - target.clear(); - - if (type_ == _OrthancPluginDatabaseAnswerType_Int32) - { - for (std::list<int32_t>::const_iterator - it = answerInt32_.begin(); it != answerInt32_.end(); ++it) - { - MetadataType type = static_cast<MetadataType>(*it); - - std::string value; - if (LookupMetadata(value, id, type)) - { - target[type] = value; - } - } - } - } - else - { - ResetAnswers(); - - answerMetadata_ = ⌖ - target.clear(); - - CheckSuccess(extensions_.getAllMetadata(GetContext(), payload_, id)); - - if (type_ != _OrthancPluginDatabaseAnswerType_None && - type_ != _OrthancPluginDatabaseAnswerType_Metadata) - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - } - } - - - void OrthancPluginDatabase::GetAllInternalIds(std::list<int64_t>& target, - ResourceType resourceType) - { - if (extensions_.getAllInternalIds == NULL) - { - throw OrthancException(ErrorCode_DatabasePlugin, - "The database plugin does not implement the mandatory GetAllInternalIds() extension"); - } - - ResetAnswers(); - CheckSuccess(extensions_.getAllInternalIds(GetContext(), payload_, Plugins::Convert(resourceType))); - ForwardAnswers(target); - } - - - void OrthancPluginDatabase::GetAllPublicIds(std::list<std::string>& target, - ResourceType resourceType) - { - ResetAnswers(); - CheckSuccess(backend_.getAllPublicIds(GetContext(), payload_, Plugins::Convert(resourceType))); - ForwardAnswers(target); - } - - - void OrthancPluginDatabase::GetAllPublicIds(std::list<std::string>& target, - ResourceType resourceType, - size_t since, - size_t limit) - { - if (extensions_.getAllPublicIdsWithLimit != NULL) - { - // This extension is available since Orthanc 0.9.4 - ResetAnswers(); - CheckSuccess(extensions_.getAllPublicIdsWithLimit - (GetContext(), payload_, Plugins::Convert(resourceType), since, limit)); - ForwardAnswers(target); - } - else - { - // The extension is not available in the database plugin, use a - // fallback implementation - target.clear(); - - if (limit == 0) - { - return; - } - - std::list<std::string> tmp; - GetAllPublicIds(tmp, resourceType); - - if (tmp.size() <= since) - { - // Not enough results => empty answer - return; - } - - std::list<std::string>::iterator current = tmp.begin(); - std::advance(current, since); - - while (limit > 0 && current != tmp.end()) - { - target.push_back(*current); - --limit; - ++current; - } - } - } - - - - void OrthancPluginDatabase::GetChanges(std::list<ServerIndexChange>& target /*out*/, - bool& done /*out*/, - int64_t since, - uint32_t maxResults) - { - ResetAnswers(); - answerChanges_ = ⌖ - answerDone_ = &done; - done = false; - - CheckSuccess(backend_.getChanges(GetContext(), payload_, since, maxResults)); - } - - - void OrthancPluginDatabase::GetChildrenInternalId(std::list<int64_t>& target, - int64_t id) - { - ResetAnswers(); - CheckSuccess(backend_.getChildrenInternalId(GetContext(), payload_, id)); - ForwardAnswers(target); - } - - - void OrthancPluginDatabase::GetChildrenPublicId(std::list<std::string>& target, - int64_t id) - { - ResetAnswers(); - CheckSuccess(backend_.getChildrenPublicId(GetContext(), payload_, id)); - ForwardAnswers(target); - } - - - void OrthancPluginDatabase::GetExportedResources(std::list<ExportedResource>& target /*out*/, - bool& done /*out*/, - int64_t since, - uint32_t maxResults) - { - ResetAnswers(); - answerExportedResources_ = ⌖ - answerDone_ = &done; - done = false; - - CheckSuccess(backend_.getExportedResources(GetContext(), payload_, since, maxResults)); - } - - - void OrthancPluginDatabase::GetLastChange(std::list<ServerIndexChange>& target /*out*/) - { - answerDoneIgnored_ = false; - - ResetAnswers(); - answerChanges_ = ⌖ - answerDone_ = &answerDoneIgnored_; - - CheckSuccess(backend_.getLastChange(GetContext(), payload_)); - } - - - void OrthancPluginDatabase::GetLastExportedResource(std::list<ExportedResource>& target /*out*/) - { - answerDoneIgnored_ = false; - - ResetAnswers(); - answerExportedResources_ = ⌖ - answerDone_ = &answerDoneIgnored_; - - CheckSuccess(backend_.getLastExportedResource(GetContext(), payload_)); - } - - - void OrthancPluginDatabase::GetMainDicomTags(DicomMap& map, - int64_t id) - { - ResetAnswers(); - answerDicomMap_ = ↦ - - CheckSuccess(backend_.getMainDicomTags(GetContext(), payload_, id)); - } - - - std::string OrthancPluginDatabase::GetPublicId(int64_t resourceId) - { - ResetAnswers(); - std::string s; - - CheckSuccess(backend_.getPublicId(GetContext(), payload_, resourceId)); - - if (!ForwardSingleAnswer(s)) - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - - return s; - } - - - uint64_t OrthancPluginDatabase::GetResourceCount(ResourceType resourceType) - { - uint64_t count; - CheckSuccess(backend_.getResourceCount(&count, payload_, Plugins::Convert(resourceType))); - return count; - } - - - ResourceType OrthancPluginDatabase::GetResourceType(int64_t resourceId) - { - OrthancPluginResourceType type; - CheckSuccess(backend_.getResourceType(&type, payload_, resourceId)); - return Plugins::Convert(type); - } - - - uint64_t OrthancPluginDatabase::GetTotalCompressedSize() - { - uint64_t size; - CheckSuccess(backend_.getTotalCompressedSize(&size, payload_)); - return size; - } - - - uint64_t OrthancPluginDatabase::GetTotalUncompressedSize() - { - uint64_t size; - CheckSuccess(backend_.getTotalUncompressedSize(&size, payload_)); - return size; - } - - - bool OrthancPluginDatabase::IsExistingResource(int64_t internalId) - { - int32_t existing; - CheckSuccess(backend_.isExistingResource(&existing, payload_, internalId)); - return (existing != 0); - } - - - bool OrthancPluginDatabase::IsProtectedPatient(int64_t internalId) - { - int32_t isProtected; - CheckSuccess(backend_.isProtectedPatient(&isProtected, payload_, internalId)); - return (isProtected != 0); - } - - - void OrthancPluginDatabase::ListAvailableAttachments(std::set<FileContentType>& target, - int64_t id) - { - ResetAnswers(); - - CheckSuccess(backend_.listAvailableAttachments(GetContext(), payload_, id)); - - if (type_ != _OrthancPluginDatabaseAnswerType_None && - type_ != _OrthancPluginDatabaseAnswerType_Int32) - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - - target.clear(); - - if (type_ == _OrthancPluginDatabaseAnswerType_Int32) - { - for (std::list<int32_t>::const_iterator - it = answerInt32_.begin(); it != answerInt32_.end(); ++it) - { - target.insert(static_cast<FileContentType>(*it)); - } - } - } - - - void OrthancPluginDatabase::LogChange(int64_t internalId, - const ServerIndexChange& change) - { - OrthancPluginChange tmp; - tmp.seq = change.GetSeq(); - tmp.changeType = static_cast<int32_t>(change.GetChangeType()); - tmp.resourceType = Plugins::Convert(change.GetResourceType()); - tmp.publicId = change.GetPublicId().c_str(); - tmp.date = change.GetDate().c_str(); - - CheckSuccess(backend_.logChange(payload_, &tmp)); - } - - - void OrthancPluginDatabase::LogExportedResource(const ExportedResource& resource) - { - OrthancPluginExportedResource tmp; - tmp.seq = resource.GetSeq(); - tmp.resourceType = Plugins::Convert(resource.GetResourceType()); - tmp.publicId = resource.GetPublicId().c_str(); - tmp.modality = resource.GetModality().c_str(); - tmp.date = resource.GetDate().c_str(); - tmp.patientId = resource.GetPatientId().c_str(); - tmp.studyInstanceUid = resource.GetStudyInstanceUid().c_str(); - tmp.seriesInstanceUid = resource.GetSeriesInstanceUid().c_str(); - tmp.sopInstanceUid = resource.GetSopInstanceUid().c_str(); - - CheckSuccess(backend_.logExportedResource(payload_, &tmp)); - } - - - bool OrthancPluginDatabase::LookupAttachment(FileInfo& attachment, - int64_t id, - FileContentType contentType) - { - ResetAnswers(); - - CheckSuccess(backend_.lookupAttachment - (GetContext(), payload_, id, static_cast<int32_t>(contentType))); - - if (type_ == _OrthancPluginDatabaseAnswerType_None) - { - return false; - } - else if (type_ == _OrthancPluginDatabaseAnswerType_Attachment && - answerAttachments_.size() == 1) - { - attachment = answerAttachments_.front(); - return true; - } - else - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - } - - - bool OrthancPluginDatabase::LookupGlobalProperty(std::string& target, - GlobalProperty property) - { - ResetAnswers(); - - CheckSuccess(backend_.lookupGlobalProperty - (GetContext(), payload_, static_cast<int32_t>(property))); - - return ForwardSingleAnswer(target); - } - - - bool OrthancPluginDatabase::LookupMetadata(std::string& target, - int64_t id, - MetadataType type) - { - ResetAnswers(); - CheckSuccess(backend_.lookupMetadata(GetContext(), payload_, id, static_cast<int32_t>(type))); - return ForwardSingleAnswer(target); - } - - - bool OrthancPluginDatabase::LookupParent(int64_t& parentId, - int64_t resourceId) - { - ResetAnswers(); - CheckSuccess(backend_.lookupParent(GetContext(), payload_, resourceId)); - return ForwardSingleAnswer(parentId); - } - - - bool OrthancPluginDatabase::LookupResource(int64_t& id, - ResourceType& type, - const std::string& publicId) - { - ResetAnswers(); - - CheckSuccess(backend_.lookupResource(GetContext(), payload_, publicId.c_str())); - - if (type_ == _OrthancPluginDatabaseAnswerType_None) - { - return false; - } - else if (type_ == _OrthancPluginDatabaseAnswerType_Resource && - answerResources_.size() == 1) - { - id = answerResources_.front().first; - type = answerResources_.front().second; - return true; - } - else - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - } - - - bool OrthancPluginDatabase::SelectPatientToRecycle(int64_t& internalId) - { - ResetAnswers(); - CheckSuccess(backend_.selectPatientToRecycle(GetContext(), payload_)); - return ForwardSingleAnswer(internalId); - } - - - bool OrthancPluginDatabase::SelectPatientToRecycle(int64_t& internalId, - int64_t patientIdToAvoid) - { - ResetAnswers(); - CheckSuccess(backend_.selectPatientToRecycle2(GetContext(), payload_, patientIdToAvoid)); - return ForwardSingleAnswer(internalId); - } - - - void OrthancPluginDatabase::SetGlobalProperty(GlobalProperty property, - const std::string& value) - { - CheckSuccess(backend_.setGlobalProperty - (payload_, static_cast<int32_t>(property), value.c_str())); - } - - - void OrthancPluginDatabase::ClearMainDicomTags(int64_t id) - { - if (extensions_.clearMainDicomTags == NULL) - { - throw OrthancException(ErrorCode_DatabasePlugin, - "Your custom index plugin does not implement the mandatory ClearMainDicomTags() extension"); - } - - CheckSuccess(extensions_.clearMainDicomTags(payload_, id)); - } - - - void OrthancPluginDatabase::SetMainDicomTag(int64_t id, - const DicomTag& tag, - const std::string& value) - { - OrthancPluginDicomTag tmp; - tmp.group = tag.GetGroup(); - tmp.element = tag.GetElement(); - tmp.value = value.c_str(); - - CheckSuccess(backend_.setMainDicomTag(payload_, id, &tmp)); - } - - - void OrthancPluginDatabase::SetIdentifierTag(int64_t id, - const DicomTag& tag, - const std::string& value) - { - OrthancPluginDicomTag tmp; - tmp.group = tag.GetGroup(); - tmp.element = tag.GetElement(); - tmp.value = value.c_str(); - - CheckSuccess(backend_.setIdentifierTag(payload_, id, &tmp)); - } - - - void OrthancPluginDatabase::SetMetadata(int64_t id, - MetadataType type, - const std::string& value) - { - CheckSuccess(backend_.setMetadata - (payload_, id, static_cast<int32_t>(type), value.c_str())); - } - - - void OrthancPluginDatabase::SetProtectedPatient(int64_t internalId, - bool isProtected) - { - CheckSuccess(backend_.setProtectedPatient(payload_, internalId, isProtected)); - } - - IDatabaseWrapper::ITransaction* OrthancPluginDatabase::StartTransaction(TransactionType type, IDatabaseListener& listener) { @@ -990,7 +1287,7 @@ void OrthancPluginDatabase::Upgrade(unsigned int targetVersion, IStorageArea& storageArea) { - VoidListener listener; + VoidDatabaseListener listener; if (extensions_.upgradeDatabase != NULL) { @@ -1267,313 +1564,4 @@ boost::lexical_cast<std::string>(answer.type)); } } - - - bool OrthancPluginDatabase::IsDiskSizeAbove(uint64_t threshold) - { - if (fastGetTotalSize_) - { - return GetTotalCompressedSize() > threshold; - } - else - { - assert(GetTotalCompressedSize() == currentDiskSize_); - return currentDiskSize_ > threshold; - } - } - - - void OrthancPluginDatabase::ApplyLookupResources(std::list<std::string>& resourcesId, - std::list<std::string>* instancesId, - const std::vector<DatabaseConstraint>& lookup, - ResourceType queryLevel, - size_t limit) - { - if (extensions_.lookupResources == NULL) - { - // Fallback to compatibility mode - ILookupResources::Apply - (*this, *this, resourcesId, instancesId, lookup, queryLevel, limit); - } - else - { - std::vector<OrthancPluginDatabaseConstraint> constraints; - std::vector< std::vector<const char*> > constraintsValues; - - constraints.resize(lookup.size()); - constraintsValues.resize(lookup.size()); - - for (size_t i = 0; i < lookup.size(); i++) - { - lookup[i].EncodeForPlugins(constraints[i], constraintsValues[i]); - } - - ResetAnswers(); - answerMatchingResources_ = &resourcesId; - answerMatchingInstances_ = instancesId; - - CheckSuccess(extensions_.lookupResources(GetContext(), payload_, lookup.size(), - (lookup.empty() ? NULL : &constraints[0]), - Plugins::Convert(queryLevel), - limit, (instancesId == NULL ? 0 : 1))); - } - } - - - bool OrthancPluginDatabase::CreateInstance( - IDatabaseWrapper::CreateInstanceResult& result, - int64_t& instanceId, - const std::string& patient, - const std::string& study, - const std::string& series, - const std::string& instance) - { - if (extensions_.createInstance == NULL) - { - // Fallback to compatibility mode - return ICreateInstance::Apply - (*this, result, instanceId, patient, study, series, instance); - } - else - { - OrthancPluginCreateInstanceResult output; - memset(&output, 0, sizeof(output)); - - CheckSuccess(extensions_.createInstance(&output, payload_, patient.c_str(), - study.c_str(), series.c_str(), instance.c_str())); - - instanceId = output.instanceId; - - if (output.isNewInstance) - { - result.isNewPatient_ = output.isNewPatient; - result.isNewStudy_ = output.isNewStudy; - result.isNewSeries_ = output.isNewSeries; - result.patientId_ = output.patientId; - result.studyId_ = output.studyId; - result.seriesId_ = output.seriesId; - return true; - } - else - { - return false; - } - } - } - - - void OrthancPluginDatabase::LookupIdentifier(std::list<int64_t>& result, - ResourceType level, - const DicomTag& tag, - Compatibility::IdentifierConstraintType type, - const std::string& value) - { - if (extensions_.lookupIdentifier3 == NULL) - { - throw OrthancException(ErrorCode_DatabasePlugin, - "The database plugin does not implement the mandatory LookupIdentifier3() extension"); - } - - OrthancPluginDicomTag tmp; - tmp.group = tag.GetGroup(); - tmp.element = tag.GetElement(); - tmp.value = value.c_str(); - - ResetAnswers(); - CheckSuccess(extensions_.lookupIdentifier3(GetContext(), payload_, Plugins::Convert(level), - &tmp, Compatibility::Convert(type))); - ForwardAnswers(result); - } - - - void OrthancPluginDatabase::LookupIdentifierRange(std::list<int64_t>& result, - ResourceType level, - const DicomTag& tag, - const std::string& start, - const std::string& end) - { - if (extensions_.lookupIdentifierRange == NULL) - { - // Default implementation, for plugins using Orthanc SDK <= 1.3.2 - - LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_GreaterOrEqual, start); - - std::list<int64_t> b; - LookupIdentifier(result, level, tag, Compatibility::IdentifierConstraintType_SmallerOrEqual, end); - - result.splice(result.end(), b); - } - else - { - ResetAnswers(); - CheckSuccess(extensions_.lookupIdentifierRange(GetContext(), payload_, Plugins::Convert(level), - tag.GetGroup(), tag.GetElement(), - start.c_str(), end.c_str())); - ForwardAnswers(result); - } - } - - - void OrthancPluginDatabase::SetResourcesContent(const Orthanc::ResourcesContent& content) - { - if (extensions_.setResourcesContent == NULL) - { - ISetResourcesContent::Apply(*this, content); - } - else - { - std::vector<OrthancPluginResourcesContentTags> identifierTags; - std::vector<OrthancPluginResourcesContentTags> mainDicomTags; - std::vector<OrthancPluginResourcesContentMetadata> metadata; - - identifierTags.reserve(content.GetListTags().size()); - mainDicomTags.reserve(content.GetListTags().size()); - metadata.reserve(content.GetListMetadata().size()); - - for (ResourcesContent::ListTags::const_iterator - it = content.GetListTags().begin(); it != content.GetListTags().end(); ++it) - { - OrthancPluginResourcesContentTags tmp; - tmp.resource = it->resourceId_; - tmp.group = it->tag_.GetGroup(); - tmp.element = it->tag_.GetElement(); - tmp.value = it->value_.c_str(); - - if (it->isIdentifier_) - { - identifierTags.push_back(tmp); - } - else - { - mainDicomTags.push_back(tmp); - } - } - - for (ResourcesContent::ListMetadata::const_iterator - it = content.GetListMetadata().begin(); it != content.GetListMetadata().end(); ++it) - { - OrthancPluginResourcesContentMetadata tmp; - tmp.resource = it->resourceId_; - tmp.metadata = it->metadata_; - tmp.value = it->value_.c_str(); - metadata.push_back(tmp); - } - - assert(identifierTags.size() + mainDicomTags.size() == content.GetListTags().size() && - metadata.size() == content.GetListMetadata().size()); - - CheckSuccess(extensions_.setResourcesContent( - payload_, - identifierTags.size(), - (identifierTags.empty() ? NULL : &identifierTags[0]), - mainDicomTags.size(), - (mainDicomTags.empty() ? NULL : &mainDicomTags[0]), - metadata.size(), - (metadata.empty() ? NULL : &metadata[0]))); - } - } - - - - void OrthancPluginDatabase::GetChildrenMetadata(std::list<std::string>& target, - int64_t resourceId, - MetadataType metadata) - { - if (extensions_.getChildrenMetadata == NULL) - { - IGetChildrenMetadata::Apply(*this, target, resourceId, metadata); - } - else - { - ResetAnswers(); - CheckSuccess(extensions_.getChildrenMetadata - (GetContext(), payload_, resourceId, static_cast<int32_t>(metadata))); - ForwardAnswers(target); - } - } - - - int64_t OrthancPluginDatabase::GetLastChangeIndex() - { - if (extensions_.getLastChangeIndex == NULL) - { - // This was the default behavior in Orthanc <= 1.5.1 - // https://groups.google.com/d/msg/orthanc-users/QhzB6vxYeZ0/YxabgqpfBAAJ - return 0; - } - else - { - int64_t result = 0; - CheckSuccess(extensions_.getLastChangeIndex(&result, payload_)); - return result; - } - } - - - void OrthancPluginDatabase::TagMostRecentPatient(int64_t patient) - { - if (extensions_.tagMostRecentPatient != NULL) - { - CheckSuccess(extensions_.tagMostRecentPatient(payload_, patient)); - } - } - - - bool OrthancPluginDatabase::LookupResourceAndParent(int64_t& id, - ResourceType& type, - std::string& parentPublicId, - const std::string& publicId) - { - if (extensions_.lookupResourceAndParent == NULL) - { - return ILookupResourceAndParent::Apply(*this, id, type, parentPublicId, publicId); - } - else - { - std::list<std::string> parent; - - uint8_t isExisting; - OrthancPluginResourceType pluginType = OrthancPluginResourceType_Patient; - - ResetAnswers(); - CheckSuccess(extensions_.lookupResourceAndParent - (GetContext(), &isExisting, &id, &pluginType, payload_, publicId.c_str())); - ForwardAnswers(parent); - - if (isExisting) - { - type = Plugins::Convert(pluginType); - - if (parent.empty()) - { - if (type != ResourceType_Patient) - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - } - else if (parent.size() == 1) - { - if ((type != ResourceType_Study && - type != ResourceType_Series && - type != ResourceType_Instance) || - parent.front().empty()) - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - - parentPublicId = parent.front(); - } - else - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - - return true; - } - else - { - return false; - } - } - } }