changeset 6919:7a09008728f5

KVS in Lua
author Alain Mazy <am@orthanc.team>
date Wed, 03 Jun 2026 16:43:52 +0200
parents 78622a71d1ae
children 2349088c03b4 be2922c57de1
files NEWS OrthancServer/Sources/LuaScripting.cpp OrthancServer/Sources/LuaScripting.h
diffstat 3 files changed, 177 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Jun 03 15:07:51 2026 +0200
+++ b/NEWS	Wed Jun 03 16:43:52 2026 +0200
@@ -14,6 +14,12 @@
 * When the "IngestTranscoding" configuration is set to a compressed transfer syntax, Orthanc
   no longer transcodes DICOM files that do not have any pixel data (e.g. DICOM-SR, RTSTRUCT,
   Encapsulated PDF,...). Such files are sometimes poorly handled by other software.
+* In Lua, added new functions to manage key-value stores in the Orthanc DB (provided that
+  the DB backend supports it: currently, PostgreSQL and SQLite):
+  - StoreKeyValue(storeId, key, value)
+  - value = GetKeyValue(storeId, key)
+  - DeleteKeyValue(storeId, key)
+
 
 REST API
 --------
--- a/OrthancServer/Sources/LuaScripting.cpp	Wed Jun 03 15:07:51 2026 +0200
+++ b/OrthancServer/Sources/LuaScripting.cpp	Wed Jun 03 16:43:52 2026 +0200
@@ -635,6 +635,170 @@
   }
 
 
