FreeRedis
CommandPacket.cs
using FreeRedis.Internal;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace FreeRedis
{
public clast CommandPacket
{
public string _command { get; private set; }
public string _subcommand { get; private set; }
public List _input { get; } = new List();
public List _keyIndexes { get; } = new List();
public string _prefix { get; private set; }
public string GetKey(int index, bool withoutPrefix = false)
{
if (withoutPrefix && !string.IsNullOrWhiteSpace(_prefix))
return _input[_keyIndexes[index]].ToInvariantCultureToString().Substring(_prefix.Length);
return _input[_keyIndexes[index]].ToInvariantCultureToString();
}
public static implicit operator List(CommandPacket cb) => cb._input;
public static implicit operator CommandPacket(string cmd) => new CommandPacket(cmd);
public override string ToString()
{
var sb = new StringBuilder();
for (var b = 0; b < _input.Count; b++)
{
if (b > 0) sb.Append(" ");
var tmpstr = _input[b].ToInvariantCultureToString().Replace("\r\n", "\\r\\n");
if (tmpstr.Length > 96) tmpstr = $"{tmpstr.Substring(0, 96).Trim()}..";
sb.Append(tmpstr);
}
return sb.ToString();
}
internal Queue _ondata;
public CommandPacket OnData(Action ondata)
{
if (_ondata == null) _ondata = new Queue();
_ondata.Enqueue(ondata);
return this;
}
internal void OnDataTrigger(RedisResult rt)
{
if (_ondata == null) return;
while (_ondata.Any())
_ondata.Dequeue()(rt);
}
public CommandPacket Prefix(string prefix)
{
if (string.IsNullOrWhiteSpace(prefix)) return this;
if (prefix == _prefix) return this;
if (!string.IsNullOrWhiteSpace(_prefix))
{
foreach (var idx in _keyIndexes)
{
var key = _input[idx].ToInvariantCultureToString();
if (key?.StartsWith(_prefix) == true)
_input[idx] = key.Substring(_prefix.Length);
}
}
_prefix = prefix;
foreach (var idx in _keyIndexes)
_input[idx] = $"{prefix}{_input[idx]}";
return this;
}
internal int _protocolErrorTryCount;
internal bool _clusterMovedAsking;
internal int _clusterMovedTryCount;
public string WriteTarget { get; internal set; }
public bool _flagReadbytes;
///
/// read byte[]
///
///
///
public CommandPacket FlagReadbytes(bool isReadbytes)
{
_flagReadbytes = isReadbytes;
return this;
}
public CommandPacket(string cmd, string subcmd = null) => this.Command(cmd, subcmd);
public CommandPacket Command(string cmd, string subcmd = null)
{
if (!string.IsNullOrWhiteSpace(_command) && _command.Equals(_input.FirstOrDefault())) _input.RemoveAt(0);
if (!string.IsNullOrWhiteSpace(_subcommand) && _subcommand.Equals(_input.FirstOrDefault())) _input.RemoveAt(0);
_command = cmd;
_subcommand = subcmd;
if (!string.IsNullOrWhiteSpace(_command))
{
if (!string.IsNullOrWhiteSpace(_subcommand)) _input.Insert(0, _subcommand);
_input.Insert(0, _command);
}
return this;
}
public CommandPacket InputKey(string key)
{
_keyIndexes.Add(_input.Count);
_input.Add(key);
return this;
}
public CommandPacket InputKey(string[] keys)
{
if (keys == null) return this;
foreach (var key in keys)
{
_keyIndexes.Add(_input.Count);
_input.Add(key);
}
return this;
}
public CommandPacket InputKeyIf(bool condition, params string[] keys)
{
if (condition == false) return this;
return InputKey(keys);
}
public CommandPacket InputRaw(object arg)
{
_input.Add(arg);
return this;
}
public CommandPacket Input(string[] args)
{
foreach (var arg in args) _input.Add(arg);
return this;
}
public CommandPacket Input(int[] args)
{
foreach (var arg in args) _input.Add(arg);
return this;
}
public CommandPacket Input(long[] args)
{
foreach (var arg in args) _input.Add(arg);
return this;
}
public CommandPacket Input(params object[] args) => this.InputIf(true, args);
public CommandPacket InputIf(bool condition, params object[] args)
{
if (condition && args != null)
{
foreach (var item in args)
{
if (item is object[] objs) _input.AddRange(objs);
else if (item is string[] strs) _input.AddRange(strs.Select(a => (object)a));
else if (item is int[] ints) _input.AddRange(ints.Select(a => (object)a));
else if (item is long[] longs) _input.AddRange(longs.Select(a => (object)a));
else if (item is KeyValuePair[] kvps1) _input.AddRange(kvps1.Select(a => new object[] { a.Key, a.Value }).SelectMany(a => a).ToArray());
else if (item is KeyValuePair[] kvps2) _input.AddRange(kvps2.Select(a => new object[] { a.Key, a.Value }).SelectMany(a => a).ToArray());
else if (item is Dictionary dict1) _input.AddRange(dict1.Select(a => new object[] { a.Key, a.Value }).SelectMany(a => a).ToArray());
else if (item is Dictionary dict2) _input.AddRange(dict2.Select(a => new object[] { a.Key, a.Value }).SelectMany(a => a).ToArray());
else _input.Add(item);
}
}
return this;
}
public CommandPacket InputKv(object[] keyValues, bool iskey, Func serialize)
{
if (keyValues == null || keyValues.Length == 0) return this;
if (keyValues.Length % 2 != 0) throw new ArgumentException($"Array {nameof(keyValues)} length is not even");
for (var a = 0;a < keyValues.Length; a += 2)
{
if (iskey) InputKey(keyValues[a].ToInvariantCultureToString());
else InputRaw(keyValues[a]);
InputRaw((serialize?.Invoke(keyValues[a + 1]) ?? keyValues[a + 1]));
}
return this;
}
public CommandPacket InputKv(Dictionary keyValues, bool iskey, Func serialize)
{
foreach (var kv in keyValues)
{
if (iskey) InputKey(kv.Key);
else InputRaw(kv.Key);
InputRaw(serialize?.Invoke(kv.Value) ?? kv.Value);
}
return this;
}
internal bool IsReadOnlyCommand()
{
var cmdset = CommandSets.Get(_command);
return cmdset != null && ((cmdset.Tag & CommandSets.ServerTag.read) == CommandSets.ServerTag.read || (cmdset.Flag & CommandSets.ServerFlag.@readonly) == CommandSets.ServerFlag.@readonly);
}
}
static clast CommandPacketExtensions
{
public static CommandPacket SubCommand(this string cmd, string subcmd) => new CommandPacket(cmd, subcmd);
public static CommandPacket InputKey(this string cmd, string key) => new CommandPacket(cmd).InputKey(key);
public static CommandPacket InputKey(this string cmd, string key, string arg1) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1);
public static CommandPacket InputKey(this string cmd, string key, string arg1, long arg2) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket InputKey(this string cmd, string key, string arg1, decimal arg2) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket InputKey(this string cmd, string key, string arg1, string arg2) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket InputKey(this string cmd, string key, decimal arg1, string arg2) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket InputKey(this string cmd, string key, string[] arg1) => new CommandPacket(cmd).InputKey(key).Input(arg1);
public static CommandPacket InputKey(this string cmd, string key, long arg1) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1);
public static CommandPacket InputKey(this string cmd, string key, long arg1, long arg2) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket InputKey(this string cmd, string key, int arg1) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1);
public static CommandPacket InputKey(this string cmd, string key, decimal arg1) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1);
public static CommandPacket InputKey(this string cmd, string key, decimal arg1, decimal arg2) => new CommandPacket(cmd).InputKey(key).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket InputKey(this string cmd, string[] keys) => new CommandPacket(cmd).InputKey(keys);
public static CommandPacket InputKey(this string cmd, string[] keys, int arg1) => new CommandPacket(cmd).InputKey(keys).InputRaw(arg1);
public static CommandPacket InputRaw(this string cmd, object arg) => new CommandPacket(cmd).InputRaw(arg);
public static CommandPacket Input(this string cmd, string arg) => new CommandPacket(cmd).InputRaw(arg);
public static CommandPacket Input(this string cmd, long arg) => new CommandPacket(cmd).InputRaw(arg);
public static CommandPacket Input(this string cmd, string arg1, string arg2) => new CommandPacket(cmd).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket Input(this string cmd, string arg1, int arg2) => new CommandPacket(cmd).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket Input(this string cmd, int arg1, int arg2) => new CommandPacket(cmd).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket Input(this string cmd, long arg1, long arg2) => new CommandPacket(cmd).InputRaw(arg1).InputRaw(arg2);
public static CommandPacket Input(this string cmd, string arg1, string arg2, string arg3) => new CommandPacket(cmd).InputRaw(arg1).InputRaw(arg2).InputRaw(arg3);
public static CommandPacket Input(this string cmd, string[] args) => new CommandPacket(cmd).Input(args);
}
}