diff --git a/NewLife.Redis/FullRedis.cs b/NewLife.Redis/FullRedis.cs index fb53e68..8b00465 100644 --- a/NewLife.Redis/FullRedis.cs +++ b/NewLife.Redis/FullRedis.cs @@ -831,10 +831,11 @@ public class FullRedis : Redis /// public virtual T? RPOPLPUSH(String source, String destination) => Execute(source, (rc, k) => rc.Execute("RPOPLPUSH", k, GetKey(destination)), true); - /// + /// 弹出并插入另一个列表 + /// /// 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 /// 适用于做安全队列(通过secTimeout决定阻塞时长) - /// + /// /// /// 源列表名称 /// 元素后写入的新列表名称 @@ -998,5 +999,33 @@ public class FullRedis : Redis /// /// public virtual T[]? SPOP(String key, Int32 count) => Execute(key, (r, k) => r.Execute("SPOP", k, count), true); + + /// 执行lua脚本 + /// + /// + /// + /// + /// + public virtual T? Eval(String script, String[] keys, Object[] args) + { + // EVAL script numkeys [key [key ...]] [arg [arg ...]] + keys ??= []; + args ??= []; + var ps = new List + { + script, + keys.Length + "" + }; + for (var i = 0; i < keys.Length && i < args.Length; i++) + { + ps.Add(keys[i]); + } + for (var i = 0; i < keys.Length && i < args.Length; i++) + { + ps.Add(args[i]); + } + + return Execute("", (rc, k) => rc.Execute("EVAL", ps), true); + } #endregion } diff --git a/XUnitTest/RedisTest.cs b/XUnitTest/RedisTest.cs index b8c8e6c..0519cc7 100644 --- a/XUnitTest/RedisTest.cs +++ b/XUnitTest/RedisTest.cs @@ -541,4 +541,44 @@ public class RedisTest Assert.NotNull(ex); Assert.Equal("命令[SET]的数据包大小[1060]超过最大限制[1028],大key会拖累整个Redis实例,可通过Redis.MaxMessageSize调节。", ex.Message); } + + [Fact] + public void EvalLua() + { + var ic = _redis; + var key = "LuaTest"; + ic.Remove(key); + var script = @" + local key = KEYS[1] + local value = ARGV[1] + redis.call('SET', key, value) + return redis.call('GET', key) + "; + var rs = ic.Execute(null, (r, k) => r.Execute("EVAL", script, 1, key, "大石头")); + Assert.Equal("大石头", rs); + + // 删除 + ic.Remove(key); + rs = ic.Execute(null, (r, k) => r.Execute("EVAL", script, 1, key, "新生命")); + Assert.Equal("新生命", rs); + } + + [Fact] + public void EvalLua2() + { + var ic = _redis; + var key = "LuaTest2"; + ic.Set(key, 666); + var script = @" + local key = KEYS[1] + local value = ARGV[1] + return redis.call('INCRBY', key, value) + "; + var rs = ic.Execute(null, (r, k) => r.Execute("EVAL", script, 1, key, 123)); + Assert.Equal(666 + 123, rs); + + // 删除 + ic.Remove(key); + + } } \ No newline at end of file