+  // Syntax in Lua: StoreKeyValue(storeId, key, value)
+  int LuaScripting::StoreKeyValue(lua_State* state)
+  {
+    ServerContext* serverContext = GetServerContext(state);
+    if (serverContext == NULL)
+    {
+      LOG(ERROR) << "Lua: The Orthanc API is unavailable";
+      lua_pushnil(state);
+      return 1;
+    }
+
+    // Check the types of the arguments
+    int nArgs = lua_gettop(state);
+    if (nArgs != 3 ||
+        !lua_isstring(state, 1) ||                 // storeId
+        !lua_isstring(state, 2) ||                 // key
+        !lua_isstring(state, 3))                   // value
+    {
+      LOG(ERROR) << "Lua: Bad parameters to StoreKeyValue()";
+      lua_pushnil(state);
+      return 1;
+    }
+
+    if (!serverContext->GetIndex().HasKeyValueStoresSupport())
+    {
+      LOG(ERROR) << "Lua: Unable to use StoreKeyValue() when the DB backend does not support Key-Value stores";
+      lua_pushnil(state);
+      return 1;
+    }
+
+
+    const char* storeId = lua_tostring(state, 1);
+    const char* key = lua_tostring(state, 2);
+    const char* value = lua_tostring(state, 3);
+    
+    try
+    {
+      serverContext->GetIndex().StoreKeyValue(storeId, key, value);
+
+      return 1;
+    }
+    catch (OrthancException& e)
+    {
+      LOG(ERROR) << "Lua: " << e.What();
+    }
+
+    LOG(ERROR) << "Lua: Error in StoreKeyValue() for storeId: " << storeId;
+    lua_pushnil(state);
+
+    return 1;
+  }
+
+
+  // Syntax in Lua: value = GetKeyValue(storeId, key)
+  int LuaScripting::GetKeyValue(lua_State* state)
+  {
+    ServerContext* serverContext = GetServerContext(state);
+    if (serverContext == NULL)
+    {
+      LOG(ERROR) << "Lua: The Orthanc API is unavailable";
+      lua_pushnil(state);
+      return 1;
+    }
+
+    // Check the types of the arguments
+    int nArgs = lua_gettop(state);
+    if (nArgs != 2 ||
+        !lua_isstring(state, 1) ||                 // storeId
+        !lua_isstring(state, 2))                   // key
+    {
+      LOG(ERROR) << "Lua: Bad parameters to GetKeyValue()";
+      lua_pushnil(state);
+      return 1;
+    }
+
+    if (!serverContext->GetIndex().HasKeyValueStoresSupport())
+    {
+      LOG(ERROR) << "Lua: Unable to use GetKeyValue() when the DB backend does not support Key-Value stores";
+      lua_pushnil(state);
+      return 1;
+    }
+
+
+    const char* storeId = lua_tostring(state, 1);
+    const char* key = lua_tostring(state, 2);
+    
+    try
+    {
+      std::string value;
+      if (serverContext->GetIndex().GetKeyValue(value, storeId, key))
+      {
+        lua_pushlstring(state, value.c_str(), value.size());
+      }
+      else
+      {
+        lua_pushnil(state);
+        return 1;
+      }
+
+      return 1;
+    }
+    catch (OrthancException& e)
+    {
+      LOG(ERROR) << "Lua: " << e.What();
+    }
+
+    LOG(ERROR) << "Lua: Error in GetKeyValue() for storeId: " << storeId;
+    lua_pushnil(state);
+
+    return 1;
+  }
+
+
+  // Syntax in Lua: DeleteKeyValue(storeId, key, value)
+  int LuaScripting::DeleteKeyValue(lua_State* state)
+  {
+    ServerContext* serverContext = GetServerContext(state);
+    if (serverContext == NULL)
+    {
+      LOG(ERROR) << "Lua: The Orthanc API is unavailable";
+      lua_pushnil(state);
+      return 1;
+    }
+
+    // Check the types of the arguments
+    int nArgs = lua_gettop(state);
+    if (nArgs != 2 ||
+        !lua_isstring(state, 1) ||                 // storeId
+        !lua_isstring(state, 2))                   // key
+    {
+      LOG(ERROR) << "Lua: Bad parameters to DeleteKeyValue()";
+      lua_pushnil(state);
+      return 1;
+    }
+
+    if (!serverContext->GetIndex().HasKeyValueStoresSupport())
+    {
+      LOG(ERROR) << "Lua: Unable to use DeleteKeyValue() when the DB backend does not support Key-Value stores";
+      lua_pushnil(state);
+      return 1;
+    }
+
+
+    const char* storeId = lua_tostring(state, 1);
+    const char* key = lua_tostring(state, 2);
+    
+    try
+    {
+      serverContext->GetIndex().DeleteKeyValue(storeId, key);
+
+      return 1;
+    }
+    catch (OrthancException& e)
+    {
+      LOG(ERROR) << "Lua: " << e.What();
+    }
+
+    LOG(ERROR) << "Lua: Error in DeleteKeyValue() for storeId: " << storeId;
+    lua_pushnil(state);
+
+    return 1;
+  }
+
+
   // Syntax in Lua: GetOrthancConfiguration()
   int LuaScripting::GetOrthancConfiguration(lua_State *state)
   {
@@ -827,6 +991,9 @@
     lua_.RegisterFunction("RestApiDelete", RestApiDelete);
     lua_.RegisterFunction("GetOrthancConfiguration", GetOrthancConfiguration);
     lua_.RegisterFunction("SetStableStatus", SetStableStatus);
+    lua_.RegisterFunction("StoreKeyValue", StoreKeyValue);
+    lua_.RegisterFunction("GetKeyValue", GetKeyValue);
+    lua_.RegisterFunction("DeleteKeyValue", DeleteKeyValue);
 
     LOG(INFO) << "Initializing Lua for the event handler";
     LoadGlobalConfiguration();
--- a/OrthancServer/Sources/LuaScripting.h	Wed Jun 03 15:07:51 2026 +0200
+++ b/OrthancServer/Sources/LuaScripting.h	Wed Jun 03 16:43:52 2026 +0200
@@ -64,6 +64,10 @@
     static int RestApiDelete(lua_State *state);
     static int GetOrthancConfiguration(lua_State *state);
     static int SetStableStatus(lua_State* state);
+    
+    static int StoreKeyValue(lua_State* state);
+    static int GetKeyValue(lua_State* state);
+    static int DeleteKeyValue(lua_State* state);
 
     void InitializeJob();