changeset 6125:42e8033618d6 attach-custom-data

initial wrapping of keys-values iterators
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 20 May 2025 19:03:11 +0200
parents 79e9fa2872cf
children 0f9dc84976ae
files OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Plugins/Engine/OrthancPlugins.h OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h
diffstat 5 files changed, 358 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Tue May 20 17:53:14 2025 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Tue May 20 19:03:11 2025 +0200
@@ -623,22 +623,6 @@
   }
 
 
-  static void CopyStringList(OrthancPluginMemoryBuffer& target,
-                             const std::list<std::string>& list)
-  {
-    Json::Value json = Json::arrayValue;
-
-    for (std::list<std::string>::const_iterator 
-           it = list.begin(); it != list.end(); ++it)
-    {
-      json.append(*it);
-    }
-        
-    std::string s;
-    Toolbox::WriteFastJson(s, json);
-    CopyToMemoryBuffer(target, s);
-  }
-
   namespace
   {
     class MemoryBufferRaii : public boost::noncopyable
@@ -4761,16 +4745,6 @@
     }
   }
 
-  void OrthancPlugins::ApplyListKeys(const _OrthancPluginListKeys& parameters)
-  {
-    PImpl::ServerContextReference lock(*pimpl_);
-
-    std::list<std::string> keys;
-
-    //lock.GetContext().GetIndex().ListKeys(keys, parameters.storeId, parameters.since, parameters.limit);
-    CopyStringList(*(parameters.keys), keys);
-  }
-
   bool OrthancPlugins::HasQueuesSupport()
   {
     PImpl::ServerContextReference lock(*pimpl_);
@@ -5903,81 +5877,136 @@
       }
 
       case _OrthancPluginService_StoreKeyValue:
-      {
         if (!HasKeyValueStoresSupport())
         {
-          LOG(ERROR) << "The DB engine does not support Key Value Store";
-          return false;
-        }
-
-        const _OrthancPluginStoreKeyValue& p =
-          *reinterpret_cast<const _OrthancPluginStoreKeyValue*>(parameters);
-        ApplyStoreKeyValue(p);
-        return true;
-      }
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support key-value stores");
+        }
+        else
+        {
+          const _OrthancPluginStoreKeyValue& p =
+            *reinterpret_cast<const _OrthancPluginStoreKeyValue*>(parameters);
+          ApplyStoreKeyValue(p);
+          return true;
+        }
 
       case _OrthancPluginService_DeleteKeyValue:
-      {
         if (!HasKeyValueStoresSupport())
         {
-          LOG(ERROR) << "The DB engine does not support Key Value Store";
-          return false;
-        }
-
-        const _OrthancPluginDeleteKeyValue& p =
-          *reinterpret_cast<const _OrthancPluginDeleteKeyValue*>(parameters);
-        ApplyDeleteKeyValue(p);
-        return true;
-      }
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support key-value stores");
+        }
+        else
+        {
+          const _OrthancPluginDeleteKeyValue& p =
+            *reinterpret_cast<const _OrthancPluginDeleteKeyValue*>(parameters);
+          ApplyDeleteKeyValue(p);
+          return true;
+        }
 
       case _OrthancPluginService_GetKeyValue:
