add project
This commit is contained in:
296
Commands/ServerCommands.cs
Normal file
296
Commands/ServerCommands.cs
Normal file
@ -0,0 +1,296 @@
|
||||
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 server operations.
|
||||
/// Provides functionality for INFO, CONFIG, SAVE, BGSAVE, LASTSAVE, TIME, and PING commands.
|
||||
/// </summary>
|
||||
[Verb("info", HelpText = "Get information and statistics about the server.")]
|
||||
public class InfoOptions
|
||||
{
|
||||
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
||||
public string Instance { get; set; }
|
||||
[Option("section", Required = false, HelpText = "Info section (server, clients, memory, etc.).")]
|
||||
public string Section { get; set; }
|
||||
[Option("table", Required = false, HelpText = "Output as table.")]
|
||||
public bool Table { get; set; }
|
||||
}
|
||||
|
||||
[Verb("config", HelpText = "Get/set Redis configuration parameters.")]
|
||||
public class ConfigOptions
|
||||
{
|
||||
[Option("list-custom", Required = false, HelpText = "List all custom config parameters for this instance.")]
|
||||
public bool ListCustom { get; set; }
|
||||
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
||||
public string Instance { get; set; }
|
||||
[Option("get", Required = false, HelpText = "Get configuration parameter.")]
|
||||
public string Get { get; set; }
|
||||
[Option("set", Required = false, HelpText = "Set configuration parameter (format: parameter value).")]
|
||||
public string Set { get; set; }
|
||||
[Option("table", Required = false, HelpText = "Output as table.")]
|
||||
public bool Table { get; set; }
|
||||
}
|
||||
|
||||
[Verb("save", HelpText = "Synchronously save the dataset to disk.")]
|
||||
public class SaveOptions
|
||||
{
|
||||
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
||||
public string Instance { get; set; }
|
||||
[Option("table", Required = false, HelpText = "Output as table.")]
|
||||
public bool Table { get; set; }
|
||||
}
|
||||
|
||||
[Verb("bgsave", HelpText = "Asynchronously save the dataset to disk.")]
|
||||
public class BgSaveOptions
|
||||
{
|
||||
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
||||
public string Instance { get; set; }
|
||||
[Option("table", Required = false, HelpText = "Output as table.")]
|
||||
public bool Table { get; set; }
|
||||
}
|
||||
|
||||
[Verb("lastsave", HelpText = "Get the timestamp of the last successful save.")]
|
||||
public class LastSaveOptions
|
||||
{
|
||||
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
||||
public string Instance { get; set; }
|
||||
[Option("table", Required = false, HelpText = "Output as table.")]
|
||||
public bool Table { get; set; }
|
||||
}
|
||||
|
||||
[Verb("time", HelpText = "Return the current server time.")]
|
||||
public class TimeOptions
|
||||
{
|
||||
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
||||
public string Instance { get; set; }
|
||||
[Option("table", Required = false, HelpText = "Output as table.")]
|
||||
public bool Table { get; set; }
|
||||
}
|
||||
|
||||
[Verb("ping", HelpText = "Ping the server.")]
|
||||
public class PingOptions
|
||||
{
|
||||
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
||||
public string Instance { get; set; }
|
||||
[Option("table", Required = false, HelpText = "Output as table.")]
|
||||
public bool Table { get; set; }
|
||||
}
|
||||
|
||||
public static class ServerCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes the INFO command to get information and statistics about the server.
|
||||
/// </summary>
|
||||
/// <param name="opts">The InfoOptions containing instance and section.</param>
|
||||
/// <param name="config">The RedisManager configuration.</param>
|
||||
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
||||
public static int RunInfo(InfoOptions opts, Config config)
|
||||
{
|
||||
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
||||
using var redis = RedisUtils.ConnectRedis(instance);
|
||||
var db = redis.GetDatabase();
|
||||
var info = db.Execute("INFO", string.IsNullOrEmpty(opts.Section) ? null : opts.Section).ToString();
|
||||
if (opts.Table)
|
||||
{
|
||||
var lines = info.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
||||
var rows = lines.Select(l => l.Split(':', 2)).Where(parts => parts.Length == 2)
|
||||
.Select(parts => new[] { parts[0], parts[1] }).ToList();
|
||||
RedisUtils.PrintTable(new[] { "Parameter", "Value" }, rows);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(Output.Green(info));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the CONFIG command to get or set Redis configuration parameters.
|
||||
/// </summary>
|
||||
/// <param name="opts">The ConfigOptions containing instance, get, set, and table options.</param>
|
||||
/// <param name="config">The RedisManager configuration.</param>
|
||||
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
||||
public static int RunConfig(ConfigOptions opts, Config config)
|
||||
{
|
||||
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
||||
using var redis = RedisUtils.ConnectRedis(instance);
|
||||
var db = redis.GetDatabase();
|
||||
|
||||
if (opts.ListCustom)
|
||||
{
|
||||
if (instance.CustomConfig != null && instance.CustomConfig.Count > 0)
|
||||
{
|
||||
RedisUtils.PrintTable(new[] { "Parameter", "Value" }, instance.CustomConfig.Select(kv => new[] { kv.Key, kv.Value }).ToList());
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(Output.Yellow("No custom config parameters set for this instance."));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(opts.Get))
|
||||
{
|
||||
var result = db.Execute("CONFIG", "GET", opts.Get);
|
||||
if (opts.Table)
|
||||
{
|
||||
var arr = (RedisResult[])result;
|
||||
var rows = new List<string[]>();
|
||||
for (int i = 0; i < arr.Length; i += 2)
|
||||
{
|
||||
if (i + 1 < arr.Length)
|
||||
rows.Add(new[] { arr[i].ToString(), arr[i + 1].ToString() });
|
||||
}
|
||||
RedisUtils.PrintTable(new[] { "Parameter", "Value" }, rows);
|
||||
}
|
||||
else
|
||||
{
|
||||
var arr = (RedisResult[])result;
|
||||
for (int i = 0; i < arr.Length; i += 2)
|
||||
{
|
||||
if (i + 1 < arr.Length)
|
||||
Console.WriteLine(Output.Green($"{arr[i]} {arr[i + 1]}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(opts.Set))
|
||||
{
|
||||
var parts = opts.Set.Split(' ', 2);
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
db.Execute("CONFIG", "SET", parts[0], parts[1]);
|
||||
|
||||
// Persist custom config in InstanceConfig and save config file
|
||||
var instanceConfig = config.Instances.FirstOrDefault(i => i.Name == opts.Instance);
|
||||
if (instanceConfig != null)
|
||||
{
|
||||
instanceConfig.CustomConfig[parts[0]] = parts[1];
|
||||
RedisManager.ConfigManager.SaveConfig(config);
|
||||
}
|
||||
|
||||
if (opts.Table)
|
||||
RedisUtils.PrintTable(new[] { "Operation", "Status" }, new List<string[]> { new[] { "CONFIG SET", "OK" } });
|
||||
else
|
||||
Console.WriteLine(Output.Green("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(Output.Red("Invalid format. Use: parameter value"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(Output.Red("Please specify --get or --set"));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the SAVE command to synchronously save the dataset to disk.
|
||||
/// </summary>
|
||||
/// <param name="opts">The SaveOptions containing instance and table option.</param>
|
||||
/// <param name="config">The RedisManager configuration.</param>
|
||||
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
||||
public static int RunSave(SaveOptions opts, Config config)
|
||||
{
|
||||
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
||||
using var redis = RedisUtils.ConnectRedis(instance);
|
||||
var db = redis.GetDatabase();
|
||||
db.Execute("SAVE");
|
||||
if (opts.Table)
|
||||
RedisUtils.PrintTable(new[] { "Operation", "Status" }, new List<string[]> { new[] { "SAVE", "OK" } });
|
||||
else
|
||||
Console.WriteLine(Output.Green("OK"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the BGSAVE command to asynchronously save the dataset to disk.
|
||||
/// </summary>
|
||||
/// <param name="opts">The BgSaveOptions containing instance and table option.</param>
|
||||
/// <param name="config">The RedisManager configuration.</param>
|
||||
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
||||
public static int RunBgSave(BgSaveOptions opts, Config config)
|
||||
{
|
||||
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
||||
using var redis = RedisUtils.ConnectRedis(instance);
|
||||
var db = redis.GetDatabase();
|
||||
db.Execute("BGSAVE");
|
||||
if (opts.Table)
|
||||
RedisUtils.PrintTable(new[] { "Operation", "Status" }, new List<string[]> { new[] { "BGSAVE", "Background save started" } });
|
||||
else
|
||||
Console.WriteLine(Output.Green("Background save started"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the LASTSAVE command to get the timestamp of the last successful save.
|
||||
/// </summary>
|
||||
/// <param name="opts">The LastSaveOptions containing instance and table option.</param>
|
||||
/// <param name="config">The RedisManager configuration.</param>
|
||||
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
||||
public static int RunLastSave(LastSaveOptions opts, Config config)
|
||||
{
|
||||
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
||||
using var redis = RedisUtils.ConnectRedis(instance);
|
||||
var db = redis.GetDatabase();
|
||||
var timestamp = db.Execute("LASTSAVE").ToString();
|
||||
var dateTime = DateTimeOffset.FromUnixTimeSeconds(long.Parse(timestamp));
|
||||
if (opts.Table)
|
||||
RedisUtils.PrintTable(new[] { "Last Save", "Timestamp", "DateTime" }, new List<string[]> { new[] { "Last Save", timestamp, dateTime.ToString() } });
|
||||
else
|
||||
Console.WriteLine(Output.Green($"{timestamp} ({dateTime})"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the TIME command to return the current server time.
|
||||
/// </summary>
|
||||
/// <param name="opts">The TimeOptions containing instance and table option.</param>
|
||||
/// <param name="config">The RedisManager configuration.</param>
|
||||
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
||||
public static int RunTime(TimeOptions opts, Config config)
|
||||
{
|
||||
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
||||
using var redis = RedisUtils.ConnectRedis(instance);
|
||||
var db = redis.GetDatabase();
|
||||
var result = db.Execute("TIME");
|
||||
var arr = (RedisResult[])result;
|
||||
var timestamp = arr[0].ToString();
|
||||
var microseconds = arr[1].ToString();
|
||||
var dateTime = DateTimeOffset.FromUnixTimeSeconds(long.Parse(timestamp));
|
||||
if (opts.Table)
|
||||
RedisUtils.PrintTable(new[] { "Timestamp", "Microseconds", "DateTime" }, new List<string[]> { new[] { timestamp, microseconds, dateTime.ToString() } });
|
||||
else
|
||||
Console.WriteLine(Output.Green($"{timestamp} {microseconds} ({dateTime})"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the PING command to ping the server.
|
||||
/// </summary>
|
||||
/// <param name="opts">The PingOptions containing instance and table option.</param>
|
||||
/// <param name="config">The RedisManager configuration.</param>
|
||||
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
||||
public static int RunPing(PingOptions opts, Config config)
|
||||
{
|
||||
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
||||
using var redis = RedisUtils.ConnectRedis(instance);
|
||||
var db = redis.GetDatabase();
|
||||
var response = db.Ping();
|
||||
if (opts.Table)
|
||||
RedisUtils.PrintTable(new[] { "Ping", "Response" }, new List<string[]> { new[] { "PING", response.ToString() } });
|
||||
else
|
||||
Console.WriteLine(Output.Green(response.ToString()));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user