From 9ee37de5cf3fb8b61ec8801c01a1f599e6d4a938 Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Tue, 26 Nov 2024 11:26:27 +0100 Subject: [PATCH] MINOR: hlua_fcn: add Patref:set() Just like "set map" on the cli, the Patref:set() method (only relevant for maps) can be used to modify an existing entry's value in the pattern reference pointed to by the Lua Patref object. Lookup is performed on the key. The update will target the live pattern reference version, unless Patref:prepare() is ongoing. --- doc/lua-api/index.rst | 16 ++++++++++++++ src/hlua_fcn.c | 51 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst index d932064cf..58a0088a2 100644 --- a/doc/lua-api/index.rst +++ b/doc/lua-api/index.rst @@ -3510,6 +3510,22 @@ Patref class Affects the live pattern reference version, unless :js:func:`Patref.prepare()` was called and is still ongoing (waiting for commit or giveup) +.. js:function:: Patref.set(ref, key, value[, force]) + + Only relevant for maps. Set existing entries matching key to the provided + value. In case of duplicate keys, all matching keys will be set to the new + value. + + :param string key: the string used as a key + :param string value: the string used as value + :param bool force: create the entry if it doesn't exist (optional, + defaults to false) + :returns: true on success and nil on failure (followed by an error message) + + .. Note:: + Affects the live pattern reference version, unless :js:func:`Patref.prepare()` + was called and is still ongoing (waiting for commit or giveup) + .. _applethttp_class: AppletHTTP class diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c index b1db46c34..6c9209df9 100644 --- a/src/hlua_fcn.c +++ b/src/hlua_fcn.c @@ -2797,6 +2797,56 @@ int hlua_patref_del(lua_State *L) return 1; } +int hlua_patref_set(lua_State *L) +{ + struct hlua_patref *ref; + const char *key; + const char *value; + char *errmsg = NULL; + unsigned int curr_gen; + int force = 0; + int ret; + + ref = hlua_checkudata(L, 1, class_patref_ref); + + BUG_ON(!ref); + + key = luaL_checkstring(L, 2); + value = luaL_checkstring(L, 3); + + if (lua_gettop(L) == 4) + force = lua_tointeger(L, 4); + + HA_RWLOCK_WRLOCK(PATREF_LOCK, &ref->ptr->lock); + if ((ref->flags & HLUA_PATREF_FL_GEN) && + pat_ref_may_commit(ref->ptr, ref->curr_gen)) + curr_gen = ref->curr_gen; + else + curr_gen = ref->ptr->curr_gen; + + if (force) { + struct pat_ref_elt *elt; + + elt = pat_ref_gen_find_elt(ref->ptr, curr_gen, key); + if (elt) + ret = pat_ref_set_elt_duplicate(ref->ptr, elt, value, &errmsg); + else + ret = !!pat_ref_load(ref->ptr, curr_gen, key, value, -1, &errmsg); + } + else + ret = pat_ref_gen_set(ref->ptr, curr_gen, key, value, &errmsg); + + HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock); + + if (!ret) { + ret = hlua_error(L, errmsg); + ha_free(&errmsg); + return ret; + } + lua_pushboolean(L, 1); + return 1; +} + void hlua_fcn_new_patref(lua_State *L, struct pat_ref *ref) { struct hlua_patref *_ref; @@ -2830,6 +2880,7 @@ void hlua_fcn_new_patref(lua_State *L, struct pat_ref *ref) hlua_class_function(L, "purge", hlua_patref_purge); hlua_class_function(L, "add", hlua_patref_add); hlua_class_function(L, "del", hlua_patref_del); + hlua_class_function(L, "set", hlua_patref_set); } int hlua_patref_gc(lua_State *L)