Commit d4dd61ad authored by Nick Craver's avatar Nick Craver

Cleanup: RedisDatabase

parent 261bc2e5
...@@ -46,6 +46,7 @@ public RedisValue DebugObject(RedisKey key, CommandFlags flags = CommandFlags.No ...@@ -46,6 +46,7 @@ public RedisValue DebugObject(RedisKey key, CommandFlags flags = CommandFlags.No
var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key); var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key);
return ExecuteSync(msg, ResultProcessor.RedisValue); return ExecuteSync(msg, ResultProcessor.RedisValue);
} }
public Task<RedisValue> DebugObjectAsync(RedisKey key, CommandFlags flags = CommandFlags.None) public Task<RedisValue> DebugObjectAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key); var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key);
...@@ -67,6 +68,7 @@ public bool GeoAdd(RedisKey key, GeoEntry value, CommandFlags flags = CommandFla ...@@ -67,6 +68,7 @@ public bool GeoAdd(RedisKey key, GeoEntry value, CommandFlags flags = CommandFla
var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, value.Longitude, value.Latitude, value.Member); var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, value.Longitude, value.Latitude, value.Member);
return ExecuteSync(msg, ResultProcessor.Boolean); return ExecuteSync(msg, ResultProcessor.Boolean);
} }
public Task<bool> GeoAddAsync(RedisKey key, GeoEntry value, CommandFlags flags = CommandFlags.None) public Task<bool> GeoAddAsync(RedisKey key, GeoEntry value, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, value.Longitude, value.Latitude, value.Member); var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, value.Longitude, value.Latitude, value.Member);
...@@ -78,6 +80,7 @@ public long GeoAdd(RedisKey key, GeoEntry[] values, CommandFlags flags = Command ...@@ -78,6 +80,7 @@ public long GeoAdd(RedisKey key, GeoEntry[] values, CommandFlags flags = Command
var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, values); var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, values);
return ExecuteSync(msg, ResultProcessor.Int64); return ExecuteSync(msg, ResultProcessor.Int64);
} }
public Task<long> GeoAddAsync(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None) public Task<long> GeoAddAsync(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, values); var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, values);
...@@ -88,6 +91,7 @@ public bool GeoRemove(RedisKey key, RedisValue member, CommandFlags flags = Comm ...@@ -88,6 +91,7 @@ public bool GeoRemove(RedisKey key, RedisValue member, CommandFlags flags = Comm
{ {
return SortedSetRemove(key, member, flags); return SortedSetRemove(key, member, flags);
} }
public Task<bool> GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) public Task<bool> GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{ {
return SortedSetRemoveAsync(key, member, flags); return SortedSetRemoveAsync(key, member, flags);
...@@ -98,11 +102,13 @@ public Task<bool> GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags f ...@@ -98,11 +102,13 @@ public Task<bool> GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags f
var msg = Message.Create(Database, flags, RedisCommand.GEODIST, key, member1, member2, StackExchange.Redis.GeoPosition.GetRedisUnit(unit)); var msg = Message.Create(Database, flags, RedisCommand.GEODIST, key, member1, member2, StackExchange.Redis.GeoPosition.GetRedisUnit(unit));
return ExecuteSync(msg, ResultProcessor.NullableDouble); return ExecuteSync(msg, ResultProcessor.NullableDouble);
} }
public Task<double?> GeoDistanceAsync(RedisKey key, RedisValue value0, RedisValue value1, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None) public Task<double?> GeoDistanceAsync(RedisKey key, RedisValue value0, RedisValue value1, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.GEODIST, key, value0, value1, StackExchange.Redis.GeoPosition.GetRedisUnit(unit)); var msg = Message.Create(Database, flags, RedisCommand.GEODIST, key, value0, value1, StackExchange.Redis.GeoPosition.GetRedisUnit(unit));
return ExecuteAsync(msg, ResultProcessor.NullableDouble); return ExecuteAsync(msg, ResultProcessor.NullableDouble);
} }
public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
{ {
if (members == null) throw new ArgumentNullException(nameof(members)); if (members == null) throw new ArgumentNullException(nameof(members));
...@@ -111,6 +117,7 @@ public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags = ...@@ -111,6 +117,7 @@ public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags =
var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, redisValues); var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, redisValues);
return ExecuteSync(msg, ResultProcessor.StringArray); return ExecuteSync(msg, ResultProcessor.StringArray);
} }
public Task<string[]> GeoHashAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) public Task<string[]> GeoHashAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
{ {
if (members == null) throw new ArgumentNullException(nameof(members)); if (members == null) throw new ArgumentNullException(nameof(members));
...@@ -125,6 +132,7 @@ public string GeoHash(RedisKey key, RedisValue member, CommandFlags flags = Comm ...@@ -125,6 +132,7 @@ public string GeoHash(RedisKey key, RedisValue member, CommandFlags flags = Comm
var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, member); var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, member);
return ExecuteSync(msg, ResultProcessor.String); return ExecuteSync(msg, ResultProcessor.String);
} }
public Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) public Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, member); var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, member);
...@@ -139,6 +147,7 @@ public Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags f ...@@ -139,6 +147,7 @@ public Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags f
var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, redisValues); var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, redisValues);
return ExecuteSync(msg, ResultProcessor.RedisGeoPositionArray); return ExecuteSync(msg, ResultProcessor.RedisGeoPositionArray);
} }
public Task<GeoPosition?[]> GeoPositionAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None) public Task<GeoPosition?[]> GeoPositionAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
{ {
if (members == null) throw new ArgumentNullException(nameof(members)); if (members == null) throw new ArgumentNullException(nameof(members));
...@@ -153,12 +162,14 @@ public Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags f ...@@ -153,12 +162,14 @@ public Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags f
var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, member); var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, member);
return ExecuteSync(msg, ResultProcessor.RedisGeoPosition); return ExecuteSync(msg, ResultProcessor.RedisGeoPosition);
} }
public Task<GeoPosition?> GeoPositionAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None) public Task<GeoPosition?> GeoPositionAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, member); var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, member);
return ExecuteAsync(msg, ResultProcessor.RedisGeoPosition); return ExecuteAsync(msg, ResultProcessor.RedisGeoPosition);
} }
static readonly RedisValue
private static readonly RedisValue
WITHCOORD = Encoding.ASCII.GetBytes("WITHCOORD"), WITHCOORD = Encoding.ASCII.GetBytes("WITHCOORD"),
WITHDIST = Encoding.ASCII.GetBytes("WITHDIST"), WITHDIST = Encoding.ASCII.GetBytes("WITHDIST"),
WITHHASH = Encoding.ASCII.GetBytes("WITHHASH"), WITHHASH = Encoding.ASCII.GetBytes("WITHHASH"),
...@@ -202,18 +213,22 @@ private Message GetGeoRadiusMessage(RedisKey key, RedisValue? member, double lon ...@@ -202,18 +213,22 @@ private Message GetGeoRadiusMessage(RedisKey key, RedisValue? member, double lon
return Message.Create(Database, flags, command, key, redisValues.ToArray()); return Message.Create(Database, flags, command, key, redisValues.ToArray());
} }
public GeoRadiusResult[] GeoRadius(RedisKey key, RedisValue member, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) public GeoRadiusResult[] GeoRadius(RedisKey key, RedisValue member, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags)
{ {
return ExecuteSync(GetGeoRadiusMessage(key, member, double.NaN, double.NaN, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options)); return ExecuteSync(GetGeoRadiusMessage(key, member, double.NaN, double.NaN, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options));
} }
public Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, RedisValue member, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) public Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, RedisValue member, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags)
{ {
return ExecuteAsync(GetGeoRadiusMessage(key, member, double.NaN, double.NaN, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options)); return ExecuteAsync(GetGeoRadiusMessage(key, member, double.NaN, double.NaN, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options));
} }
public GeoRadiusResult[] GeoRadius(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) public GeoRadiusResult[] GeoRadius(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags)
{ {
return ExecuteSync(GetGeoRadiusMessage(key, null, longitude, latitude, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options)); return ExecuteSync(GetGeoRadiusMessage(key, null, longitude, latitude, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options));
} }
public Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags) public Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags)
{ {
return ExecuteAsync(GetGeoRadiusMessage(key, null, longitude, latitude, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options)); return ExecuteAsync(GetGeoRadiusMessage(key, null, longitude, latitude, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options));
...@@ -460,8 +475,7 @@ public Task<bool> HyperLogLogAddAsync(RedisKey key, RedisValue[] values, Command ...@@ -460,8 +475,7 @@ public Task<bool> HyperLogLogAddAsync(RedisKey key, RedisValue[] values, Command
public long HyperLogLogLength(RedisKey key, CommandFlags flags = CommandFlags.None) public long HyperLogLogLength(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var features = GetFeatures(Database, key, flags, out ServerEndPoint server);
var features = GetFeatures(Database, key, flags, out server);
var cmd = Message.Create(Database, flags, RedisCommand.PFCOUNT, key); var cmd = Message.Create(Database, flags, RedisCommand.PFCOUNT, key);
// technically a write / master-only command until 2.8.18 // technically a write / master-only command until 2.8.18
if (server != null && !features.HyperLogLogCountSlaveSafe) cmd.SetMasterOnly(); if (server != null && !features.HyperLogLogCountSlaveSafe) cmd.SetMasterOnly();
...@@ -484,8 +498,7 @@ public long HyperLogLogLength(RedisKey[] keys, CommandFlags flags = CommandFlags ...@@ -484,8 +498,7 @@ public long HyperLogLogLength(RedisKey[] keys, CommandFlags flags = CommandFlags
public Task<long> HyperLogLogLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) public Task<long> HyperLogLogLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var features = GetFeatures(Database, key, flags, out ServerEndPoint server);
var features = GetFeatures(Database, key, flags, out server);
var cmd = Message.Create(Database, flags, RedisCommand.PFCOUNT, key); var cmd = Message.Create(Database, flags, RedisCommand.PFCOUNT, key);
// technically a write / master-only command until 2.8.18 // technically a write / master-only command until 2.8.18
if (server != null && !features.HyperLogLogCountSlaveSafe) cmd.SetMasterOnly(); if (server != null && !features.HyperLogLogCountSlaveSafe) cmd.SetMasterOnly();
...@@ -545,7 +558,7 @@ public Task<EndPoint> IdentifyEndpointAsync(RedisKey key = default(RedisKey), Co ...@@ -545,7 +558,7 @@ public Task<EndPoint> IdentifyEndpointAsync(RedisKey key = default(RedisKey), Co
public bool IsConnected(RedisKey key, CommandFlags flags = CommandFlags.None) public bool IsConnected(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
var server = multiplexer.SelectServer(Database, RedisCommand.PING, flags, key); var server = multiplexer.SelectServer(Database, RedisCommand.PING, flags, key);
return server != null && server.IsConnected; return server?.IsConnected == true;
} }
public bool KeyDelete(RedisKey key, CommandFlags flags = CommandFlags.None) public bool KeyDelete(RedisKey key, CommandFlags flags = CommandFlags.None)
...@@ -601,29 +614,25 @@ public Task<bool> KeyExistsAsync(RedisKey key, CommandFlags flags = CommandFlags ...@@ -601,29 +614,25 @@ public Task<bool> KeyExistsAsync(RedisKey key, CommandFlags flags = CommandFlags
public bool KeyExpire(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None) public bool KeyExpire(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var msg = GetExpiryMessage(key, flags, expiry, out ServerEndPoint server);
var msg = GetExpiryMessage(key, flags, expiry, out server);
return ExecuteSync(msg, ResultProcessor.Boolean, server: server); return ExecuteSync(msg, ResultProcessor.Boolean, server: server);
} }
public bool KeyExpire(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None) public bool KeyExpire(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var msg = GetExpiryMessage(key, flags, expiry, out ServerEndPoint server);
var msg = GetExpiryMessage(key, flags, expiry, out server);
return ExecuteSync(msg, ResultProcessor.Boolean, server: server); return ExecuteSync(msg, ResultProcessor.Boolean, server: server);
} }
public Task<bool> KeyExpireAsync(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None) public Task<bool> KeyExpireAsync(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var msg = GetExpiryMessage(key, flags, expiry, out ServerEndPoint server);
var msg = GetExpiryMessage(key, flags, expiry, out server);
return ExecuteAsync(msg, ResultProcessor.Boolean, server: server); return ExecuteAsync(msg, ResultProcessor.Boolean, server: server);
} }
public Task<bool> KeyExpireAsync(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None) public Task<bool> KeyExpireAsync(RedisKey key, DateTime? expiry, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var msg = GetExpiryMessage(key, flags, expiry, out ServerEndPoint server);
var msg = GetExpiryMessage(key, flags, expiry, out server);
return ExecuteAsync(msg, ResultProcessor.Boolean, server: server); return ExecuteAsync(msg, ResultProcessor.Boolean, server: server);
} }
...@@ -633,6 +642,7 @@ public void KeyMigrate(RedisKey key, EndPoint toServer, int toDatabase = 0, int ...@@ -633,6 +642,7 @@ public void KeyMigrate(RedisKey key, EndPoint toServer, int toDatabase = 0, int
var msg = new KeyMigrateCommandMessage(Database, key, toServer, toDatabase, timeoutMilliseconds, migrateOptions, flags); var msg = new KeyMigrateCommandMessage(Database, key, toServer, toDatabase, timeoutMilliseconds, migrateOptions, flags);
ExecuteSync(msg, ResultProcessor.DemandOK); ExecuteSync(msg, ResultProcessor.DemandOK);
} }
public Task KeyMigrateAsync(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None) public Task KeyMigrateAsync(RedisKey key, EndPoint toServer, int toDatabase = 0, int timeoutMilliseconds = 0, MigrateOptions migrateOptions = MigrateOptions.None, CommandFlags flags = CommandFlags.None)
{ {
if (timeoutMilliseconds <= 0) timeoutMilliseconds = multiplexer.TimeoutMilliseconds; if (timeoutMilliseconds <= 0) timeoutMilliseconds = multiplexer.TimeoutMilliseconds;
...@@ -640,20 +650,18 @@ public Task KeyMigrateAsync(RedisKey key, EndPoint toServer, int toDatabase = 0, ...@@ -640,20 +650,18 @@ public Task KeyMigrateAsync(RedisKey key, EndPoint toServer, int toDatabase = 0,
return ExecuteAsync(msg, ResultProcessor.DemandOK); return ExecuteAsync(msg, ResultProcessor.DemandOK);
} }
sealed class KeyMigrateCommandMessage : Message.CommandKeyBase // MIGRATE is atypical private sealed class KeyMigrateCommandMessage : Message.CommandKeyBase // MIGRATE is atypical
{ {
private MigrateOptions migrateOptions; private readonly MigrateOptions migrateOptions;
private int timeoutMilliseconds; private readonly int timeoutMilliseconds;
private int toDatabase; private readonly int toDatabase;
RedisValue toHost, toPort; private RedisValue toHost, toPort;
public KeyMigrateCommandMessage(int db, RedisKey key, EndPoint toServer, int toDatabase, int timeoutMilliseconds, MigrateOptions migrateOptions, CommandFlags flags) public KeyMigrateCommandMessage(int db, RedisKey key, EndPoint toServer, int toDatabase, int timeoutMilliseconds, MigrateOptions migrateOptions, CommandFlags flags)
: base(db, flags, RedisCommand.MIGRATE, key) : base(db, flags, RedisCommand.MIGRATE, key)
{ {
if (toServer == null) throw new ArgumentNullException(nameof(toServer)); if (toServer == null) throw new ArgumentNullException(nameof(toServer));
string toHost; if (!Format.TryGetHostPort(toServer, out string toHost, out int toPort)) throw new ArgumentException("toServer");
int toPort;
if (!Format.TryGetHostPort(toServer, out toHost, out toPort)) throw new ArgumentException("toServer");
this.toHost = toHost; this.toHost = toHost;
this.toPort = toPort; this.toPort = toPort;
if (toDatabase < 0) throw new ArgumentOutOfRangeException(nameof(toDatabase)); if (toDatabase < 0) throw new ArgumentOutOfRangeException(nameof(toDatabase));
...@@ -741,8 +749,7 @@ public Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null, ...@@ -741,8 +749,7 @@ public Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null,
public TimeSpan? KeyTimeToLive(RedisKey key, CommandFlags flags = CommandFlags.None) public TimeSpan? KeyTimeToLive(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var features = GetFeatures(Database, key, flags, out ServerEndPoint server);
var features = GetFeatures(Database, key, flags, out server);
Message msg; Message msg;
if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL)) if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL))
{ {
...@@ -755,8 +762,7 @@ public Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null, ...@@ -755,8 +762,7 @@ public Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null,
public Task<TimeSpan?> KeyTimeToLiveAsync(RedisKey key, CommandFlags flags = CommandFlags.None) public Task<TimeSpan?> KeyTimeToLiveAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var features = GetFeatures(Database, key, flags, out ServerEndPoint server);
var features = GetFeatures(Database, key, flags, out server);
Message msg; Message msg;
if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL)) if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL))
{ {
...@@ -765,7 +771,6 @@ public Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null, ...@@ -765,7 +771,6 @@ public Task KeyRestoreAsync(RedisKey key, byte[] value, TimeSpan? expiry = null,
} }
msg = Message.Create(Database, flags, RedisCommand.TTL, key); msg = Message.Create(Database, flags, RedisCommand.TTL, key);
return ExecuteAsync(msg, ResultProcessor.TimeSpanFromSeconds); return ExecuteAsync(msg, ResultProcessor.TimeSpanFromSeconds);
} }
public RedisType KeyType(RedisKey key, CommandFlags flags = CommandFlags.None) public RedisType KeyType(RedisKey key, CommandFlags flags = CommandFlags.None)
...@@ -1044,13 +1049,13 @@ public Task<long> PublishAsync(RedisChannel channel, RedisValue message, Command ...@@ -1044,13 +1049,13 @@ public Task<long> PublishAsync(RedisChannel channel, RedisValue message, Command
var msg = Message.Create(-1, flags, RedisCommand.PUBLISH, channel, message); var msg = Message.Create(-1, flags, RedisCommand.PUBLISH, channel, message);
return ExecuteAsync(msg, ResultProcessor.Int64); return ExecuteAsync(msg, ResultProcessor.Int64);
} }
public RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) public RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None)
{ {
var msg = new ScriptEvalMessage(Database, flags, script, keys, values); var msg = new ScriptEvalMessage(Database, flags, script, keys, values);
try try
{ {
return ExecuteSync(msg, ResultProcessor.ScriptResult); return ExecuteSync(msg, ResultProcessor.ScriptResult);
} }
catch (RedisServerException) catch (RedisServerException)
{ {
...@@ -1059,6 +1064,7 @@ public RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisVa ...@@ -1059,6 +1064,7 @@ public RedisResult ScriptEvaluate(string script, RedisKey[] keys = null, RedisVa
throw; throw;
} }
} }
public RedisResult Execute(string command, params object[] args) public RedisResult Execute(string command, params object[] args)
=> Execute(command, args, CommandFlags.None); => Execute(command, args, CommandFlags.None);
public RedisResult Execute(string command, ICollection<object> args, CommandFlags flags = CommandFlags.None) public RedisResult Execute(string command, ICollection<object> args, CommandFlags flags = CommandFlags.None)
...@@ -1066,6 +1072,7 @@ public RedisResult Execute(string command, ICollection<object> args, CommandFlag ...@@ -1066,6 +1072,7 @@ public RedisResult Execute(string command, ICollection<object> args, CommandFlag
var msg = new ExecuteMessage(Database, flags, command, args); var msg = new ExecuteMessage(Database, flags, command, args);
return ExecuteSync(msg, ResultProcessor.ScriptResult); return ExecuteSync(msg, ResultProcessor.ScriptResult);
} }
public Task<RedisResult> ExecuteAsync(string command, params object[] args) public Task<RedisResult> ExecuteAsync(string command, params object[] args)
=> ExecuteAsync(command, args, CommandFlags.None); => ExecuteAsync(command, args, CommandFlags.None);
public Task<RedisResult> ExecuteAsync(string command, ICollection<object> args, CommandFlags flags = CommandFlags.None) public Task<RedisResult> ExecuteAsync(string command, ICollection<object> args, CommandFlags flags = CommandFlags.None)
...@@ -1073,6 +1080,7 @@ public Task<RedisResult> ExecuteAsync(string command, ICollection<object> args, ...@@ -1073,6 +1080,7 @@ public Task<RedisResult> ExecuteAsync(string command, ICollection<object> args,
var msg = new ExecuteMessage(Database, flags, command, args); var msg = new ExecuteMessage(Database, flags, command, args);
return ExecuteAsync(msg, ResultProcessor.ScriptResult); return ExecuteAsync(msg, ResultProcessor.ScriptResult);
} }
public RedisResult ScriptEvaluate(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) public RedisResult ScriptEvaluate(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None)
{ {
var msg = new ScriptEvalMessage(Database, flags, hash, keys, values); var msg = new ScriptEvalMessage(Database, flags, hash, keys, values);
...@@ -1083,17 +1091,18 @@ public RedisResult ScriptEvaluate(LuaScript script, object parameters = null, Co ...@@ -1083,17 +1091,18 @@ public RedisResult ScriptEvaluate(LuaScript script, object parameters = null, Co
{ {
return script.Evaluate(this, parameters, null, flags); return script.Evaluate(this, parameters, null, flags);
} }
public RedisResult ScriptEvaluate(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) public RedisResult ScriptEvaluate(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{ {
return script.Evaluate(this, parameters, null, flags); return script.Evaluate(this, parameters, null, flags);
} }
public Task<RedisResult> ScriptEvaluateAsync(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) public Task<RedisResult> ScriptEvaluateAsync(string script, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None)
{ {
var msg = new ScriptEvalMessage(Database, flags, script, keys, values); var msg = new ScriptEvalMessage(Database, flags, script, keys, values);
return ExecuteAsync(msg, ResultProcessor.ScriptResult); return ExecuteAsync(msg, ResultProcessor.ScriptResult);
} }
public Task<RedisResult> ScriptEvaluateAsync(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None) public Task<RedisResult> ScriptEvaluateAsync(byte[] hash, RedisKey[] keys = null, RedisValue[] values = null, CommandFlags flags = CommandFlags.None)
{ {
var msg = new ScriptEvalMessage(Database, flags, hash, keys, values); var msg = new ScriptEvalMessage(Database, flags, hash, keys, values);
...@@ -1104,10 +1113,12 @@ public Task<RedisResult> ScriptEvaluateAsync(LuaScript script, object parameters ...@@ -1104,10 +1113,12 @@ public Task<RedisResult> ScriptEvaluateAsync(LuaScript script, object parameters
{ {
return script.EvaluateAsync(this, parameters, null, flags); return script.EvaluateAsync(this, parameters, null, flags);
} }
public Task<RedisResult> ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None) public Task<RedisResult> ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{ {
return script.EvaluateAsync(this, parameters, null, flags); return script.EvaluateAsync(this, parameters, null, flags);
} }
public bool SetAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None) public bool SetAdd(RedisKey key, RedisValue value, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.SADD, key, value); var msg = Message.Create(Database, flags, RedisCommand.SADD, key, value);
...@@ -1192,7 +1203,6 @@ public Task<bool> SetContainsAsync(RedisKey key, RedisValue value, CommandFlags ...@@ -1192,7 +1203,6 @@ public Task<bool> SetContainsAsync(RedisKey key, RedisValue value, CommandFlags
return ExecuteAsync(msg, ResultProcessor.Boolean); return ExecuteAsync(msg, ResultProcessor.Boolean);
} }
public long SetLength(RedisKey key, CommandFlags flags = CommandFlags.None) public long SetLength(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.SCARD, key); var msg = Message.Create(Database, flags, RedisCommand.SCARD, key);
...@@ -1303,6 +1313,7 @@ public IEnumerable<RedisValue> SetScan(RedisKey key, RedisValue pattern = defaul ...@@ -1303,6 +1313,7 @@ public IEnumerable<RedisValue> SetScan(RedisKey key, RedisValue pattern = defaul
if (pattern.IsNull) return SetMembers(key, flags); if (pattern.IsNull) return SetMembers(key, flags);
throw ExceptionFactory.NotSupported(true, RedisCommand.SSCAN); throw ExceptionFactory.NotSupported(true, RedisCommand.SSCAN);
} }
public RedisValue[] Sort(RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None) public RedisValue[] Sort(RedisKey key, long skip = 0, long take = -1, Order order = Order.Ascending, SortType sortType = SortType.Numeric, RedisValue by = default(RedisValue), RedisValue[] get = null, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetAddMessage(default(RedisKey), key, skip, take, order, sortType, by, get, flags); var msg = GetSortedSetAddMessage(default(RedisKey), key, skip, take, order, sortType, by, get, flags);
...@@ -1326,21 +1337,25 @@ public Task<RedisValue[]> SortAsync(RedisKey key, long skip = 0, long take = -1, ...@@ -1326,21 +1337,25 @@ public Task<RedisValue[]> SortAsync(RedisKey key, long skip = 0, long take = -1,
var msg = GetSortedSetAddMessage(default(RedisKey), key, skip, take, order, sortType, by, get, flags); var msg = GetSortedSetAddMessage(default(RedisKey), key, skip, take, order, sortType, by, get, flags);
return ExecuteAsync(msg, ResultProcessor.RedisValueArray); return ExecuteAsync(msg, ResultProcessor.RedisValueArray);
} }
public bool SortedSetAdd(RedisKey key, RedisValue member, double score, CommandFlags flags) public bool SortedSetAdd(RedisKey key, RedisValue member, double score, CommandFlags flags)
{ {
var msg = GetSortedSetAddMessage(key, member, score, When.Always, flags); var msg = GetSortedSetAddMessage(key, member, score, When.Always, flags);
return ExecuteSync(msg, ResultProcessor.Boolean); return ExecuteSync(msg, ResultProcessor.Boolean);
} }
public bool SortedSetAdd(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None) public bool SortedSetAdd(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetAddMessage(key, member, score, when, flags); var msg = GetSortedSetAddMessage(key, member, score, when, flags);
return ExecuteSync(msg, ResultProcessor.Boolean); return ExecuteSync(msg, ResultProcessor.Boolean);
} }
public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, CommandFlags flags) public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, CommandFlags flags)
{ {
var msg = GetSortedSetAddMessage(key, values, When.Always, flags); var msg = GetSortedSetAddMessage(key, values, When.Always, flags);
return ExecuteSync(msg, ResultProcessor.Int64); return ExecuteSync(msg, ResultProcessor.Int64);
} }
public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetAddMessage(key, values, when, flags); var msg = GetSortedSetAddMessage(key, values, when, flags);
...@@ -1352,16 +1367,19 @@ public Task<bool> SortedSetAddAsync(RedisKey key, RedisValue member, double scor ...@@ -1352,16 +1367,19 @@ public Task<bool> SortedSetAddAsync(RedisKey key, RedisValue member, double scor
var msg = GetSortedSetAddMessage(key, member, score, When.Always, flags); var msg = GetSortedSetAddMessage(key, member, score, When.Always, flags);
return ExecuteAsync(msg, ResultProcessor.Boolean); return ExecuteAsync(msg, ResultProcessor.Boolean);
} }
public Task<bool> SortedSetAddAsync(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None) public Task<bool> SortedSetAddAsync(RedisKey key, RedisValue member, double score, When when = When.Always, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetAddMessage(key, member, score, when, flags); var msg = GetSortedSetAddMessage(key, member, score, when, flags);
return ExecuteAsync(msg, ResultProcessor.Boolean); return ExecuteAsync(msg, ResultProcessor.Boolean);
} }
public Task<long> SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, CommandFlags flags) public Task<long> SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, CommandFlags flags)
{ {
var msg = GetSortedSetAddMessage(key, values, When.Always, flags); var msg = GetSortedSetAddMessage(key, values, When.Always, flags);
return ExecuteAsync(msg, ResultProcessor.Int64); return ExecuteAsync(msg, ResultProcessor.Int64);
} }
public Task<long> SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None) public Task<long> SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, When when = When.Always, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetAddMessage(key, values, when, flags); var msg = GetSortedSetAddMessage(key, values, when, flags);
...@@ -1707,17 +1725,13 @@ public Task<RedisValue> StringGetSetAsync(RedisKey key, RedisValue value, Comman ...@@ -1707,17 +1725,13 @@ public Task<RedisValue> StringGetSetAsync(RedisKey key, RedisValue value, Comman
public RedisValueWithExpiry StringGetWithExpiry(RedisKey key, CommandFlags flags = CommandFlags.None) public RedisValueWithExpiry StringGetWithExpiry(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var msg = GetStringGetWithExpiryMessage(key, flags, out ResultProcessor<RedisValueWithExpiry> processor, out ServerEndPoint server);
ResultProcessor<RedisValueWithExpiry> processor;
var msg = GetStringGetWithExpiryMessage(key, flags, out processor, out server);
return ExecuteSync(msg, processor, server); return ExecuteSync(msg, processor, server);
} }
public Task<RedisValueWithExpiry> StringGetWithExpiryAsync(RedisKey key, CommandFlags flags = CommandFlags.None) public Task<RedisValueWithExpiry> StringGetWithExpiryAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
ServerEndPoint server; var msg = GetStringGetWithExpiryMessage(key, flags, out ResultProcessor<RedisValueWithExpiry> processor, out ServerEndPoint server);
ResultProcessor<RedisValueWithExpiry> processor;
var msg = GetStringGetWithExpiryMessage(key, flags, out processor, out server);
return ExecuteAsync(msg, processor, server); return ExecuteAsync(msg, processor, server);
} }
...@@ -1807,7 +1821,7 @@ public Task<RedisValue> StringSetRangeAsync(RedisKey key, long offset, RedisValu ...@@ -1807,7 +1821,7 @@ public Task<RedisValue> StringSetRangeAsync(RedisKey key, long offset, RedisValu
return ExecuteAsync(msg, ResultProcessor.RedisValue); return ExecuteAsync(msg, ResultProcessor.RedisValue);
} }
Message GetExpiryMessage(RedisKey key, CommandFlags flags, TimeSpan? expiry, out ServerEndPoint server) private Message GetExpiryMessage(RedisKey key, CommandFlags flags, TimeSpan? expiry, out ServerEndPoint server)
{ {
TimeSpan duration; TimeSpan duration;
if (expiry == null || (duration = expiry.Value) == TimeSpan.MaxValue) if (expiry == null || (duration = expiry.Value) == TimeSpan.MaxValue)
...@@ -1829,7 +1843,7 @@ Message GetExpiryMessage(RedisKey key, CommandFlags flags, TimeSpan? expiry, out ...@@ -1829,7 +1843,7 @@ Message GetExpiryMessage(RedisKey key, CommandFlags flags, TimeSpan? expiry, out
return Message.Create(Database, flags, RedisCommand.EXPIRE, key, seconds); return Message.Create(Database, flags, RedisCommand.EXPIRE, key, seconds);
} }
Message GetExpiryMessage(RedisKey key, CommandFlags flags, DateTime? expiry, out ServerEndPoint server) private Message GetExpiryMessage(RedisKey key, CommandFlags flags, DateTime? expiry, out ServerEndPoint server)
{ {
DateTime when; DateTime when;
if (expiry == null || (when = expiry.Value) == DateTime.MaxValue) if (expiry == null || (when = expiry.Value) == DateTime.MaxValue)
...@@ -1885,7 +1899,7 @@ private Message GetHashSetMessage(RedisKey key, HashEntry[] hashFields, CommandF ...@@ -1885,7 +1899,7 @@ private Message GetHashSetMessage(RedisKey key, HashEntry[] hashFields, CommandF
} }
} }
ITransaction GetLockExtendTransaction(RedisKey key, RedisValue value, TimeSpan expiry) private ITransaction GetLockExtendTransaction(RedisKey key, RedisValue value, TimeSpan expiry)
{ {
var tran = CreateTransactionIfAvailable(asyncState); var tran = CreateTransactionIfAvailable(asyncState);
if (tran != null) if (tran != null)
...@@ -1896,7 +1910,7 @@ ITransaction GetLockExtendTransaction(RedisKey key, RedisValue value, TimeSpan e ...@@ -1896,7 +1910,7 @@ ITransaction GetLockExtendTransaction(RedisKey key, RedisValue value, TimeSpan e
return tran; return tran;
} }
ITransaction GetLockReleaseTransaction(RedisKey key, RedisValue value) private ITransaction GetLockReleaseTransaction(RedisKey key, RedisValue value)
{ {
var tran = CreateTransactionIfAvailable(asyncState); var tran = CreateTransactionIfAvailable(asyncState);
if (tran != null) if (tran != null)
...@@ -1921,6 +1935,7 @@ private RedisValue GetLexRange(RedisValue value, Exclude exclude, bool isStart) ...@@ -1921,6 +1935,7 @@ private RedisValue GetLexRange(RedisValue value, Exclude exclude, bool isStart)
Buffer.BlockCopy(orig, 0, result, 1, orig.Length); Buffer.BlockCopy(orig, 0, result, 1, orig.Length);
return result; return result;
} }
private RedisValue GetRange(double value, Exclude exclude, bool isStart) private RedisValue GetRange(double value, Exclude exclude, bool isStart)
{ {
if (isStart) if (isStart)
...@@ -1934,7 +1949,7 @@ private RedisValue GetRange(double value, Exclude exclude, bool isStart) ...@@ -1934,7 +1949,7 @@ private RedisValue GetRange(double value, Exclude exclude, bool isStart)
return "(" + Format.ToString(value); // '(' prefix means exclusive return "(" + Format.ToString(value); // '(' prefix means exclusive
} }
Message GetRestoreMessage(RedisKey key, byte[] value, TimeSpan? expiry, CommandFlags flags) private Message GetRestoreMessage(RedisKey key, byte[] value, TimeSpan? expiry, CommandFlags flags)
{ {
long pttl = (expiry == null || expiry.Value == TimeSpan.MaxValue) ? 0 : (expiry.Value.Ticks / TimeSpan.TicksPerMillisecond); long pttl = (expiry == null || expiry.Value == TimeSpan.MaxValue) ? 0 : (expiry.Value.Ticks / TimeSpan.TicksPerMillisecond);
return Message.Create(Database, flags, RedisCommand.RESTORE, key, pttl, value); return Message.Create(Database, flags, RedisCommand.RESTORE, key, pttl, value);
...@@ -1970,11 +1985,11 @@ private Message GetSortedSetAddMessage(RedisKey key, SortedSetEntry[] values, Wh ...@@ -1970,11 +1985,11 @@ private Message GetSortedSetAddMessage(RedisKey key, SortedSetEntry[] values, Wh
arr = new RedisValue[values.Length * 2]; arr = new RedisValue[values.Length * 2];
break; break;
case When.NotExists: case When.NotExists:
arr = new RedisValue[values.Length * 2 + 1]; arr = new RedisValue[(values.Length * 2) + 1];
arr[index++] = RedisLiterals.NX; arr[index++] = RedisLiterals.NX;
break; break;
case When.Exists: case When.Exists:
arr = new RedisValue[values.Length * 2 + 1]; arr = new RedisValue[(values.Length * 2) + 1];
arr[index++] = RedisLiterals.XX; arr[index++] = RedisLiterals.XX;
break; break;
default: throw new ArgumentOutOfRangeException(nameof(when)); default: throw new ArgumentOutOfRangeException(nameof(when));
...@@ -2013,7 +2028,7 @@ private Message GetSortedSetAddMessage(RedisKey destination, RedisKey key, long ...@@ -2013,7 +2028,7 @@ private Message GetSortedSetAddMessage(RedisKey destination, RedisKey key, long
} }
// and now: more complicated scenarios... // and now: more complicated scenarios...
List<RedisValue> values = new List<RedisValue>(); var values = new List<RedisValue>();
if (!by.IsNull) if (!by.IsNull)
{ {
values.Add(RedisLiterals.BY); values.Add(RedisLiterals.BY);
...@@ -2098,7 +2113,6 @@ private Message GetSortedSetCombineAndStoreCommandMessage(SetOperation operation ...@@ -2098,7 +2113,6 @@ private Message GetSortedSetCombineAndStoreCommandMessage(SetOperation operation
throw new ArgumentOutOfRangeException(nameof(aggregate)); throw new ArgumentOutOfRangeException(nameof(aggregate));
} }
return new SortedSetCombineAndStoreCommandMessage(Database, flags, command, destination, keys, values?.ToArray() ?? RedisValue.EmptyArray); return new SortedSetCombineAndStoreCommandMessage(Database, flags, command, destination, keys, values?.ToArray() ?? RedisValue.EmptyArray);
} }
private Message GetSortedSetLengthMessage(RedisKey key, double min, double max, Exclude exclude, CommandFlags flags) private Message GetSortedSetLengthMessage(RedisKey key, double min, double max, Exclude exclude, CommandFlags flags)
...@@ -2185,7 +2199,7 @@ private Message GetStringBitOperationMessage(Bitwise operation, RedisKey destina ...@@ -2185,7 +2199,7 @@ private Message GetStringBitOperationMessage(Bitwise operation, RedisKey destina
return Message.CreateInSlot(Database, slot, flags, RedisCommand.BITOP, new[] { op, destination.AsRedisValue(), first.AsRedisValue(), second.AsRedisValue() }); return Message.CreateInSlot(Database, slot, flags, RedisCommand.BITOP, new[] { op, destination.AsRedisValue(), first.AsRedisValue(), second.AsRedisValue() });
} }
Message GetStringGetWithExpiryMessage(RedisKey key, CommandFlags flags, out ResultProcessor<RedisValueWithExpiry> processor, out ServerEndPoint server) private Message GetStringGetWithExpiryMessage(RedisKey key, CommandFlags flags, out ResultProcessor<RedisValueWithExpiry> processor, out ServerEndPoint server)
{ {
if (this is IBatch) if (this is IBatch)
{ {
...@@ -2224,7 +2238,7 @@ private Message GetStringSetMessage(KeyValuePair<RedisKey, RedisValue>[] values, ...@@ -2224,7 +2238,7 @@ private Message GetStringSetMessage(KeyValuePair<RedisKey, RedisValue>[] values,
} }
} }
Message GetStringSetMessage(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None) private Message GetStringSetMessage(RedisKey key, RedisValue value, TimeSpan? expiry = null, When when = When.Always, CommandFlags flags = CommandFlags.None)
{ {
WhenAlwaysOrExistsOrNotExists(when); WhenAlwaysOrExistsOrNotExists(when);
if (value.IsNull) return Message.Create(Database, flags, RedisCommand.DEL, key); if (value.IsNull) return Message.Create(Database, flags, RedisCommand.DEL, key);
...@@ -2261,7 +2275,7 @@ Message GetStringSetMessage(RedisKey key, RedisValue value, TimeSpan? expiry = n ...@@ -2261,7 +2275,7 @@ Message GetStringSetMessage(RedisKey key, RedisValue value, TimeSpan? expiry = n
throw new NotSupportedException(); throw new NotSupportedException();
} }
Message IncrMessage(RedisKey key, long value, CommandFlags flags) private Message IncrMessage(RedisKey key, long value, CommandFlags flags)
{ {
switch (value) switch (value)
{ {
...@@ -2295,8 +2309,7 @@ private IEnumerable<T> TryScan<T>(RedisKey key, RedisValue pattern, int pageSize ...@@ -2295,8 +2309,7 @@ private IEnumerable<T> TryScan<T>(RedisKey key, RedisValue pattern, int pageSize
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize)); if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
if (!multiplexer.CommandMap.IsAvailable(command)) return null; if (!multiplexer.CommandMap.IsAvailable(command)) return null;
ServerEndPoint server; var features = GetFeatures(Database, key, flags, out ServerEndPoint server);
var features = GetFeatures(Database, key, flags, out server);
if (!features.Scan) return null; if (!features.Scan) return null;
if (CursorUtils.IsNil(pattern)) pattern = (byte[])null; if (CursorUtils.IsNil(pattern)) pattern = (byte[])null;
...@@ -2312,6 +2325,7 @@ private Message GetLexMessage(RedisCommand command, RedisKey key, RedisValue min ...@@ -2312,6 +2325,7 @@ private Message GetLexMessage(RedisCommand command, RedisKey key, RedisValue min
return Message.Create(Database, flags, command, key, new[] { start, stop, RedisLiterals.LIMIT, skip, take }); return Message.Create(Database, flags, command, key, new[] { start, stop, RedisLiterals.LIMIT, skip, take });
} }
public long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None) public long SortedSetLengthByValue(RedisKey key, RedisValue min, RedisValue max, Exclude exclude = Exclude.None, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetLexMessage(RedisCommand.ZLEXCOUNT, key, min, max, exclude, 0, -1, flags); var msg = GetLexMessage(RedisCommand.ZLEXCOUNT, key, min, max, exclude, 0, -1, flags);
...@@ -2348,7 +2362,6 @@ public Task<long> SortedSetRemoveRangeByValueAsync(RedisKey key, RedisValue min, ...@@ -2348,7 +2362,6 @@ public Task<long> SortedSetRemoveRangeByValueAsync(RedisKey key, RedisValue min,
return ExecuteAsync(msg, ResultProcessor.Int64); return ExecuteAsync(msg, ResultProcessor.Int64);
} }
internal class ScanIterator<T> : CursorEnumerable<T> internal class ScanIterator<T> : CursorEnumerable<T>
{ {
private readonly RedisKey key; private readonly RedisKey key;
...@@ -2364,6 +2377,7 @@ internal class ScanIterator<T> : CursorEnumerable<T> ...@@ -2364,6 +2377,7 @@ internal class ScanIterator<T> : CursorEnumerable<T>
this.command = command; this.command = command;
this.Processor = processor; this.Processor = processor;
} }
protected override ResultProcessor<CursorEnumerable<T>.ScanResult> Processor { get; } protected override ResultProcessor<CursorEnumerable<T>.ScanResult> Processor { get; }
protected override Message CreateMessage(long cursor) protected override Message CreateMessage(long cursor)
...@@ -2399,9 +2413,9 @@ internal sealed class ScriptLoadMessage : Message ...@@ -2399,9 +2413,9 @@ internal sealed class ScriptLoadMessage : Message
public ScriptLoadMessage(CommandFlags flags, string script) public ScriptLoadMessage(CommandFlags flags, string script)
: base(-1, flags, RedisCommand.SCRIPT) : base(-1, flags, RedisCommand.SCRIPT)
{ {
if (script == null) throw new ArgumentNullException(nameof(script)); Script = script ?? throw new ArgumentNullException(nameof(script));
this.Script = script;
} }
internal override void WriteImpl(PhysicalConnection physical) internal override void WriteImpl(PhysicalConnection physical)
{ {
physical.WriteHeader(Command, 2); physical.WriteHeader(Command, 2);
...@@ -2409,14 +2423,14 @@ internal override void WriteImpl(PhysicalConnection physical) ...@@ -2409,14 +2423,14 @@ internal override void WriteImpl(PhysicalConnection physical)
physical.Write((RedisValue)Script); physical.Write((RedisValue)Script);
} }
} }
sealed class HashScanResultProcessor : ScanResultProcessor<HashEntry>
private sealed class HashScanResultProcessor : ScanResultProcessor<HashEntry>
{ {
public static readonly ResultProcessor<ScanIterator<HashEntry>.ScanResult> Default = new HashScanResultProcessor(); public static readonly ResultProcessor<ScanIterator<HashEntry>.ScanResult> Default = new HashScanResultProcessor();
private HashScanResultProcessor() { } private HashScanResultProcessor() { }
protected override HashEntry[] Parse(RawResult result) protected override HashEntry[] Parse(RawResult result)
{ {
HashEntry[] pairs; if (!HashEntryArray.TryParse(result, out HashEntry[] pairs)) pairs = null;
if (!HashEntryArray.TryParse(result, out pairs)) pairs = null;
return pairs; return pairs;
} }
} }
...@@ -2443,6 +2457,7 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes ...@@ -2443,6 +2457,7 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
return false; return false;
} }
} }
private sealed class ExecuteMessage : Message private sealed class ExecuteMessage : Message
{ {
private readonly string _command; private readonly string _command;
...@@ -2453,10 +2468,11 @@ public ExecuteMessage(int db, CommandFlags flags, string command, ICollection<ob ...@@ -2453,10 +2468,11 @@ public ExecuteMessage(int db, CommandFlags flags, string command, ICollection<ob
_command = command; _command = command;
this.args = args ?? NoArgs; this.args = args ?? NoArgs;
} }
internal override void WriteImpl(PhysicalConnection physical) internal override void WriteImpl(PhysicalConnection physical)
{ {
physical.WriteHeader(_command, args.Count); physical.WriteHeader(_command, args.Count);
foreach(object arg in args) foreach (object arg in args)
{ {
if (arg is RedisKey) if (arg is RedisKey)
{ {
...@@ -2472,14 +2488,15 @@ internal override void WriteImpl(PhysicalConnection physical) ...@@ -2472,14 +2488,15 @@ internal override void WriteImpl(PhysicalConnection physical)
} }
} }
} }
public override string CommandAndKey => _command; public override string CommandAndKey => _command;
public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
{ {
int slot = ServerSelectionStrategy.NoSlot; int slot = ServerSelectionStrategy.NoSlot;
foreach(object arg in args) foreach (object arg in args)
{ {
if(arg is RedisKey) if (arg is RedisKey)
{ {
slot = serverSelectionStrategy.CombineSlot(slot, (RedisKey)arg); slot = serverSelectionStrategy.CombineSlot(slot, (RedisKey)arg);
} }
...@@ -2487,6 +2504,7 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) ...@@ -2487,6 +2504,7 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
return slot; return slot;
} }
} }
private sealed class ScriptEvalMessage : Message, IMultiMessage private sealed class ScriptEvalMessage : Message, IMultiMessage
{ {
private readonly RedisKey[] keys; private readonly RedisKey[] keys;
...@@ -2498,6 +2516,7 @@ public ScriptEvalMessage(int db, CommandFlags flags, string script, RedisKey[] k ...@@ -2498,6 +2516,7 @@ public ScriptEvalMessage(int db, CommandFlags flags, string script, RedisKey[] k
{ {
if (script == null) throw new ArgumentNullException(nameof(script)); if (script == null) throw new ArgumentNullException(nameof(script));
} }
public ScriptEvalMessage(int db, CommandFlags flags, byte[] hash, RedisKey[] keys, RedisValue[] values) public ScriptEvalMessage(int db, CommandFlags flags, byte[] hash, RedisKey[] keys, RedisValue[] values)
: this(db, flags, RedisCommand.EVAL, null, hash, keys, values) : this(db, flags, RedisCommand.EVAL, null, hash, keys, values)
{ {
...@@ -2531,7 +2550,7 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) ...@@ -2531,7 +2550,7 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
public IEnumerable<Message> GetMessages(PhysicalConnection connection) public IEnumerable<Message> GetMessages(PhysicalConnection connection)
{ {
if (script != null && connection.Multiplexer.CommandMap.IsAvailable(RedisCommand.SCRIPT) if (script != null && connection.Multiplexer.CommandMap.IsAvailable(RedisCommand.SCRIPT)
&& (Flags & CommandFlags.NoScriptCache) == 0) && (Flags & CommandFlags.NoScriptCache) == 0)
{ {
// a script was provided (rather than a hash); check it is known and supported // a script was provided (rather than a hash); check it is known and supported
asciiHash = connection.Bridge.ServerEndPoint.GetScriptHash(script, command); asciiHash = connection.Bridge.ServerEndPoint.GetScriptHash(script, command);
...@@ -2572,7 +2591,7 @@ internal override void WriteImpl(PhysicalConnection physical) ...@@ -2572,7 +2591,7 @@ internal override void WriteImpl(PhysicalConnection physical)
} }
} }
sealed class SetScanResultProcessor : ScanResultProcessor<RedisValue> private sealed class SetScanResultProcessor : ScanResultProcessor<RedisValue>
{ {
public static readonly ResultProcessor<ScanIterator<RedisValue>.ScanResult> Default = new SetScanResultProcessor(); public static readonly ResultProcessor<ScanIterator<RedisValue>.ScanResult> Default = new SetScanResultProcessor();
private SetScanResultProcessor() { } private SetScanResultProcessor() { }
...@@ -2581,7 +2600,8 @@ protected override RedisValue[] Parse(RawResult result) ...@@ -2581,7 +2600,8 @@ protected override RedisValue[] Parse(RawResult result)
return result.GetItemsAsValues(); return result.GetItemsAsValues();
} }
} }
sealed class SortedSetCombineAndStoreCommandMessage : Message.CommandKeyBase // ZINTERSTORE and ZUNIONSTORE have a very unusual signature
private sealed class SortedSetCombineAndStoreCommandMessage : Message.CommandKeyBase // ZINTERSTORE and ZUNIONSTORE have a very unusual signature
{ {
private readonly RedisKey[] keys; private readonly RedisKey[] keys;
private readonly RedisValue[] values; private readonly RedisValue[] values;
...@@ -2595,6 +2615,7 @@ public SortedSetCombineAndStoreCommandMessage(int db, CommandFlags flags, RedisC ...@@ -2595,6 +2615,7 @@ public SortedSetCombineAndStoreCommandMessage(int db, CommandFlags flags, RedisC
values[i].AssertNotNull(); values[i].AssertNotNull();
this.values = values; this.values = values;
} }
public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
{ {
int slot = base.GetHashSlot(serverSelectionStrategy); int slot = base.GetHashSlot(serverSelectionStrategy);
...@@ -2602,6 +2623,7 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy) ...@@ -2602,6 +2623,7 @@ public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
slot = serverSelectionStrategy.CombineSlot(slot, keys[i]); slot = serverSelectionStrategy.CombineSlot(slot, keys[i]);
return slot; return slot;
} }
internal override void WriteImpl(PhysicalConnection physical) internal override void WriteImpl(PhysicalConnection physical)
{ {
physical.WriteHeader(Command, 2 + keys.Length + values.Length); physical.WriteHeader(Command, 2 + keys.Length + values.Length);
...@@ -2614,17 +2636,17 @@ internal override void WriteImpl(PhysicalConnection physical) ...@@ -2614,17 +2636,17 @@ internal override void WriteImpl(PhysicalConnection physical)
} }
} }
sealed class SortedSetScanResultProcessor : ScanResultProcessor<SortedSetEntry> private sealed class SortedSetScanResultProcessor : ScanResultProcessor<SortedSetEntry>
{ {
public static readonly ResultProcessor<ScanIterator<SortedSetEntry>.ScanResult> Default = new SortedSetScanResultProcessor(); public static readonly ResultProcessor<ScanIterator<SortedSetEntry>.ScanResult> Default = new SortedSetScanResultProcessor();
private SortedSetScanResultProcessor() { } private SortedSetScanResultProcessor() { }
protected override SortedSetEntry[] Parse(RawResult result) protected override SortedSetEntry[] Parse(RawResult result)
{ {
SortedSetEntry[] pairs; if (!SortedSetWithScores.TryParse(result, out SortedSetEntry[] pairs)) pairs = null;
if (!SortedSetWithScores.TryParse(result, out pairs)) pairs = null;
return pairs; return pairs;
} }
} }
private class StringGetWithExpiryMessage : Message.CommandKeyBase, IMultiMessage private class StringGetWithExpiryMessage : Message.CommandKeyBase, IMultiMessage
{ {
private readonly RedisCommand ttlCommand; private readonly RedisCommand ttlCommand;
...@@ -2635,6 +2657,7 @@ public StringGetWithExpiryMessage(int db, CommandFlags flags, RedisCommand ttlCo ...@@ -2635,6 +2657,7 @@ public StringGetWithExpiryMessage(int db, CommandFlags flags, RedisCommand ttlCo
{ {
this.ttlCommand = ttlCommand; this.ttlCommand = ttlCommand;
} }
public override string CommandAndKey => ttlCommand + "+" + RedisCommand.GET + " " + (string)Key; public override string CommandAndKey => ttlCommand + "+" + RedisCommand.GET + " " + (string)Key;
public IEnumerable<Message> GetMessages(PhysicalConnection connection) public IEnumerable<Message> GetMessages(PhysicalConnection connection)
...@@ -2659,6 +2682,7 @@ public bool UnwrapValue(out TimeSpan? value, out Exception ex) ...@@ -2659,6 +2682,7 @@ public bool UnwrapValue(out TimeSpan? value, out Exception ex)
ex = null; ex = null;
return false; return false;
} }
internal override void WriteImpl(PhysicalConnection physical) internal override void WriteImpl(PhysicalConnection physical)
{ {
physical.WriteHeader(command, 1); physical.WriteHeader(command, 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment