using CommandLine; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using RedisManager.Utils; namespace RedisManager.Commands { /// /// Contains command line options and implementations for advanced Redis string operations. /// Provides functionality for APPEND, INCR, DECR, INCRBY, DECRBY, INCRBYFLOAT, GETRANGE, SETRANGE, STRLEN, MGET, and MSET commands. /// [Verb("append", HelpText = "Append a value to a key.")] public class AppendOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } [Value(1, MetaName = "value", Required = true, HelpText = "Value to append.")] public string Value { get; set; } } [Verb("incr", HelpText = "Increment the integer value of a key by one.")] public class IncrOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } } [Verb("decr", HelpText = "Decrement the integer value of a key by one.")] public class DecrOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } } [Verb("incrby", HelpText = "Increment the integer value of a key by a given amount.")] public class IncrByOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } [Value(1, MetaName = "amount", Required = true, HelpText = "Amount to increment by.")] public long Amount { get; set; } } [Verb("decrby", HelpText = "Decrement the integer value of a key by a given amount.")] public class DecrByOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } [Value(1, MetaName = "amount", Required = true, HelpText = "Amount to decrement by.")] public long Amount { get; set; } } [Verb("incrbyfloat", HelpText = "Increment the float value of a key by a given amount.")] public class IncrByFloatOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } [Value(1, MetaName = "amount", Required = true, HelpText = "Amount to increment by.")] public double Amount { get; set; } } [Verb("getrange", HelpText = "Get a substring of the string stored at a key.")] public class GetRangeOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } [Value(1, MetaName = "start", Required = true, HelpText = "Start offset.")] public long Start { get; set; } [Value(2, MetaName = "end", Required = true, HelpText = "End offset.")] public long End { get; set; } } [Verb("setrange", HelpText = "Overwrite part of a string at key starting at the specified offset.")] public class SetRangeOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } [Value(1, MetaName = "offset", Required = true, HelpText = "Offset.")] public long Offset { get; set; } [Value(2, MetaName = "value", Required = true, HelpText = "Value to set.")] public string Value { get; set; } } [Verb("strlen", HelpText = "Get the length of the value stored in a key.")] public class StrLenOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Key.")] public string Key { get; set; } } [Verb("mget", HelpText = "Get the values of all the given keys.")] public class MGetOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "keys", Min = 1, Required = true, HelpText = "Keys.")] public IEnumerable Keys { get; set; } } [Verb("mset", HelpText = "Set multiple keys to multiple values.")] public class MSetOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Option("pairs", Required = true, HelpText = "Comma-separated key=value pairs.")] public string Pairs { get; set; } } public static class AdvancedStringCommands { /// /// Executes the APPEND command to append a value to a key. /// /// The AppendOptions containing instance, key, and value. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunAppend(AppendOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var len = db.StringAppend(opts.Key, opts.Value); Console.WriteLine(Output.Green(len.ToString())); return 0; } /// /// Executes the INCR command to increment the integer value of a key by one. /// /// The IncrOptions containing instance and key. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunIncr(IncrOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var val = db.StringIncrement(opts.Key); Console.WriteLine(Output.Green(val.ToString())); return 0; } /// /// Executes the DECR command to decrement the integer value of a key by one. /// /// The DecrOptions containing instance and key. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunDecr(DecrOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var val = db.StringDecrement(opts.Key); Console.WriteLine(Output.Green(val.ToString())); return 0; } /// /// Executes the INCRBY command to increment the integer value of a key by a given amount. /// /// The IncrByOptions containing instance, key, and amount. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunIncrBy(IncrByOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var val = db.StringIncrement(opts.Key, opts.Amount); Console.WriteLine(Output.Green(val.ToString())); return 0; } /// /// Executes the DECRBY command to decrement the integer value of a key by a given amount. /// /// The DecrByOptions containing instance, key, and amount. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunDecrBy(DecrByOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var val = db.StringDecrement(opts.Key, opts.Amount); Console.WriteLine(Output.Green(val.ToString())); return 0; } /// /// Executes the INCRBYFLOAT command to increment the float value of a key by a given amount. /// /// The IncrByFloatOptions containing instance, key, and amount. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunIncrByFloat(IncrByFloatOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var val = db.StringIncrement(opts.Key, opts.Amount); Console.WriteLine(Output.Green(val.ToString())); return 0; } /// /// Executes the GETRANGE command to get a substring of the string stored at a key. /// /// The GetRangeOptions containing instance, key, start, and end. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunGetRange(GetRangeOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var val = db.StringGetRange(opts.Key, opts.Start, opts.End); Console.WriteLine(Output.Green(val.ToString())); return 0; } /// /// Executes the SETRANGE command to overwrite part of a string at key starting at the specified offset. /// /// The SetRangeOptions containing instance, key, offset, and value. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunSetRange(SetRangeOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var len = db.StringSetRange(opts.Key, opts.Offset, opts.Value); Console.WriteLine(Output.Green(len.ToString())); return 0; } /// /// Executes the STRLEN command to get the length of the value stored in a key. /// /// The StrLenOptions containing instance and key. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunStrLen(StrLenOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var len = db.StringLength(opts.Key); Console.WriteLine(Output.Green(len.ToString())); return 0; } /// /// Executes the MGET command to get the values of all the given keys. /// /// The MGetOptions containing instance and keys. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunMGet(MGetOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var keys = opts.Keys.Select(k => (RedisKey)k).ToArray(); var vals = db.StringGet(keys); for (int i = 0; i < keys.Length; i++) { Console.WriteLine(Output.Green($"{keys[i]}: {vals[i]}")); } return 0; } /// /// Executes the MSET command to set multiple keys to multiple values. /// /// The MSetOptions containing instance and pairs. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunMSet(MSetOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var pairs = opts.Pairs.Split(',').Select(p => p.Split('=', 2)).Where(p => p.Length == 2).Select(p => new KeyValuePair(p[0].Trim(), p[1].Trim())).ToArray(); db.StringSet(pairs); Console.WriteLine(Output.Green("OK")); return 0; } } }