156 lines
7.4 KiB
C#
156 lines
7.4 KiB
C#
using CommandLine;
|
|
using StackExchange.Redis;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using RedisManager.Utils;
|
|
|
|
namespace RedisManager.Commands
|
|
{
|
|
/// <summary>
|
|
/// Contains command line options and implementations for Redis scripting operations.
|
|
/// Provides functionality for EVAL, EVALSHA, SCRIPT LOAD, SCRIPT EXISTS, and SCRIPT FLUSH commands.
|
|
/// </summary>
|
|
[Verb("eval", HelpText = "Evaluate a Lua script.")]
|
|
public class EvalOptions
|
|
{
|
|
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
|
public string Instance { get; set; }
|
|
[Value(0, MetaName = "script", Required = true, HelpText = "Lua script.")]
|
|
public string Script { get; set; }
|
|
[Option("keys", Required = false, HelpText = "Comma-separated keys.")]
|
|
public string Keys { get; set; }
|
|
[Option("args", Required = false, HelpText = "Comma-separated arguments.")]
|
|
public string Args { get; set; }
|
|
}
|
|
|
|
[Verb("evalsha", HelpText = "Evaluate a Lua script by its SHA1 hash.")]
|
|
public class EvalShaOptions
|
|
{
|
|
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
|
public string Instance { get; set; }
|
|
[Value(0, MetaName = "sha1", Required = true, HelpText = "SHA1 hash.")]
|
|
public string Sha1 { get; set; }
|
|
[Option("keys", Required = false, HelpText = "Comma-separated keys.")]
|
|
public string Keys { get; set; }
|
|
[Option("args", Required = false, HelpText = "Comma-separated arguments.")]
|
|
public string Args { get; set; }
|
|
}
|
|
|
|
[Verb("scriptload", HelpText = "Load a Lua script into the script cache.")]
|
|
public class ScriptLoadOptions
|
|
{
|
|
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
|
public string Instance { get; set; }
|
|
[Value(0, MetaName = "script", Required = true, HelpText = "Lua script.")]
|
|
public string Script { get; set; }
|
|
}
|
|
|
|
[Verb("scriptexists", HelpText = "Check if scripts exist in the script cache.")]
|
|
public class ScriptExistsOptions
|
|
{
|
|
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
|
public string Instance { get; set; }
|
|
[Value(0, MetaName = "sha1s", Min = 1, Required = true, HelpText = "SHA1 hashes.")]
|
|
public IEnumerable<string> Sha1s { get; set; }
|
|
}
|
|
|
|
[Verb("scriptflush", HelpText = "Remove all scripts from the script cache.")]
|
|
public class ScriptFlushOptions
|
|
{
|
|
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
|
public string Instance { get; set; }
|
|
}
|
|
|
|
public static class ScriptingCommands
|
|
{
|
|
/// <summary>
|
|
/// Executes the EVAL command to evaluate a Lua script.
|
|
/// </summary>
|
|
/// <param name="opts">The EvalOptions containing instance, script, keys, and arguments.</param>
|
|
/// <param name="config">The RedisManager configuration.</param>
|
|
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
|
public static int RunEval(EvalOptions opts, Config config)
|
|
{
|
|
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
|
using var redis = RedisUtils.ConnectRedis(instance);
|
|
var db = redis.GetDatabase();
|
|
var keys = string.IsNullOrEmpty(opts.Keys) ? Array.Empty<RedisKey>() : opts.Keys.Split(',').Select(k => (RedisKey)k.Trim()).ToArray();
|
|
var args = string.IsNullOrEmpty(opts.Args) ? Array.Empty<RedisValue>() : opts.Args.Split(',').Select(a => (RedisValue)a.Trim()).ToArray();
|
|
var result = db.ScriptEvaluate(opts.Script, keys, args);
|
|
Console.WriteLine(Output.Green(result.ToString()));
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the EVALSHA command to evaluate a Lua script by its SHA1 hash.
|
|
/// </summary>
|
|
/// <param name="opts">The EvalShaOptions containing instance, sha1, keys, and arguments.</param>
|
|
/// <param name="config">The RedisManager configuration.</param>
|
|
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
|
public static int RunEvalSha(EvalShaOptions opts, Config config)
|
|
{
|
|
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
|
using var redis = RedisUtils.ConnectRedis(instance);
|
|
var db = redis.GetDatabase();
|
|
var keys = string.IsNullOrEmpty(opts.Keys) ? Array.Empty<RedisKey>() : opts.Keys.Split(',').Select(k => (RedisKey)k.Trim()).ToArray();
|
|
var args = string.IsNullOrEmpty(opts.Args) ? Array.Empty<RedisValue>() : opts.Args.Split(',').Select(a => (RedisValue)a.Trim()).ToArray();
|
|
var result = db.ScriptEvaluate(opts.Sha1, keys, args);
|
|
Console.WriteLine(Output.Green(result.ToString()));
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the SCRIPT LOAD command to load a Lua script into the script cache.
|
|
/// </summary>
|
|
/// <param name="opts">The ScriptLoadOptions containing instance and script.</param>
|
|
/// <param name="config">The RedisManager configuration.</param>
|
|
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
|
public static int RunScriptLoad(ScriptLoadOptions opts, Config config)
|
|
{
|
|
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
|
using var redis = RedisUtils.ConnectRedis(instance);
|
|
var server = redis.GetServer(redis.GetEndPoints().First());
|
|
var sha1Bytes = server.ScriptLoad(opts.Script);
|
|
// Convert byte[] to hex string
|
|
var sha1 = BitConverter.ToString(sha1Bytes).Replace("-", string.Empty).ToLower();
|
|
Console.WriteLine(Output.Green(sha1));
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the SCRIPT EXISTS command to check if scripts exist in the script cache.
|
|
/// </summary>
|
|
/// <param name="opts">The ScriptExistsOptions containing instance and SHA1 hashes.</param>
|
|
/// <param name="config">The RedisManager configuration.</param>
|
|
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
|
public static int RunScriptExists(ScriptExistsOptions opts, Config config)
|
|
{
|
|
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
|
using var redis = RedisUtils.ConnectRedis(instance);
|
|
var server = redis.GetServer(redis.GetEndPoints().First());
|
|
foreach (var sha in opts.Sha1s)
|
|
{
|
|
var exists = server.ScriptExists(sha);
|
|
Console.WriteLine(Output.Green($"{sha}: {(exists ? "YES" : "NO")}"));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the SCRIPT FLUSH command to remove all scripts from the script cache.
|
|
/// </summary>
|
|
/// <param name="opts">The ScriptFlushOptions containing instance.</param>
|
|
/// <param name="config">The RedisManager configuration.</param>
|
|
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
|
public static int RunScriptFlush(ScriptFlushOptions opts, Config config)
|
|
{
|
|
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
|
using var redis = RedisUtils.ConnectRedis(instance);
|
|
var server = redis.GetServer(redis.GetEndPoints().First());
|
|
server.ScriptFlush();
|
|
Console.WriteLine(Output.Green("Script cache flushed."));
|
|
return 0;
|
|
}
|
|
}
|
|
} |