-      {
+        if (!HasKeyValueStoresSupport())
+        {
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support key-value stores");
+        }
+        else
+        {
+          const _OrthancPluginGetKeyValue& p =
+            *reinterpret_cast<const _OrthancPluginGetKeyValue*>(parameters);
+          ApplyGetKeyValue(p);
+          return true;
+        }
+
+      case _OrthancPluginService_CreateKeysValuesIterator:
+        if (!HasKeyValueStoresSupport())
+        {
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support key-value stores");
+        }
+        else
+        {
+          const _OrthancPluginCreateKeysValuesIterator& p =
+            *reinterpret_cast<const _OrthancPluginCreateKeysValuesIterator*>(parameters);
+
+          {
+            PImpl::ServerContextReference lock(*pimpl_);
+            *p.target = reinterpret_cast<OrthancPluginKeysValuesIterator*>(new StatelessDatabaseOperations::KeysValuesIterator(lock.GetContext().GetIndex(), p.storeId));
+          }
+
+          return true;
+        }
+
+      case _OrthancPluginService_FreeKeysValuesIterator:
         if (!HasKeyValueStoresSupport())
         {
-          LOG(ERROR) << "The DB engine does not support Key Value Store";
-          return false;
-        }
-
-        const _OrthancPluginGetKeyValue& p =
-          *reinterpret_cast<const _OrthancPluginGetKeyValue*>(parameters);
-        ApplyGetKeyValue(p);
-        return true;
-      }
-
-      case _OrthancPluginService_ListKeys:
-      {
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support key-value stores");
+        }
+        else
+        {
+          const _OrthancPluginFreeKeysValuesIterator& p =
+            *reinterpret_cast<const _OrthancPluginFreeKeysValuesIterator*>(parameters);
+          delete reinterpret_cast<StatelessDatabaseOperations::KeysValuesIterator*>(p.iterator);
+          return true;
+        }
+
+      case _OrthancPluginService_KeysValuesIteratorNext:
         if (!HasKeyValueStoresSupport())
         {
-          LOG(ERROR) << "The DB engine does not support Key Value Store";
-          return false;
-        }
-
-        const _OrthancPluginListKeys& p =
-          *reinterpret_cast<const _OrthancPluginListKeys*>(parameters);
-        ApplyListKeys(p);
-        return true;
-      }
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support key-value stores");
+        }
+        else
+        {
+          const _OrthancPluginKeysValuesIteratorNext& p =
+            *reinterpret_cast<const _OrthancPluginKeysValuesIteratorNext*>(parameters);
+
+          StatelessDatabaseOperations::KeysValuesIterator& iterator = *reinterpret_cast<StatelessDatabaseOperations::KeysValuesIterator*>(p.iterator);
+          *p.done = iterator.Next() ? 1 : 0;
+          return true;
+        }
+
+      case _OrthancPluginService_KeysValuesIteratorGetKey:
+      case _OrthancPluginService_KeysValuesIteratorGetValue:
+        if (!HasKeyValueStoresSupport())
+        {
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support key-value stores");
+        }
+        else
+        {
+          const _OrthancPluginKeysValuesIteratorGetString& p =
+            *reinterpret_cast<const _OrthancPluginKeysValuesIteratorGetString*>(parameters);
+
+          StatelessDatabaseOperations::KeysValuesIterator& iterator = *reinterpret_cast<StatelessDatabaseOperations::KeysValuesIterator*>(p.iterator);
+
+          if (service == _OrthancPluginService_KeysValuesIteratorGetKey)
+          {
+            *p.target = iterator.GetKey().c_str();
+            return true;
+          }
+          else if (service == _OrthancPluginService_KeysValuesIteratorGetValue)
+          {
+            *p.target = iterator.GetValue().c_str();
+            return true;
+          }
+          else
+          {
+            throw OrthancException(ErrorCode_InternalError);
+          }
+        }
 
       case _OrthancPluginService_EnqueueValue:
-      {
         if (!HasQueuesSupport())
         {
-          LOG(ERROR) << "The DB engine does not support Queues";
-          return false;
-        }
-
-        const _OrthancPluginEnqueueValue& p =
-          *reinterpret_cast<const _OrthancPluginEnqueueValue*>(parameters);
-        ApplyEnqueueValue(p);
-        return true;
-      }
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support queues");
+        }
+        else
+        {
+          const _OrthancPluginEnqueueValue& p =
+            *reinterpret_cast<const _OrthancPluginEnqueueValue*>(parameters);
+          ApplyEnqueueValue(p);
+          return true;
+        }
 
       case _OrthancPluginService_DequeueValue:
-      {
         if (!HasQueuesSupport())
         {
-          LOG(ERROR) << "The DB engine does not support Queues";
-          return false;
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support queues");
         }
         else
         {
@@ -5986,21 +6015,19 @@
           ApplyDequeueValue(p);
           return true;
         }
-      }
 
       case _OrthancPluginService_GetQueueSize:
-      {
         if (!HasQueuesSupport())
         {
-          LOG(ERROR) << "The DB engine does not support Queues";
-          return false;
-        }
-
-        const _OrthancPluginGetQueueSize& p =
-          *reinterpret_cast<const _OrthancPluginGetQueueSize*>(parameters);
-        ApplyGetQueueSize(p);
-        return true;
-      }
+          throw OrthancException(ErrorCode_NotImplemented, "The DB engine does not support queues");
+        }
+        else
+        {
+          const _OrthancPluginGetQueueSize& p =
+            *reinterpret_cast<const _OrthancPluginGetQueueSize*>(parameters);
+          ApplyGetQueueSize(p);
+          return true;
+        }
 
       default:
         return false;
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.h	Tue May 20 17:53:14 2025 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h	Tue May 20 19:03:11 2025 +0200
@@ -237,8 +237,6 @@
 
     void ApplyGetKeyValue(const _OrthancPluginGetKeyValue& parameters);
 
