diff --git a/src/lua/hmsetnx.lua b/src/lua/hmsetnx.lua new file mode 100644 index 00000000..4d603fa6 --- /dev/null +++ b/src/lua/hmsetnx.lua @@ -0,0 +1,23 @@ +local hkey = KEYS[1]; + +if redis.call('exists', hkey) == 0 then + redis.call('hmset', hkey, unpack(ARGV)); + return 1; +else + local proceed = true; + for i,x in ipairs(ARGV) do + if (i % 2 ~= 0) then -- odd i => `x` is field + if redis.call('hexists', hkey, x) == 1 then + proceed = false; + break; + end + end + end + + if proceed then + redis.call('hmset', hkey, unpack(ARGV)); + return 1; + else + return 0; + end +end diff --git a/src/taoensso/carmine.clj b/src/taoensso/carmine.clj index 4d53f090..21d4fe2a 100644 --- a/src/taoensso/carmine.clj +++ b/src/taoensso/carmine.clj @@ -635,6 +635,17 @@ ;;;; +(def hmsetnx "Experimental." + (let [script (enc/slurp-resource "lua/hmsetnx.lua")] + (fn [key field value & more] + (-eval* script 1 (into [key field value] more))))) + +(comment + (wcar {} (hgetall "foo")) + (wcar {} (hmsetnx "foo" "f1" "v1" "f2" "v2"))) + +;;;; + (defn reduce-scan "For use with `scan`, `zscan`, etc. Takes: - (fn rf [acc scan-result]) -> next accumulator