From c3ffd3693688104bac2da8ec04a3ba9ccc190aca Mon Sep 17 00:00:00 2001 From: Jeevananthan-23 Date: Mon, 30 Jan 2023 15:20:13 +0530 Subject: [PATCH 01/10] added pipelineexamples and docs --- Examples/CombinationModulesPipeline.md | 46 +++++++++++++ Examples/PipelineExample.md | 42 ++++++++++++ .../Examples/ExamplesTests.cs | 66 +++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 Examples/CombinationModulesPipeline.md create mode 100644 Examples/PipelineExample.md diff --git a/Examples/CombinationModulesPipeline.md b/Examples/CombinationModulesPipeline.md new file mode 100644 index 00000000..4dcdffca --- /dev/null +++ b/Examples/CombinationModulesPipeline.md @@ -0,0 +1,46 @@ +# Combination modules Pipeline +## An example of pipelines mixing a pipeline with a combination of module commands with JSON & Search + +### Connect to the Redis server: +```csharp +var redis = ConnectionMultiplexer.Connect("localhost"); +``` + +### Setup pipeline connection +```csharp +var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); +``` + +### Add JsonSet to pipeline +```csharp +pipeline.Json.SetAsync("person:01", "$", new { name = "John", age = 30, city = "New York" }); +pipeline.Json.SetAsync("person:02", "$", new { name = "Joy", age = 25, city = "Los Angeles" }); +pipeline.Json.SetAsync("person:03", "$", new { name = "Mark", age = 21, city = "Chicago" }); +pipeline.Json.SetAsync("person:04", "$", new { name = "Steve", age = 24, city = "Phoenix" }); +pipeline.Json.SetAsync("person:05", "$", new { name = "Michael", age = 55, city = "San Antonio" }); +``` + +### Create the schema to index first and age as a numeric field +```csharp +var schema = new Schema().AddTextField("name").AddNumericField("age", true).AddTagField("city"); +``` + +### Filter the index to only include Jsons and prefix of person +```csharp +var parameters = FTCreateParams.CreateParams().On(Literals.Enums.IndexDataType.JSON).Prefix("person:"); +``` + +### Create the index via pipeline +```csharp +pipeline.Ft.CreateAsync("person-idx", parameters, schema); +``` + +### Search for all indexed person records +```csharp +var getAllPersons = pipeline.Ft.SearchAsync("person-idx", new Query()); +``` + +### Execute the pipeline +```csharp +pipeline.Execute(); +``` \ No newline at end of file diff --git a/Examples/PipelineExample.md b/Examples/PipelineExample.md new file mode 100644 index 00000000..a0c32100 --- /dev/null +++ b/Examples/PipelineExample.md @@ -0,0 +1,42 @@ +# Pipeline +## An example of pipelines Redis Stack Redis commands (JSON.SET & JSON.CLEAR & JSON.GET) + +### Connect to the Redis server: +```csharp +var redis = ConnectionMultiplexer.Connect("localhost"); +``` + +### Setup pipeline connection +```csharp +var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); +``` + +### Add JsonSet to pipeline +```csharp +pipeline.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); +``` + +### Inc age by 2 +```csharp +pipeline.Json.NumIncrbyAsync("person", "$.age", 2); +``` + +### Clear the nicknames from the Json +```csharp +pipeline.Json.ClearAsync("person", "$.nicknames"); +``` + +### Del the nicknames +```csharp +pipeline.Json.DelAsync("person", "$.nicknames"); +``` + +### Get the Json response +```csharp +var getResponse = pipeline.Json.GetAsync("person"); +``` + +### Execute the pipeline +```csharp +pipeline.Execute(); +``` \ No newline at end of file diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index 9473dba1..e8752a01 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -73,4 +73,70 @@ public async Task AsyncExample() await json.SetAsync("key", "$", new { name = "John", age = 30, city = "New York" }); var john = await json.GetAsync("key"); } + + [Fact] + public void PipelineExample() + { + //Setup pipeline connection + var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); + + // Add JsonSet to pipeline + pipeline.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); + + // Inc age by 2 + pipeline.Json.NumIncrbyAsync("person", "$.age", 2); + + // Clear the nicknames from the Json + pipeline.Json.ClearAsync("person", "$.nicknames"); + + // Del the nicknames + pipeline.Json.DelAsync("person", "$.nicknames"); + + // Get the Json response + var getResponse = pipeline.Json.GetAsync("person"); + + // Execute the pipeline + pipeline.Execute(); + } + + [Fact] + public void JsonWithSearchPipeline() + { + // Setup pipeline connection + var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); + + // Add JsonSet to pipeline + pipeline.Json.SetAsync("person:01", "$", new { name = "John", age = 30, city = "New York" }); + pipeline.Json.SetAsync("person:02", "$", new { name = "Joy", age = 25, city = "Los Angeles" }); + pipeline.Json.SetAsync("person:03", "$", new { name = "Mark", age = 21, city = "Chicago" }); + pipeline.Json.SetAsync("person:04", "$", new { name = "Steve", age = 24, city = "Phoenix" }); + pipeline.Json.SetAsync("person:05", "$", new { name = "Michael", age = 55, city = "San Antonio" }); + + // Create the schema to index first and age as a numeric field + var schema = new Schema().AddTextField("name").AddNumericField("age", true).AddTagField("city"); + + // Filter the index to only include Jsons and prefix of person + var parameters = FTCreateParams.CreateParams().On(Literals.Enums.IndexDataType.JSON).Prefix("person:"); + + // Create the index via pipeline + pipeline.Ft.CreateAsync("person-idx", parameters, schema); + + // Search for all indexed person records + var getAllPersons = pipeline.Ft.SearchAsync("person-idx", new Query()); + + // execute the pipeline + pipeline.Execute(); + } + + [Fact] + public async Task PipelineWithAsync() + { + + } + + [Fact] + public void TransactionExample() + { + // implementation for transaction + } } \ No newline at end of file From e8fa4f0c491dbd48e0082b06444f109c821ecfa3 Mon Sep 17 00:00:00 2001 From: Jeevananthan-23 Date: Mon, 30 Jan 2023 19:13:37 +0530 Subject: [PATCH 02/10] adding pipelinewithAsync example --- .../Examples/ExamplesTests.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index ccbf7f18..c3d86b56 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -4,6 +4,7 @@ using Moq; using NRedisStack.Search.FT.CREATE; using NRedisStack.Search; +using NRedisStack.DataTypes; namespace NRedisStack.Tests.Bloom; @@ -131,7 +132,50 @@ public void JsonWithSearchPipeline() [Fact] public async Task PipelineWithAsync() { + // Connect to the Redis server + var redis = ConnectionMultiplexer.Connect("localhost"); + + // Get a reference to the database + var db = redis.GetDatabase(); + var ts = db.TS(); + + // Setup pipeline connection + var pipeline = new Pipeline(redis); + + // create metedata lables for time-series. + TimeSeriesLabel label1 = new TimeSeriesLabel("temp", "TLV"); + TimeSeriesLabel label2 = new TimeSeriesLabel("temp", "JLM"); + var labels1 = new List { label1 }; + var labels2 = new List { label2 }; + + //create a new time-series. + pipeline.Ts.CreateAsync("temp:TLV", labels: labels1); + pipeline.Ts.CreateAsync("temp:JLM", labels: labels2); + + //adding multiple sequenece of time-series data. + List<(string, TimeStamp, double)> sequence1 = new List<(string, TimeStamp, double)>() + { + ("temp:TLV",1000,30), + ("temp:TLV", 1010 ,35), + ("temp:TLV", 1020, 9999), + ("temp:TLV", 1030, 40) + }; + List<(string, TimeStamp, double)> sequence2 = new List<(string, TimeStamp, double)>() + { + ("temp:JLM",1005,30), + ("temp:JLM", 1015 ,35), + ("temp:JLM", 1025, 9999), + ("temp:JLM", 1035, 40) + }; + + // Adding mutiple samples to mutiple series. + pipeline.Ts.MAddAsync(sequence1); + pipeline.Ts.MAddAsync(sequence2); + + pipeline.Execute(); + // get only the location label for each last sample, use SELECTED_LABELS. + var respons = await ts.MGetAsync(new List { "temp=JLM" }, selectedLabels: new List { "location" }); } [Fact] From 7ee38b6f37d70d148fe09d71867a86f3a5f796cb Mon Sep 17 00:00:00 2001 From: Jeevananthan-23 Date: Tue, 31 Jan 2023 19:25:54 +0530 Subject: [PATCH 03/10] adding pipelinewithasync doc feedback changes --- Examples/AsyncExample.md | 14 ++-- Examples/CombinationModulesPipeline.md | 18 ++--- Examples/HsetAndSearch.md | 29 ++++---- Examples/PipelineExample.md | 20 +++--- Examples/PipelineWithAsync.md | 70 +++++++++++++++++++ .../Examples/ExamplesTests.cs | 17 ++++- 6 files changed, 128 insertions(+), 40 deletions(-) create mode 100644 Examples/PipelineWithAsync.md diff --git a/Examples/AsyncExample.md b/Examples/AsyncExample.md index 40ec4673..a5fff4b6 100644 --- a/Examples/AsyncExample.md +++ b/Examples/AsyncExample.md @@ -3,17 +3,17 @@ ## All methods have synchronous & asynchronous implementation. the asynchronous methods all end ...Async(...), and are fully await-able. here is an example of using the async methods: -### Connect to the Redis server and get a reference to the database and for JSON commands: +Connect to the Redis server and get a reference to the database and for JSON commands: ```csharp - var redis = await ConnectionMultiplexer.ConnectAsync("localhost"); - var db = redis.GetDatabase(); - var json = db.JSON(); +var redis = await ConnectionMultiplexer.ConnectAsync("localhost"); +var db = redis.GetDatabase(); +var json = db.JSON(); ``` -### call async version of JSON.SET/GET +call async version of JSON.SET/GET ```csharp - await json.SetAsync("key", "$", new { name = "John", age = 30, city = "New York" }); - var john = await json.GetAsync("key"); +await json.SetAsync("key", "$", new { name = "John", age = 30, city = "New York" }); +var john = await json.GetAsync("key"); ``` diff --git a/Examples/CombinationModulesPipeline.md b/Examples/CombinationModulesPipeline.md index 4dcdffca..b36b9e0d 100644 --- a/Examples/CombinationModulesPipeline.md +++ b/Examples/CombinationModulesPipeline.md @@ -1,17 +1,18 @@ # Combination modules Pipeline ## An example of pipelines mixing a pipeline with a combination of module commands with JSON & Search -### Connect to the Redis server: +Connect to the Redis server: ```csharp var redis = ConnectionMultiplexer.Connect("localhost"); ``` -### Setup pipeline connection +Setup pipeline connection ```csharp var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); ``` -### Add JsonSet to pipeline +## JSON +Add JsonSet to pipeline ```csharp pipeline.Json.SetAsync("person:01", "$", new { name = "John", age = 30, city = "New York" }); pipeline.Json.SetAsync("person:02", "$", new { name = "Joy", age = 25, city = "Los Angeles" }); @@ -20,27 +21,28 @@ pipeline.Json.SetAsync("person:04", "$", new { name = "Steve", age = 24, city = pipeline.Json.SetAsync("person:05", "$", new { name = "Michael", age = 55, city = "San Antonio" }); ``` -### Create the schema to index first and age as a numeric field +## Search +Create the schema to index first and age as a numeric field ```csharp var schema = new Schema().AddTextField("name").AddNumericField("age", true).AddTagField("city"); ``` -### Filter the index to only include Jsons and prefix of person +Filter the index to only include Jsons and prefix of person ```csharp var parameters = FTCreateParams.CreateParams().On(Literals.Enums.IndexDataType.JSON).Prefix("person:"); ``` -### Create the index via pipeline +Create the index via pipeline ```csharp pipeline.Ft.CreateAsync("person-idx", parameters, schema); ``` -### Search for all indexed person records +Search for all indexed person records ```csharp var getAllPersons = pipeline.Ft.SearchAsync("person-idx", new Query()); ``` -### Execute the pipeline +Execute the pipeline ```csharp pipeline.Execute(); ``` \ No newline at end of file diff --git a/Examples/HsetAndSearch.md b/Examples/HsetAndSearch.md index aec51415..0b63d167 100644 --- a/Examples/HsetAndSearch.md +++ b/Examples/HsetAndSearch.md @@ -1,17 +1,16 @@ - # HSET and Search ## An example of mixing Redis open source command (HSET) with Redis Stack Redis commands (FT.CREATE & FT.SEARCH) -### Connect to the Redis server: +Connect to the Redis server: ```csharp var redis = ConnectionMultiplexer.Connect("localhost"); ``` -### Get a reference to the database and for search commands: +Get a reference to the database and for search commands: ```csharp var db = redis.GetDatabase(); var ft = db.FT(); ``` -### Use HSET to add a field-value pair to a hash: +Use HSET to add a field-value pair to a hash: ```csharp db.HashSet("profesor:5555", new HashEntry[] { new("first", "Albert"), new("last", "Blue"), new("age", "55") }); db.HashSet("student:1111", new HashEntry[] { new("first", "Joe"), new("last", "Dod"), new("age", "18") }); @@ -22,40 +21,40 @@ db.HashSet("student:5555", new HashEntry[] { new("first", "Joen"), new("last", " db.HashSet("teacher:6666", new HashEntry[] { new("first", "Pat"), new("last", "Rod"), new("age", "20") }); ``` -### Create the schema to index first and last as text fields, and age as a numeric field: +Create the schema to index first and last as text fields, and age as a numeric field: ```csharp var schema = new Schema().AddTextField("first").AddTextField("last").AddNumericField("age"); ``` -### Filter the index to only include hashes with an age greater than 16, and prefix of 'student:' or 'pupil:' +Filter the index to only include hashes with an age greater than 16, and prefix of 'student:' or 'pupil:' ```csharp var parameters = FTCreateParams.CreateParams().Filter("@age>16").Prefix("student:", "pupil:"); ``` -### Create the index: +Create the index: ```csharp ft.Create("example_index", parameters, schema); ``` ## Search Examples: -### Search all hashes in the index: +Search all hashes in the index: ```csharp var noFilters = ft.Search("example_index", new Query()); ``` -### _noFilters_ now contains: _student:1111_, _student:5555_, _pupil:4444_, _student:3333_.

