From e84b2f559c8d3d399e78bf599efab5295733214d Mon Sep 17 00:00:00 2001 From: Shaun Sales Date: Sun, 6 Sep 2020 13:42:09 +0800 Subject: [PATCH] Implemented new aggregation type. Updated examples and tests. --- NRedisTimeSeries.Example/MRangeExample.cs | 8 +- .../MRangeExampleAsync.cs | 2 +- NRedisTimeSeries.Example/RangeExample.cs | 2 +- NRedisTimeSeries.Example/RangeExampleAsync.cs | 2 +- NRedisTimeSeries.Example/RulesExample.cs | 2 +- NRedisTimeSeries.Example/RulesExampleAsync.cs | 2 +- NRedisTimeSeries.Test/TestAPI/TestMRange.cs | 4 +- .../TestAPI/TestMRangeAsync.cs | 4 +- .../TestAPI/TestMRevRange.cs | 4 +- .../TestAPI/TestMRevRangeAsync.cs | 4 +- NRedisTimeSeries.Test/TestAPI/TestRange.cs | 4 +- .../TestAPI/TestRangeAsync.cs | 4 +- NRedisTimeSeries.Test/TestAPI/TestRevRange.cs | 4 +- .../TestAPI/TestRevRangeAsync.cs | 4 +- NRedisTimeSeries.Test/TestAPI/TestRules.cs | 38 +++--- .../TestAPI/TestRulesAsync.cs | 24 ++-- .../TestDataTypes/TestTimeSeriesRule.cs | 24 ++-- NRedisTimeSeries/Commands/Aggregation.cs | 122 +++++------------- NRedisTimeSeries/DataTypes/TimeSeriesRule.cs | 8 +- .../Extensions/AggregationExtensions.cs | 42 ++++++ NRedisTimeSeries/NRedisTimeSeries.csproj | 3 +- NRedisTimeSeries/TimeSeriesClient.cs | 8 +- NRedisTimeSeries/TimeSeriesClientAsync.cs | 8 +- NRedisTimeSeries/TimeSeriesClientAux.cs | 11 +- .../TimeSeriesClientResponseParser.cs | 5 +- 25 files changed, 166 insertions(+), 177 deletions(-) create mode 100644 NRedisTimeSeries/Extensions/AggregationExtensions.cs diff --git a/NRedisTimeSeries.Example/MRangeExample.cs b/NRedisTimeSeries.Example/MRangeExample.cs index e415a7f..769fa01 100644 --- a/NRedisTimeSeries.Example/MRangeExample.cs +++ b/NRedisTimeSeries.Example/MRangeExample.cs @@ -17,7 +17,7 @@ internal class MRangeExample /// In this case, the strings are implicitly casted into TimeStamp objects. /// The TimeSeriesMRange command returns an IReadOnlyList<(string key, IReadOnlyList labels, IReadOnlyList values)>collection. /// - public static void BasicMRangeExample() + public static void BasicMRangeExample() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); @@ -43,7 +43,7 @@ public static void CountMRangeExample() ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); var filter = new List { "MRANGEkey=MRANGEvalue" }; - var results = db.TimeSeriesMRange("-", "+", filter, count:50); + var results = db.TimeSeriesMRange("-", "+", filter, count: 50); // Values extraction example. No lables in this case. foreach (var result in results) { @@ -64,7 +64,7 @@ public static void MRangeAggregationExample() ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); var filter = new List { "MRANGEkey=MRANGEvalue" }; - var results = db.TimeSeriesMRange("-", "+", filter, aggregation:Aggregation.MIN, timeBucket:50); + var results = db.TimeSeriesMRange("-", "+", filter, aggregation: TsAggregation.Min, timeBucket: 50); // Values extraction example. No lables in this case. foreach (var result in results) { @@ -85,7 +85,7 @@ public static void MRangeWithLabelsExample() ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); var filter = new List { "MRANGEkey=MRANGEvalue" }; - var results = db.TimeSeriesMRange("-", "+", filter,withLabels:true); + var results = db.TimeSeriesMRange("-", "+", filter, withLabels: true); // Values extraction example. foreach (var result in results) { diff --git a/NRedisTimeSeries.Example/MRangeExampleAsync.cs b/NRedisTimeSeries.Example/MRangeExampleAsync.cs index 1ce96f5..fd4789f 100644 --- a/NRedisTimeSeries.Example/MRangeExampleAsync.cs +++ b/NRedisTimeSeries.Example/MRangeExampleAsync.cs @@ -64,7 +64,7 @@ public static async Task MRangeAggregationAsyncExample() ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); var filter = new List { "MRANGEkey=MRANGEvalue" }; - var results = await db.TimeSeriesMRangeAsync("-", "+", filter, aggregation: Aggregation.MIN, timeBucket: 50); + var results = await db.TimeSeriesMRangeAsync("-", "+", filter, aggregation: TsAggregation.Min, timeBucket: 50); // Values extraction example. No lables in this case. foreach (var result in results) { diff --git a/NRedisTimeSeries.Example/RangeExample.cs b/NRedisTimeSeries.Example/RangeExample.cs index 380c21a..2969462 100644 --- a/NRedisTimeSeries.Example/RangeExample.cs +++ b/NRedisTimeSeries.Example/RangeExample.cs @@ -49,7 +49,7 @@ public static void RangeAggregationExample() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); - db.TimeSeriesRange("my_ts", "-", "+", aggregation: Aggregation.MIN, timeBucket: 50); + db.TimeSeriesRange("my_ts", "-", "+", aggregation: TsAggregation.Min, timeBucket: 50); redis.Close(); } } diff --git a/NRedisTimeSeries.Example/RangeExampleAsync.cs b/NRedisTimeSeries.Example/RangeExampleAsync.cs index 22db1f2..8338e1b 100644 --- a/NRedisTimeSeries.Example/RangeExampleAsync.cs +++ b/NRedisTimeSeries.Example/RangeExampleAsync.cs @@ -49,7 +49,7 @@ public static async Task RangeAggregationAsyncExample() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); - await db.TimeSeriesRangeAsync("my_ts", "-", "+", aggregation: Aggregation.MIN, timeBucket: 50); + await db.TimeSeriesRangeAsync("my_ts", "-", "+", aggregation: TsAggregation.Min, timeBucket: 50); redis.Close(); } } diff --git a/NRedisTimeSeries.Example/RulesExample.cs b/NRedisTimeSeries.Example/RulesExample.cs index e953b20..c658a54 100644 --- a/NRedisTimeSeries.Example/RulesExample.cs +++ b/NRedisTimeSeries.Example/RulesExample.cs @@ -18,7 +18,7 @@ public static void RulesCreateDeleteExample() ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); // Create you rule with destination key, time bucket and aggregation type. - TimeSeriesRule rule = new TimeSeriesRule("dest_ts", 50, Aggregation.AVG); + TimeSeriesRule rule = new TimeSeriesRule("dest_ts", 50, TsAggregation.Avg); db.TimeSeriesCreateRule("my_ts", rule); db.TimeSeriesDeleteRule("my_ts", "dest"); redis.Close(); diff --git a/NRedisTimeSeries.Example/RulesExampleAsync.cs b/NRedisTimeSeries.Example/RulesExampleAsync.cs index a1def16..49d08ae 100644 --- a/NRedisTimeSeries.Example/RulesExampleAsync.cs +++ b/NRedisTimeSeries.Example/RulesExampleAsync.cs @@ -18,7 +18,7 @@ public static async Task RulesCreateDeleteAsyncExample() ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); IDatabase db = redis.GetDatabase(); // Create your rule with destination key, time bucket and aggregation type. - TimeSeriesRule rule = new TimeSeriesRule("dest_ts", 50, Aggregation.AVG); + TimeSeriesRule rule = new TimeSeriesRule("dest_ts", 50, TsAggregation.Avg); await db.TimeSeriesCreateRuleAsync("my_ts", rule); await db.TimeSeriesDeleteRuleAsync("my_ts", "dest"); redis.Close(); diff --git a/NRedisTimeSeries.Test/TestAPI/TestMRange.cs b/NRedisTimeSeries.Test/TestAPI/TestMRange.cs index c55cbd6..2a9b892 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestMRange.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestMRange.cs @@ -133,7 +133,7 @@ public void TestMRangeAggregation() } var tuples = CreateData(db, 50); - var results = db.TimeSeriesMRange("-", "+", new List { "key=MRangeAggregation" }, aggregation: Aggregation.MIN, timeBucket: 50); + var results = db.TimeSeriesMRange("-", "+", new List { "key=MRangeAggregation" }, aggregation: TsAggregation.Min, timeBucket: 50); Assert.Equal(keys.Length, results.Count); for (int i = 0; i < results.Count; i++) { @@ -171,7 +171,7 @@ public void TestMissingTimeBucket() } var tuples = CreateData(db, 50); - var ex = Assert.Throws(() => db.TimeSeriesMRange("-", "+", new List { "key=MissingTimeBucket" }, aggregation: Aggregation.AVG)); + var ex = Assert.Throws(() => db.TimeSeriesMRange("-", "+", new List { "key=MissingTimeBucket" }, aggregation: TsAggregation.Avg)); Assert.Equal("RANGE Aggregation should have timeBucket value", ex.Message); } diff --git a/NRedisTimeSeries.Test/TestAPI/TestMRangeAsync.cs b/NRedisTimeSeries.Test/TestAPI/TestMRangeAsync.cs index bfe560c..a63d41c 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestMRangeAsync.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestMRangeAsync.cs @@ -128,7 +128,7 @@ public async Task TestMRangeAggregation() } var tuples = await CreateData(db, keys, 50); - var results = await db.TimeSeriesMRangeAsync("-", "+", new List { $"{keys[0]}=value" }, aggregation: Aggregation.MIN, timeBucket: 50); + var results = await db.TimeSeriesMRangeAsync("-", "+", new List { $"{keys[0]}=value" }, aggregation: TsAggregation.Min, timeBucket: 50); Assert.Equal(keys.Length, results.Count); for (var i = 0; i < results.Count; i++) { @@ -172,7 +172,7 @@ public async Task TestMissingTimeBucket() { await db.TimeSeriesMRangeAsync("-", "+", filter: new List() { $"key=value" }, - aggregation: Aggregation.AVG); + aggregation: TsAggregation.Avg); }); Assert.Equal("RANGE Aggregation should have timeBucket value", ex.Message); } diff --git a/NRedisTimeSeries.Test/TestAPI/TestMRevRange.cs b/NRedisTimeSeries.Test/TestAPI/TestMRevRange.cs index aff8844..bb5c345 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestMRevRange.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestMRevRange.cs @@ -128,7 +128,7 @@ public void TestMRevRangeAggregation() } var tuples = CreateData(db, keys, 50); - var results = db.TimeSeriesMRevRange("-", "+", new List { $"{keys[0]}=value" }, aggregation: Aggregation.MIN, timeBucket: 50); + var results = db.TimeSeriesMRevRange("-", "+", new List { $"{keys[0]}=value" }, aggregation: TsAggregation.Min, timeBucket: 50); Assert.Equal(keys.Length, results.Count); for (var i = 0; i < results.Count; i++) { @@ -168,7 +168,7 @@ public void TestMissingTimeBucket() } var tuples = CreateData(db, keys, 50); - var ex = Assert.Throws(() => db.TimeSeriesMRevRange("-", "+", new List { "key=MissingTimeBucket" }, aggregation: Aggregation.AVG)); + var ex = Assert.Throws(() => db.TimeSeriesMRevRange("-", "+", new List { "key=MissingTimeBucket" }, aggregation: TsAggregation.Avg)); Assert.Equal("RANGE Aggregation should have timeBucket value", ex.Message); } diff --git a/NRedisTimeSeries.Test/TestAPI/TestMRevRangeAsync.cs b/NRedisTimeSeries.Test/TestAPI/TestMRevRangeAsync.cs index c34dd05..6054b95 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestMRevRangeAsync.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestMRevRangeAsync.cs @@ -128,7 +128,7 @@ public async Task TestMRangeAggregation() } var tuples = await CreateData(db, keys, 50); - var results = await db.TimeSeriesMRevRangeAsync("-", "+", new List { $"{keys[0]}=value" }, aggregation: Aggregation.MIN, timeBucket: 50); + var results = await db.TimeSeriesMRevRangeAsync("-", "+", new List { $"{keys[0]}=value" }, aggregation: TsAggregation.Min, timeBucket: 50); Assert.Equal(keys.Length, results.Count); for (var i = 0; i < results.Count; i++) { @@ -172,7 +172,7 @@ public async Task TestMissingTimeBucket() { await db.TimeSeriesMRevRangeAsync("-", "+", filter: new List() { $"key=value" }, - aggregation: Aggregation.AVG); + aggregation: TsAggregation.Avg); }); Assert.Equal("RANGE Aggregation should have timeBucket value", ex.Message); } diff --git a/NRedisTimeSeries.Test/TestAPI/TestRange.cs b/NRedisTimeSeries.Test/TestAPI/TestRange.cs index fed807a..e9edd79 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestRange.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestRange.cs @@ -50,7 +50,7 @@ public void TestRangeAggregation() { IDatabase db = redisFixture.Redis.GetDatabase(); var tuples = CreateData(db, 50); - Assert.Equal(tuples, db.TimeSeriesRange(key, "-", "+", aggregation: Aggregation.MIN, timeBucket: 50)); + Assert.Equal(tuples, db.TimeSeriesRange(key, "-", "+", aggregation: TsAggregation.Min, timeBucket: 50)); } [Fact] @@ -58,7 +58,7 @@ public void TestMissingTimeBucket() { IDatabase db = redisFixture.Redis.GetDatabase(); var tuples = CreateData(db, 50); - var ex = Assert.Throws(() => db.TimeSeriesRange(key, "-", "+", aggregation: Aggregation.AVG)); + var ex = Assert.Throws(() => db.TimeSeriesRange(key, "-", "+", aggregation: TsAggregation.Avg)); Assert.Equal("RANGE Aggregation should have timeBucket value", ex.Message); } diff --git a/NRedisTimeSeries.Test/TestAPI/TestRangeAsync.cs b/NRedisTimeSeries.Test/TestAPI/TestRangeAsync.cs index ef8a26d..15a5b1f 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestRangeAsync.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestRangeAsync.cs @@ -47,7 +47,7 @@ public async Task TestRangeAggregation() var key = CreateKeyName(); var db = redisFixture.Redis.GetDatabase(); var tuples = await CreateData(db, key, 50); - Assert.Equal(tuples, await db.TimeSeriesRangeAsync(key, "-", "+", aggregation: Aggregation.MIN, timeBucket: 50)); + Assert.Equal(tuples, await db.TimeSeriesRangeAsync(key, "-", "+", aggregation: TsAggregation.Min, timeBucket: 50)); } [Fact] @@ -56,7 +56,7 @@ public async Task TestMissingTimeBucket() var key = CreateKeyName(); var db = redisFixture.Redis.GetDatabase(); var tuples = await CreateData(db, key, 50); - var ex = await Assert.ThrowsAsync(async () => await db.TimeSeriesRangeAsync(key, "-", "+", aggregation: Aggregation.AVG)); + var ex = await Assert.ThrowsAsync(async () => await db.TimeSeriesRangeAsync(key, "-", "+", aggregation: TsAggregation.Avg)); Assert.Equal("RANGE Aggregation should have timeBucket value", ex.Message); } } diff --git a/NRedisTimeSeries.Test/TestAPI/TestRevRange.cs b/NRedisTimeSeries.Test/TestAPI/TestRevRange.cs index 2d40d3a..d778ab1 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestRevRange.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestRevRange.cs @@ -46,7 +46,7 @@ public void TestRevRangeAggregation() var key = CreateKeyName(); var db = redisFixture.Redis.GetDatabase(); var tuples = CreateData(db, key, 50); - Assert.Equal(ReverseData(tuples), db.TimeSeriesRevRange(key, "-", "+", aggregation: Aggregation.MIN, timeBucket: 50)); + Assert.Equal(ReverseData(tuples), db.TimeSeriesRevRange(key, "-", "+", aggregation: TsAggregation.Min, timeBucket: 50)); } [Fact] @@ -55,7 +55,7 @@ public void TestMissingTimeBucket() var key = CreateKeyName(); var db = redisFixture.Redis.GetDatabase(); var tuples = CreateData(db, key, 50); - var ex = Assert.Throws(() => db.TimeSeriesRevRange(key, "-", "+", aggregation: Aggregation.AVG)); + var ex = Assert.Throws(() => db.TimeSeriesRevRange(key, "-", "+", aggregation: TsAggregation.Avg)); Assert.Equal("RANGE Aggregation should have timeBucket value", ex.Message); } diff --git a/NRedisTimeSeries.Test/TestAPI/TestRevRangeAsync.cs b/NRedisTimeSeries.Test/TestAPI/TestRevRangeAsync.cs index 04062a8..0c07dd5 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestRevRangeAsync.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestRevRangeAsync.cs @@ -47,7 +47,7 @@ public async Task TestRevRangeAggregation() var key = CreateKeyName(); var db = redisFixture.Redis.GetDatabase(); var tuples = await CreateData(db, key, 50); - Assert.Equal(ReverseData(tuples), await db.TimeSeriesRevRangeAsync(key, "-", "+", aggregation: Aggregation.MIN, timeBucket: 50)); + Assert.Equal(ReverseData(tuples), await db.TimeSeriesRevRangeAsync(key, "-", "+", aggregation: TsAggregation.Min, timeBucket: 50)); } [Fact] @@ -56,7 +56,7 @@ public async Task TestMissingTimeBucket() var key = CreateKeyName(); var db = redisFixture.Redis.GetDatabase(); var tuples = await CreateData(db, key, 50); - var ex = await Assert.ThrowsAsync(async () => await db.TimeSeriesRevRangeAsync(key, "-", "+", aggregation: Aggregation.AVG)); + var ex = await Assert.ThrowsAsync(async () => await db.TimeSeriesRevRangeAsync(key, "-", "+", aggregation: TsAggregation.Avg)); Assert.Equal("RANGE Aggregation should have timeBucket value", ex.Message); } } diff --git a/NRedisTimeSeries.Test/TestAPI/TestRules.cs b/NRedisTimeSeries.Test/TestAPI/TestRules.cs index 096ada7..6d3b3bf 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestRules.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestRules.cs @@ -11,25 +11,25 @@ public class TestRules : AbstractTimeSeriesTest, IDisposable { private string srcKey = "RULES_TEST_SRC"; - private Dictionary destKeys; + private Dictionary destKeys; public TestRules(RedisFixture redisFixture) : base(redisFixture) { - destKeys = new Dictionary + destKeys = new Dictionary { - { Aggregation.AVG, "RULES_DEST_" + Aggregation.AVG }, - { Aggregation.COUNT, "RULES_DEST_" + Aggregation.COUNT }, - { Aggregation.FIRST, "RULES_DEST_" + Aggregation.FIRST }, - { Aggregation.LAST, "RULES_DEST_" + Aggregation.LAST }, - { Aggregation.MAX, "RULES_DEST_" + Aggregation.MAX }, - { Aggregation.MIN, "RULES_DEST_" + Aggregation.MIN }, - { Aggregation.RANGE, "RULES_DEST_" + Aggregation.RANGE }, - { Aggregation.STDP, "RULES_DEST_" + Aggregation.STDP }, - { Aggregation.STDS, "RULES_DEST_" + Aggregation.STDS }, - { Aggregation.SUM, "RULES_DEST_" + Aggregation.SUM }, - { Aggregation.VARP, "RULES_DEST_" + Aggregation.VARP }, - { Aggregation.VARS, "RULES_DEST_" + Aggregation.VARS } + { TsAggregation.Avg, "RULES_DEST_" + TsAggregation.Avg }, + { TsAggregation.Count, "RULES_DEST_" + TsAggregation.Count }, + { TsAggregation.First, "RULES_DEST_" + TsAggregation.First }, + { TsAggregation.Last, "RULES_DEST_" + TsAggregation.Last }, + { TsAggregation.Max, "RULES_DEST_" + TsAggregation.Max }, + { TsAggregation.Min, "RULES_DEST_" + TsAggregation.Min }, + { TsAggregation.Range, "RULES_DEST_" + TsAggregation.Range }, + { TsAggregation.StdP, "RULES_DEST_" + TsAggregation.StdP }, + { TsAggregation.StdS, "RULES_DEST_" + TsAggregation.StdS }, + { TsAggregation.Sum, "RULES_DEST_" + TsAggregation.Sum }, + { TsAggregation.VarP, "RULES_DEST_" + TsAggregation.VarP }, + { TsAggregation.VarS, "RULES_DEST_" + TsAggregation.VarS } }; } @@ -53,7 +53,7 @@ public void TestRulesAdditionDeletion() } long timeBucket = 50; var rules = new List(); - var rulesMap = new Dictionary(); + var rulesMap = new Dictionary(); foreach(var aggregation in destKeys.Keys) { var rule = new TimeSeriesRule(destKeys[aggregation], timeBucket, aggregation); @@ -77,9 +77,9 @@ public void TestRulesAdditionDeletion() public void TestNonExistingSrc() { IDatabase db = redisFixture.Redis.GetDatabase(); - string destKey = "RULES_DEST_" + Aggregation.AVG; + string destKey = "RULES_DEST_" + TsAggregation.Avg; db.TimeSeriesCreate(destKey); - TimeSeriesRule rule = new TimeSeriesRule(destKey, 50, Aggregation.AVG); + TimeSeriesRule rule = new TimeSeriesRule(destKey, 50, TsAggregation.Avg); var ex = Assert.Throws(() => db.TimeSeriesCreateRule(srcKey, rule)); Assert.Equal("ERR TSDB: the key does not exist", ex.Message); ex = Assert.Throws(() => db.TimeSeriesDeleteRule(srcKey, destKey)); @@ -90,9 +90,9 @@ public void TestNonExistingSrc() public void TestNonExisitingDestinaion() { IDatabase db = redisFixture.Redis.GetDatabase(); - string destKey = "RULES_DEST_" + Aggregation.AVG; + string destKey = "RULES_DEST_" + TsAggregation.Avg; db.TimeSeriesCreate(srcKey); - TimeSeriesRule rule = new TimeSeriesRule(destKey, 50, Aggregation.AVG); + TimeSeriesRule rule = new TimeSeriesRule(destKey, 50, TsAggregation.Avg); var ex = Assert.Throws(() => db.TimeSeriesCreateRule(srcKey, rule)); Assert.Equal("ERR TSDB: the key does not exist", ex.Message); ex = Assert.Throws(() => db.TimeSeriesDeleteRule(srcKey, destKey)); diff --git a/NRedisTimeSeries.Test/TestAPI/TestRulesAsync.cs b/NRedisTimeSeries.Test/TestAPI/TestRulesAsync.cs index ba7fa81..3a6a263 100644 --- a/NRedisTimeSeries.Test/TestAPI/TestRulesAsync.cs +++ b/NRedisTimeSeries.Test/TestAPI/TestRulesAsync.cs @@ -1,6 +1,7 @@ using NRedisTimeSeries.Commands; using NRedisTimeSeries.DataTypes; using StackExchange.Redis; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -18,18 +19,19 @@ public async Task TestRulesAdditionDeletion() var key = CreateKeyName(); var db = redisFixture.Redis.GetDatabase(); await db.TimeSeriesCreateAsync(key); + var aggregations = (TsAggregation[])Enum.GetValues(typeof(TsAggregation)); - foreach (var aggregation in Aggregation.GetEnumerator()) + foreach (var aggregation in aggregations) { - await db.TimeSeriesCreateAsync($"{key}:{aggregation.Name}"); + await db.TimeSeriesCreateAsync($"{key}:{aggregation}"); } var timeBucket = 50L; var rules = new List(); - var rulesMap = new Dictionary(); - foreach (var aggregation in Aggregation.GetEnumerator()) + var rulesMap = new Dictionary(); + foreach (var aggregation in aggregations) { - var rule = new TimeSeriesRule($"{key}:{aggregation.Name}", timeBucket, aggregation); + var rule = new TimeSeriesRule($"{key}:{aggregation}", timeBucket, aggregation); rules.Add(rule); rulesMap[aggregation] = rule; Assert.True(await db.TimeSeriesCreateRuleAsync(key, rule)); @@ -38,7 +40,7 @@ public async Task TestRulesAdditionDeletion() Assert.Equal(rules, info.Rules); } - foreach (var aggregation in Aggregation.GetEnumerator()) + foreach (var aggregation in aggregations) { var rule = rulesMap[aggregation]; rules.Remove(rule); @@ -48,17 +50,17 @@ public async Task TestRulesAdditionDeletion() Assert.Equal(rules, info.Rules); } - await db.KeyDeleteAsync(Aggregation.GetEnumerator().Select(i => (RedisKey)$"{key}:{i.Name}").ToArray()); + await db.KeyDeleteAsync(aggregations.Select(i => (RedisKey)$"{key}:{i}").ToArray()); } [Fact] public async Task TestNonExistingSrc() { var key = CreateKeyName(); - var aggKey = $"{key}:{Aggregation.AVG}"; + var aggKey = $"{key}:{TsAggregation.Avg}"; var db = redisFixture.Redis.GetDatabase(); await db.TimeSeriesCreateAsync(aggKey); - var rule = new TimeSeriesRule(aggKey, 50, Aggregation.AVG); + var rule = new TimeSeriesRule(aggKey, 50, TsAggregation.Avg); var ex = await Assert.ThrowsAsync(async () => await db.TimeSeriesCreateRuleAsync(key, rule)); Assert.Equal("ERR TSDB: the key does not exist", ex.Message); @@ -72,10 +74,10 @@ public async Task TestNonExistingSrc() public async Task TestNonExisitingDestinaion() { var key = CreateKeyName(); - var aggKey = $"{key}:{Aggregation.AVG}"; + var aggKey = $"{key}:{TsAggregation.Avg}"; var db = redisFixture.Redis.GetDatabase(); await db.TimeSeriesCreateAsync(key); - var rule = new TimeSeriesRule(aggKey, 50, Aggregation.AVG); + var rule = new TimeSeriesRule(aggKey, 50, TsAggregation.Avg); var ex = await Assert.ThrowsAsync(async () => await db.TimeSeriesCreateRuleAsync(key, rule)); Assert.Equal("ERR TSDB: the key does not exist", ex.Message); diff --git a/NRedisTimeSeries.Test/TestDataTypes/TestTimeSeriesRule.cs b/NRedisTimeSeries.Test/TestDataTypes/TestTimeSeriesRule.cs index 981e417..a7d70d8 100644 --- a/NRedisTimeSeries.Test/TestDataTypes/TestTimeSeriesRule.cs +++ b/NRedisTimeSeries.Test/TestDataTypes/TestTimeSeriesRule.cs @@ -12,21 +12,21 @@ public TestTimeSeriesRule() { } [Fact] public void TestRuleConstructor() { - TimeSeriesRule rule = new TimeSeriesRule("key", 50, Aggregation.AVG); + TimeSeriesRule rule = new TimeSeriesRule("key", 50, TsAggregation.Avg); Assert.Equal("key", rule.DestKey); - Assert.Equal(Aggregation.AVG, rule.Aggregation); + Assert.Equal(TsAggregation.Avg, rule.Aggregation); Assert.Equal(50, rule.TimeBucket); } [Fact] public void TestRuleEquals() { - TimeSeriesRule rule = new TimeSeriesRule("key", 50, Aggregation.AVG); + TimeSeriesRule rule = new TimeSeriesRule("key", 50, TsAggregation.Avg); - TimeSeriesRule rule1 = new TimeSeriesRule("key", 50, Aggregation.AVG); - TimeSeriesRule rule2 = new TimeSeriesRule("key2", 50, Aggregation.AVG); - TimeSeriesRule rule3 = new TimeSeriesRule("key", 51, Aggregation.AVG); - TimeSeriesRule rule4 = new TimeSeriesRule("key", 50, Aggregation.COUNT); + TimeSeriesRule rule1 = new TimeSeriesRule("key", 50, TsAggregation.Avg); + TimeSeriesRule rule2 = new TimeSeriesRule("key2", 50, TsAggregation.Avg); + TimeSeriesRule rule3 = new TimeSeriesRule("key", 51, TsAggregation.Avg); + TimeSeriesRule rule4 = new TimeSeriesRule("key", 50, TsAggregation.Count); Assert.Equal(rule, rule1); Assert.NotEqual(rule, rule2); @@ -37,12 +37,12 @@ public void TestRuleEquals() [Fact] public void TestRuleHashCode() { - TimeSeriesRule rule = new TimeSeriesRule("key", 50, Aggregation.AVG); + TimeSeriesRule rule = new TimeSeriesRule("key", 50, TsAggregation.Avg); - TimeSeriesRule rule1 = new TimeSeriesRule("key", 50, Aggregation.AVG); - TimeSeriesRule rule2 = new TimeSeriesRule("key2", 50, Aggregation.AVG); - TimeSeriesRule rule3 = new TimeSeriesRule("key", 51, Aggregation.AVG); - TimeSeriesRule rule4 = new TimeSeriesRule("key", 50, Aggregation.COUNT); + TimeSeriesRule rule1 = new TimeSeriesRule("key", 50, TsAggregation.Avg); + TimeSeriesRule rule2 = new TimeSeriesRule("key2", 50, TsAggregation.Avg); + TimeSeriesRule rule3 = new TimeSeriesRule("key", 51, TsAggregation.Avg); + TimeSeriesRule rule4 = new TimeSeriesRule("key", 50, TsAggregation.Count); Assert.Equal(rule.GetHashCode(), rule1.GetHashCode()); Assert.NotEqual(rule.GetHashCode(), rule2.GetHashCode()); diff --git a/NRedisTimeSeries/Commands/Aggregation.cs b/NRedisTimeSeries/Commands/Aggregation.cs index bb70347..7481c21 100644 --- a/NRedisTimeSeries/Commands/Aggregation.cs +++ b/NRedisTimeSeries/Commands/Aggregation.cs @@ -1,131 +1,73 @@ -using System; -using System.Collections.Generic; - -namespace NRedisTimeSeries.Commands +namespace NRedisTimeSeries.Commands { /// - /// A wrapper class around aggregation name. Each static member of the class is a wrapper around RedisTimerSeries aggregation. - /// This class can be cast to and from string. + /// An aggregation type to be used with a time bucket. /// - public class Aggregation + public enum TsAggregation { - private Aggregation(string name) => this.Name = name; - - /// - /// String property with the aggregation name. - /// - public string Name { get; private set; } - - /// - /// AVG Aggregation - /// - public static Aggregation AVG { get { return new Aggregation("avg"); } } - - /// - /// SUM Aggregation - /// - public static Aggregation SUM { get { return new Aggregation("sum"); } } - - /// - /// MIN Aggregation - /// - public static Aggregation MIN { get { return new Aggregation("min"); } } - - /// - /// MAX Aggregation - /// - public static Aggregation MAX { get { return new Aggregation("max"); } } - - /// - /// RANGE Aggregation - /// - public static Aggregation RANGE { get { return new Aggregation("range"); } } - /// - /// COUNT Aggregation + /// The average of all samples in the aggregation /// - public static Aggregation COUNT { get { return new Aggregation("count"); } } + Avg, /// - /// FIRST Aggregarion + /// A sum of all samples in the aggregation /// - public static Aggregation FIRST { get { return new Aggregation("first"); } } + Sum, /// - /// LAST Aggregation + /// A minimum sample of all samples in the aggregation /// - public static Aggregation LAST { get { return new Aggregation("last"); } } + Min, /// - /// STD.P Aggregation + /// A maximum sample of all samples in the aggregation /// - public static Aggregation STDP { get { return new Aggregation("std.p"); } } + Max, /// - /// STD.S Aggregation + /// A range of the min and max sample of all samples in the aggregation (range r = max-min) + /// For example if the min sample was 100 and the max was 400, the range aggregation would return 300 /// - public static Aggregation STDS { get { return new Aggregation("std.s"); } } + Range, /// - /// VAR.P Aggregation + /// The total number of all samples in the aggregation /// - public static Aggregation VARP { get { return new Aggregation("var.p"); } } + Count, /// - /// VAR.S Aggregation + /// The first sample in the aggregation /// - public static Aggregation VARS { get { return new Aggregation("var.s"); } } + First, /// - /// Implicit cast to string. + /// The last sample in the aggregation /// - /// Aggregation object - public static implicit operator string(Aggregation aggregation) => aggregation.Name; + Last, /// - /// Implicit cast from string. + /// The standard deviation based on the entire population + /// The standard deviation is a measure of how widely values are dispersed from the average sample in the aggregation /// - /// string - public static implicit operator Aggregation(string s) => new Aggregation(s); + StdP, /// - /// Enumerator of all possible Aggregation types + /// The standard deviation based on a sample of the population + /// The standard deviation is a measure of how widely values are dispersed from the average sample in the aggregation /// - /// An Enumerator of all Aggregation types. i.e. AVG, SUM, MIN etc... - public static IEnumerable GetEnumerator() - { - yield return AVG; - yield return SUM; - yield return MIN; - yield return MAX; - yield return RANGE; - yield return COUNT; - yield return FIRST; - yield return LAST; - yield return STDP; - yield return STDS; - yield return VARP; - yield return VARS; - } + StdS, /// - /// Equality of Aggregation objects. Case Insensitive for the Name property string. + /// The variance based on the entire population + /// The variance is the average of the squared differences from the mean /// - /// Object to compare - /// If two Aggregation objects are equal. - public override bool Equals(object obj) - { - return obj is Aggregation aggregation && - Name.Equals(aggregation.Name, StringComparison.OrdinalIgnoreCase); - } + VarP, /// - /// Aggregation object hash code. + /// The variance based on a sample of the population + /// The variance is the average of the squared differences from the mean /// - /// Aggregation object hash code. - public override int GetHashCode() - { - return 539060726 + EqualityComparer.Default.GetHashCode(Name); - } + VarS, } } diff --git a/NRedisTimeSeries/DataTypes/TimeSeriesRule.cs b/NRedisTimeSeries/DataTypes/TimeSeriesRule.cs index 55e8863..cd3546f 100644 --- a/NRedisTimeSeries/DataTypes/TimeSeriesRule.cs +++ b/NRedisTimeSeries/DataTypes/TimeSeriesRule.cs @@ -21,7 +21,7 @@ public class TimeSeriesRule /// /// Rule's aggregation type. /// - public Aggregation Aggregation { get; private set; } + public TsAggregation Aggregation { get; private set; } /// /// Builds a time-series aggregation rule @@ -29,7 +29,7 @@ public class TimeSeriesRule /// Rule's destination key. /// Rule's aggregation time bucket. /// Rule's aggregation type. - public TimeSeriesRule(string destKey, long timeBucket, Aggregation aggregation) => + public TimeSeriesRule(string destKey, long timeBucket, TsAggregation aggregation) => (DestKey, TimeBucket, Aggregation) = (destKey, timeBucket, aggregation); /// @@ -41,7 +41,7 @@ public override bool Equals(object obj) => obj is TimeSeriesRule rule && DestKey == rule.DestKey && TimeBucket == rule.TimeBucket && - EqualityComparer.Default.Equals(Aggregation, rule.Aggregation); + Aggregation == rule.Aggregation; /// /// TimeSeriesRule object hash code. @@ -52,7 +52,7 @@ public override int GetHashCode() var hashCode = 1554951643; hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(DestKey); hashCode = (hashCode * -1521134295) + TimeBucket.GetHashCode(); - hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(Aggregation); + hashCode = (hashCode * -1521134295) + ((int)Aggregation).GetHashCode(); return hashCode; } } diff --git a/NRedisTimeSeries/Extensions/AggregationExtensions.cs b/NRedisTimeSeries/Extensions/AggregationExtensions.cs new file mode 100644 index 0000000..7e5b72e --- /dev/null +++ b/NRedisTimeSeries/Extensions/AggregationExtensions.cs @@ -0,0 +1,42 @@ +using NRedisTimeSeries.Commands; +using System; + +namespace NRedisTimeSeries.Extensions +{ + internal static class AggregationExtensions + { + public static string AsArg(this TsAggregation aggregation) => aggregation switch + { + TsAggregation.Avg => "AVG", + TsAggregation.Sum => "SUM", + TsAggregation.Min => "MIN", + TsAggregation.Max => "MAX", + TsAggregation.Range => "RANGE", + TsAggregation.Count => "COUNT", + TsAggregation.First => "FIRST", + TsAggregation.Last => "LAST", + TsAggregation.StdP => "STD.P", + TsAggregation.StdS => "STD.S", + TsAggregation.VarP => "VAR.P", + TsAggregation.VarS => "VAR.S", + _ => throw new ArgumentOutOfRangeException(nameof(aggregation), "Invalid aggregation type"), + }; + + public static TsAggregation AsAggregation(string aggregation) => aggregation switch + { + "AVG" => TsAggregation.Avg, + "SUM" => TsAggregation.Sum, + "MIN" => TsAggregation.Min, + "MAX" => TsAggregation.Max, + "RANGE" => TsAggregation.Range, + "COUNT" => TsAggregation.Count, + "FIRST" => TsAggregation.First, + "LAST" => TsAggregation.Last, + "STD.P" => TsAggregation.StdP, + "STD.S" => TsAggregation.StdS, + "VAR.P" => TsAggregation.VarP, + "VAR.S" => TsAggregation.VarS, + _ => throw new ArgumentOutOfRangeException(nameof(aggregation), $"Invalid aggregation type '{aggregation}'"), + }; + } +} diff --git a/NRedisTimeSeries/NRedisTimeSeries.csproj b/NRedisTimeSeries/NRedisTimeSeries.csproj index b4f154e..3142c4b 100644 --- a/NRedisTimeSeries/NRedisTimeSeries.csproj +++ b/NRedisTimeSeries/NRedisTimeSeries.csproj @@ -1,7 +1,8 @@ - + netstandard2.0 + 8.0 1.3.0 Dvir Dukhan Redis Labs diff --git a/NRedisTimeSeries/TimeSeriesClient.cs b/NRedisTimeSeries/TimeSeriesClient.cs index 2e0c6bc..b72358a 100644 --- a/NRedisTimeSeries/TimeSeriesClient.cs +++ b/NRedisTimeSeries/TimeSeriesClient.cs @@ -189,7 +189,7 @@ public static TimeSeriesTuple TimeSeriesGet(this IDatabase db, string key) /// Optional: Aggregation type /// Optional: Time bucket for aggregation in milliseconds /// A list of TimeSeriesTuple - public static IReadOnlyList TimeSeriesRange(this IDatabase db, string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count = null, Aggregation aggregation = null, long? timeBucket = null) + public static IReadOnlyList TimeSeriesRange(this IDatabase db, string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count = null, TsAggregation? aggregation = null, long? timeBucket = null) { var args = BuildRangeArgs(key, fromTimeStamp, toTimeStamp, count, aggregation, timeBucket); return ParseTimeSeriesTupleArray(db.Execute(TS.RANGE, args)); @@ -206,7 +206,7 @@ public static IReadOnlyList TimeSeriesRange(this IDatabase db, /// Optional: Aggregation type /// Optional: Time bucket for aggregation in milliseconds /// A list of TimeSeriesTuple - public static IReadOnlyList TimeSeriesRevRange(this IDatabase db, string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count = null, Aggregation aggregation = null, long? timeBucket = null) + public static IReadOnlyList TimeSeriesRevRange(this IDatabase db, string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count = null, TsAggregation? aggregation = null, long? timeBucket = null) { var args = BuildRangeArgs(key, fromTimeStamp, toTimeStamp, count, aggregation, timeBucket); return ParseTimeSeriesTupleArray(db.Execute(TS.REVRANGE, args)); @@ -224,7 +224,7 @@ public static IReadOnlyList TimeSeriesRevRange(this IDatabase d /// Optional: Time bucket for aggregation in milliseconds /// Optional: Include in the reply the label-value pairs that represent metadata labels of the time-series /// A list of <(key, labels, values)> tuples. Each tuple contains the key name, its labels and the values which satisfies the given range and filters. - public static IReadOnlyList<(string key, IReadOnlyList labels, IReadOnlyList values)> TimeSeriesMRange(this IDatabase db, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, long? count = null, Aggregation aggregation = null, long? timeBucket = null, bool? withLabels = null) + public static IReadOnlyList<(string key, IReadOnlyList labels, IReadOnlyList values)> TimeSeriesMRange(this IDatabase db, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, long? count = null, TsAggregation? aggregation = null, long? timeBucket = null, bool? withLabels = null) { var args = BuildMultiRangeArgs(fromTimeStamp, toTimeStamp, filter, count, aggregation, timeBucket, withLabels); return ParseMRangeResponse(db.Execute(TS.MRANGE, args)); @@ -242,7 +242,7 @@ public static IReadOnlyList TimeSeriesRevRange(this IDatabase d /// Optional: Time bucket for aggregation in milliseconds /// Optional: Include in the reply the label-value pairs that represent metadata labels of the time-series /// A list of <(key, labels, values)> tuples. Each tuple contains the key name, its labels and the values which satisfies the given range and filters. - public static IReadOnlyList<(string key, IReadOnlyList labels, IReadOnlyList values)> TimeSeriesMRevRange(this IDatabase db, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, long? count = null, Aggregation aggregation = null, long? timeBucket = null, bool? withLabels = null) + public static IReadOnlyList<(string key, IReadOnlyList labels, IReadOnlyList values)> TimeSeriesMRevRange(this IDatabase db, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, long? count = null, TsAggregation? aggregation = null, long? timeBucket = null, bool? withLabels = null) { var args = BuildMultiRangeArgs(fromTimeStamp, toTimeStamp, filter, count, aggregation, timeBucket, withLabels); return ParseMRangeResponse(db.Execute(TS.MREVRANGE, args)); diff --git a/NRedisTimeSeries/TimeSeriesClientAsync.cs b/NRedisTimeSeries/TimeSeriesClientAsync.cs index 76bf0aa..fc4a419 100644 --- a/NRedisTimeSeries/TimeSeriesClientAsync.cs +++ b/NRedisTimeSeries/TimeSeriesClientAsync.cs @@ -188,7 +188,7 @@ public static async Task TimeSeriesGetAsync(this IDatabase db, /// Optional: Aggregation type /// Optional: Time bucket for aggregation in milliseconds /// A list of TimeSeriesTuple - public static async Task> TimeSeriesRangeAsync(this IDatabase db, string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count = null, Aggregation aggregation = null, long? timeBucket = null) + public static async Task> TimeSeriesRangeAsync(this IDatabase db, string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count = null, TsAggregation? aggregation = null, long? timeBucket = null) { var args = BuildRangeArgs(key, fromTimeStamp, toTimeStamp, count, aggregation, timeBucket); return ParseTimeSeriesTupleArray(await db.ExecuteAsync(TS.RANGE, args)); @@ -205,7 +205,7 @@ public static async Task> TimeSeriesRangeAsync(th /// Optional: Aggregation type /// Optional: Time bucket for aggregation in milliseconds /// A list of TimeSeriesTuple - public static async Task> TimeSeriesRevRangeAsync(this IDatabase db, string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count = null, Aggregation aggregation = null, long? timeBucket = null) + public static async Task> TimeSeriesRevRangeAsync(this IDatabase db, string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count = null, TsAggregation? aggregation = null, long? timeBucket = null) { var args = BuildRangeArgs(key, fromTimeStamp, toTimeStamp, count, aggregation, timeBucket); return ParseTimeSeriesTupleArray(await db.ExecuteAsync(TS.REVRANGE, args)); @@ -223,7 +223,7 @@ public static async Task> TimeSeriesRevRangeAsync /// Optional: Time bucket for aggregation in milliseconds /// Optional: Include in the reply the label-value pairs that represent metadata labels of the time-series /// A list of <(key, labels, values)> tuples. Each tuple contains the key name, its labels and the values which satisfies the given range and filters. - public static async Task labels, IReadOnlyList values)>> TimeSeriesMRangeAsync(this IDatabase db, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, long? count = null, Aggregation aggregation = null, long? timeBucket = null, bool? withLabels = null) + public static async Task labels, IReadOnlyList values)>> TimeSeriesMRangeAsync(this IDatabase db, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, long? count = null, TsAggregation? aggregation = null, long? timeBucket = null, bool? withLabels = null) { var args = BuildMultiRangeArgs(fromTimeStamp, toTimeStamp, filter, count, aggregation, timeBucket, withLabels); return ParseMRangeResponse(await db.ExecuteAsync(TS.MRANGE, args)); @@ -241,7 +241,7 @@ public static async Task> TimeSeriesRevRangeAsync /// Optional: Time bucket for aggregation in milliseconds /// Optional: Include in the reply the label-value pairs that represent metadata labels of the time-series /// A list of <(key, labels, values)> tuples. Each tuple contains the key name, its labels and the values which satisfies the given range and filters. - public static async Task labels, IReadOnlyList values)>> TimeSeriesMRevRangeAsync(this IDatabase db, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, long? count = null, Aggregation aggregation = null, long? timeBucket = null, bool? withLabels = null) + public static async Task labels, IReadOnlyList values)>> TimeSeriesMRevRangeAsync(this IDatabase db, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, long? count = null, TsAggregation? aggregation = null, long? timeBucket = null, bool? withLabels = null) { var args = BuildMultiRangeArgs(fromTimeStamp, toTimeStamp, filter, count, aggregation, timeBucket, withLabels); return ParseMRangeResponse(await db.ExecuteAsync(TS.MREVRANGE, args)); diff --git a/NRedisTimeSeries/TimeSeriesClientAux.cs b/NRedisTimeSeries/TimeSeriesClientAux.cs index f7b1ebd..39bcf46 100644 --- a/NRedisTimeSeries/TimeSeriesClientAux.cs +++ b/NRedisTimeSeries/TimeSeriesClientAux.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using NRedisTimeSeries.Commands; using NRedisTimeSeries.DataTypes; +using NRedisTimeSeries.Extensions; namespace NRedisTimeSeries { @@ -55,12 +56,12 @@ private static void AddCount(this IList args, long? count) } } - private static void AddAggregation(this IList args, Aggregation aggregation, long? timeBucket) + private static void AddAggregation(this IList args, TsAggregation? aggregation, long? timeBucket) { if(aggregation != null) { args.Add(CommandArgs.AGGREGATION); - args.Add(aggregation.Name); + args.Add(aggregation.Value.AsArg()); if (!timeBucket.HasValue) { throw new ArgumentException("RANGE Aggregation should have timeBucket value"); @@ -103,7 +104,7 @@ private static void AddRule(this IList args, TimeSeriesRule rule) { args.Add(rule.DestKey); args.Add(CommandArgs.AGGREGATION); - args.Add(rule.Aggregation.Name); + args.Add(rule.Aggregation.AsArg()); args.Add(rule.TimeBucket); } @@ -171,7 +172,7 @@ private static List BuildTsMgetArgs(IReadOnlyCollection filter, } private static List BuildRangeArgs(string key, TimeStamp fromTimeStamp, TimeStamp toTimeStamp, long? count, - Aggregation aggregation, long? timeBucket) + TsAggregation? aggregation, long? timeBucket) { var args = new List() {key, fromTimeStamp.Value, toTimeStamp.Value}; @@ -181,7 +182,7 @@ private static List BuildRangeArgs(string key, TimeStamp fromTimeStamp, } private static List BuildMultiRangeArgs(TimeStamp fromTimeStamp, TimeStamp toTimeStamp, IReadOnlyCollection filter, - long? count, Aggregation aggregation, long? timeBucket, bool? withLabels) + long? count, TsAggregation? aggregation, long? timeBucket, bool? withLabels) { var args = new List() {fromTimeStamp.Value, toTimeStamp.Value}; args.AddCount(count); diff --git a/NRedisTimeSeries/TimeSeriesClientResponseParser.cs b/NRedisTimeSeries/TimeSeriesClientResponseParser.cs index 356b64a..40b7303 100644 --- a/NRedisTimeSeries/TimeSeriesClientResponseParser.cs +++ b/NRedisTimeSeries/TimeSeriesClientResponseParser.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using NRedisTimeSeries.Commands; using NRedisTimeSeries.DataTypes; +using NRedisTimeSeries.Extensions; using StackExchange.Redis; namespace NRedisTimeSeries @@ -94,7 +95,7 @@ private static TimeSeriesRule ParseRule(RedisResult result) RedisResult[] redisResults = (RedisResult[])result; string destKey = (string)redisResults[0]; long bucketTime = (long)redisResults[1]; - Aggregation aggregation = (string)redisResults[2]; + var aggregation = AggregationExtensions.AsAggregation((string)redisResults[2]); return new TimeSeriesRule(destKey, bucketTime, aggregation); } @@ -125,7 +126,7 @@ private static TimeSeriesInformation ParseInfo(RedisResult result) } IReadOnlyList labels = ParseLabelArray(redisResults[15]); string destKey = (string)redisResults[17]; - IReadOnlyList rules = ParseRuleArray(redisResults[19]); + IReadOnlyList rules = ParseRuleArray(redisResults[19]); return new TimeSeriesInformation(totalSamples, memoryUsage, firstTimeStamp, lastTimeStamp, retentionTime, chunkCount, chunkSize, labels, destKey, rules); }