Commit 4ef40bf2 authored by Marc Gravell's avatar Marc Gravell

Implement Async; fixup return from GeoHash single-member to non-array; move...

Implement Async; fixup return from GeoHash single-member to non-array; move the last of the post-processors to result-processors; apply correct keyspace isolation (prefix) fixups in proxy code
parent b1fd15ee
......@@ -93,7 +93,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// </summary>
/// <returns>The command returns an array where each element is the Geohash corresponding to each member name passed as argument to the command.</returns>
/// <remarks>http://redis.io/commands/geohash</remarks>
string[] GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None);
string GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None);
/// <summary>
......
......@@ -16,6 +16,87 @@ public interface IDatabaseAsync : IRedisAsync
/// <remarks>http://redis.io/commands/debug-object</remarks>
Task<RedisValue> DebugObjectAsync(RedisKey key, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members.
/// </summary>
/// <returns>True if the specified member was not already present in the set, else False</returns>
/// <remarks>http://redis.io/commands/geoadd</remarks>
Task<bool> GeoAddAsync(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Add the specified member to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members.
/// </summary>
/// <returns>True if the specified member was not already present in the set, else False</returns>
/// <remarks>http://redis.io/commands/geoadd</remarks>
Task<bool> GeoAddAsync(RedisKey key, StackExchange.Redis.GeoEntry value, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Add the specified members to the set stored at key. Specified members that are already a member of this set are ignored. If key does not exist, a new set is created before adding the specified members.
/// </summary>
/// <returns>the number of elements that were added to the set, not including all the elements already present into the set.</returns>
/// <remarks>http://redis.io/commands/geoadd</remarks>
Task<long> GeoAddAsync(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Removes the specified member from the geo sorted set stored at key. Non existing members are ignored.
/// </summary>
/// <returns>True if the member existed in the sorted set and was removed; False otherwise.</returns>
/// <remarks>http://redis.io/commands/zrem</remarks>
Task<bool> GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Return the distance between two members in the geospatial index represented by the sorted set.
/// </summary>
/// <returns>The command returns the distance as a double (represented as a string) in the specified unit, or NULL if one or both the elements are missing.</returns>
/// <remarks>http://redis.io/commands/geodist</remarks>
Task<double> GeoDistanceAsync(RedisKey key, RedisValue member1, RedisValue member2, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Return valid Geohash strings representing the position of one or more elements in a sorted set value representing a geospatial index (where elements were added using GEOADD).
/// </summary>
/// <returns>The command returns an array where each element is the Geohash corresponding to each member name passed as argument to the command.</returns>
/// <remarks>http://redis.io/commands/geohash</remarks>
Task<string[]> GeoHashAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Return valid Geohash strings representing the position of one or more elements in a sorted set value representing a geospatial index (where elements were added using GEOADD).
/// </summary>
/// <returns>The command returns an array where each element is the Geohash corresponding to each member name passed as argument to the command.</returns>
/// <remarks>http://redis.io/commands/geohash</remarks>
Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Return the positions (longitude,latitude) of all the specified members of the geospatial index represented by the sorted set at key.
/// </summary>
/// <returns>The command returns an array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command.Non existing elements are reported as NULL elements of the array.</returns>
/// <remarks>http://redis.io/commands/geopos</remarks>
Task<GeoPosition?[]> GeoPositionAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Return the positions (longitude,latitude) of all the specified members of the geospatial index represented by the sorted set at key.
/// </summary>
/// <returns>The command returns an array where each element is a two elements array representing longitude and latitude (x,y) of each member name passed as argument to the command.Non existing elements are reported as NULL elements of the array.</returns>
/// <remarks>http://redis.io/commands/geopos</remarks>
Task<GeoPosition?> GeoPositionAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Return the members of a sorted set populated with geospatial information using GEOADD, which are within the borders of the area specified with the center location and the maximum distance from the center (the radius).
/// </summary>
/// <returns>GeoRadiusResult[]</returns>
/// <remarks>http://redis.io/commands/georadius</remarks>
Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, RedisValue member, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Return the members of a sorted set populated with geospatial information using GEOADD, which are within the borders of the area specified with the center location and the maximum distance from the center (the radius).
/// </summary>
/// <returns>GeoRadiusResult[]</returns>
/// <remarks>http://redis.io/commands/georadius</remarks>
Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None);
/// <summary>
/// Increments the number stored at field in the hash stored at key by increment. If key does not exist, a new key holding a hash is created. If field does not exist or holds a string that cannot be interpreted as integer, the value is set to 0 before the operation is performed.
/// </summary>
......
......@@ -38,46 +38,46 @@ public long GeoAdd(RedisKey key, GeoEntry[] geoEntries, CommandFlags flags = Com
}
public bool GeoAdd(RedisKey key, GeoEntry geoEntry, CommandFlags flags = CommandFlags.None)
{
return Inner.GeoAdd(key, geoEntry, flags);
return Inner.GeoAdd(ToInner(key), geoEntry, flags);
}
public bool GeoRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return Inner.GeoRemove(key, member, flags);
return Inner.GeoRemove(ToInner(key), member, flags);
}
public double GeoDistance(RedisKey key, RedisValue value0, RedisValue value1, GeoUnit geoUnit = GeoUnit.Meters,CommandFlags flags = CommandFlags.None)
public double GeoDistance(RedisKey key, RedisValue value0, RedisValue value1, GeoUnit unit = GeoUnit.Meters,CommandFlags flags = CommandFlags.None)
{
return Inner.GeoDistance(ToInner(key), value0, value1, geoUnit, flags);
return Inner.GeoDistance(ToInner(key), value0, value1, unit, flags);
}
public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
{
return Inner.GeoHash(key, members, flags);
return Inner.GeoHash(ToInner(key), members, flags);
}
public string[] GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
public string GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return Inner.GeoHash(key, member, flags);
return Inner.GeoHash(ToInner(key), member, flags);
}
public GeoPosition?[] GeoPosition(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
{
return Inner.GeoPosition(key, members, flags);
return Inner.GeoPosition(ToInner(key), members, flags);
}
public GeoPosition? GeoPosition(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return Inner.GeoPosition(key, member, flags);
return Inner.GeoPosition(ToInner(key), member, flags);
}
public GeoRadiusResult[] GeoRadius(RedisKey key, RedisValue member, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null,GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None)
{
return Inner.GeoRadius(key, member, radius, unit, count, order, options, flags);
return Inner.GeoRadius(ToInner(key), member, radius, unit, count, order, options, flags);
}
public GeoRadiusResult[] GeoRadius(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None)
{
return Inner.GeoRadius(key, longitude, latitude, radius, unit, count, order, options, flags);
return Inner.GeoRadius(ToInner(key), longitude, latitude, radius, unit, count, order, options, flags);
}
public double HashDecrement(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None)
......
......@@ -24,6 +24,41 @@ public Task<RedisValue> DebugObjectAsync(RedisKey key, CommandFlags flags = Comm
return Inner.DebugObjectAsync(ToInner(key), flags);
}
public Task<bool> GeoAddAsync(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None)
=> Inner.GeoAddAsync(ToInner(key), longitude, latitude, member, flags);
public Task<bool> GeoAddAsync(RedisKey key, StackExchange.Redis.GeoEntry value, CommandFlags flags = CommandFlags.None)
=> Inner.GeoAddAsync(ToInner(key), value, flags);
public Task<long> GeoAddAsync(RedisKey key, StackExchange.Redis.GeoEntry[] values, CommandFlags flags = CommandFlags.None)
=> Inner.GeoAddAsync(ToInner(key), values, flags);
public Task<bool> GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
=> Inner.GeoRemoveAsync(ToInner(key), member, flags);
public Task<double> GeoDistanceAsync(RedisKey key, RedisValue member1, RedisValue member2, GeoUnit unit = GeoUnit.Meters, CommandFlags flags = CommandFlags.None)
=> Inner.GeoDistanceAsync(ToInner(key), member1, member2, unit, flags);
public Task<string[]> GeoHashAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
=> Inner.GeoHashAsync(ToInner(key), members, flags);
public Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
=> Inner.GeoHashAsync(ToInner(key), member, flags);
public Task<GeoPosition?[]> GeoPositionAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
=> Inner.GeoPositionAsync(ToInner(key), members, flags);
public Task<GeoPosition?> GeoPositionAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
=> Inner.GeoPositionAsync(ToInner(key), member, flags);
public Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, RedisValue member, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None)
=> Inner.GeoRadiusAsync(ToInner(key), member, radius, unit, count, order, options, flags);
public Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit = GeoUnit.Meters, int count = -1, Order? order = null, GeoRadiusOptions options = GeoRadiusOptions.Default, CommandFlags flags = CommandFlags.None)
=> Inner.GeoRadiusAsync(ToInner(key), longitude, latitude, radius, unit, count, order, options, flags);
public Task<double> HashDecrementAsync(RedisKey key, RedisValue hashField, double value, CommandFlags flags = CommandFlags.None)
{
return Inner.HashDecrementAsync(ToInner(key), hashField, value, flags);
......
......@@ -252,7 +252,21 @@ internal string[] GetItemsAsStrings()
return arr;
}
}
internal GeoPosition? GetItemsAsGeoPosition()
{
RawResult[] items = GetItems();
if (items == null || items.Length == 0)
{
return null;
}
var coords = items[0].GetArrayOfRawResults();
if (coords == null)
{
return null;
}
return new GeoPosition((double)coords[0].AsRedisValue(), (double)coords[1].AsRedisValue());
}
internal GeoPosition?[] GetItemsAsGeoPositionArray()
{
RawResult[] items = GetItems();
......
......@@ -45,33 +45,62 @@ public RedisValue DebugObject(RedisKey key, CommandFlags flags = CommandFlags.No
var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key);
return ExecuteSync(msg, ResultProcessor.RedisValue);
}
public Task<RedisValue> DebugObjectAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key);
return ExecuteAsync(msg, ResultProcessor.RedisValue);
}
public bool GeoAdd(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return GeoAdd(key, new GeoEntry(longitude, latitude, member), flags);
}
public Task<bool> GeoAddAsync(RedisKey key, double longitude, double latitude, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return GeoAddAsync(key, new GeoEntry(longitude, latitude, member), flags);
}
public bool GeoAdd(RedisKey key, GeoEntry value, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, value.Longitude, value.Latitude, value.Member);
return ExecuteSync(msg, ResultProcessor.Boolean);
}
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);
return ExecuteAsync(msg, ResultProcessor.Boolean);
}
public long GeoAdd(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, values);
return ExecuteSync(msg, ResultProcessor.Int64);
}
public Task<long> GeoAddAsync(RedisKey key, GeoEntry[] values, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(Database, flags, RedisCommand.GEOADD, key, values);
return ExecuteAsync(msg, ResultProcessor.Int64);
}
public bool GeoRemove(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return SortedSetRemove(key, member, flags);
}
public Task<bool> GeoRemoveAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return SortedSetRemoveAsync(key, member, flags);
}
public double GeoDistance(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));
return (double)ExecuteSync(msg, ResultProcessor.RedisValue);
return ExecuteSync(msg, ResultProcessor.Double);
}
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));
return ExecuteAsync(msg, ResultProcessor.Double);
}
public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
......@@ -82,10 +111,24 @@ public string[] GeoHash(RedisKey key, RedisValue[] members, CommandFlags flags =
var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, redisValues);
return ExecuteSync(msg, ResultProcessor.StringArray);
}
public Task<string[]> GeoHashAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
{
if (members == null) throw new ArgumentNullException(nameof(members));
var redisValues = new RedisValue[members.Length];
for (var i = 0; i < members.Length; i++) redisValues[i] = members[i];
var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, redisValues);
return ExecuteAsync(msg, ResultProcessor.StringArray);
}
public string[] GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
public string GeoHash(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return GeoHash(key, new[] { member }, flags);
var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, member);
return ExecuteSync(msg, ResultProcessor.String);
}
public Task<string> GeoHashAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(Database, flags, RedisCommand.GEOHASH, key, member);
return ExecuteAsync(msg, ResultProcessor.String);
}
public GeoPosition?[] GeoPosition(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
......@@ -94,12 +137,26 @@ public string[] GeoHash(RedisKey key, RedisValue member, CommandFlags flags = Co
var redisValues = new RedisValue[members.Length];
for (var i = 0; i < members.Length; i++) redisValues[i] = members[i];
var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, redisValues);
return ExecuteSync(msg, ResultProcessor.RedisGeoPosition);
return ExecuteSync(msg, ResultProcessor.RedisGeoPositionArray);
}
public Task<GeoPosition?[]> GeoPositionAsync(RedisKey key, RedisValue[] members, CommandFlags flags = CommandFlags.None)
{
if (members == null) throw new ArgumentNullException(nameof(members));
var redisValues = new RedisValue[members.Length];
for (var i = 0; i < members.Length; i++) redisValues[i] = members[i];
var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, redisValues);
return ExecuteAsync(msg, ResultProcessor.RedisGeoPositionArray);
}
public GeoPosition? GeoPosition(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
return GeoPosition(key, new[] { member }, flags)[0];
var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, member);
return ExecuteSync(msg, ResultProcessor.RedisGeoPosition);
}
public Task<GeoPosition?> GeoPositionAsync(RedisKey key, RedisValue member, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(Database, flags, RedisCommand.GEOPOS, key, member);
return ExecuteAsync(msg, ResultProcessor.RedisGeoPosition);
}
private Message GetGeoRadiusMessage(RedisKey key, RedisValue? member, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags)
{
......@@ -138,14 +195,17 @@ public GeoRadiusResult[] GeoRadius(RedisKey key, RedisValue member, double radiu
{
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)
{
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)
{
return ExecuteSync(GetGeoRadiusMessage(key, null, longitude, latitude, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options));
}
public Task<RedisValue> DebugObjectAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
public Task<GeoRadiusResult[]> GeoRadiusAsync(RedisKey key, double longitude, double latitude, double radius, GeoUnit unit, int count, Order? order, GeoRadiusOptions options, CommandFlags flags)
{
var msg = Message.Create(Database, flags, RedisCommand.DEBUG, RedisLiterals.OBJECT, key);
return ExecuteAsync(msg, ResultProcessor.RedisValue);
return ExecuteAsync(GetGeoRadiusMessage(key, null, longitude, latitude, radius, unit, count, order, options, flags), ResultProcessor.GeoRadiusArray(options));
}
public long HashDecrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None)
......
......@@ -71,6 +71,8 @@ abstract class ResultProcessor
StringArray = new StringArrayProcessor();
public static readonly ResultProcessor<GeoPosition?[]>
RedisGeoPositionArray = new RedisValueGeoPositionArrayProcessor();
public static readonly ResultProcessor<GeoPosition?>
RedisGeoPosition = new RedisValueGeoPositionProcessor();
public static readonly ResultProcessor<TimeSpan>
......@@ -1116,7 +1118,22 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
}
}
sealed class RedisValueGeoPositionProcessor : ResultProcessor<GeoPosition?[]>
sealed class RedisValueGeoPositionProcessor : ResultProcessor<GeoPosition?>
{
protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
{
switch (result.Type)
{
case ResultType.MultiBulk:
var pos = result.GetItemsAsGeoPosition();
SetResult(message, pos);
return true;
}
return false;
}
}
sealed class RedisValueGeoPositionArrayProcessor : ResultProcessor<GeoPosition?[]>
{
protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
{
......
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