Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions src/NRedisStack/Gears/GearsCommandBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using NRedisStack.RedisStackCommands;
using NRedisStack.Gears.Literals;
namespace NRedisStack
{

public static class GearsCommandBuilder
{
public static SerializedCommand TFunctionLoad(string libraryCode, string? config = null, bool replace = false)
{
var args = new List<object>() { "LOAD" };

if (replace)
{
args.Add(GearsArgs.REPLACE);
}

if (config != null)
{
args.Add(GearsArgs.CONFIG);
args.Add(config);
}
args.Add(libraryCode);
return new SerializedCommand("TFUNCTION", args);
}

public static SerializedCommand TFunctionDelete(string libraryName)
{
return new SerializedCommand("TFUNCTION", "DELETE", libraryName);
}

public static SerializedCommand TFunctionList(bool withCode = false, int verbose = 0, string? libraryName = null)
{
var args = new List<object>() { "LIST" };

if (withCode)
{
args.Add("WITHCODE");
}

if (verbose > 0)
{
args.Add(new string('v', Math.Min(3, verbose)));
}

if (libraryName != null)
{
args.Add("LIBRARY");
args.Add(libraryName);
}

return new SerializedCommand("TFUNCTION", args);
}

public static SerializedCommand TFCall(string libraryName, string functionName, string[]? keys = null, string[]? args = null, bool async = false)
{
string command = async ? "TFCALLASYNC" : "TFCALL";
var commandArgs = new List<object>() {libraryName, functionName};

if (keys != null)
{
commandArgs.Add(keys.Length);
commandArgs.AddRange(keys);
}
else
{
commandArgs.Add(0);
}

if (args != null)
{
commandArgs.AddRange(args);
}

return new SerializedCommand(command, commandArgs);
}
}
}
65 changes: 65 additions & 0 deletions src/NRedisStack/Gears/GearsCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using StackExchange.Redis;
namespace NRedisStack
{

public static class GearsCommands //: GearsCommandsAsync, IGearsCommands
{

/// <summary>
/// Load a new library to RedisGears.
/// </summary>
/// <param name="libraryCode">the library code.</param>
/// <param name="config">a string representation of a JSON object
/// that will be provided to the library on load time,
/// for more information refer to
/// <see href="https://github.com/RedisGears/RedisGears/blob/master/docs/function_advance_topics.md#library-configuration">
/// library configuration</see></param>
/// <param name="replace">an optional argument, instructs RedisGears to replace the function if its already exists.</param>
/// <returns><see langword="true"/> if everything was done correctly, Error otherwise.</returns>
/// <remarks><seealso href="https://redis.io/commands/"/></remarks> //TODO: add link to the command when it's available
public static bool TFunctionLoad(this IDatabase db, string libraryCode, string? config = null, bool replace = false)
{
return db.Execute(GearsCommandBuilder.TFunctionLoad(libraryCode, config, replace)).OKtoBoolean();
}

/// <summary>
/// Delete a library from RedisGears.
/// </summary>
/// <param name="libraryName">the name of the library to delete.</param>
/// <returns><see langword="true"/> if the library was deleted successfully, Error otherwise.</returns>
/// <remarks><seealso href="https://redis.io/commands/"/></remarks> //TODO: add link to the command when it's available
public static bool TFunctionDelete(this IDatabase db, string libraryName)
{
return db.Execute(GearsCommandBuilder.TFunctionDelete(libraryName)).OKtoBoolean();
}

/// <summary>
/// List the functions with additional information about each function.
/// </summary>
/// <param name="withCode">Show libraries code.</param>
/// <param name="verbose">output verbosity level, higher number will increase verbosity level</param>
/// <param name="libraryName">specifying a library name (can be used
/// multiple times to show multiple libraries in a single command)</param>
/// <returns>Information about the requested libraries.</returns>
/// <remarks><seealso href="https://redis.io/commands/"/></remarks> //TODO: add link to the command when it's available
public static Dictionary<string, RedisResult>[] TFunctionList(this IDatabase db, bool withCode = false, int verbose = 0, string? libraryName = null)
{
return db.Execute(GearsCommandBuilder.TFunctionList(withCode, verbose, libraryName)).ToDictionarys();
}

/// <summary>
/// Invoke a sync or async (Coroutine) function.
/// </summary>
/// <param name="libraryName">The library name contains the function.</param>
/// <param name="functionName">The function name to run.</param>
/// <param name="keys">keys that will be touched by the function.</param>
/// <param name="args">Additional argument to pass to the function.</param>
/// <param name="async">If true, Invoke an async function (Coroutine).</param>
/// <returns>The return value from the sync & async function on error in case of failure.</returns>
/// <remarks><seealso href="https://redis.io/commands/"/></remarks> //TODO: add link to the command when it's available
public static RedisResult TFCall(this IDatabase db, string libraryName, string functionName, string[]? keys = null, string[]? args = null, bool async = false)
{
return db.Execute(GearsCommandBuilder.TFCall(libraryName, functionName, keys, args, async));
}
}
}
64 changes: 64 additions & 0 deletions src/NRedisStack/Gears/GearsCommandsAsync.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using StackExchange.Redis;
namespace NRedisStack
{

public static class GearsCommandsAsync //: IGearsCommandsAsync
{
/// <summary>
/// Load a new library to RedisGears.
/// </summary>
/// <param name="libraryCode">the library code.</param>
/// <param name="config">a string representation of a JSON object
/// that will be provided to the library on load time,
/// for more information refer to
/// <see href="https://github.com/RedisGears/RedisGears/blob/master/docs/function_advance_topics.md#library-configuration">
/// library configuration</see></param>
/// <param name="replace">an optional argument, instructs RedisGears to replace the function if its already exists.</param>
/// <returns><see langword="true"/> if everything was done correctly, Error otherwise.</returns>
/// <remarks><seealso href="https://redis.io/commands/"/></remarks> //TODO: add link to the command when it's available
public static async Task<bool> TFunctionLoadAsync(this IDatabase db, string libraryCode, string? config = null, bool replace = false)
{
return (await db.ExecuteAsync(GearsCommandBuilder.TFunctionLoad(libraryCode, config, replace))).OKtoBoolean();
}

/// <summary>
/// Delete a library from RedisGears.
/// </summary>
/// <param name="libraryName">the name of the library to delete.</param>
/// <returns><see langword="true"/> if the library was deleted successfully, Error otherwise.</returns>
/// <remarks><seealso href="https://redis.io/commands/"/></remarks> //TODO: add link to the command when it's available
public static async Task<bool> TFunctionDeleteAsync(this IDatabase db, string libraryName)
{
return (await db.ExecuteAsync(GearsCommandBuilder.TFunctionDelete(libraryName))).OKtoBoolean();
}

/// <summary>
/// List the functions with additional information about each function.
/// </summary>
/// <param name="withCode">Show libraries code.</param>
/// <param name="verbose">output verbosity level, higher number will increase verbosity level</param>
/// <param name="libraryName">specifying a library name (can be used
/// multiple times to show multiple libraries in a single command)</param>
/// <returns>Information about the requested libraries.</returns>
/// <remarks><seealso href="https://redis.io/commands/"/></remarks> //TODO: add link to the command when it's available
public static async Task<Dictionary<string, RedisResult>[]> TFunctionListAsync(this IDatabase db, bool withCode = false, int verbose = 0, string? libraryName = null)
{
return (await db.ExecuteAsync(GearsCommandBuilder.TFunctionList(withCode, verbose, libraryName))).ToDictionarys();
}

/// <summary>
/// Invoke a sync or async (Coroutine) function.
/// </summary>
/// <param name="libraryName">The library name contains the function.</param>
/// <param name="functionName">The function name to run.</param>
/// <param name="keys">keys that will be touched by the function.</param>
/// <param name="args">Additional argument to pass to the function.</param>
/// <param name="async">If true, Invoke an async function (Coroutine).</param>
/// <returns>The return value from the sync & async function on error in case of failure.</returns>
/// <remarks><seealso href="https://redis.io/commands/"/></remarks> //TODO: add link to the command when it's available
public static async Task<RedisResult> TFCallAsync(this IDatabase db, string libraryName, string functionName, string[]? keys = null, string[]? args = null, bool async = false)
{
return await db.ExecuteAsync(GearsCommandBuilder.TFCall(libraryName, functionName, keys, args, async));
}
}
}
8 changes: 8 additions & 0 deletions src/NRedisStack/Gears/Literals/CommandArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace NRedisStack.Gears.Literals
{
internal class GearsArgs
{
public const string CONFIG = "CONFIG";
public const string REPLACE = "REPLACE";
}
}
12 changes: 12 additions & 0 deletions src/NRedisStack/ResponseParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -613,5 +613,17 @@ public static IEnumerable<HashSet<string>> ToHashSets(this RedisResult result)

return sets;
}

public static Dictionary<string, RedisResult>[] ToDictionarys(this RedisResult result)
{
var resArr = (RedisResult[])result!;
var dicts = new Dictionary<string, RedisResult>[resArr.Length];
for (int i = 0; i < resArr.Length; i++)
{
dicts[i] = resArr[i].ToDictionary();
}

return dicts;
}
}
}
Loading