diff PostgreSQL/Plugins/StoragePlugin.cpp @ 12:41543239072d

transactions for storage area
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 09 Jul 2018 18:34:56 +0200
parents 17bce6a07b2b
children 9774802fd05f
line wrap: on
line diff
--- a/PostgreSQL/Plugins/StoragePlugin.cpp	Mon Jul 09 11:45:52 2018 +0200
+++ b/PostgreSQL/Plugins/StoragePlugin.cpp	Mon Jul 09 18:34:56 2018 +0200
@@ -21,10 +21,154 @@
 
 #include "../../Framework/Plugins/StorageBackend.h"
 
+#include "../../Framework/Common/FileValue.h"
+#include "../../Framework/PostgreSQL/PostgreSQLDatabase.h"
+#include "../../Framework/PostgreSQL/PostgreSQLLargeObject.h"
+#include "../../Framework/PostgreSQL/PostgreSQLTransaction.h"
+
 #include <Plugins/Samples/Common/OrthancPluginCppWrapper.h>
 #include <Core/Logging.h>
 
 
+namespace OrthancDatabases
+{
+  class PostgreSQLStorageArea : public StorageBackend
+  {
+  private:
+    class Factory : public IDatabaseFactory
+    {
+    private:
+      PostgreSQLStorageArea&  that_;
+
+    public:
+      Factory(PostgreSQLStorageArea& that) :
+      that_(that)
+      {
+      }
+
+      virtual Dialect GetDialect() const
+      {
+        return Dialect_PostgreSQL;
+      }
+
+      virtual IDatabase* Open()
+      {
+        return that_.OpenInternal();
+      }
+    };
+
+    OrthancPluginContext*  context_;
+    PostgreSQLParameters   parameters_;
+    bool                   clearAll_;
+
+    IDatabase* OpenInternal()
+    {
+      std::auto_ptr<PostgreSQLDatabase> db(new PostgreSQLDatabase(parameters_));
+
+      db->Open();
+
+      if (parameters_.HasLock())
+      {
+        db->AdvisoryLock(43 /* some arbitrary constant */);
+      }
+
+      if (clearAll_)
+      {
+        db->ClearAll();
+      }
+
+      {
+        PostgreSQLTransaction t(*db);
+
+        if (!db->DoesTableExist("StorageArea"))
+        {
+          db->Execute("CREATE TABLE IF NOT EXISTS StorageArea("
+                      "uuid VARCHAR NOT NULL PRIMARY KEY,"
+                      "content OID NOT NULL,"
+                      "type INTEGER NOT NULL)");
+
+          // Automatically remove the large objects associated with the table
+          db->Execute("CREATE OR REPLACE RULE StorageAreaDelete AS ON DELETE "
+                      "TO StorageArea DO SELECT lo_unlink(old.content);");
+        }
+
+        t.Commit();
+      }
+
+      return db.release();
+    }
+
+  public:
+    PostgreSQLStorageArea(const PostgreSQLParameters& parameters) :
+    StorageBackend(new Factory(*this)),
+    parameters_(parameters),
+    clearAll_(false)
+    {
+    }
+
+    void SetClearAll(bool clear)
+    {
+      clearAll_ = clear;
+    }
+
+
+    virtual void Create(DatabaseManager::Transaction& transaction,
+                        const std::string& uuid,
+                        const void* content,
+                        size_t size,
+                        OrthancPluginContentType type)
+    {
+      std::auto_ptr<FileValue> file(new FileValue(content, size));
+      
+      {
+        DatabaseManager::CachedStatement statement(
+          STATEMENT_FROM_HERE, GetManager(),
+          "INSERT INTO StorageArea VALUES (${uuid}, ${content}, ${type})");
+     
+        statement.SetParameterType("uuid", ValueType_Utf8String);
+        statement.SetParameterType("content", ValueType_File);
+        statement.SetParameterType("type", ValueType_Integer64);
+
+        Dictionary args;
+        args.SetUtf8Value("uuid", uuid);
+        args.SetValue("content", file.release());
+        args.SetIntegerValue("type", type);
+     
+        statement.Execute(args);
+      }
+    }
+
+
+    virtual void Read(void*& content,
+                      size_t& size,
+                      DatabaseManager::Transaction& transaction, 
+                      const std::string& uuid,
+                      OrthancPluginContentType type) 
+    {
+    }
+
+
+    virtual void Remove(DatabaseManager::Transaction& transaction,
+                        const std::string& uuid,
+                        OrthancPluginContentType type)
+    {
+      DatabaseManager::CachedStatement statement(
+        STATEMENT_FROM_HERE, GetManager(),
+        "DELETE FROM StorageArea WHERE uuid=${uuid} AND type=${type}");
+     
+      statement.SetParameterType("uuid", ValueType_Utf8String);
+      statement.SetParameterType("type", ValueType_Integer64);
+
+      Dictionary args;
+      args.SetUtf8Value("uuid", uuid);
+      args.SetIntegerValue("type", type);
+     
+      statement.Execute(args);
+    }
+  };
+}
+
+
 static bool DisplayPerformanceWarning()
 {
   (void) DisplayPerformanceWarning;   // Disable warning about unused function
@@ -79,8 +223,9 @@
 
     try
     {
-      // TODO
-      //OrthancDatabases::StorageBackend::Register();
+      OrthancDatabases::PostgreSQLParameters parameters(postgresql);
+      OrthancDatabases::StorageBackend::Register
+        (context, new OrthancDatabases::PostgreSQLStorageArea(parameters));
     }
     catch (Orthanc::OrthancException& e)
     {