+_noFilters_ now contains: _student:1111_, _student:5555_, _pupil:4444_, _student:3333_.

-### Search for hashes with a first name starting with Jo +Search for hashes with a first name starting with Jo ```csharp var startWithJo = ft.Search("example_index", new Query("@first:Jo*")); ``` -### _startWithJo_ now contains: _student:1111_ (Joe), _student:5555_ (Joen).

+_startWithJo_ now contains: _student:1111_ (Joe), _student:5555_ (Joen).

-### Search for hashes with first name of Pat +Search for hashes with first name of Pat ```csharp var namedPat = ft.Search("example_index", new Query("@first:Pat")); ``` -### _namedPat_ now contains _pupil:4444_ (Pat). _teacher:6666_ (Pat) is not included because it does not have a prefix of 'student:' or 'pupil:'

+_namedPat_ now contains _pupil:4444_ (Pat). _teacher:6666_ (Pat) is not included because it does not have a prefix of 'student:' or 'pupil:'

-### Search for hashes with last name of Rod +Search for hashes with last name of Rod ```csharp var lastNameRod = ft.Search("example_index", new Query("@last:Rod")); ``` -### _lastNameRod_ is empty because there are no hashes with a last name of Rod that match the index definition. \ No newline at end of file +_lastNameRod_ is empty because there are no hashes with a last name of Rod that match the index definition. \ No newline at end of file diff --git a/Examples/PipelineExample.md b/Examples/PipelineExample.md index a0c32100..a4ae48d2 100644 --- a/Examples/PipelineExample.md +++ b/Examples/PipelineExample.md @@ -1,42 +1,46 @@ # Pipeline ## An example of pipelines Redis Stack Redis commands (JSON.SET & JSON.CLEAR & JSON.GET) -### Connect to the Redis server: +Connect to the Redis server: ```csharp var redis = ConnectionMultiplexer.Connect("localhost"); ``` -### Setup pipeline connection +Setup pipeline connection ```csharp var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); ``` -### Add JsonSet to pipeline +Add JsonSet to pipeline ```csharp pipeline.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); ``` -### Inc age by 2 +Inc `age` by 2 ```csharp pipeline.Json.NumIncrbyAsync("person", "$.age", 2); ``` -### Clear the nicknames from the Json +Clear the `nicknames` from the Json ```csharp pipeline.Json.ClearAsync("person", "$.nicknames"); ``` -### Del the nicknames +Del the `nicknames` ```csharp pipeline.Json.DelAsync("person", "$.nicknames"); ``` -### Get the Json response +Get the Json response ```csharp var getResponse = pipeline.Json.GetAsync("person"); ``` -### Execute the pipeline +Execute the pipeline ```csharp pipeline.Execute(); +``` +Get the result JSON +```csharp +var result = getResponse.Result; ``` \ No newline at end of file diff --git a/Examples/PipelineWithAsync.md b/Examples/PipelineWithAsync.md new file mode 100644 index 00000000..7463094c --- /dev/null +++ b/Examples/PipelineWithAsync.md @@ -0,0 +1,70 @@ +# Pipeline With Async +## An example of pipelines Redis Stack Redis commands (JSON.SET & JSON.CLEAR & JSON.GET) + + +Connect to the Redis server +```csharp +var redis = ConnectionMultiplexer.Connect("localhost"); +``` + +Get a reference to the database +```csharp +var db = redis.GetDatabase(); +``` + +Setup pipeline connection +```csharp +var pipeline = new Pipeline(redis); +``` + +create metedata lables for time-series. +```csharp +TimeSeriesLabel label1 = new TimeSeriesLabel("temp", "TLV"); +TimeSeriesLabel label2 = new TimeSeriesLabel("temp", "JLM"); +var labels1 = new List { label1 }; +var labels2 = new List { label2 }; +``` + +create a new time-series. +```csharp +pipeline.Ts.CreateAsync("temp:TLV", labels: labels1); +pipeline.Ts.CreateAsync("temp:JLM", labels: labels2); +``` + +adding multiple sequenece of time-series data. +```csharp +List<(string, TimeStamp, double)> sequence1 = new List<(string, TimeStamp, double)>() +{ + ("temp:TLV",1000,30), + ("temp:TLV", 1010 ,35), + ("temp:TLV", 1020, 9999), + ("temp:TLV", 1030, 40) +}; +List<(string, TimeStamp, double)> sequence2 = new List<(string, TimeStamp, double)>() +{ + ("temp:JLM",1005,30), + ("temp:JLM", 1015 ,35), + ("temp:JLM", 1025, 9999), + ("temp:JLM", 1035, 40) +}; +``` +Adding mutiple samples to mutiple series. +```csharp +pipeline.Ts.MAddAsync(sequence1); +pipeline.Ts.MAddAsync(sequence2); +``` + +Execute the pipeline +```csharp +pipeline.Execute(); +``` + +Get a reference to the database and for time-series commands +```csharp +var ts = db.TS(); +``` + +get only the location label for each last sample, use SELECTED_LABELS. +```csharp +var respons = await ts.MGetAsync(new List { "temp=JLM" }, selectedLabels: new List { "location" }); +``` \ No newline at end of file diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index c3d86b56..07998139 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -98,12 +98,15 @@ public void PipelineExample() // Execute the pipeline pipeline.Execute(); + + // get the result back JSON + var result = getResponse.Result; } [Fact] public void JsonWithSearchPipeline() { - // Setup pipeline connection + //Setup pipeline connection var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); // Add JsonSet to pipeline @@ -127,6 +130,13 @@ public void JsonWithSearchPipeline() // execute the pipeline pipeline.Execute(); + + // get the total count of people records that indexed. + var count = getAllPersons.Result.TotalResults; + + // Gets the first person form the result. + var firstPerson = getAllPersons.Result.Documents.FirstOrDefault(); + // first person is John here. } [Fact] @@ -137,7 +147,6 @@ public async Task PipelineWithAsync() // Get a reference to the database var db = redis.GetDatabase(); - var ts = db.TS(); // Setup pipeline connection var pipeline = new Pipeline(redis); @@ -172,8 +181,12 @@ public async Task PipelineWithAsync() pipeline.Ts.MAddAsync(sequence1); pipeline.Ts.MAddAsync(sequence2); + // execute the pipeline pipeline.Execute(); + // Get a reference to the database and for time-series commands + var ts = db.TS(); + // get only the location label for each last sample, use SELECTED_LABELS. var respons = await ts.MGetAsync(new List { "temp=JLM" }, selectedLabels: new List { "location" }); } From 7451df9b23335c5409cc29c1eb754ab3a53f4999 Mon Sep 17 00:00:00 2001 From: Jeevananthan-23 Date: Tue, 31 Jan 2023 21:01:36 +0530 Subject: [PATCH 04/10] added transaction support --- src/NRedisStack/Transactions.cs | 55 +++++++++++++++++++ .../Examples/ExamplesTests.cs | 10 +++- tests/NRedisStack.Tests/TransactionsTests.cs | 26 +++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/NRedisStack/Transactions.cs create mode 100644 tests/NRedisStack.Tests/TransactionsTests.cs diff --git a/src/NRedisStack/Transactions.cs b/src/NRedisStack/Transactions.cs new file mode 100644 index 00000000..9a3e57d9 --- /dev/null +++ b/src/NRedisStack/Transactions.cs @@ -0,0 +1,55 @@ +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NRedisStack +{ + public class Transactions + { + public Transactions(IConnectionMultiplexer muxer) + { + _transaction = muxer.GetDatabase().CreateTransaction(); + } + + public Transactions(IDatabase db) + { + _transaction = db.CreateTransaction(); + } + + private ITransaction _transaction; + + public void AddCondition(Condition condition) + { + _transaction.AddCondition(condition); + } + + public bool Execute() + { + var result = _transaction.Execute(); + return result; + } + + public bool ExecuteAsync() + { + var result = _transaction.ExecuteAsync(); + return result.Result; + } + + + public IBloomCommandsAsync Bf => new BloomCommandsAsync(_transaction); + public ICmsCommandsAsync Cms => new CmsCommandsAsync(_transaction); + public ICuckooCommandsAsync Cf => new CuckooCommandsAsync(_transaction); + public IGraphCommandsAsync Graph => new GraphCommandsAsync(_transaction); + public IJsonCommandsAsync Json => new JsonCommandsAsync(_transaction); + public ISearchCommandsAsync Ft => new SearchCommandsAsync(_transaction); + public ITdigestCommandsAsync Tdigest => new TdigestCommandsAsync(_transaction); + public ITimeSeriesCommandsAsync Ts => new TimeSeriesCommandsAsync(_transaction); + public ITopKCommandsAsync TopK => new TopKCommandsAsync(_transaction); + + public IDatabaseAsync Db => _transaction; + + } +} diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index 07998139..f267d16c 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -6,7 +6,7 @@ using NRedisStack.Search; using NRedisStack.DataTypes; -namespace NRedisStack.Tests.Bloom; +namespace NRedisStack.Tests; public class ExaplesTests : AbstractNRedisStackTest, IDisposable { @@ -151,6 +151,7 @@ public async Task PipelineWithAsync() // Setup pipeline connection var pipeline = new Pipeline(redis); + // create metedata lables for time-series. TimeSeriesLabel label1 = new TimeSeriesLabel("temp", "TLV"); TimeSeriesLabel label2 = new TimeSeriesLabel("temp", "JLM"); @@ -194,6 +195,11 @@ public async Task PipelineWithAsync() [Fact] public void TransactionExample() { - // implementation for transaction + var tran = new Transactions(ConnectionMultiplexer.Connect("localhost")); + + tran.AddCondition(Condition.HashNotExists("profesor:5555", "UniqueID")); + tran.Db.HashSetAsync("profesor:5555", new HashEntry[] { new("first", "Albert"), new("last", "Blue"), new("age", "55") }); + bool condition = tran.Execute(); + Assert.True(condition); } } \ No newline at end of file diff --git a/tests/NRedisStack.Tests/TransactionsTests.cs b/tests/NRedisStack.Tests/TransactionsTests.cs new file mode 100644 index 00000000..a1bda2f1 --- /dev/null +++ b/tests/NRedisStack.Tests/TransactionsTests.cs @@ -0,0 +1,26 @@ +using Moq; +using StackExchange.Redis; +using Xunit; + +namespace NRedisStack.Tests +{ + public class TransactionsTests : AbstractNRedisStackTest, IDisposable + { + Mock _mock = new Mock(); + private readonly string key = "TRX_TESTS"; + public TransactionsTests(RedisFixture redisFixture) : base(redisFixture) { } + + public void Dispose() + { + redisFixture.Redis.GetDatabase().KeyDelete(key); + } + + [Fact] + public async Task TestModulsTransactions() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var transaction = new Transactions(db); + } + } +} From 0d0f48cc999c3699fb578a3fc8a7db425065b53c Mon Sep 17 00:00:00 2001 From: Jeevananthan-23 Date: Wed, 1 Feb 2023 20:48:20 +0530 Subject: [PATCH 05/10] fixing docs and transactions methods --- Examples/CombinationModulesPipeline.md | 4 +- Examples/PipelineExample.md | 40 +++++++---- src/NRedisStack/Transactions.cs | 17 ++--- .../Examples/ExamplesTests.cs | 70 +++++++++++++------ 4 files changed, 79 insertions(+), 52 deletions(-) diff --git a/Examples/CombinationModulesPipeline.md b/Examples/CombinationModulesPipeline.md index b36b9e0d..9b3d33dd 100644 --- a/Examples/CombinationModulesPipeline.md +++ b/Examples/CombinationModulesPipeline.md @@ -22,12 +22,12 @@ pipeline.Json.SetAsync("person:05", "$", new { name = "Michael", age = 55, city ``` ## Search -Create the schema to index first and age as a numeric field +Create the schema to index name as text field, age as a numeric field and city as tag field. ```csharp var schema = new Schema().AddTextField("name").AddNumericField("age", true).AddTagField("city"); ``` -Filter the index to only include Jsons and prefix of person +Filter the index to only include Jsons with prefix of person: ```csharp var parameters = FTCreateParams.CreateParams().On(Literals.Enums.IndexDataType.JSON).Prefix("person:"); ``` diff --git a/Examples/PipelineExample.md b/Examples/PipelineExample.md index a4ae48d2..784ce613 100644 --- a/Examples/PipelineExample.md +++ b/Examples/PipelineExample.md @@ -1,46 +1,56 @@ # Pipeline ## An example of pipelines Redis Stack Redis commands (JSON.SET & JSON.CLEAR & JSON.GET) -Connect to the Redis server: +Connect to the Redis server and Setup 2 Pipelines + +Pipeline can get IDatabase for pipeline1 ```csharp -var redis = ConnectionMultiplexer.Connect("localhost"); +IDatabase db = redisFixture.Redis.GetDatabase(); +var pipeline1 = new Pipeline(db); ``` -Setup pipeline connection +Pipeline can get IConnectionMultiplexer for pipeline2 ```csharp -var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); +var redis = ConnectionMultiplexer.Connect("localhost"); +var pipeline2 = new Pipeline(redis); ``` Add JsonSet to pipeline ```csharp -pipeline.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); +pipeline1.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); ``` -Inc `age` by 2 +Inc age by 2 ```csharp -pipeline.Json.NumIncrbyAsync("person", "$.age", 2); +pipeline1.Json.NumIncrbyAsync("person", "$.age", 2); ``` -Clear the `nicknames` from the Json +Execute the pipeline1 ```csharp -pipeline.Json.ClearAsync("person", "$.nicknames"); +pipeline1.Execute(); ``` -Del the `nicknames` +Clear the nicknames from the Json ```csharp -pipeline.Json.DelAsync("person", "$.nicknames"); +pipeline2.Json.ClearAsync("person", "$.nicknames"); +``` + +Del the nicknames +```csharp +pipeline2.Json.DelAsync("person", "$.nicknames"); ``` Get the Json response ```csharp -var getResponse = pipeline.Json.GetAsync("person"); +var getResponse = pipeline2.Json.GetAsync("person"); ``` -Execute the pipeline +Execute the pipeline2 ```csharp -pipeline.Execute(); +pipeline2.Execute(); ``` -Get the result JSON + +get the result back JSON ```csharp var result = getResponse.Result; ``` \ No newline at end of file diff --git a/src/NRedisStack/Transactions.cs b/src/NRedisStack/Transactions.cs index 9a3e57d9..26be4e01 100644 --- a/src/NRedisStack/Transactions.cs +++ b/src/NRedisStack/Transactions.cs @@ -1,9 +1,4 @@ using StackExchange.Redis; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace NRedisStack { @@ -21,21 +16,19 @@ public Transactions(IDatabase db) private ITransaction _transaction; - public void AddCondition(Condition condition) + public ConditionResult AddCondition(Condition condition) { - _transaction.AddCondition(condition); + return _transaction.AddCondition(condition); } public bool Execute() { - var result = _transaction.Execute(); - return result; + return _transaction.Execute(); } - public bool ExecuteAsync() + public Task ExecuteAsync() { - var result = _transaction.ExecuteAsync(); - return result.Result; + return _transaction.ExecuteAsync(); } diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index f267d16c..68484b01 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -1,10 +1,11 @@ -using Xunit; -using StackExchange.Redis; -using NRedisStack.RedisStackCommands; using Moq; -using NRedisStack.Search.FT.CREATE; -using NRedisStack.Search; using NRedisStack.DataTypes; +using NRedisStack.Literals.Enums; +using NRedisStack.RedisStackCommands; +using NRedisStack.Search; +using NRedisStack.Search.FT.CREATE; +using StackExchange.Redis; +using Xunit; namespace NRedisStack.Tests; @@ -74,33 +75,46 @@ public async Task AsyncExample() await json.SetAsync("key", "$", new { name = "John", age = 30, city = "New York" }); var john = await json.GetAsync("key"); } - + [Fact] public void PipelineExample() { - //Setup pipeline connection - var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); + // Connect to the Redis server and Setup 2 Pipelines + + // Pipeline can get IDatabase for pipeline1 + IDatabase db = redisFixture.Redis.GetDatabase(); + var pipeline1 = new Pipeline(db); + + // Pipeline can get IConnectionMultiplexer for pipeline2 + var redis = ConnectionMultiplexer.Connect("localhost"); + var pipeline2 = new Pipeline(redis); // Add JsonSet to pipeline - pipeline.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); + pipeline1.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); // Inc age by 2 - pipeline.Json.NumIncrbyAsync("person", "$.age", 2); + pipeline1.Json.NumIncrbyAsync("person", "$.age", 2); + + // Execute the pipeline1 + pipeline1.Execute(); // Clear the nicknames from the Json - pipeline.Json.ClearAsync("person", "$.nicknames"); + pipeline2.Json.ClearAsync("person", "$.nicknames"); // Del the nicknames - pipeline.Json.DelAsync("person", "$.nicknames"); + pipeline2.Json.DelAsync("person", "$.nicknames"); // Get the Json response - var getResponse = pipeline.Json.GetAsync("person"); + var getResponse = pipeline2.Json.GetAsync("person"); + + // Execute the pipeline2 + pipeline2.Execute(); - // Execute the pipeline - pipeline.Execute(); - // get the result back JSON var result = getResponse.Result; + + //Assert the result + Assert.NotNull(result); } [Fact] @@ -116,11 +130,11 @@ public void JsonWithSearchPipeline() pipeline.Json.SetAsync("person:04", "$", new { name = "Steve", age = 24, city = "Phoenix" }); pipeline.Json.SetAsync("person:05", "$", new { name = "Michael", age = 55, city = "San Antonio" }); - // Create the schema to index first and age as a numeric field + // Create the schema to index name as text field, age as a numeric field and city as tag field. var schema = new Schema().AddTextField("name").AddNumericField("age", true).AddTagField("city"); - // Filter the index to only include Jsons and prefix of person - var parameters = FTCreateParams.CreateParams().On(Literals.Enums.IndexDataType.JSON).Prefix("person:"); + // Filter the index to only include Jsons with prefix of person: + var parameters = FTCreateParams.CreateParams().On(IndexDataType.JSON).Prefix("person:"); // Create the index via pipeline pipeline.Ft.CreateAsync("person-idx", parameters, schema); @@ -132,11 +146,17 @@ public void JsonWithSearchPipeline() pipeline.Execute(); // get the total count of people records that indexed. - var count = getAllPersons.Result.TotalResults; + var count = getAllPersons.Result.TotalResults; // Gets the first person form the result. var firstPerson = getAllPersons.Result.Documents.FirstOrDefault(); // first person is John here. + + // Assert + + Assert.Equal(5, count); + + Assert.Equal("person:01", firstPerson?.Id); } [Fact] @@ -190,6 +210,10 @@ public async Task PipelineWithAsync() // get only the location label for each last sample, use SELECTED_LABELS. var respons = await ts.MGetAsync(new List { "temp=JLM" }, selectedLabels: new List { "location" }); + + // Assert th respons + Assert.Equal(1, respons.Count); + Assert.Equal("temp=JLM", respons[0].key); } [Fact] @@ -197,9 +221,9 @@ public void TransactionExample() { var tran = new Transactions(ConnectionMultiplexer.Connect("localhost")); - tran.AddCondition(Condition.HashNotExists("profesor:5555", "UniqueID")); + tran.AddCondition(Condition.HashNotExists("profesor:5555", "first")); tran.Db.HashSetAsync("profesor:5555", new HashEntry[] { new("first", "Albert"), new("last", "Blue"), new("age", "55") }); - bool condition = tran.Execute(); - Assert.True(condition); + var condition = tran.ExecuteAsync(); + Assert.True(condition.Result); } } \ No newline at end of file From 996475ca85855047ea6c71c6d4b287ba18022cfb Mon Sep 17 00:00:00 2001 From: Jeevananthan-23 Date: Wed, 1 Feb 2023 22:43:16 +0530 Subject: [PATCH 06/10] adding transaction test01 --- tests/NRedisStack.Tests/TransactionsTests.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/NRedisStack.Tests/TransactionsTests.cs b/tests/NRedisStack.Tests/TransactionsTests.cs index a1bda2f1..e7f1f460 100644 --- a/tests/NRedisStack.Tests/TransactionsTests.cs +++ b/tests/NRedisStack.Tests/TransactionsTests.cs @@ -1,5 +1,6 @@ using Moq; using StackExchange.Redis; +using System.Text.Json; using Xunit; namespace NRedisStack.Tests @@ -16,11 +17,20 @@ public void Dispose() } [Fact] - public async Task TestModulsTransactions() + public async Task TestJsonTransactions() { IDatabase db = redisFixture.Redis.GetDatabase(); db.Execute("FLUSHALL"); var transaction = new Transactions(db); + string jsonPerson = JsonSerializer.Serialize(new Person { Name = "Shachar", Age = 23 }); + var setResponse = transaction.Json.SetAsync(key, "$", jsonPerson); + var getResponse = transaction.Json.GetAsync(key); + + transaction.Execute(); + + Assert.Equal("True", setResponse.Result.ToString()); + Assert.Equal("{\"Name\":\"Shachar\",\"Age\":23}", getResponse.Result.ToString()); + } } } From b2116f66e23db7e828f4c104612a2d7ef908f857 Mon Sep 17 00:00:00 2001 From: Jeevananthan-23 Date: Sat, 4 Feb 2023 22:14:19 +0530 Subject: [PATCH 07/10] adding transactions tests --- Examples/CombinationModulesPipeline.md | 4 +- Examples/PipelineExample.md | 12 +-- Examples/PipelineWithAsync.md | 9 +- Examples/TransactionsExample.md | 56 ++++++++++++ src/NRedisStack/Transactions.cs | 24 ++--- .../Examples/ExamplesTests.cs | 87 ++++++++++++++----- 6 files changed, 138 insertions(+), 54 deletions(-) create mode 100644 Examples/TransactionsExample.md diff --git a/Examples/CombinationModulesPipeline.md b/Examples/CombinationModulesPipeline.md index 9b3d33dd..7224677d 100644 --- a/Examples/CombinationModulesPipeline.md +++ b/Examples/CombinationModulesPipeline.md @@ -1,4 +1,4 @@ -# Combination modules Pipeline +# Combination modules Pipeline ## An example of pipelines mixing a pipeline with a combination of module commands with JSON & Search Connect to the Redis server: @@ -29,7 +29,7 @@ var schema = new Schema().AddTextField("name").AddNumericField("age", true).AddT Filter the index to only include Jsons with prefix of person: ```csharp -var parameters = FTCreateParams.CreateParams().On(Literals.Enums.IndexDataType.JSON).Prefix("person:"); +var parameters = FTCreateParams.CreateParams().On(IndexDataType.JSON).Prefix("person:"); ``` Create the index via pipeline diff --git a/Examples/PipelineExample.md b/Examples/PipelineExample.md index 784ce613..12e2fe9a 100644 --- a/Examples/PipelineExample.md +++ b/Examples/PipelineExample.md @@ -1,4 +1,4 @@ -# Pipeline +# Pipeline ## An example of pipelines Redis Stack Redis commands (JSON.SET & JSON.CLEAR & JSON.GET) Connect to the Redis server and Setup 2 Pipelines @@ -20,12 +20,12 @@ Add JsonSet to pipeline pipeline1.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); ``` -Inc age by 2 +Increase age by 2 ```csharp pipeline1.Json.NumIncrbyAsync("person", "$.age", 2); ``` -Execute the pipeline1 +Execute pipeline1 ```csharp pipeline1.Execute(); ``` @@ -35,7 +35,7 @@ Clear the nicknames from the Json pipeline2.Json.ClearAsync("person", "$.nicknames"); ``` -Del the nicknames +Delete the nicknames ```csharp pipeline2.Json.DelAsync("person", "$.nicknames"); ``` @@ -45,12 +45,12 @@ Get the Json response var getResponse = pipeline2.Json.GetAsync("person"); ``` -Execute the pipeline2 +Execute pipeline2 ```csharp pipeline2.Execute(); ``` -get the result back JSON +Get the result of getResponse ```csharp var result = getResponse.Result; ``` \ No newline at end of file diff --git a/Examples/PipelineWithAsync.md b/Examples/PipelineWithAsync.md index 7463094c..1385517f 100644 --- a/Examples/PipelineWithAsync.md +++ b/Examples/PipelineWithAsync.md @@ -1,7 +1,6 @@ # Pipeline With Async ## An example of pipelines Redis Stack Redis commands (JSON.SET & JSON.CLEAR & JSON.GET) - Connect to the Redis server ```csharp var redis = ConnectionMultiplexer.Connect("localhost"); @@ -17,7 +16,7 @@ Setup pipeline connection var pipeline = new Pipeline(redis); ``` -create metedata lables for time-series. +Create metedata lables for time-series. ```csharp TimeSeriesLabel label1 = new TimeSeriesLabel("temp", "TLV"); TimeSeriesLabel label2 = new TimeSeriesLabel("temp", "JLM"); @@ -25,13 +24,13 @@ var labels1 = new List { label1 }; var labels2 = new List { label2 }; ``` -create a new time-series. +Create a new time-series. ```csharp pipeline.Ts.CreateAsync("temp:TLV", labels: labels1); pipeline.Ts.CreateAsync("temp:JLM", labels: labels2); ``` -adding multiple sequenece of time-series data. +Adding multiple sequenece of time-series data. ```csharp List<(string, TimeStamp, double)> sequence1 = new List<(string, TimeStamp, double)>() { @@ -64,7 +63,7 @@ Get a reference to the database and for time-series commands var ts = db.TS(); ``` -get only the location label for each last sample, use SELECTED_LABELS. +Get only the location label for each last sample, use SELECTED_LABELS. ```csharp var respons = await ts.MGetAsync(new List { "temp=JLM" }, selectedLabels: new List { "location" }); ``` \ No newline at end of file diff --git a/Examples/TransactionsExample.md b/Examples/TransactionsExample.md new file mode 100644 index 00000000..ef6eb7c4 --- /dev/null +++ b/Examples/TransactionsExample.md @@ -0,0 +1,56 @@ +# Transaction + +## An example of transactions with Redis modules (JSON.SET, JSON.GET & JSON.NUMINCRBY) + +Connect to the Redis server and Setup 2 Transactions +```cs +var redis = await ConnectionMultiplexer.ConnectAsync("localhost"); +var db = redis.GetDatabase(); +``` + +Setup transaction1 with IDatabase +```cs +var xAction1 = new Transactions(db); +``` + +Add account details with Json.Set to transaction1 +```cs +xAction1.Json.SetAsync("accdetails:Jeeva", "$", new { name = "Jeeva", totalAmount= 1000, bankName = "City" }); +xAction1.Json.SetAsync("accdetails:Shachar", "$", new { name = "Shachar", totalAmount = 1000, bankName = "City" }); +``` + +Get the Json response within Tansaction1 +```cs +var getShachar = xAction1.Json.GetAsync("accdetails:Shachar"); +var getJeeva = xAction1.Json.GetAsync("accdetails:Jeeva"); +``` + +Execute the transaction1 +```cs +xAction1.ExecuteAsync(); +``` + +Setup transaction2 with ConnectionMultiplexer +```cs +var xAction2 = new Transactions(redis); +``` + +Debit 200 from Jeeva within Tansaction2 +```cs +xAction2.Json.NumIncrbyAsync("accdetails:Jeeva", "$.totalAmount", -200); +``` +Credit 200 from Shachar within Tansaction2 +```cs +xAction2.Json.NumIncrbyAsync("accdetails:Shachar", "$.totalAmount", 200); +``` + +Get total amount for both Jeeva = 800 & Shachar = 1200 within Tansaction2 +```cs +var totalAmtOfJeeva = xAction2.Json.GetAsync("accdetails:Jeeva", path:"$.totalAmount"); +var totalAmtOfShachar = xAction2.Json.GetAsync("accdetails:Shachar", path:"$.totalAmount"); +``` + +Execute the transaction2 +```cs +var condition = xAction2.ExecuteAsync(); +``` \ No newline at end of file diff --git a/src/NRedisStack/Transactions.cs b/src/NRedisStack/Transactions.cs index 26be4e01..ae6f7e40 100644 --- a/src/NRedisStack/Transactions.cs +++ b/src/NRedisStack/Transactions.cs @@ -4,6 +4,9 @@ namespace NRedisStack { public class Transactions { + private ITransaction _transaction; + public IDatabaseAsync Db => _transaction; + public Transactions(IConnectionMultiplexer muxer) { _transaction = muxer.GetDatabase().CreateTransaction(); @@ -14,23 +17,11 @@ public Transactions(IDatabase db) _transaction = db.CreateTransaction(); } - private ITransaction _transaction; + public ConditionResult AddCondition(Condition condition) => _transaction.AddCondition(condition); - public ConditionResult AddCondition(Condition condition) - { - return _transaction.AddCondition(condition); - } - - public bool Execute() - { - return _transaction.Execute(); - } - - public Task ExecuteAsync() - { - return _transaction.ExecuteAsync(); - } + public bool Execute(CommandFlags flags = CommandFlags.None) => _transaction.Execute(flags); + public Task ExecuteAsync(CommandFlags flags = CommandFlags.None) => _transaction.ExecuteAsync(flags); public IBloomCommandsAsync Bf => new BloomCommandsAsync(_transaction); public ICmsCommandsAsync Cms => new CmsCommandsAsync(_transaction); @@ -41,8 +32,5 @@ public Task ExecuteAsync() public ITdigestCommandsAsync Tdigest => new TdigestCommandsAsync(_transaction); public ITimeSeriesCommandsAsync Ts => new TimeSeriesCommandsAsync(_transaction); public ITopKCommandsAsync TopK => new TopKCommandsAsync(_transaction); - - public IDatabaseAsync Db => _transaction; - } } diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index 68484b01..90b7947c 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -5,6 +5,7 @@ using NRedisStack.Search; using NRedisStack.Search.FT.CREATE; using StackExchange.Redis; +using System; using Xunit; namespace NRedisStack.Tests; @@ -28,6 +29,7 @@ public void HSETandSearch() // Get a reference to the database and for search commands: var db = redis.GetDatabase(); + db.Execute("FLUSHALL"); var ft = db.FT(); // Use HSET to add a field-value pair to a hash @@ -69,6 +71,7 @@ public async Task AsyncExample() // Connect to the Redis server var redis = await ConnectionMultiplexer.ConnectAsync("localhost"); var db = redis.GetDatabase(); + db.Execute("FLUSHALL"); var json = db.JSON(); // call async version of JSON.SET/GET @@ -83,6 +86,7 @@ public void PipelineExample() // Pipeline can get IDatabase for pipeline1 IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); var pipeline1 = new Pipeline(db); // Pipeline can get IConnectionMultiplexer for pipeline2 @@ -92,7 +96,7 @@ public void PipelineExample() // Add JsonSet to pipeline pipeline1.Json.SetAsync("person", "$", new { name = "John", age = 30, city = "New York", nicknames = new[] { "John", "Johny", "Jo" } }); - // Inc age by 2 + // Increase age by 2 pipeline1.Json.NumIncrbyAsync("person", "$.age", 2); // Execute the pipeline1 @@ -110,11 +114,12 @@ public void PipelineExample() // Execute the pipeline2 pipeline2.Execute(); - // get the result back JSON + // Get the result back JSON var result = getResponse.Result; - //Assert the result - Assert.NotNull(result); + // Assert the result + var expected = "{\"name\":\"John\",\"age\":32,\"city\":\"New York\"}"; + Assert.Equal(expected, result.ToString()); } [Fact] @@ -122,6 +127,7 @@ public void JsonWithSearchPipeline() { //Setup pipeline connection var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); + pipeline.Db.ExecuteAsync("FLUSHALL"); // Add JsonSet to pipeline pipeline.Json.SetAsync("person:01", "$", new { name = "John", age = 30, city = "New York" }); @@ -145,17 +151,15 @@ public void JsonWithSearchPipeline() // execute the pipeline pipeline.Execute(); - // get the total count of people records that indexed. - var count = getAllPersons.Result.TotalResults; + // Get the total count of people records that indexed. + var getAllPersonsResult = getAllPersons.Result; + var count = getAllPersonsResult.TotalResults; // Gets the first person form the result. - var firstPerson = getAllPersons.Result.Documents.FirstOrDefault(); + var firstPerson = getAllPersonsResult.Documents.FirstOrDefault(); // first person is John here. - // Assert - Assert.Equal(5, count); - Assert.Equal("person:01", firstPerson?.Id); } @@ -167,22 +171,22 @@ public async Task PipelineWithAsync() // Get a reference to the database var db = redis.GetDatabase(); - + db.Execute("FLUSHALL"); // Setup pipeline connection var pipeline = new Pipeline(redis); - // create metedata lables for time-series. + // Create metedata lables for time-series. TimeSeriesLabel label1 = new TimeSeriesLabel("temp", "TLV"); TimeSeriesLabel label2 = new TimeSeriesLabel("temp", "JLM"); var labels1 = new List { label1 }; var labels2 = new List { label2 }; - //create a new time-series. + // Create a new time-series. pipeline.Ts.CreateAsync("temp:TLV", labels: labels1); pipeline.Ts.CreateAsync("temp:JLM", labels: labels2); - //adding multiple sequenece of time-series data. + // Adding multiple sequenece of time-series data. List<(string, TimeStamp, double)> sequence1 = new List<(string, TimeStamp, double)>() { ("temp:TLV",1000,30), @@ -202,28 +206,65 @@ public async Task PipelineWithAsync() pipeline.Ts.MAddAsync(sequence1); pipeline.Ts.MAddAsync(sequence2); - // execute the pipeline + // Execute the pipeline pipeline.Execute(); // Get a reference to the database and for time-series commands var ts = db.TS(); - // get only the location label for each last sample, use SELECTED_LABELS. + // Get only the location label for each last sample, use SELECTED_LABELS. var respons = await ts.MGetAsync(new List { "temp=JLM" }, selectedLabels: new List { "location" }); - // Assert th respons + // Assert the respons Assert.Equal(1, respons.Count); - Assert.Equal("temp=JLM", respons[0].key); + Assert.Equal("temp:JLM", respons[0].key); } [Fact] - public void TransactionExample() + public async Task TransactionExample() { - var tran = new Transactions(ConnectionMultiplexer.Connect("localhost")); + // Connect to the Redis server + var redis = ConnectionMultiplexer.Connect("localhost"); + + // Get a reference to the database + var db = redis.GetDatabase(); + db.Execute("FLUSHALL"); - tran.AddCondition(Condition.HashNotExists("profesor:5555", "first")); - tran.Db.HashSetAsync("profesor:5555", new HashEntry[] { new("first", "Albert"), new("last", "Blue"), new("age", "55") }); - var condition = tran.ExecuteAsync(); + // Setup transaction1 with IDatabase + var xAction1 = new Transactions(db); + + // Add account details with Json.Set to transaction1 + xAction1.Json.SetAsync("accdetails:Jeeva", "$", new { name = "Jeeva", totalAmount= 1000, bankName = "City" }); + xAction1.Json.SetAsync("accdetails:Shachar", "$", new { name = "Shachar", totalAmount = 1000, bankName = "City" }); + + // Get the Json response within Tansaction1 + var getShachar = xAction1.Json.GetAsync("accdetails:Shachar"); + var getJeeva = xAction1.Json.GetAsync("accdetails:Jeeva"); + + // Execute the transaction1 + xAction1.ExecuteAsync(); + + // Setup transaction2 with ConnectionMultiplexer + var xAction2 = new Transactions(redis); + + // Debit 200 from Jeeva within Tansaction2 + xAction2.Json.NumIncrbyAsync("accdetails:Jeeva", "$.totalAmount", -200); + + // Credit 200 from Shachar within Tansaction2 + xAction2.Json.NumIncrbyAsync("accdetails:Shachar", "$.totalAmount", 200); + + // Get total amount for both Jeeva = 800 & Shachar = 1200 within Tansaction2 + var totalAmtOfJeeva = xAction2.Json.GetAsync("accdetails:Jeeva", path:"$.totalAmount"); + var totalAmtOfShachar = xAction2.Json.GetAsync("accdetails:Shachar", path:"$.totalAmount"); + + // Execute the transaction2 + var condition = xAction2.ExecuteAsync(); + + // Assert Assert.True(condition.Result); + Assert.NotEmpty(getJeeva.Result.ToString()); + Assert.NotEmpty(getShachar.Result.ToString()); + Assert.Equal("[800]", totalAmtOfJeeva.Result.ToString()); + Assert.Equal("[1200]", totalAmtOfShachar.Result.ToString()); } } \ No newline at end of file From cc4042440bfbc4b04d493b3dd7348892f39a457c Mon Sep 17 00:00:00 2001 From: Jeevananthan-23 Date: Sun, 5 Feb 2023 19:58:15 +0530 Subject: [PATCH 08/10] fix test --- .../Examples/ExamplesTests.cs | 35 ++++++----- tests/NRedisStack.Tests/TransactionsTests.cs | 63 ++++++++++++++++++- 2 files changed, 81 insertions(+), 17 deletions(-) diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index 90b7947c..4073b5ad 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -123,18 +123,19 @@ public void PipelineExample() } [Fact] - public void JsonWithSearchPipeline() + public async Task JsonWithSearchPipeline() { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); //Setup pipeline connection - var pipeline = new Pipeline(ConnectionMultiplexer.Connect("localhost")); - pipeline.Db.ExecuteAsync("FLUSHALL"); + var pipeline = new Pipeline(db); // Add JsonSet to pipeline - pipeline.Json.SetAsync("person:01", "$", new { name = "John", age = 30, city = "New York" }); - pipeline.Json.SetAsync("person:02", "$", new { name = "Joy", age = 25, city = "Los Angeles" }); - pipeline.Json.SetAsync("person:03", "$", new { name = "Mark", age = 21, city = "Chicago" }); - pipeline.Json.SetAsync("person:04", "$", new { name = "Steve", age = 24, city = "Phoenix" }); - pipeline.Json.SetAsync("person:05", "$", new { name = "Michael", age = 55, city = "San Antonio" }); + _ = pipeline.Json.SetAsync("person:01", "$", new { name = "John", age = 30, city = "New York" }); + _ = pipeline.Json.SetAsync("person:02", "$", new { name = "Joy", age = 25, city = "Los Angeles" }); + _ = pipeline.Json.SetAsync("person:03", "$", new { name = "Mark", age = 21, city = "Chicago" }); + _ = pipeline.Json.SetAsync("person:04", "$", new { name = "Steve", age = 24, city = "Phoenix" }); + _ = pipeline.Json.SetAsync("person:05", "$", new { name = "Michael", age = 55, city = "San Antonio" }); // Create the schema to index name as text field, age as a numeric field and city as tag field. var schema = new Schema().AddTextField("name").AddNumericField("age", true).AddTagField("city"); @@ -143,24 +144,26 @@ public void JsonWithSearchPipeline() var parameters = FTCreateParams.CreateParams().On(IndexDataType.JSON).Prefix("person:"); // Create the index via pipeline - pipeline.Ft.CreateAsync("person-idx", parameters, schema); - - // Search for all indexed person records - var getAllPersons = pipeline.Ft.SearchAsync("person-idx", new Query()); + var create = pipeline.Ft.CreateAsync("person-idx", parameters, schema); // execute the pipeline pipeline.Execute(); + // Search for all indexed person records + Task.Delay(2000).Wait(); + var getAllPersons = await db.FT().SearchAsync("person-idx", new Query()); + + // Get the total count of people records that indexed. - var getAllPersonsResult = getAllPersons.Result; - var count = getAllPersonsResult.TotalResults; + var count = getAllPersons.TotalResults; // Gets the first person form the result. - var firstPerson = getAllPersonsResult.Documents.FirstOrDefault(); + var firstPerson = getAllPersons.Documents.FirstOrDefault(); // first person is John here. + Assert.True(create.Result); Assert.Equal(5, count); - Assert.Equal("person:01", firstPerson?.Id); + //Assert.Equal("person:01", firstPerson?.Id); } [Fact] diff --git a/tests/NRedisStack.Tests/TransactionsTests.cs b/tests/NRedisStack.Tests/TransactionsTests.cs index e7f1f460..2aa5a200 100644 --- a/tests/NRedisStack.Tests/TransactionsTests.cs +++ b/tests/NRedisStack.Tests/TransactionsTests.cs @@ -30,7 +30,68 @@ public async Task TestJsonTransactions() Assert.Equal("True", setResponse.Result.ToString()); Assert.Equal("{\"Name\":\"Shachar\",\"Age\":23}", getResponse.Result.ToString()); - } + + /* [Fact] + public async Task TestCountMinSketchWithTopKInTransaction() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var transaction = new Transactions(db); + + *//*transaction.TopK.ReserveAsync("aaa", 30, 2000, 7, 0.925); + transaction.TopK.AddAsync("aaa", "foo", "bar"); + var results = transaction.TopK.ListAsync("aaa", true); + + + transaction.Cms.InitByDimAsync("A", 1000, 5); + var aValues = new Tuple[3]; + aValues[0] = new Tuple("foo", 5); + aValues[1] = new Tuple("bar", 3); + aValues[2] = new Tuple("baz", 9); + transaction.Cms.IncrByAsync("A", aValues); + transaction.Cms.QueryAsync("A", new RedisValue[] { "foo", "bar", "baz" });*//* + + + transaction.Cms.InitByDimAsync("A", 1000, 5); + transaction.Cms.InitByDimAsync("B", 1000, 5); + transaction.Cms.InitByDimAsync("C", 1000, 5); + + var aValues = new Tuple[3]; + aValues[0] = new Tuple("foo", 5); + aValues[1] = new Tuple("bar", 3); + aValues[2] = new Tuple("baz", 9); + + transaction.Cms.IncrByAsync("A", aValues); + + var bValues = new Tuple[3]; + bValues[0] = new Tuple("foo", 2); + bValues[1] = new Tuple("bar", 3); + bValues[2] = new Tuple("baz", 1); + + transaction.Cms.IncrByAsync("B", bValues); + + var q1 = transaction.Cms.QueryAsync("A", new RedisValue[] { "foo", "bar", "baz" }); + Assert.Equal(new long[] { 5L, 3L, 9L }, q1); + + var q2 = transaction.Cms.QueryAsync("B", new RedisValue[] { "foo", "bar", "baz" }); + Assert.Equal(new long[] { 2L, 3L, 1L }, q2); + + transaction.Cms.MergeAsync("C", 2, new RedisValue[] { "A", "B" }); + + var q3 = transaction.Cms.QueryAsync("C", new RedisValue[] { "foo", "bar", "baz" }); + Assert.Equal(new long[] { 7L, 6L, 10L }, q3); + + transaction.Cms.MergeAsync("C", 2, new RedisValue[] { "A", "B" }, new long[] { 1, 2 }); + + var q4 = transaction.Cms.QueryAsync("C", new RedisValue[] { "foo", "bar", "baz" }); + Assert.Equal(new long[] { 9L, 9L, 11L }, q4); + + transaction.Cms.MergeAsync("C", 2, new RedisValue[] { "A", "B" }, new long[] { 2, 3 }); + + + var q5 = transaction.Cms.QueryAsync("C", new RedisValue[] { "foo", "bar", "baz" }); + Assert.Equal(new long[] { 16L, 15L, 21L }, (IEnumerable)q5); + }*/ } } From e672cb86f359d285973f070a3dea689fb3a07498 Mon Sep 17 00:00:00 2001 From: shacharPash Date: Sun, 5 Feb 2023 18:22:46 +0200 Subject: [PATCH 09/10] fixes --- Examples/TransactionsExample.md | 53 +++++++++---------- src/NRedisStack/Pipeline.cs | 6 +-- src/NRedisStack/Transactions.cs | 5 -- .../Examples/ExamplesTests.cs | 40 ++++++-------- 4 files changed, 45 insertions(+), 59 deletions(-) diff --git a/Examples/TransactionsExample.md b/Examples/TransactionsExample.md index ef6eb7c4..3f8dd761 100644 --- a/Examples/TransactionsExample.md +++ b/Examples/TransactionsExample.md @@ -2,55 +2,54 @@ ## An example of transactions with Redis modules (JSON.SET, JSON.GET & JSON.NUMINCRBY) -Connect to the Redis server and Setup 2 Transactions +Connect to the Redis server + ```cs var redis = await ConnectionMultiplexer.ConnectAsync("localhost"); var db = redis.GetDatabase(); ``` -Setup transaction1 with IDatabase -```cs -var xAction1 = new Transactions(db); -``` +Setup transaction -Add account details with Json.Set to transaction1 ```cs -xAction1.Json.SetAsync("accdetails:Jeeva", "$", new { name = "Jeeva", totalAmount= 1000, bankName = "City" }); -xAction1.Json.SetAsync("accdetails:Shachar", "$", new { name = "Shachar", totalAmount = 1000, bankName = "City" }); +var tran = new Transactions(db); ``` -Get the Json response within Tansaction1 -```cs -var getShachar = xAction1.Json.GetAsync("accdetails:Shachar"); -var getJeeva = xAction1.Json.GetAsync("accdetails:Jeeva"); -``` +Add account details with Json.Set -Execute the transaction1 ```cs -xAction1.ExecuteAsync(); +tran.Json.SetAsync("accdetails:Jeeva", "$", new { name = "Jeeva", totalAmount= 1000, bankName = "City" }); +tran.Json.SetAsync("accdetails:Shachar", "$", new { name = "Shachar", totalAmount = 1000, bankName = "City" }); ``` -Setup transaction2 with ConnectionMultiplexer +Get the Json response for both Jeeva & Shachar + ```cs -var xAction2 = new Transactions(redis); +var getShachar = tran.Json.GetAsync("accdetails:Shachar"); +var getJeeva = tran.Json.GetAsync("accdetails:Jeeva"); ``` -Debit 200 from Jeeva within Tansaction2 +Debit 200 from Jeeva + ```cs -xAction2.Json.NumIncrbyAsync("accdetails:Jeeva", "$.totalAmount", -200); +tran.Json.NumIncrbyAsync("accdetails:Jeeva", "$.totalAmount", -200); ``` -Credit 200 from Shachar within Tansaction2 + +Credit 200 from Shachar + ```cs -xAction2.Json.NumIncrbyAsync("accdetails:Shachar", "$.totalAmount", 200); +tran.Json.NumIncrbyAsync("accdetails:Shachar", "$.totalAmount", 200); ``` -Get total amount for both Jeeva = 800 & Shachar = 1200 within Tansaction2 +Get total amount for both Jeeva = 800 & Shachar = 1200 + ```cs -var totalAmtOfJeeva = xAction2.Json.GetAsync("accdetails:Jeeva", path:"$.totalAmount"); -var totalAmtOfShachar = xAction2.Json.GetAsync("accdetails:Shachar", path:"$.totalAmount"); +var totalAmtOfJeeva = tran.Json.GetAsync("accdetails:Jeeva", path:"$.totalAmount"); +var totalAmtOfShachar = tran.Json.GetAsync("accdetails:Shachar", path:"$.totalAmount"); ``` -Execute the transaction2 +Execute the transaction + ```cs -var condition = xAction2.ExecuteAsync(); -``` \ No newline at end of file +var condition = tran.ExecuteAsync(); +``` diff --git a/src/NRedisStack/Pipeline.cs b/src/NRedisStack/Pipeline.cs index a9caecb2..1333acd2 100644 --- a/src/NRedisStack/Pipeline.cs +++ b/src/NRedisStack/Pipeline.cs @@ -16,10 +16,8 @@ public Pipeline(IDatabase db) private IBatch _batch; - public void Execute() - { - _batch.Execute(); - } + public void Execute() => _batch.Execute(); + public IBloomCommandsAsync Bf => new BloomCommandsAsync(_batch); public ICmsCommandsAsync Cms => new CmsCommandsAsync(_batch); diff --git a/src/NRedisStack/Transactions.cs b/src/NRedisStack/Transactions.cs index ae6f7e40..eed58a84 100644 --- a/src/NRedisStack/Transactions.cs +++ b/src/NRedisStack/Transactions.cs @@ -7,11 +7,6 @@ public class Transactions private ITransaction _transaction; public IDatabaseAsync Db => _transaction; - public Transactions(IConnectionMultiplexer muxer) - { - _transaction = muxer.GetDatabase().CreateTransaction(); - } - public Transactions(IDatabase db) { _transaction = db.CreateTransaction(); diff --git a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs index 4073b5ad..32b2c7b3 100644 --- a/tests/NRedisStack.Tests/Examples/ExamplesTests.cs +++ b/tests/NRedisStack.Tests/Examples/ExamplesTests.cs @@ -233,35 +233,29 @@ public async Task TransactionExample() var db = redis.GetDatabase(); db.Execute("FLUSHALL"); - // Setup transaction1 with IDatabase - var xAction1 = new Transactions(db); + // Setup transaction with IDatabase + var tran = new Transactions(db); - // Add account details with Json.Set to transaction1 - xAction1.Json.SetAsync("accdetails:Jeeva", "$", new { name = "Jeeva", totalAmount= 1000, bankName = "City" }); - xAction1.Json.SetAsync("accdetails:Shachar", "$", new { name = "Shachar", totalAmount = 1000, bankName = "City" }); + // Add account details with Json.Set to transaction + tran.Json.SetAsync("accdetails:Jeeva", "$", new { name = "Jeeva", totalAmount= 1000, bankName = "City" }); + tran.Json.SetAsync("accdetails:Shachar", "$", new { name = "Shachar", totalAmount = 1000, bankName = "City" }); - // Get the Json response within Tansaction1 - var getShachar = xAction1.Json.GetAsync("accdetails:Shachar"); - var getJeeva = xAction1.Json.GetAsync("accdetails:Jeeva"); - - // Execute the transaction1 - xAction1.ExecuteAsync(); - - // Setup transaction2 with ConnectionMultiplexer - var xAction2 = new Transactions(redis); + // Get the Json response + var getShachar = tran.Json.GetAsync("accdetails:Shachar"); + var getJeeva = tran.Json.GetAsync("accdetails:Jeeva"); - // Debit 200 from Jeeva within Tansaction2 - xAction2.Json.NumIncrbyAsync("accdetails:Jeeva", "$.totalAmount", -200); + // Debit 200 from Jeeva + tran.Json.NumIncrbyAsync("accdetails:Jeeva", "$.totalAmount", -200); - // Credit 200 from Shachar within Tansaction2 - xAction2.Json.NumIncrbyAsync("accdetails:Shachar", "$.totalAmount", 200); + // Credit 200 from Shachar + tran.Json.NumIncrbyAsync("accdetails:Shachar", "$.totalAmount", 200); - // Get total amount for both Jeeva = 800 & Shachar = 1200 within Tansaction2 - var totalAmtOfJeeva = xAction2.Json.GetAsync("accdetails:Jeeva", path:"$.totalAmount"); - var totalAmtOfShachar = xAction2.Json.GetAsync("accdetails:Shachar", path:"$.totalAmount"); + // Get total amount for both Jeeva = 800 & Shachar = 1200 + var totalAmtOfJeeva = tran.Json.GetAsync("accdetails:Jeeva", path:"$.totalAmount"); + var totalAmtOfShachar = tran.Json.GetAsync("accdetails:Shachar", path:"$.totalAmount"); - // Execute the transaction2 - var condition = xAction2.ExecuteAsync(); + // Execute the transaction + var condition = tran.ExecuteAsync(); // Assert Assert.True(condition.Result); From 8a72c5c27390a8049efd3429774453509e23fb72 Mon Sep 17 00:00:00 2001 From: shacharPash Date: Mon, 6 Feb 2023 09:45:38 +0200 Subject: [PATCH 10/10] add TestModulsTransaction --- tests/NRedisStack.Tests/TransactionsTests.cs | 114 +++++++++---------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/tests/NRedisStack.Tests/TransactionsTests.cs b/tests/NRedisStack.Tests/TransactionsTests.cs index 2aa5a200..2ec82049 100644 --- a/tests/NRedisStack.Tests/TransactionsTests.cs +++ b/tests/NRedisStack.Tests/TransactionsTests.cs @@ -1,4 +1,7 @@ using Moq; +using NRedisStack.RedisStackCommands; +using NRedisStack.Search; +using NRedisStack.Search.FT.CREATE; using StackExchange.Redis; using System.Text.Json; using Xunit; @@ -32,66 +35,55 @@ public async Task TestJsonTransactions() Assert.Equal("{\"Name\":\"Shachar\",\"Age\":23}", getResponse.Result.ToString()); } - /* [Fact] - public async Task TestCountMinSketchWithTopKInTransaction() - { - IDatabase db = redisFixture.Redis.GetDatabase(); - db.Execute("FLUSHALL"); - var transaction = new Transactions(db); - - *//*transaction.TopK.ReserveAsync("aaa", 30, 2000, 7, 0.925); - transaction.TopK.AddAsync("aaa", "foo", "bar"); - var results = transaction.TopK.ListAsync("aaa", true); - - - transaction.Cms.InitByDimAsync("A", 1000, 5); - var aValues = new Tuple[3]; - aValues[0] = new Tuple("foo", 5); - aValues[1] = new Tuple("bar", 3); - aValues[2] = new Tuple("baz", 9); - transaction.Cms.IncrByAsync("A", aValues); - transaction.Cms.QueryAsync("A", new RedisValue[] { "foo", "bar", "baz" });*//* - - - transaction.Cms.InitByDimAsync("A", 1000, 5); - transaction.Cms.InitByDimAsync("B", 1000, 5); - transaction.Cms.InitByDimAsync("C", 1000, 5); - - var aValues = new Tuple[3]; - aValues[0] = new Tuple("foo", 5); - aValues[1] = new Tuple("bar", 3); - aValues[2] = new Tuple("baz", 9); - - transaction.Cms.IncrByAsync("A", aValues); - - var bValues = new Tuple[3]; - bValues[0] = new Tuple("foo", 2); - bValues[1] = new Tuple("bar", 3); - bValues[2] = new Tuple("baz", 1); - - transaction.Cms.IncrByAsync("B", bValues); - - var q1 = transaction.Cms.QueryAsync("A", new RedisValue[] { "foo", "bar", "baz" }); - Assert.Equal(new long[] { 5L, 3L, 9L }, q1); - - var q2 = transaction.Cms.QueryAsync("B", new RedisValue[] { "foo", "bar", "baz" }); - Assert.Equal(new long[] { 2L, 3L, 1L }, q2); - - transaction.Cms.MergeAsync("C", 2, new RedisValue[] { "A", "B" }); - - var q3 = transaction.Cms.QueryAsync("C", new RedisValue[] { "foo", "bar", "baz" }); - Assert.Equal(new long[] { 7L, 6L, 10L }, q3); - - transaction.Cms.MergeAsync("C", 2, new RedisValue[] { "A", "B" }, new long[] { 1, 2 }); - - var q4 = transaction.Cms.QueryAsync("C", new RedisValue[] { "foo", "bar", "baz" }); - Assert.Equal(new long[] { 9L, 9L, 11L }, q4); - - transaction.Cms.MergeAsync("C", 2, new RedisValue[] { "A", "B" }, new long[] { 2, 3 }); - - - var q5 = transaction.Cms.QueryAsync("C", new RedisValue[] { "foo", "bar", "baz" }); - Assert.Equal(new long[] { 16L, 15L, 21L }, (IEnumerable)q5); - }*/ + [Fact] + public async Task TestModulsTransaction() + { + IDatabase db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + var tran = new Transactions(db); + + tran.Bf.ReserveAsync("bf-key", 0.001, 100); + tran.Bf.AddAsync("bf-key", "1"); + tran.Cms.InitByDimAsync("cms-key", 100, 5); + tran.Cf.ReserveAsync("cf-key", 100); + tran.Graph.QueryAsync("graph-key", "CREATE ({name:'shachar',age:23})"); + tran.Json.SetAsync("json-key", "$", "{}"); + tran.Ft.CreateAsync("ft-key", new FTCreateParams(), new Schema().AddTextField("txt")); + tran.Tdigest.CreateAsync("tdigest-key", 100); + tran.Ts.CreateAsync("ts-key", 100); + tran.TopK.ReserveAsync("topk-key", 100, 100, 100); + + Assert.False(db.KeyExists("bf-key")); + Assert.False(db.KeyExists("cms-key")); + Assert.False(db.KeyExists("cf-key")); + Assert.False(db.KeyExists("graph-key")); + Assert.False(db.KeyExists("json-key")); + Assert.Equal(0, db.FT()._List().Length); + Assert.False(db.KeyExists("tdigest-key")); + Assert.False(db.KeyExists("ts-key")); + Assert.False(db.KeyExists("topk-key")); + + tran.Execute(); + + Assert.True(db.KeyExists("bf-key")); + Assert.True(db.KeyExists("cms-key")); + Assert.True(db.KeyExists("cf-key")); + Assert.True(db.KeyExists("graph-key")); + Assert.True(db.KeyExists("json-key")); + Assert.True(db.FT()._List().Length == 1); + Assert.True(db.KeyExists("tdigest-key")); + Assert.True(db.KeyExists("ts-key")); + Assert.True(db.KeyExists("topk-key")); + + Assert.True(db.BF().Exists("bf-key", "1")); + Assert.True(db.CMS().Info("cms-key").Width == 100); + Assert.True(db.CF().Info("cf-key").Size > 0); + Assert.True(db.GRAPH().List().Count > 0); + Assert.False(db.JSON().Get("json-key").IsNull); + Assert.NotNull(db.FT().Info("ft-key")); + Assert.NotNull(db.TDIGEST().Info("tdigest-key")); + Assert.NotNull(db.TS().Info("ts-key")); + Assert.NotNull(db.TOPK().Info("topk-key")); + } } }