Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Support JSON.MERGE Command #132

Merged
merged 35 commits into from
May 14, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ac44147
Support JSON.MSET Command
shacharPash May 8, 2023
bd52427
add tests
shacharPash May 8, 2023
bc635e4
Merge branch 'master' into Issue128/JSON.MSET
shacharPash May 8, 2023
3936612
fixes
shacharPash May 8, 2023
8407c90
Support JSON.MERGE Command
shacharPash May 9, 2023
ed2751f
adding edge filter
slorello89 May 9, 2023
fd16eeb
bump
slorello89 May 9, 2023
eabd24d
applying to .NET 6 too
slorello89 May 9, 2023
f2ccf86
think it might be picking up the version env var
slorello89 May 9, 2023
7258335
Merge branch 'master' into Issue128/JSON.MSET
shacharPash May 10, 2023
cb72354
Merge branch 'Issue128/JSON.MSET' into Issue129/JSON.MERGE
shacharPash May 10, 2023
b92cbeb
Merge branch 'master' into Issue129/JSON.MERGE
shacharPash May 10, 2023
6faac3b
Sync test for json.merge
shacharPash May 10, 2023
f8ec082
push
shacharPash May 10, 2023
5812a16
add async test
shacharPash May 10, 2023
0019127
add JSON. to MERGE in commands.cs
shacharPash May 10, 2023
a9a5104
Merge branch 'master' into Issue129/JSON.MERGE
shacharPash May 10, 2023
0527323
test from redisJson
shacharPash May 10, 2023
2666927
add async test
shacharPash May 10, 2023
17534bf
fix windows test
shacharPash May 10, 2023
0adef83
fix word mistake
shacharPash May 10, 2023
1f936dd
Merge branch 'master' into Issue129/JSON.MERGE
chayim May 11, 2023
c99e258
check if its passing
shacharPash May 11, 2023
da7fa5f
check 2
shacharPash May 11, 2023
a91e3ae
check 3
shacharPash May 11, 2023
049162e
adding Merge input options
shacharPash May 11, 2023
9579342
change $.a.b test merge
shacharPash May 11, 2023
9ba17df
trying somthing else
shacharPash May 11, 2023
d0abeab
fix mistake
shacharPash May 11, 2023
b25242d
change order
shacharPash May 11, 2023
ae4e3c2
fix }
shacharPash May 11, 2023
af083fb
change to KeyPathValue
shacharPash May 11, 2023
a633e3b
null test
shacharPash May 11, 2023
53551f5
async test + fixes
shacharPash May 11, 2023
8279820
change order
shacharPash May 11, 2023
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
10 changes: 10 additions & 0 deletions src/NRedisStack/Json/IJsonCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ public interface IJsonCommands
/// <remarks><seealso href="https://redis.io/commands/json.mset"/></remarks>
bool MSet(KeyValuePath[] keyValuePathList);

/// <summary>
/// Sets or updates the JSON value at a path.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is accurate?

/// </summary>
/// <param name="key">The key.</param>
/// <param name="path">The path to set within the key.</param>
/// <param name="json">The value to set.</param>
/// <returns>The disposition of the command</returns>
/// <remarks><seealso href="https://redis.io/commands/json.merge"/></remarks>
bool Merge(RedisKey key, RedisValue path, RedisValue json);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So clean!


/// <summary>
/// Sets or updates the JSON value of one or more keys.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions src/NRedisStack/Json/IJsonCommandsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,17 @@ public interface IJsonCommandsAsync
Task<bool> MSetAsync(KeyValuePath[] keyValuePathList);

/// <summary>
/// Sets or updates the JSON value at a path.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="path">The path to set within the key.</param>
/// <param name="json">The value to set.</param>
/// <returns>The disposition of the command</returns>
/// <remarks><seealso href="https://redis.io/commands/json.merge"/></remarks>
Task<bool> MergeAsync(RedisKey key, RedisValue path, RedisValue json);