-    void ApplyListKeys(const _OrthancPluginListKeys& parameters);
-
     bool HasQueuesSupport();
 
     void ApplyEnqueueValue(const _OrthancPluginEnqueueValue& parameters);
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h	Tue May 20 17:53:14 2025 +0200
+++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h	Tue May 20 19:03:11 2025 +0200
@@ -470,15 +470,19 @@
     _OrthancPluginService_SetCurrentThreadName = 44,                /* New in Orthanc 1.12.2 */
     _OrthancPluginService_LogMessage = 45,                          /* New in Orthanc 1.12.4 */
     _OrthancPluginService_AdoptAttachment = 46,                     /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_StoreKeyValue = 47,                       /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_DeleteKeyValue = 48,                      /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_GetKeyValue = 49,                         /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_ListKeys = 50,                            /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_EnqueueValue = 51,                        /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_DequeueValue = 52,                        /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_GetQueueSize = 53,                        /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_GetAttachmentCustomData = 54,             /* New in Orthanc 1.12.99 */
-    _OrthancPluginService_UpdateAttachmentCustomData = 55,          /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_GetAttachmentCustomData = 47,             /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_UpdateAttachmentCustomData = 48,          /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_StoreKeyValue = 49,                       /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_DeleteKeyValue = 50,                      /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_GetKeyValue = 51,                         /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_CreateKeysValuesIterator = 52,            /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_FreeKeysValuesIterator = 53,              /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_KeysValuesIteratorNext = 54,              /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_KeysValuesIteratorGetKey = 55,            /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_KeysValuesIteratorGetValue = 56,          /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_EnqueueValue = 57,                        /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_DequeueValue = 58,                        /* New in Orthanc 1.12.99 */
+    _OrthancPluginService_GetQueueSize = 59,                        /* New in Orthanc 1.12.99 */
 
 
     /* Registration of callbacks */
@@ -9849,7 +9853,7 @@
   typedef struct
   {
     const char*                   attachmentUuid; /* in */
-    // OrthancPluginContentType      contentType; /* in */
+    /* OrthancPluginContentType      contentType; */ /* in */
     OrthancPluginMemoryBuffer*    customData;  /* out */
   } _OrthancPluginGetAttachmentCustomData;
 
@@ -9862,13 +9866,13 @@
   ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginGetAttachmentCustomData(
     OrthancPluginContext*         context,
     const char*                   attachmentUuid, /* in */
-    // OrthancPluginContentType      contentType, /* in */
+    /* OrthancPluginContentType      contentType, */ /* in */
     OrthancPluginMemoryBuffer*    customData /* out */
   ) 
   {
     _OrthancPluginGetAttachmentCustomData params;
     params.attachmentUuid = attachmentUuid;
-    // params.contentType = contentType;
+    /* params.contentType = contentType; */
     params.customData = customData;
 
     return context->InvokeService(context, _OrthancPluginService_GetAttachmentCustomData, &params);
@@ -9998,40 +10002,138 @@
     return context->InvokeService(context, _OrthancPluginService_GetKeyValue, &params);
   }
 
