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 Redis sorted set operations. /// Provides functionality for ZADD, ZREM, ZRANGE, ZREVRANGE, ZRANGEBYSCORE, ZCARD, ZSCORE, ZRANK, ZREVRANK, ZINCRBY, ZREVRANGEBYSCORE, ZCOUNT, ZUNIONSTORE, ZINTERSTORE, ZSCAN, ZPOPMAX, ZPOPMIN, ZREMRANGEBYRANK, and ZREMRANGEBYSCORE commands. /// [Verb("zadd", HelpText = "Add members to a sorted set.")] public class ZAddOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "score", Required = true, HelpText = "Score for the member.")] public double Score { get; set; } [Value(2, MetaName = "member", Required = true, HelpText = "Member to add.")] public string Member { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zrem", HelpText = "Remove members from a sorted set.")] public class ZRemOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "members", Min = 1, Required = true, HelpText = "Members to remove.")] public IEnumerable Members { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zrange", HelpText = "Get range of members by rank.")] public class ZRangeOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "start", Required = true, HelpText = "Start rank.")] public long Start { get; set; } [Value(2, MetaName = "stop", Required = true, HelpText = "Stop rank.")] public long Stop { get; set; } [Option("withscores", Required = false, HelpText = "Include scores in output.")] public bool WithScores { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zrevrange", HelpText = "Get range of members by rank (reverse order).")] public class ZRevRangeOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "start", Required = true, HelpText = "Start rank.")] public long Start { get; set; } [Value(2, MetaName = "stop", Required = true, HelpText = "Stop rank.")] public long Stop { get; set; } [Option("withscores", Required = false, HelpText = "Include scores in output.")] public bool WithScores { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zrangebyscore", HelpText = "Get range of members by score.")] public class ZRangeByScoreOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "min", Required = true, HelpText = "Minimum score.")] public double Min { get; set; } [Value(2, MetaName = "max", Required = true, HelpText = "Maximum score.")] public double Max { get; set; } [Option("withscores", Required = false, HelpText = "Include scores in output.")] public bool WithScores { get; set; } [Option("limit", Required = false, HelpText = "Limit results (offset count).")] public string Limit { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zcard", HelpText = "Get the number of members in a sorted set.")] public class ZCardOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zscore", HelpText = "Get the score of a member.")] public class ZScoreOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "member", Required = true, HelpText = "Member name.")] public string Member { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zrank", HelpText = "Get the rank of a member.")] public class ZRankOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "member", Required = true, HelpText = "Member name.")] public string Member { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zrevrank", HelpText = "Get the reverse rank of a member.")] public class ZRevRankOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "member", Required = true, HelpText = "Member name.")] public string Member { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zincrby", HelpText = "Increment the score of a member.")] public class ZIncrByOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "increment", Required = true, HelpText = "Score increment.")] public double Increment { get; set; } [Value(2, MetaName = "member", Required = true, HelpText = "Member name.")] public string Member { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zrevrangebyscore", HelpText = "Get range of members by score (reverse order).")] public class ZRevRangeByScoreOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "max", Required = true, HelpText = "Maximum score.")] public double Max { get; set; } [Value(2, MetaName = "min", Required = true, HelpText = "Minimum score.")] public double Min { get; set; } [Option("withscores", Required = false, HelpText = "Include scores in output.")] public bool WithScores { get; set; } [Option("limit", Required = false, HelpText = "Limit results (offset count).")] public string Limit { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zcount", HelpText = "Count members within a score range.")] public class ZCountOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "min", Required = true, HelpText = "Minimum score.")] public double Min { get; set; } [Value(2, MetaName = "max", Required = true, HelpText = "Maximum score.")] public double Max { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zunionstore", HelpText = "Store union of multiple sorted sets.")] public class ZUnionStoreOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "destination", Required = true, HelpText = "Destination sorted set key.")] public string Destination { get; set; } [Value(1, MetaName = "numkeys", Required = true, HelpText = "Number of source keys.")] public int NumKeys { get; set; } [Value(2, MetaName = "keys", Min = 1, Required = true, HelpText = "Source sorted set keys.")] public IEnumerable Keys { get; set; } [Option("weights", Required = false, HelpText = "Weights for each source set.")] public IEnumerable Weights { get; set; } [Option("aggregate", Required = false, HelpText = "Aggregation method (sum, min, max).")] public string Aggregate { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zinterstore", HelpText = "Store intersection of multiple sorted sets.")] public class ZInterStoreOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "destination", Required = true, HelpText = "Destination sorted set key.")] public string Destination { get; set; } [Value(1, MetaName = "numkeys", Required = true, HelpText = "Number of source keys.")] public int NumKeys { get; set; } [Value(2, MetaName = "keys", Min = 1, Required = true, HelpText = "Source sorted set keys.")] public IEnumerable Keys { get; set; } [Option("weights", Required = false, HelpText = "Weights for each source set.")] public IEnumerable Weights { get; set; } [Option("aggregate", Required = false, HelpText = "Aggregation method (sum, min, max).")] public string Aggregate { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zscan", HelpText = "Scan sorted set members.")] public class ZScanOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "cursor", Required = true, HelpText = "Cursor position.")] public int Cursor { get; set; } [Option("match", Required = false, HelpText = "Pattern to match.")] public string Match { get; set; } [Option("count", Required = false, HelpText = "Count hint.")] public int? Count { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zpopmax", HelpText = "Remove and return members with highest scores.")] public class ZPopMaxOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Option("count", Required = false, HelpText = "Number of members to pop.")] public int? Count { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zpopmin", HelpText = "Remove and return members with lowest scores.")] public class ZPopMinOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Option("count", Required = false, HelpText = "Number of members to pop.")] public int? Count { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zremrangebyrank", HelpText = "Remove members by rank range.")] public class ZRemRangeByRankOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "start", Required = true, HelpText = "Start rank.")] public long Start { get; set; } [Value(2, MetaName = "stop", Required = true, HelpText = "Stop rank.")] public long Stop { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } [Verb("zremrangebyscore", HelpText = "Remove members by score range.")] public class ZRemRangeByScoreOptions { [Option('i', "instance", Required = true, HelpText = "Instance name.")] public string Instance { get; set; } [Value(0, MetaName = "key", Required = true, HelpText = "Sorted set key.")] public string Key { get; set; } [Value(1, MetaName = "min", Required = true, HelpText = "Minimum score.")] public double Min { get; set; } [Value(2, MetaName = "max", Required = true, HelpText = "Maximum score.")] public double Max { get; set; } [Option("table", Required = false, HelpText = "Output as table.")] public bool Table { get; set; } } public static class SortedSetCommands { /// /// Executes the ZADD command to add members to a sorted set. /// /// The ZAddOptions containing instance, key, score, and member. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZAdd(ZAddOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var count = db.SortedSetAdd(opts.Key, opts.Member, opts.Score); if (opts.Table) { RedisUtils.PrintTable(new[] { "Key", "Added Count" }, new List { new[] { opts.Key, count.ToString() } }); } else Console.WriteLine(Output.Green($"Added {count} new member(s)")); return 0; } /// /// Executes the ZREM command to remove members from a sorted set. /// /// The ZRemOptions containing instance, key, and members. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRem(ZRemOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var members = opts.Members.ToArray(); var count = db.SortedSetRemove(opts.Key, members.Select(m => (RedisValue)m).ToArray()); if (opts.Table) { var rows = members.Select(m => new[] { m, "Removed" }).ToList(); RedisUtils.PrintTable(new[] { "Member", "Status" }, rows); RedisUtils.PrintTable(new[] { "Key", "Removed Count" }, new List { new[] { opts.Key, count.ToString() } }); } else Console.WriteLine(Output.Green($"Removed {count} member(s)")); return 0; } /// /// Executes the ZRANGE command to get a range of members by rank. /// /// The ZRangeOptions containing instance, key, start, and stop. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRange(ZRangeOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); if (opts.WithScores) { var entries = db.SortedSetRangeByRankWithScores(opts.Key, opts.Start, opts.Stop, Order.Ascending); if (opts.Table) { var rows = entries.Select(e => new string[] { e.Element.ToString(), e.Score.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member", "Score" }, rows); } else { foreach (var e in entries) Console.WriteLine(Output.Green($"{e.Element} {e.Score}")); } } else { var members = db.SortedSetRangeByRank(opts.Key, opts.Start, opts.Stop, Order.Ascending); if (opts.Table) { var rows = members.Select(m => new[] { m.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member" }, rows); } else { foreach (var member in members) Console.WriteLine(Output.Green(member.ToString())); } } return 0; } /// /// Executes the ZREVRANGE command to get a range of members by rank in reverse order. /// /// The ZRevRangeOptions containing instance, key, start, and stop. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRevRange(ZRevRangeOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); if (opts.WithScores) { var entries = db.SortedSetRangeByRankWithScores(opts.Key, opts.Start, opts.Stop, Order.Descending); if (opts.Table) { var rows = entries.Select(e => new string[] { e.Element.ToString(), e.Score.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member", "Score" }, rows); } else { foreach (var e in entries) Console.WriteLine(Output.Green($"{e.Element} {e.Score}")); } } else { var members = db.SortedSetRangeByRank(opts.Key, opts.Start, opts.Stop, Order.Descending); if (opts.Table) { var rows = members.Select(m => new[] { m.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member" }, rows); } else { foreach (var member in members) Console.WriteLine(Output.Green(member.ToString())); } } return 0; } /// /// Executes the ZRANGEBYSCORE command to get a range of members by score. /// /// The ZRangeByScoreOptions containing instance, key, min, and max. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRangeByScore(ZRangeByScoreOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); if (opts.WithScores) { var entries = db.SortedSetRangeByScoreWithScores(opts.Key, opts.Min, opts.Max, Exclude.None, Order.Ascending); if (opts.Table) { var rows = entries.Select(e => new string[] { e.Element.ToString(), e.Score.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member", "Score" }, rows); } else { foreach (var e in entries) Console.WriteLine(Output.Green($"{e.Element} {e.Score}")); } } else { var members = db.SortedSetRangeByScore(opts.Key, opts.Min, opts.Max, Exclude.None, Order.Ascending); if (opts.Table) { var rows = members.Select(m => new[] { m.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member" }, rows); } else { foreach (var member in members) Console.WriteLine(Output.Green(member.ToString())); } } return 0; } /// /// Executes the ZCARD command to get the number of members in a sorted set. /// /// The ZCardOptions containing instance and key. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZCard(ZCardOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var count = db.SortedSetLength(opts.Key); if (opts.Table) RedisUtils.PrintTable(new[] { "Key", "Cardinality" }, new List { new[] { opts.Key, count.ToString() } }); else Console.WriteLine(Output.Green(count.ToString())); return 0; } /// /// Executes the ZSCORE command to get the score of a member in a sorted set. /// /// The ZScoreOptions containing instance, key, and member. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZScore(ZScoreOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var score = db.SortedSetScore(opts.Key, opts.Member); if (opts.Table) RedisUtils.PrintTable(new[] { "Key", "Member", "Score" }, new List { new[] { opts.Key, opts.Member, score?.ToString() ?? "[null]" } }); else if (score.HasValue) Console.WriteLine(Output.Green(score.Value.ToString())); else Console.WriteLine(Output.Yellow("[null]")); return 0; } /// /// Executes the ZRANK command to get the rank of a member in a sorted set. /// /// The ZRankOptions containing instance, key, and member. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRank(ZRankOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var rank = db.SortedSetRank(opts.Key, opts.Member); if (opts.Table) RedisUtils.PrintTable(new[] { "Key", "Member", "Rank" }, new List { new[] { opts.Key, opts.Member, rank?.ToString() ?? "[null]" } }); else if (rank.HasValue) Console.WriteLine(Output.Green(rank.Value.ToString())); else Console.WriteLine(Output.Yellow("[null]")); return 0; } /// /// Executes the ZREVRANK command to get the reverse rank of a member in a sorted set. /// /// The ZRevRankOptions containing instance, key, and member. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRevRank(ZRevRankOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var rank = db.SortedSetRank(opts.Key, opts.Member, Order.Descending); if (opts.Table) RedisUtils.PrintTable(new[] { "Key", "Member", "Reverse Rank" }, new List { new[] { opts.Key, opts.Member, rank?.ToString() ?? "[null]" } }); else if (rank.HasValue) Console.WriteLine(Output.Green(rank.Value.ToString())); else Console.WriteLine(Output.Yellow("[null]")); return 0; } /// /// Executes the ZINCRBY command to increment the score of a member in a sorted set. /// /// The ZIncrByOptions containing instance, key, increment, and member. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZIncrBy(ZIncrByOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var newScore = db.SortedSetIncrement(opts.Key, opts.Member, opts.Increment); if (opts.Table) RedisUtils.PrintTable(new[] { "Key", "Member", "New Score" }, new List { new[] { opts.Key, opts.Member, newScore.ToString() } }); else Console.WriteLine(Output.Green(newScore.ToString())); return 0; } /// /// Executes the ZREVRANGEBYSCORE command to get a range of members by score in reverse order. /// /// The ZRevRangeByScoreOptions containing instance, key, max, and min. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRevRangeByScore(ZRevRangeByScoreOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); if (opts.WithScores) { var entries = db.SortedSetRangeByScoreWithScores(opts.Key, opts.Min, opts.Max, Exclude.None, Order.Descending); if (opts.Table) { var rows = entries.Select(e => new string[] { e.Element.ToString(), e.Score.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member", "Score" }, rows); } else foreach (var entry in entries) Console.WriteLine(Output.Green($"{entry.Element}: {entry.Score}")); } else { var members = db.SortedSetRangeByScore(opts.Key, opts.Min, opts.Max, Exclude.None, Order.Descending); if (opts.Table) { var rows = members.Select(m => new string[] { m.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member" }, rows); } else foreach (var member in members) Console.WriteLine(Output.Green(member.ToString())); } return 0; } /// /// Executes the ZCOUNT command to count members within a score range in a sorted set. /// /// The ZCountOptions containing instance, key, min, and max. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZCount(ZCountOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var count = db.SortedSetLengthByValue(opts.Key, opts.Min, opts.Max); if (opts.Table) RedisUtils.PrintTable(new[] { "Key", "Count" }, new List { new[] { opts.Key, count.ToString() } }); else Console.WriteLine(Output.Green(count.ToString())); return 0; } /// /// Executes the ZUNIONSTORE command to store the union of multiple sorted sets. /// /// The ZUnionStoreOptions containing instance, destination, numkeys, and keys. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZUnionStore(ZUnionStoreOptions 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 count = db.SortedSetCombineAndStore(SetOperation.Union, opts.Destination, keys); if (opts.Table) RedisUtils.PrintTable(new[] { "Destination", "Stored Count" }, new List { new[] { opts.Destination, count.ToString() } }); else Console.WriteLine(Output.Green($"Stored {count} member(s) in {opts.Destination}")); return 0; } /// /// Executes the ZINTERSTORE command to store the intersection of multiple sorted sets. /// /// The ZInterStoreOptions containing instance, destination, numkeys, and keys. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZInterStore(ZInterStoreOptions 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 count = db.SortedSetCombineAndStore(SetOperation.Intersect, opts.Destination, keys); if (opts.Table) RedisUtils.PrintTable(new[] { "Destination", "Stored Count" }, new List { new[] { opts.Destination, count.ToString() } }); else Console.WriteLine(Output.Green($"Stored {count} member(s) in {opts.Destination}")); return 0; } /// /// Executes the ZSCAN command to scan sorted set members. /// /// The ZScanOptions containing instance, key, cursor, and scan options. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZScan(ZScanOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var result = db.SortedSetScan(opts.Key, opts.Match ?? "*", pageSize: opts.Count ?? 10, cursor: opts.Cursor); if (opts.Table) { var rows = result.Select(e => new[] { e.Element.ToString(), e.Score.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Member", "Score" }, rows); } else { foreach (var entry in result) Console.WriteLine(Output.Green($"{entry.Element}: {entry.Score}")); } return 0; } /// /// Executes the ZPOPMAX command to remove and return members with the highest scores. /// /// The ZPopMaxOptions containing instance, key, and count. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZPopMax(ZPopMaxOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); if (opts.Count.HasValue) { var entries = db.SortedSetPop(opts.Key, opts.Count.Value); if (opts.Table) { var rows = entries.Select(e => new string[] { e.Element.ToString(), e.Score.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Popped Member", "Score" }, rows); } else foreach (var entry in entries) Console.WriteLine(Output.Green($"{entry.Element}: {entry.Score}")); } else { var entry = db.SortedSetPop(opts.Key); if (opts.Table) RedisUtils.PrintTable(new[] { "Popped Member", "Score" }, new List { new[] { entry.Value.Element.ToString(), entry.Value.Score.ToString() } }); else Console.WriteLine(Output.Green($"{entry.Value.Element}: {entry.Value.Score}")); } return 0; } /// /// Executes the ZPOPMIN command to remove and return members with the lowest scores. /// /// The ZPopMinOptions containing instance, key, and count. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZPopMin(ZPopMinOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); if (opts.Count.HasValue) { var entries = db.SortedSetPop(opts.Key, opts.Count.Value); if (opts.Table) { var rows = entries.Select(e => new string[] { e.Element.ToString(), e.Score.ToString() }).ToList(); RedisUtils.PrintTable(new[] { "Popped Member", "Score" }, rows); } else foreach (var entry in entries) Console.WriteLine(Output.Green($"{entry.Element}: {entry.Score}")); } else { var entry = db.SortedSetPop(opts.Key); if (opts.Table) RedisUtils.PrintTable(new[] { "Popped Member", "Score" }, new List { new[] { entry.Value.Element.ToString(), entry.Value.Score.ToString() } }); else Console.WriteLine(Output.Green($"{entry.Value.Element}: {entry.Value.Score}")); } return 0; } /// /// Executes the ZREMRANGEBYRANK command to remove members by rank range. /// /// The ZRemRangeByRankOptions containing instance, key, start, and stop. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRemRangeByRank(ZRemRangeByRankOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var count = db.SortedSetRemoveRangeByRank(opts.Key, opts.Start, opts.Stop); if (opts.Table) RedisUtils.PrintTable(new[] { "Key", "Removed Count" }, new List { new[] { opts.Key, count.ToString() } }); else Console.WriteLine(Output.Green($"Removed {count} member(s)")); return 0; } /// /// Executes the ZREMRANGEBYSCORE command to remove members by score range. /// /// The ZRemRangeByScoreOptions containing instance, key, min, and max. /// The RedisManager configuration. /// Exit code (0 for success, non-zero for failure). public static int RunZRemRangeByScore(ZRemRangeByScoreOptions opts, Config config) { var instance = RedisUtils.GetInstance(config, opts.Instance); using var redis = RedisUtils.ConnectRedis(instance); var db = redis.GetDatabase(); var count = db.SortedSetRemoveRangeByScore(opts.Key, opts.Min, opts.Max); if (opts.Table) RedisUtils.PrintTable(new[] { "Key", "Removed Count" }, new List { new[] { opts.Key, count.ToString() } }); else Console.WriteLine(Output.Green($"Removed {count} member(s)")); return 0; } } }