/// <summary>

/// Set json file from the provided file Path.
/// </summary>
/// <param name="key">The key.</param>
Expand Down
5 changes: 5 additions & 0 deletions src/NRedisStack/Json/JsonCommandBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public static SerializedCommand MSet(KeyValuePath[] keyValuePathList)
return new SerializedCommand(JSON.MSET, args);
}

public static SerializedCommand Merge(RedisKey key, RedisValue path, RedisValue json)
{
return new SerializedCommand(JSON.MERGE, key, path, json);
}

public static SerializedCommand StrAppend(RedisKey key, string value, string? path = null)
{
if (path == null)
Expand Down
6 changes: 6 additions & 0 deletions src/NRedisStack/Json/JsonCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public bool MSet(KeyValuePath[] keyValuePathList)
return _db.Execute(JsonCommandBuilder.MSet(keyValuePathList)).OKtoBoolean();
}

/// <inheritdoc/>
public bool Merge(RedisKey key, RedisValue path, RedisValue json)
{
return _db.Execute(JsonCommandBuilder.Merge(key, path, json)).OKtoBoolean();
}

/// <inheritdoc/>
public bool SetFromFile(RedisKey key, RedisValue path, string filePath, When when = When.Always)
{
Expand Down
6 changes: 6 additions & 0 deletions src/NRedisStack/Json/JsonCommandsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ public async Task<bool> MSetAsync(KeyValuePath[] keyValuePathList)
return (await _db.ExecuteAsync(JsonCommandBuilder.MSet(keyValuePathList))).OKtoBoolean();
}

/// <inheritdoc/>
public async Task<bool> MergeAsync(RedisKey key, RedisValue path, RedisValue json)
{
return (await _db.ExecuteAsync(JsonCommandBuilder.Merge(key, path, json))).OKtoBoolean();
}

public async Task<bool> SetFromFileAsync(RedisKey key, RedisValue path, string filePath, When when = When.Always)
{
if (!File.Exists(filePath))
Expand Down
1 change: 1 addition & 0 deletions src/NRedisStack/Json/Literals/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ internal class JSON
public const string FORGET = "JSON.FORGET";
public const string GET = "JSON.GET";
public const string MEMORY = "MEMORY";
public const string MERGE = "JSON.MERGE";
public const string MSET = "JSON.MSET";
public const string MGET = "JSON.MGET";
public const string NUMINCRBY = "JSON.NUMINCRBY";
Expand Down
53 changes: 45 additions & 8 deletions tests/NRedisStack.Tests/Json/JsonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ public async Task GetAsync()
}

[Fact]
[Trait("Category","edge")]
[Trait("Category", "edge")]
public void MSet()
{
IJsonCommands commands = new JsonCommands(redisFixture.Redis.GetDatabase());
Expand All @@ -748,11 +748,10 @@ public void MSet()

// test errors:
Assert.Throws<ArgumentOutOfRangeException>(() => commands.MSet(new KeyValuePath[0]));

}

[Fact]
[Trait("Category","edge")]
[Trait("Category", "edge")]
public async Task MSetAsync()
{
IJsonCommandsAsync commands = new JsonCommands(redisFixture.Redis.GetDatabase());
Expand All @@ -775,11 +774,49 @@ await commands.MSetAsync(values)
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await commands.MSetAsync(new KeyValuePath[0]));
}

