# HG changeset patch # User Sebastien Jodogne # Date 1549291676 -3600 # Node ID 6f89d22a6ec01571627b6478ecc238017259d9c2 # Parent 70356580e310be85845fc3b3a24c3eb74c487456 New extensions in the database SDK: LookupResourceAndParent and GetAllMetadata diff -r 70356580e310 -r 6f89d22a6ec0 NEWS --- a/NEWS Mon Feb 04 12:09:26 2019 +0100 +++ b/NEWS Mon Feb 04 15:47:56 2019 +0100 @@ -20,6 +20,7 @@ ------- * New primitives in the plugin SDK to set and refresh metrics +* New extensions in the database SDK: LookupResourceAndParent and GetAllMetadata Maintenance ----------- diff -r 70356580e310 -r 6f89d22a6ec0 Plugins/Engine/OrthancPluginDatabase.cpp --- a/Plugins/Engine/OrthancPluginDatabase.cpp Mon Feb 04 12:09:26 2019 +0100 +++ b/Plugins/Engine/OrthancPluginDatabase.cpp Mon Feb 04 15:47:56 2019 +0100 @@ -135,6 +135,7 @@ answerDone_ = NULL; answerMatchingResources_ = NULL; answerMatchingInstances_ = NULL; + answerMetadata_ = NULL; } @@ -390,35 +391,52 @@ void OrthancPluginDatabase::GetAllMetadata(std::map& target, int64_t id) { - // TODO - Add primitive in SDK + if (extensions_.getAllMetadata == NULL) + { + // Fallback implementation if extension is missing + target.clear(); - target.clear(); + ResetAnswers(); + CheckSuccess(backend_.listAvailableMetadata(GetContext(), payload_, id)); - ResetAnswers(); - CheckSuccess(backend_.listAvailableMetadata(GetContext(), payload_, id)); + if (type_ != _OrthancPluginDatabaseAnswerType_None && + type_ != _OrthancPluginDatabaseAnswerType_Int32) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } - if (type_ != _OrthancPluginDatabaseAnswerType_None && - type_ != _OrthancPluginDatabaseAnswerType_Int32) - { - throw OrthancException(ErrorCode_DatabasePlugin); - } + target.clear(); - target.clear(); - - if (type_ == _OrthancPluginDatabaseAnswerType_Int32) - { - for (std::list::const_iterator - it = answerInt32_.begin(); it != answerInt32_.end(); ++it) + if (type_ == _OrthancPluginDatabaseAnswerType_Int32) { - MetadataType type = static_cast(*it); + for (std::list::const_iterator + it = answerInt32_.begin(); it != answerInt32_.end(); ++it) + { + MetadataType type = static_cast(*it); - std::string value; - if (LookupMetadata(value, id, type)) - { - target[type] = value; + 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); + } + } } @@ -1008,6 +1026,11 @@ break; + case _OrthancPluginDatabaseAnswerType_Metadata: + assert(answerMetadata_ != NULL); + answerMetadata_->clear(); + break; + default: throw OrthancException(ErrorCode_DatabasePlugin, "Unhandled type of answer for custom index plugin: " + @@ -1163,6 +1186,24 @@ break; } + case _OrthancPluginDatabaseAnswerType_Metadata: + { + const OrthancPluginResourcesContentMetadata& metadata = + *reinterpret_cast(answer.valueGeneric); + + MetadataType type = static_cast(metadata.metadata); + + if (metadata.value == NULL) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + + assert(answerMetadata_ != NULL && + answerMetadata_->find(type) == answerMetadata_->end()); + (*answerMetadata_) [type] = metadata.value; + break; + } + default: throw OrthancException(ErrorCode_DatabasePlugin, "Unhandled type of answer for custom index plugin: " + @@ -1426,7 +1467,56 @@ std::string& parentPublicId, const std::string& publicId) { - // TODO - Add primitive in SDK - return ILookupResourceAndParent::Apply(*this, id, type, parentPublicId, publicId); + if (extensions_.lookupResourceAndParent == NULL) + { + return ILookupResourceAndParent::Apply(*this, id, type, parentPublicId, publicId); + } + else + { + std::list 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; + } + } } } diff -r 70356580e310 -r 6f89d22a6ec0 Plugins/Engine/OrthancPluginDatabase.h --- a/Plugins/Engine/OrthancPluginDatabase.h Mon Feb 04 12:09:26 2019 +0100 +++ b/Plugins/Engine/OrthancPluginDatabase.h Mon Feb 04 15:47:56 2019 +0100 @@ -57,7 +57,8 @@ private: class Transaction; - typedef std::pair AnswerResource; + typedef std::pair AnswerResource; + typedef std::map AnswerMetadata; SharedLibrary& library_; PluginsErrorDictionary& errorDictionary_; @@ -82,6 +83,7 @@ bool* answerDone_; std::list* answerMatchingResources_; std::list* answerMatchingInstances_; + AnswerMetadata* answerMetadata_; OrthancPluginDatabaseContext* GetContext() { diff -r 70356580e310 -r 6f89d22a6ec0 Plugins/Include/orthanc/OrthancCDatabasePlugin.h --- a/Plugins/Include/orthanc/OrthancCDatabasePlugin.h Mon Feb 04 12:09:26 2019 +0100 +++ b/Plugins/Include/orthanc/OrthancCDatabasePlugin.h Mon Feb 04 15:47:56 2019 +0100 @@ -76,6 +76,7 @@ _OrthancPluginDatabaseAnswerType_Resource = 16, _OrthancPluginDatabaseAnswerType_String = 17, _OrthancPluginDatabaseAnswerType_MatchingResource = 18, /* New in Orthanc 1.5.2 */ + _OrthancPluginDatabaseAnswerType_Metadata = 19, /* New in Orthanc 1.5.4 */ _OrthancPluginDatabaseAnswerType_INTERNAL = 0x7fffffff } _OrthancPluginDatabaseAnswerType; @@ -335,6 +336,25 @@ context->InvokeService(context, _OrthancPluginService_DatabaseAnswer, ¶ms); } + ORTHANC_PLUGIN_INLINE void OrthancPluginDatabaseAnswerMetadata( + OrthancPluginContext* context, + OrthancPluginDatabaseContext* database, + int64_t resourceId, + int32_t type, + const char* value) + { + OrthancPluginResourcesContentMetadata metadata; + _OrthancPluginDatabaseAnswer params; + metadata.resource = resourceId; + metadata.metadata = type; + metadata.value = value; + memset(¶ms, 0, sizeof(params)); + params.database = database; + params.type = _OrthancPluginDatabaseAnswerType_Metadata; + params.valueGeneric = &metadata; + context->InvokeService(context, _OrthancPluginService_DatabaseAnswer, ¶ms); + } + ORTHANC_PLUGIN_INLINE void OrthancPluginDatabaseSignalDeletedAttachment( OrthancPluginContext* context, OrthancPluginDatabaseContext* database, @@ -783,7 +803,6 @@ OrthancPluginResourceType queryLevel, uint32_t limit, uint8_t requestSomeInstance); - OrthancPluginErrorCode (*createInstance) ( /* output */ @@ -825,6 +844,32 @@ void* payload, int64_t patientId); + + /** + * Extensions since Orthanc 1.5.4 + **/ + + /* Ouput: Use OrthancPluginDatabaseAnswerMetadata */ + OrthancPluginErrorCode (*getAllMetadata) ( + /* outputs */ + OrthancPluginDatabaseContext* context, + /* inputs */ + void* payload, + int64_t resourceId); + + /* Ouput: Use OrthancPluginDatabaseAnswerString to send + the public ID of the parent (if the resource is not a patient) */ + OrthancPluginErrorCode (*lookupResourceAndParent) ( + /* outputs */ + OrthancPluginDatabaseContext* context, + uint8_t* isExisting, + int64_t* id, + OrthancPluginResourceType* type, + + /* inputs */ + void* payload, + const char* publicId); + } OrthancPluginDatabaseExtensions; /*