changeset 396:7b3acfa95bd8 db-protobuf

implementation of list/add/remove labels in postgresql
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 06 Apr 2023 19:00:29 +0200
parents a7a029043670
children c4f0f8087564
files Framework/Plugins/DatabaseBackendAdapterV4.cpp Framework/Plugins/IDatabaseBackend.h Framework/Plugins/IndexBackend.cpp Framework/Plugins/IndexBackend.h PostgreSQL/Plugins/PostgreSQLIndex.cpp PostgreSQL/Plugins/PostgreSQLIndex.h
diffstat 6 files changed, 110 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Plugins/DatabaseBackendAdapterV4.cpp	Wed Apr 05 14:53:57 2023 +0200
+++ b/Framework/Plugins/DatabaseBackendAdapterV4.cpp	Thu Apr 06 19:00:29 2023 +0200
@@ -408,6 +408,7 @@
         response.mutable_get_system_information()->set_database_version(accessor.GetBackend().GetDatabaseVersion(accessor.GetManager()));
         response.mutable_get_system_information()->set_supports_flush_to_disk(false);
         response.mutable_get_system_information()->set_supports_revisions(accessor.GetBackend().HasRevisionsSupport());
+        response.mutable_get_system_information()->set_supports_labels(accessor.GetBackend().HasLabelsSupport());
         break;
       }
 
@@ -1166,6 +1167,32 @@
         break;
       }
       
+      case Orthanc::DatabasePluginMessages::OPERATION_ADD_LABEL:
+      {
+        backend.AddLabel(manager, request.add_label().id(), request.add_label().label());
+        break;
+      }
+      
+      case Orthanc::DatabasePluginMessages::OPERATION_REMOVE_LABEL:
+      {
+        backend.RemoveLabel(manager, request.remove_label().id(), request.remove_label().label());
+        break;
+      }
+      
+      case Orthanc::DatabasePluginMessages::OPERATION_LIST_LABELS:
+      {
+        std::list<std::string>  labels;
+        backend.ListLabels(labels, manager, request.list_labels().id());
+
+        response.mutable_list_available_attachments()->mutable_attachments()->Reserve(labels.size());
+        for (std::list<std::string>::const_iterator it = labels.begin(); it != labels.end(); ++it)
+        {
+          response.mutable_list_labels()->add_labels(*it);
+        }
+        
+        break;
+      }
+      
       default:
         LOG(ERROR) << "Not implemented transaction operation from protobuf: " << request.operation();
         throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
--- a/Framework/Plugins/IDatabaseBackend.h	Wed Apr 05 14:53:57 2023 +0200
+++ b/Framework/Plugins/IDatabaseBackend.h	Thu Apr 06 19:00:29 2023 +0200
@@ -324,15 +324,18 @@
     virtual bool HasLabelsSupport() const = 0;
 
     // New in Orthanc 1.12.0
