changeset 238:f033cc039264

new table: "ServerProperties"
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 08 Apr 2021 19:33:36 +0200
parents 35598014f140
children e9ba888f371b
files Framework/Plugins/IndexBackend.cpp MySQL/Plugins/MySQLIndex.cpp SQLite/Plugins/SQLiteIndex.cpp
diffstat 3 files changed, 152 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Plugins/IndexBackend.cpp	Thu Apr 08 19:09:04 2021 +0200
+++ b/Framework/Plugins/IndexBackend.cpp	Thu Apr 08 19:33:36 2021 +0200
@@ -1062,22 +1062,11 @@
     }
   }
 
-    
-  bool IndexBackend::LookupGlobalProperty(std::string& target /*out*/,
-                                          DatabaseManager& manager,
-                                          const char* serverIdentifier,
-                                          int32_t property)
+
+  static bool ReadGlobalProperty(std::string& target,
+                                 DatabaseManager::CachedStatement& statement,
+                                 const Dictionary& args)
   {
-    DatabaseManager::CachedStatement statement(
-      STATEMENT_FROM_HERE, manager,
-      "SELECT value FROM GlobalProperties WHERE property=${property}");
-
-    statement.SetReadOnly(true);
-    statement.SetParameterType("property", ValueType_Integer64);
-
-    Dictionary args;
-    args.SetIntegerValue("property", property);
-
     statement.Execute(args);
     statement.SetResultFieldType(0, ValueType_Utf8String);
 
@@ -1104,6 +1093,51 @@
       }
     }
   }
+  
+    
+  bool IndexBackend::LookupGlobalProperty(std::string& target /*out*/,
+                                          DatabaseManager& manager,
+                                          const char* serverIdentifier,
+                                          int32_t property)
+  {
+    if (serverIdentifier == NULL)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
+    }
+    else
+    {
+      if (strlen(serverIdentifier) == 0)
+      {
+        DatabaseManager::CachedStatement statement(
+          STATEMENT_FROM_HERE, manager,
+          "SELECT value FROM GlobalProperties WHERE property=${property}");
+
+        statement.SetReadOnly(true);
+        statement.SetParameterType("property", ValueType_Integer64);
+
+        Dictionary args;
+        args.SetIntegerValue("property", property);
+
+        return ReadGlobalProperty(target, statement, args);
+      }
+      else
+      {
+        DatabaseManager::CachedStatement statement(
+          STATEMENT_FROM_HERE, manager,
+          "SELECT value FROM ServerProperties WHERE server=${server} AND property=${property}");
+
+        statement.SetReadOnly(true);
+        statement.SetParameterType("server", ValueType_Utf8String);
+        statement.SetParameterType("property", ValueType_Integer64);
+
+        Dictionary args;
+        args.SetUtf8Value("server", serverIdentifier);
+        args.SetIntegerValue("property", property);
+
+        return ReadGlobalProperty(target, statement, args);
+      }
+    }
+  }
 
     
   void IndexBackend::LookupIdentifier(std::list<int64_t>& target /*out*/,
@@ -1367,49 +1401,106 @@
                                        int32_t property,
                                        const char* utf8)
   {
-    if (manager.GetDialect() == Dialect_SQLite)
+    if (serverIdentifier == NULL)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
+    }
+    else if (manager.GetDialect() == Dialect_SQLite)
     {
-      DatabaseManager::CachedStatement statement(
-        STATEMENT_FROM_HERE, manager,
-        "INSERT OR REPLACE INTO GlobalProperties VALUES (${property}, ${value})");
+      bool hasServer = (strlen(serverIdentifier) != 0);
+
+      std::unique_ptr<DatabaseManager::CachedStatement> statement;
+
+      if (hasServer)
+      {
+        statement.reset(new DatabaseManager::CachedStatement(
+                          STATEMENT_FROM_HERE, manager,
+                          "INSERT OR REPLACE INTO ServerProperties VALUES (${server}, ${property}, ${value})"));
+      }
+      else
+      {
+        statement.reset(new DatabaseManager::CachedStatement(
+                          STATEMENT_FROM_HERE, manager,
+                          "INSERT OR REPLACE INTO GlobalProperties VALUES (${property}, ${value})"));
+      }
         
-      statement.SetParameterType("property", ValueType_Integer64);
-      statement.SetParameterType("value", ValueType_Utf8String);
+      statement->SetParameterType("property", ValueType_Integer64);
+      statement->SetParameterType("value", ValueType_Utf8String);
         
       Dictionary args;
       args.SetIntegerValue("property", static_cast<int>(property));
       args.SetUtf8Value("value", utf8);
-        
-      statement.Execute(args);
+
+      if (hasServer)
+      {
+        statement->SetParameterType("server", ValueType_Utf8String);
+        args.SetUtf8Value("server", serverIdentifier);
+      }
+      
+      statement->Execute(args);
     }
     else
     {
+      bool hasServer = (strlen(serverIdentifier) != 0);
+
+      std::unique_ptr<DatabaseManager::CachedStatement> statement;
+
       {
-        DatabaseManager::CachedStatement statement(
-          STATEMENT_FROM_HERE, manager,
-          "DELETE FROM GlobalProperties WHERE property=${property}");
+        if (hasServer)
+        {
+          statement.reset(new DatabaseManager::CachedStatement(
+                            STATEMENT_FROM_HERE, manager,
+                            "DELETE FROM ServerProperties WHERE server=${server} AND property=${property}"));
+        }
+        else
+        {
+          statement.reset(new DatabaseManager::CachedStatement(
+                            STATEMENT_FROM_HERE, manager,
+                            "DELETE FROM GlobalProperties WHERE property=${property}"));
+        }
         
-        statement.SetParameterType("property", ValueType_Integer64);
+        statement->SetParameterType("property", ValueType_Integer64);
         
         Dictionary args;
         args.SetIntegerValue("property", property);
+
+        if (hasServer)
+        {
+          statement->SetParameterType("server", ValueType_Utf8String);
+          args.SetUtf8Value("server", serverIdentifier);
+        }
         
-        statement.Execute(args);
+        statement->Execute(args);
       }
 
       {
-        DatabaseManager::CachedStatement statement(
-          STATEMENT_FROM_HERE, manager,
-          "INSERT INTO GlobalProperties VALUES (${property}, ${value})");
+        if (hasServer)
+        {
+          statement.reset(new DatabaseManager::CachedStatement(
+                            STATEMENT_FROM_HERE, manager,
+                            "INSERT INTO ServerProperties VALUES (${server}, ${property}, ${value})"));
+        }
+        else
+        {
+          statement.reset(new DatabaseManager::CachedStatement(
+                            STATEMENT_FROM_HERE, manager,
+                            "INSERT INTO GlobalProperties VALUES (${property}, ${value})"));
+        }
         
-        statement.SetParameterType("property", ValueType_Integer64);
-        statement.SetParameterType("value", ValueType_Utf8String);
+        statement->SetParameterType("property", ValueType_Integer64);
+        statement->SetParameterType("value", ValueType_Utf8String);
         
         Dictionary args;
         args.SetIntegerValue("property", static_cast<int>(property));
         args.SetUtf8Value("value", utf8);
         
-        statement.Execute(args);
+        if (hasServer)
+        {
+          statement->SetParameterType("server", ValueType_Utf8String);
+          args.SetUtf8Value("server", serverIdentifier);
+        }
+
+        statement->Execute(args);
       }
     }
   }
