[feat] 支持执行Lua脚本

This commit is contained in:
智能大石头 2025-05-03 22:55:07 +08:00
parent 44bb1203ac
commit f4a1cb811d
2 changed files with 71 additions and 2 deletions

View File

@ -831,10 +831,11 @@ public class FullRedis : Redis
/// <returns></returns>
public virtual T? RPOPLPUSH<T>(String source, String destination) => Execute(source, (rc, k) => rc.Execute<T>("RPOPLPUSH", k, GetKey(destination)), true);
/// <summary>
/// <summary>弹出并插入另一个列表</summary>
/// <remarks>
/// 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
/// 适用于做安全队列(通过secTimeout决定阻塞时长)
/// </summary>
/// </remarks>
/// <typeparam name="T"></typeparam>
/// <param name="source">源列表名称</param>
/// <param name="destination">元素后写入的新列表名称</param>
@ -998,5 +999,33 @@ public class FullRedis : Redis
/// <param name="count"></param>
/// <returns></returns>
public virtual T[]? SPOP<T>(String key, Int32 count) => Execute(key, (r, k) => r.Execute<T[]>("SPOP", k, count), true);
/// <summary>执行lua脚本</summary>
/// <typeparam name="T"></typeparam>
/// <param name="script"></param>
/// <param name="keys"></param>
/// <param name="args"></param>
/// <returns></returns>
public virtual T? Eval<T>(String script, String[] keys, Object[] args)
{
// EVAL script numkeys [key [key ...]] [arg [arg ...]]
keys ??= [];
args ??= [];
var ps = new List<Object>
{
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<T>("EVAL", ps), true);
}
#endregion
}

View File

@ -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<String>("EVAL", script, 1, key, "大石头"));
Assert.Equal("大石头", rs);
// 删除
ic.Remove(key);
rs = ic.Execute(null, (r, k) => r.Execute<String>("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<Int32>("EVAL", script, 1, key, 123));
Assert.Equal(666 + 123, rs);
// 删除
ic.Remove(key);
}
}