[Fact]
[Trait("Category", "edge")]
public void Merge()
{
IJsonCommands commands = new JsonCommands(redisFixture.Redis.GetDatabase());

// Create a key
Assert.True(commands.Set("test_merge", "$", "{\"a\":{\"b\":{\"c\":\"d\"}}}"));
Assert.True(commands.Merge("test_merge", "$", "{\"a\":{\"b\":{\"e\":\"f\"}}}"));
Assert.Equal("{\"a\":{\"b\":{\"c\":\"d\",\"e\":\"f\"}}}", commands.Get("test_merge").ToString());
// Test with root path path $.a.b

Assert.True(commands.Merge("test_merge", "$.a.b", "{\"h\":\"i\"}"));
Assert.Equal("{\"a\":{\"b\":{\"c\":\"d\",\"e\":\"f\",\"h\":\"i\"}}}", commands.Get("test_merge").ToString());
// Test with null value to delete a value
Assert.True(commands.Merge("test_merge", "$.a.b", "{\"c\":null}"));
Assert.Equal("{\"a\":{\"b\":{\"h\":\"i\",\"e\":\"f\"}}}", commands.Get("test_merge").ToString());
}

[Fact]
[Trait("Category", "edge")]
public async Task MergeAsync()
{
IJsonCommandsAsync commands = new JsonCommands(redisFixture.Redis.GetDatabase());

// Create a key
Assert.True(await commands.SetAsync("test_merge", "$", "{\"a\":{\"b\":{\"c\":\"d\"}}}"));
Assert.True(await commands.MergeAsync("test_merge", "$", "{\"a\":{\"b\":{\"e\":\"f\"}}}"));
Assert.Equal("{\"a\":{\"b\":{\"c\":\"d\",\"e\":\"f\"}}}", (await commands.GetAsync("test_merge")).ToString());
// Test with root path path $.a.b

Assert.True(await commands.MergeAsync("test_merge", "$.a.b", "{\"h\":\"i\"}"));
Assert.Equal("{\"a\":{\"b\":{\"c\":\"d\",\"e\":\"f\",\"h\":\"i\"}}}", (await commands.GetAsync("test_merge")).ToString());
// Test with null value to delete a value
Assert.True(await commands.MergeAsync("test_merge", "$.a.b", "{\"c\":null}"));
Assert.Equal("{\"a\":{\"b\":{\"h\":\"i\",\"e\":\"f\"}}}", (await commands.GetAsync("test_merge")).ToString());
}

[Fact]
public void TestKeyValuePathErrors()
{
Assert.Throws<ArgumentNullException>(() => new KeyValuePath(null!, new { a = "hello" }));
Assert.Throws<ArgumentNullException>(() => new KeyValuePath("key", null!) );
Assert.Throws<ArgumentNullException>(() => new KeyValuePath("key", null!));
}

[Fact]
Expand Down Expand Up @@ -1067,18 +1104,18 @@ public async Task TestSetFromDirectoryAsync()
public void TestJsonCommandBuilder()
{
var getBuild1 = JsonCommandBuilder.Get("key", "indent", "newline", "space", "path");
var getBuild2 = JsonCommandBuilder.Get("key",new string[]{"path1", "path2", "path3"}, "indent", "newline", "space");
var expectedArgs1 = new object[] { "key", "INDENT", "indent", "NEWLINE","newline", "SPACE", "space", "path" };
var getBuild2 = JsonCommandBuilder.Get("key", new string[] { "path1", "path2", "path3" }, "indent", "newline", "space");
var expectedArgs1 = new object[] { "key", "INDENT", "indent", "NEWLINE", "newline", "SPACE", "space", "path" };
var expectedArgs2 = new object[] { "key", "INDENT", "indent", "NEWLINE", "newline", "SPACE", "space", "path1", "path2", "path3" };


for(int i = 0; i < expectedArgs1.Length; i++)
for (int i = 0; i < expectedArgs1.Length; i++)
{
Assert.Equal(expectedArgs1[i].ToString(), getBuild1.Args[i].ToString());
}
Assert.Equal("JSON.GET", getBuild1.Command);

for(int i = 0; i < expectedArgs2.Length; i++)
for (int i = 0; i < expectedArgs2.Length; i++)
{
Assert.Equal(expectedArgs2[i].ToString(), getBuild2.Args[i].ToString());
}
Expand Down