-  typedef struct
-  {
-    const char*                   storeId;
-    uint64_t                      since;
-    uint64_t                      limit;
-    OrthancPluginMemoryBuffer*    keys;
-  } _OrthancPluginListKeys;
-
-
-  /**
-   * @brief Create an iterator over the keys and values stored in a key-value store.
-   *
-   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
-   * @param storeId A unique identifier identifying both the plugin and the store
-   * @param since The index of the first key to return when sorted alphabetically
-   * @param limit The number of keys to return (0 for no limit)
-   * @param keys The keys serialized in a json string
-   * @return 0 if success, other value if error.
-   **/
-  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginListKeys(
-    OrthancPluginContext*         context,
-    const char*                   storeId, /* in */
-    uint64_t                      since, /* in */
-    uint64_t                      limit, /* in */
-    OrthancPluginMemoryBuffer*    keys /* out */)
-  {
-    _OrthancPluginListKeys params;
+
+  /**
+   * @brief Opaque structure that represents an iterator to the keys and values of
+   * a key-value store.
+   * @ingroup Callbacks
+   **/
+  typedef struct _OrthancPluginKeysValuesIterator_t OrthancPluginKeysValuesIterator;
+
+
+
+  typedef struct
+  {
+    OrthancPluginKeysValuesIterator**  target;
+    const char*                        storeId;
+  } _OrthancPluginCreateKeysValuesIterator;
+
+
+  /* TODO_ATTACH_CUSTOM_DATA TODO DOCUMENT */
+
+  ORTHANC_PLUGIN_INLINE OrthancPluginKeysValuesIterator* OrthancPluginCreateKeysValuesIterator(
+    OrthancPluginContext*  context,
+    const char*            storeId)
+  {
+    OrthancPluginKeysValuesIterator* target = NULL;
+
+    _OrthancPluginCreateKeysValuesIterator params;
+    params.target = &target;
     params.storeId = storeId;
-    params.since = since;
-    params.limit = limit;
-    params.keys = keys;
-
-    return context->InvokeService(context, _OrthancPluginService_ListKeys, &params);
-  }
+
+    if (context->InvokeService(context, _OrthancPluginService_CreateKeysValuesIterator, &params) != OrthancPluginErrorCode_Success)
+    {
+      return NULL;
+    }
+    else
+    {
+      return target;
+    }
+  }
+
+
+  typedef struct
+  {
+    OrthancPluginKeysValuesIterator*   iterator;
+  } _OrthancPluginFreeKeysValuesIterator;
+
+  /* TODO_ATTACH_CUSTOM_DATA TODO DOCUMENT */
+
+  ORTHANC_PLUGIN_INLINE void  OrthancPluginFreeKeysValuesIterator(
+    OrthancPluginContext*             context,
+    OrthancPluginKeysValuesIterator*  iterator)
+  {
+    _OrthancPluginFreeKeysValuesIterator params;
+    params.iterator = iterator;
+
+    context->InvokeService(context, _OrthancPluginService_FreeKeysValuesIterator, &params);
+  }
+
+
+  typedef struct
+  {
+    uint8_t*                          done;
+    OrthancPluginKeysValuesIterator*  iterator;
+  } _OrthancPluginKeysValuesIteratorNext;
+
+
+  /* TODO_ATTACH_CUSTOM_DATA TODO DOCUMENT */
+
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginKeysValuesIteratorNext(
+    OrthancPluginContext*             context,
+    uint8_t*                          done,
+    OrthancPluginKeysValuesIterator*  iterator)
+  {
+    _OrthancPluginKeysValuesIteratorNext params;
+    params.done = done;
+    params.iterator = iterator;
+
+    return context->InvokeService(context, _OrthancPluginService_KeysValuesIteratorNext, &params);
+  }
+
+
+  typedef struct
+  {
+    const char**                      target;
+    OrthancPluginKeysValuesIterator*  iterator;
+  } _OrthancPluginKeysValuesIteratorGetString;
+
+
+  /* TODO_ATTACH_CUSTOM_DATA TODO DOCUMENT */
+
+  ORTHANC_PLUGIN_INLINE const char* OrthancPluginKeysValuesIteratorGetKey(
+    OrthancPluginContext*             context,
+    OrthancPluginKeysValuesIterator*  iterator)
+  {
+    const char* target = NULL;
+
+    _OrthancPluginKeysValuesIteratorGetString params;
+    params.target = &target;
+    params.iterator = iterator;
+
+    if (context->InvokeService(context, _OrthancPluginService_KeysValuesIteratorGetKey, &params) == OrthancPluginErrorCode_Success)
+    {
+      return target;
+    }
+    else
+    {
+      return NULL;
+    }
+  }
+
+
+  /* TODO_ATTACH_CUSTOM_DATA TODO DOCUMENT */
+
+  ORTHANC_PLUGIN_INLINE const char* OrthancPluginKeysValuesIteratorGetValue(
+    OrthancPluginContext*             context,
+    OrthancPluginKeysValuesIterator*  iterator)
+  {
+    const char* target = NULL;
+
+    _OrthancPluginKeysValuesIteratorGetString params;
+    params.target = &target;
+    params.iterator = iterator;
+
+    if (context->InvokeService(context, _OrthancPluginService_KeysValuesIteratorGetValue, &params) == OrthancPluginErrorCode_Success)
+    {
+      return target;
+    }
+    else
+    {
+      return NULL;
+    }
+  }
+
 
 
   typedef struct
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Tue May 20 17:53:14 2025 +0200
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Tue May 20 19:03:11 2025 +0200
@@ -4350,6 +4350,76 @@
 
 
 #if HAS_ORTHANC_PLUGIN_KEY_VALUE_STORES == 1