-    virtual void AddLabel(int64_t resource,
+    virtual void AddLabel(DatabaseManager& manager,
+                          int64_t resource,
                           const std::string& label) = 0;
 
     // New in Orthanc 1.12.0
-    virtual void RemoveLabel(int64_t resource,
+    virtual void RemoveLabel(DatabaseManager& manager,
+                             int64_t resource,
                              const std::string& label) = 0;
 
     // New in Orthanc 1.12.0
-    virtual void ListLabels(std::set<std::string>& target,
+    virtual void ListLabels(std::list<std::string>& target,
+                            DatabaseManager& manager,
                             int64_t resource) = 0;
   };
 }
--- a/Framework/Plugins/IndexBackend.cpp	Wed Apr 05 14:53:57 2023 +0200
+++ b/Framework/Plugins/IndexBackend.cpp	Thu Apr 06 19:00:29 2023 +0200
@@ -2617,24 +2617,69 @@
 #endif
 
 
-  void IndexBackend::AddLabel(int64_t resource,
+  void IndexBackend::AddLabel(DatabaseManager& manager,
+                              int64_t resource,
                               const std::string& label)
   {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
+    std::unique_ptr<DatabaseManager::CachedStatement> statement;
+
+    switch (manager.GetDialect())
+    {
+      case Dialect_PostgreSQL:
+        statement.reset(new DatabaseManager::CachedStatement(
+                          STATEMENT_FROM_HERE, manager,
+                          "INSERT INTO Labels VALUES(${id}, ${label}) ON CONFLICT DO NOTHING"));
+        break;
+
+      default:
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
+    }
+    
+    statement->SetParameterType("id", ValueType_Integer64);
+    statement->SetParameterType("label", ValueType_Utf8String);
+
+    Dictionary args;
+    args.SetIntegerValue("id", resource);
+    args.SetUtf8Value("label", label);
+
+    statement->Execute(args);
   }
 
 
-  void IndexBackend::RemoveLabel(int64_t resource,
+  void IndexBackend::RemoveLabel(DatabaseManager& manager,
+                                 int64_t resource,
                                  const std::string& label)
   {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
+    DatabaseManager::CachedStatement statement(
+      STATEMENT_FROM_HERE, manager,
+      "DELETE FROM Labels WHERE id=${id} AND label=${label}");
+
+    statement.SetParameterType("id", ValueType_Integer64);
+    statement.SetParameterType("label", ValueType_Utf8String);
+
+    Dictionary args;
+    args.SetIntegerValue("id", resource);
+    args.SetUtf8Value("label", label);
+
+    statement.Execute(args);
   }
 
 
-  void IndexBackend::ListLabels(std::set<std::string>& target,
+  void IndexBackend::ListLabels(std::list<std::string>& target,
+                                DatabaseManager& manager,
                                 int64_t resource)
   {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
+    DatabaseManager::CachedStatement statement(
+      STATEMENT_FROM_HERE, manager,
+      "SELECT label FROM Labels WHERE id=${id}");
+      
+    statement.SetReadOnly(true);
+    statement.SetParameterType("id", ValueType_Integer64);
+
+    Dictionary args;
+    args.SetIntegerValue("id", resource);
+
+    ReadListOfStrings(target, statement, args);
   }
   
 
@@ -2691,7 +2736,7 @@
       }
       catch (boost::bad_lexical_cast&)
       {
-        LOG(ERROR) << "Corrupted PostgreSQL database";
+        LOG(ERROR) << "Corrupted database";
         throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);
       }      
     }
--- a/Framework/Plugins/IndexBackend.h	Wed Apr 05 14:53:57 2023 +0200
+++ b/Framework/Plugins/IndexBackend.h	Thu Apr 06 19:00:29 2023 +0200
@@ -381,13 +381,16 @@
                                   int32_t property,
                                   int value);
 
-    virtual void AddLabel(int64_t resource,
+    virtual void AddLabel(DatabaseManager& manager,
+                          int64_t resource,
                           const std::string& label) ORTHANC_OVERRIDE;
 
-    virtual void RemoveLabel(int64_t resource,
+    virtual void RemoveLabel(DatabaseManager& manager,
+                             int64_t resource,
                              const std::string& label) ORTHANC_OVERRIDE;
 
-    virtual void ListLabels(std::set<std::string>& target,
+    virtual void ListLabels(std::list<std::string>& target,
+                            DatabaseManager& manager,
                             int64_t resource) ORTHANC_OVERRIDE;
     
     /**
--- a/PostgreSQL/Plugins/PostgreSQLIndex.cpp	Wed Apr 05 14:53:57 2023 +0200
+++ b/PostgreSQL/Plugins/PostgreSQLIndex.cpp	Thu Apr 06 19:00:29 2023 +0200
@@ -297,6 +297,24 @@
 
         t.Commit();
       }
+ 
+
+      {
+        // New in release 5.0 to deal with labels
+        DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
+
+        if (!t.GetDatabaseTransaction().DoesTableExist("Labels"))
+        {
+          t.GetDatabaseTransaction().ExecuteMultiLines(
+            "CREATE TABLE Labels("
+            "id BIGINT REFERENCES Resources(internalId) ON DELETE CASCADE,"
+            "label TEXT, PRIMARY KEY(id, label));"
+            "CREATE INDEX LabelsIndex1 ON LABELS(id);"
+            "CREATE INDEX LabelsIndex2 ON LABELS(label);");
+        }
+
+        t.Commit();
+      }
     }
   }
 
--- a/PostgreSQL/Plugins/PostgreSQLIndex.h	Wed Apr 05 14:53:57 2023 +0200
+++ b/PostgreSQL/Plugins/PostgreSQLIndex.h	Thu Apr 06 19:00:29 2023 +0200
@@ -86,7 +86,7 @@
     // New primitive since Orthanc 1.12.0
     virtual bool HasLabelsSupport() const ORTHANC_OVERRIDE
     {
-      return false;
+      return true;
     }
   };
 }