--- a/MySQL/Plugins/MySQLIndex.cpp	Thu Apr 08 19:09:04 2021 +0200
+++ b/MySQL/Plugins/MySQLIndex.cpp	Thu Apr 08 19:33:36 2021 +0200
@@ -267,8 +267,23 @@
         LOG(ERROR) << "MySQL plugin is incompatible with database schema revision: " << revision;
         throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);        
       }
+
+
+      {
+        // New in release 4.0 to deal with multiple writers
+        DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
+
+        if (!t.DoesTableExist("ServerProperties"))
+        {
+          t.ExecuteMultiLines("CREATE TABLE ServerProperties(server VARCHAR(64) NOT NULL, "
+                              "property INTEGER, value TEXT, PRIMARY KEY(server, property))");
+        }
+
+        t.Commit();
+      }
     }
 
+    
     /**
      * WARNING: This lock must be acquired after
      * "MYSQL_LOCK_DATABASE_SETUP" is released. Indeed, in MySQL <
--- a/SQLite/Plugins/SQLiteIndex.cpp	Thu Apr 08 19:09:04 2021 +0200
+++ b/SQLite/Plugins/SQLiteIndex.cpp	Thu Apr 08 19:33:36 2021 +0200
@@ -133,6 +133,18 @@
           
       t.Commit();
     }
+
+    {
+      DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
+
+      if (!t.DoesTableExist("ServerProperties"))
+      {
+        t.ExecuteMultiLines("CREATE TABLE ServerProperties(server TEXT, "
+                            "property INTEGER, value TEXT, PRIMARY KEY(server, property))");
+      }
+
+      t.Commit();
+    }    
   }