+  KeyValueStore::Iterator::Iterator(OrthancPluginKeysValuesIterator  *iterator) :
+    iterator_(iterator)
+  {
+    if (iterator_ == NULL)
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_KEY_VALUE_STORES == 1
+  KeyValueStore::Iterator::~Iterator()
+  {
+    OrthancPluginFreeKeysValuesIterator(OrthancPlugins::GetGlobalContext(), iterator_);
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_KEY_VALUE_STORES == 1
+  bool KeyValueStore::Iterator::Next()
+  {
+    uint8_t done;
+    OrthancPluginErrorCode code = OrthancPluginKeysValuesIteratorNext(OrthancPlugins::GetGlobalContext(), &done, iterator_);
+
+    if (code != OrthancPluginErrorCode_Success)
+    {
+      ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code);
+    }
+    else
+    {
+      return (done != 0);
+    }
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_KEY_VALUE_STORES == 1
+  std::string KeyValueStore::Iterator::GetKey() const
+  {
+    const char* s = OrthancPluginKeysValuesIteratorGetKey(OrthancPlugins::GetGlobalContext(), iterator_);
+    if (s == NULL)
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+    else
+    {
+      return s;
+    }
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_KEY_VALUE_STORES == 1
+  std::string KeyValueStore::Iterator::GetValue() const
+  {
+    const char* s = OrthancPluginKeysValuesIteratorGetValue(OrthancPlugins::GetGlobalContext(), iterator_);
+    if (s == NULL)
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+    else
+    {
+      return s;
+    }
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_KEY_VALUE_STORES == 1
   void KeyValueStore::Store(const std::string& key,
                             const std::string& value)
   {
@@ -4404,32 +4474,9 @@
 
 
 #if HAS_ORTHANC_PLUGIN_KEY_VALUE_STORES == 1
-  bool KeyValueStore::GetAllKeys(std::list<std::string>& keys, uint64_t since, uint64_t limit)
-  {
-    OrthancPlugins::MemoryBuffer keysListBuffer;
-    OrthancPluginErrorCode ret = OrthancPluginListKeys(OrthancPlugins::GetGlobalContext(), storeId_.c_str(),
-                                                       since, limit, *keysListBuffer);
-
-    if (ret == OrthancPluginErrorCode_Success)
-    {
-      Json::Value jsonKeys;
-      keysListBuffer.ToJson(jsonKeys);
-
-      for (Json::ArrayIndex i = 0; i < jsonKeys.size(); ++i)
-      {
-        keys.push_back(jsonKeys[i].asString());
-      }
-
-      // return true if all values have been read
-      return limit == 0 || (jsonKeys.size() < limit);
-    }
-    
-#if HAS_ORTHANC_EXCEPTION == 1
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Unable to list keys");
-#else
-    ORTHANC_PLUGINS_LOG_ERROR("Unable to list keys");
-    ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
-#endif
+  KeyValueStore::Iterator* KeyValueStore::CreateIterator()
+  {
+    return new Iterator(OrthancPluginCreateKeysValuesIterator(OrthancPlugins::GetGlobalContext(), storeId_.c_str()));
   }
 #endif
 
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Tue May 20 17:53:14 2025 +0200
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Tue May 20 19:03:11 2025 +0200
@@ -1631,6 +1631,24 @@
 #if HAS_ORTHANC_PLUGIN_KEY_VALUE_STORES == 1
   class KeyValueStore : public boost::noncopyable
   {
+  public:
+    class Iterator : public boost::noncopyable
+    {
+    private:
+      OrthancPluginKeysValuesIterator  *iterator_;
+
+    public:
+      Iterator(OrthancPluginKeysValuesIterator  *iterator);
+
+      ~Iterator();
+
+      bool Next();
+
+      std::string GetKey() const;
+
+      std::string GetValue() const;
+    };
+
   private:
     std::string storeId_;
 
@@ -1648,7 +1666,7 @@
 
     void Delete(const std::string& key);
 
-    bool GetAllKeys(std::list<std::string>& keys, uint64_t since, uint64_t limit);
+    Iterator* CreateIterator();
   };
 #endif