diff OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp @ 5207:e7529e6241d2 db-protobuf

first successful protobuf communication
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 30 Mar 2023 21:31:56 +0200
parents
children 154d37a56500
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp	Thu Mar 30 21:31:56 2023 +0200
@@ -0,0 +1,570 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2021-2023 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../../Sources/PrecompiledHeadersServer.h"
+#include "OrthancPluginDatabaseV4.h"
+
+#if ORTHANC_ENABLE_PLUGINS != 1
+#  error The plugin support is disabled
+#endif
+
+#include "../../../OrthancFramework/Sources/Logging.h"
+#include "../../../OrthancFramework/Sources/OrthancException.h"
+#include "PluginsEnumerations.h"
+
+#include "OrthancDatabasePlugin.pb.h"
+
+#include <cassert>
+
+
+namespace Orthanc
+{
+  class OrthancPluginDatabaseV4::Transaction : public IDatabaseWrapper::ITransaction
+  {
+  private:
+    OrthancPluginDatabaseV4&  that_;
+    IDatabaseListener&        listener_;
+    void*                     transaction_;
+
+    void CheckSuccess(OrthancPluginErrorCode code) const
+    {
+      that_.CheckSuccess(code);
+    }
+    
+  public:
+    Transaction(OrthancPluginDatabaseV4& that,
+                IDatabaseListener& listener,
+                TransactionType type) :
+      that_(that),
+      listener_(listener)
+    {
+#if 0
+      CheckSuccess(that.database_.startTransaction(that.database_, &transaction_, type));
+      if (transaction_ == NULL)
+      {
+        throw OrthancException(ErrorCode_DatabasePlugin);
+      }
+#endif
+    }
+
+    
+    virtual ~Transaction()
+    {
+#if 0
+      OrthancPluginErrorCode code = that_.database_.destructTransaction(transaction_);
+      if (code != OrthancPluginErrorCode_Success)
+      {
+        // Don't throw exception in destructors
+        that_.errorDictionary_.LogError(code, true);
+      }
+#endif
+    }
+    
+
+    virtual void Rollback() ORTHANC_OVERRIDE
+    {
+    }
+    
+
+    virtual void Commit(int64_t fileSizeDelta) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void AddAttachment(int64_t id,
+                               const FileInfo& attachment,
+                               int64_t revision) ORTHANC_OVERRIDE
+    {
+    }
+
+
+    virtual void ClearChanges() ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void ClearExportedResources() ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void DeleteAttachment(int64_t id,
+                                  FileContentType attachment) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void DeleteMetadata(int64_t id,
+                                MetadataType type) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetAllMetadata(std::map<MetadataType, std::string>& target,
+                                int64_t id) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetAllPublicIds(std::list<std::string>& target,
+                                 ResourceType resourceType) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetAllPublicIds(std::list<std::string>& target,
+                                 ResourceType resourceType,
+                                 size_t since,
+                                 size_t limit) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/,
+                            bool& done /*out*/,
+                            int64_t since,
+                            uint32_t maxResults) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetChildrenInternalId(std::list<int64_t>& target,
+                                       int64_t id) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetChildrenPublicId(std::list<std::string>& target,
+                                     int64_t id) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetExportedResources(std::list<ExportedResource>& target /*out*/,
+                                      bool& done /*out*/,
+                                      int64_t since,
+                                      uint32_t maxResults) ORTHANC_OVERRIDE
+    {
+    }
+
+
+    virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetMainDicomTags(DicomMap& target,
+                                  int64_t id) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual std::string GetPublicId(int64_t resourceId) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual uint64_t GetResourcesCount(ResourceType resourceType) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual ResourceType GetResourceType(int64_t resourceId) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual uint64_t GetTotalCompressedSize() ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual uint64_t GetTotalUncompressedSize() ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool IsProtectedPatient(int64_t internalId) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void ListAvailableAttachments(std::set<FileContentType>& target,
+                                          int64_t id) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void LogChange(int64_t internalId,
+                           const ServerIndexChange& change) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void LogExportedResource(const ExportedResource& resource) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool LookupAttachment(FileInfo& attachment,
+                                  int64_t& revision,
+                                  int64_t id,
+                                  FileContentType contentType) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool LookupGlobalProperty(std::string& target,
+                                      GlobalProperty property,
+                                      bool shared) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool LookupMetadata(std::string& target,
+                                int64_t& revision,
+                                int64_t id,
+                                MetadataType type) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool LookupParent(int64_t& parentId,
+                              int64_t resourceId) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool LookupResource(int64_t& id,
+                                ResourceType& type,
+                                const std::string& publicId) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool SelectPatientToRecycle(int64_t& internalId,
+                                        int64_t patientIdToAvoid) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void SetGlobalProperty(GlobalProperty property,
+                                   bool shared,
+                                   const std::string& value) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void SetMetadata(int64_t id,
+                             MetadataType type,
+                             const std::string& value,
+                             int64_t revision) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void SetProtectedPatient(int64_t internalId, 
+                                     bool isProtected) ORTHANC_OVERRIDE
+    {
+    }
+
+
+    virtual bool IsDiskSizeAbove(uint64_t threshold) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void ApplyLookupResources(std::list<std::string>& resourcesId,
+                                      std::list<std::string>* instancesId, // Can be NULL if not needed
+                                      const std::vector<DatabaseConstraint>& lookup,
+                                      ResourceType queryLevel,
+                                      size_t limit) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool CreateInstance(CreateInstanceResult& result, /* out */
+                                int64_t& instanceId,          /* out */
+                                const std::string& patient,
+                                const std::string& study,
+                                const std::string& series,
+                                const std::string& instance) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void SetResourcesContent(const ResourcesContent& content) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual void GetChildrenMetadata(std::list<std::string>& target,
+                                     int64_t resourceId,
+                                     MetadataType metadata) ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual int64_t GetLastChangeIndex() ORTHANC_OVERRIDE
+    {
+    }
+
+    
+    virtual bool LookupResourceAndParent(int64_t& id,
+                                         ResourceType& type,
+                                         std::string& parentPublicId,
+                                         const std::string& publicId) ORTHANC_OVERRIDE
+    {
+    }
+  };
+
+
+  static void CheckSuccess(PluginsErrorDictionary& errorDictionary,
+                           OrthancPluginErrorCode code)
+  {
+    if (code != OrthancPluginErrorCode_Success)
+    {
+      errorDictionary.LogError(code, true);
+      throw OrthancException(static_cast<ErrorCode>(code));
+    }
+  }
+
+
+  static void Execute(DatabasePluginMessages::Response& response,
+                      const _OrthancPluginRegisterDatabaseBackendV4& database,
+                      PluginsErrorDictionary& errorDictionary,
+                      const DatabasePluginMessages::Request& request)
+  {
+    std::string requestSerialized;
+    request.SerializeToString(&requestSerialized);
+
+    OrthancPluginMemoryBuffer64 responseSerialized;
+    CheckSuccess(errorDictionary, database.operations(
+                   &responseSerialized, database.backend,
+                   requestSerialized.empty() ? NULL : requestSerialized.c_str(),
+                   requestSerialized.size()));
+
+    bool success = response.ParseFromArray(responseSerialized.data, responseSerialized.size);
+
+    if (responseSerialized.size > 0)
+    {
+      free(responseSerialized.data);
+    }
+
+    if (!success)
+    {
+      throw OrthancException(ErrorCode_DatabasePlugin, "Cannot unserialize protobuf originating from the database plugin");
+    }
+  }
+
+  static void ExecuteDatabase(DatabasePluginMessages::DatabaseResponse& response,
+                              const _OrthancPluginRegisterDatabaseBackendV4& database,
+                              PluginsErrorDictionary& errorDictionary,
+                              DatabasePluginMessages::DatabaseOperation operation,
+                              const DatabasePluginMessages::DatabaseRequest& request)
+  {
+    DatabasePluginMessages::Request fullRequest;
+    fullRequest.set_type(DatabasePluginMessages::REQUEST_DATABASE);
+    fullRequest.mutable_database_request()->CopyFrom(request);
+    fullRequest.mutable_database_request()->set_operation(operation);
+
+    DatabasePluginMessages::Response fullResponse;
+    Execute(fullResponse, database, errorDictionary, fullRequest);
+    
+    response.CopyFrom(fullResponse.database_response());
+  }
+
+
+  OrthancPluginDatabaseV4::OrthancPluginDatabaseV4(SharedLibrary& library,
+                                                   PluginsErrorDictionary&  errorDictionary,
+                                                   const _OrthancPluginRegisterDatabaseBackendV4& database,
+                                                   const std::string& serverIdentifier) :
+    library_(library),
+    errorDictionary_(errorDictionary),
+    database_(database),
+    serverIdentifier_(serverIdentifier),
+    open_(false),
+    databaseVersion_(0),
+    hasFlushToDisk_(false),
+    hasRevisionsSupport_(false)
+  {
+    CLOG(INFO, PLUGINS) << "Identifier of this Orthanc server for the global properties "
+                        << "of the custom database: \"" << serverIdentifier << "\"";
+
+    if (database_.backend == NULL ||
+        database_.operations == NULL ||
+        database_.finalize == NULL)
+    {
+      throw OrthancException(ErrorCode_NullPointer);
+    }
+  }
+
+  
+  OrthancPluginDatabaseV4::~OrthancPluginDatabaseV4()
+  {
+    database_.finalize(database_.backend);
+  }
+
+  
+  void OrthancPluginDatabaseV4::Open()
+  {
+    if (open_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    
+    {
+      DatabasePluginMessages::DatabaseRequest request;
+      DatabasePluginMessages::DatabaseResponse response;
+      ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_OPEN, request);
+    }
+
+    {
+      DatabasePluginMessages::DatabaseRequest request;
+      DatabasePluginMessages::DatabaseResponse response;
+      ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_GET_SYSTEM_INFORMATION, request);
+      hasFlushToDisk_ = response.get_system_information().supports_flush_to_disk();
+      hasRevisionsSupport_ = response.get_system_information().supports_revisions();
+    }
+
+    open_ = true;    
+  }
+
+
+  void OrthancPluginDatabaseV4::Close()
+  {
+    if (!open_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      DatabasePluginMessages::DatabaseRequest request;
+      DatabasePluginMessages::DatabaseResponse response;
+      ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_CLOSE, request);
+    }
+  }
+  
+
+  bool OrthancPluginDatabaseV4::HasFlushToDisk() const
+  {
+    if (!open_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      return hasFlushToDisk_;
+    }
+  }
+
+
+  void OrthancPluginDatabaseV4::FlushToDisk()
+  {
+    if (!open_ ||
+        !hasFlushToDisk_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      DatabasePluginMessages::DatabaseRequest request;
+      DatabasePluginMessages::DatabaseResponse response;
+      ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_FLUSH_TO_DISK, request);
+    }
+  }
+  
+
+  IDatabaseWrapper::ITransaction* OrthancPluginDatabaseV4::StartTransaction(TransactionType type,
+                                                                            IDatabaseListener& listener)
+  {
+    if (!open_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+
+    switch (type)
+    {
+      case TransactionType_ReadOnly:
+
+      case TransactionType_ReadWrite:
+
+      default:
+        throw OrthancException(ErrorCode_InternalError);
+    }
+  }
+
+  
+  unsigned int OrthancPluginDatabaseV4::GetDatabaseVersion()
+  {
+    if (!open_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      return databaseVersion_;
+    }
+  }
+
+  
+  void OrthancPluginDatabaseV4::Upgrade(unsigned int targetVersion,
+                                        IStorageArea& storageArea)
+  {
+    if (!open_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      // TODO
+    }
+  }
+
+  
+  bool OrthancPluginDatabaseV4::HasRevisionsSupport() const
+  {
+    if (!open_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      return hasRevisionsSupport_;
+    }
+  }
+}