diff --git a/src/NRedisStack.Core/Bloom/BloomCommands.cs b/src/NRedisStack.Core/Bloom/BloomCommands.cs
index 513cc0c6..94168ca5 100644
--- a/src/NRedisStack.Core/Bloom/BloomCommands.cs
+++ b/src/NRedisStack.Core/Bloom/BloomCommands.cs
@@ -1,3 +1,4 @@
+using NRedisStack.Core.Bloom.DataTypes;
using NRedisStack.Core.Literals;
using StackExchange.Redis;
namespace NRedisStack.Core
@@ -11,24 +12,62 @@ public BloomCommands(IDatabase db)
_db = db;
}
- public RedisResult Add(RedisKey key, string item)
+ ///
+ /// Adds an item to a Bloom Filter.
+ ///
+ /// The key under which the filter is found.
+ /// The item to add.
+ /// if the item did not exist in the filter, otherwise.
+ ///
+ public bool Add(RedisKey key, RedisValue item)
{
- return _db.Execute(BF.ADD, key, item);
+ return _db.Execute(BF.ADD, key, item).ToString() == "1";
}
- public bool Exists(RedisKey key, string item)
+ ///
+ /// Checks whether an item exist in the Bloom Filter or not.
+ ///
+ /// The name of the filter.
+ /// The item to check for.
+ /// means the item may exist in the filter,
+ /// and means the item may exist in the filter.
+ ///
+ public bool Exists(RedisKey key, RedisValue item)
{
return _db.Execute(BF.EXISTS, key, item).ToString() == "1";
}
- public RedisResult Info(RedisKey key)
+ ///
+ /// Return information about a bloom filter.
+ ///
+ /// Name of the key to return information about.
+ /// Array with information of the filter.
+ ///
+ public BloomInformation? Info(RedisKey key)
{
- return _db.Execute(BF.INFO, key);
+ var info = _db.Execute(BF.INFO, key);
+ return ResponseParser.ToBloomInfo(info);
}
- public RedisResult Insert(RedisKey key, RedisValue[] items, int? capacity = null,
+ ///
+ /// Adds one or more items to a Bloom Filter. A filter will be created if it does not exist.
+ ///
+ /// The name of the filter.
+ /// One or more items to add.
+ /// (Optional) Specifies the desired capacity for the filter to be created.
+ /// (Optional) Specifies the error ratio of the newly created filter if it does not yet exist.
+ /// (Optional) When capacity is reached, an additional sub-filter is
+ /// created in size of the last sub-filter multiplied by expansion.
+ /// (Optional) to indicates that the
+ /// filter should not be created if it does not already exist.
+ /// (Optional) toprevent the filter
+ /// from creating additional sub-filters if initial capacity is reached.
+ /// An array of booleans. Each element is either true or false depending on whether the
+ /// corresponding input element was newly added to the filter or may have previously existed.
+ ///
+ public bool[] Insert(RedisKey key, RedisValue[] items, int? capacity = null,
double? error = null, int? expansion = null,
- bool nocreate = false, bool nonscaling = false) //NOT DONE
+ bool nocreate = false, bool nonscaling = false)
{
if (items == null)
throw new ArgumentNullException(nameof(items));
@@ -54,10 +93,15 @@ public RedisResult Insert(RedisKey key, RedisValue[] items, int? capacity = null
}
if (nocreate)
+ {
args.Add(BloomArgs.NOCREATE);
+ }
+
if (nonscaling)
+ {
args.Add(BloomArgs.NONSCALING);
+ }
args.Add(BloomArgs.ITEMS);
foreach (var item in items)
@@ -65,18 +109,109 @@ public RedisResult Insert(RedisKey key, RedisValue[] items, int? capacity = null
args.Add(item);
}
- return _db.Execute(BF.INSERT, args);
+ return ResponseParser.ToBooleanArray(_db.Execute(BF.INSERT, args));
}
- public RedisResult ScanDump(RedisKey key, int iterator)
+ ///
+ /// Restores a filter previosly saved using SCANDUMP.
+ ///
+ /// Name of the key to restore.
+ /// Iterator value associated with data (returned by SCANDUMP).
+ /// Current data chunk (returned by SCANDUMP).
+ /// Array with information of the filter.
+ ///
+ public bool LoadChunk(RedisKey key, long iterator, Byte[] data)
{
- return _db.Execute(BF.SCANDUMP, key, iterator);
+ return ResponseParser.ParseOKtoBoolean(_db.Execute(BF.LOADCHUNK, key, iterator, data));
}
- public RedisResult LoadChunk(RedisKey key, int iterator, RedisValue data)
+ ///
+ /// Adds one or more items to the Bloom Filter. A filter will be created if it does not exist yet.
+ ///
+ /// The name of the filter.
+ /// One or more items to add.
+ /// An array of booleans. Each element is either true or false depending on whether the
+ /// corresponding input element was newly added to the filter or may have previously existed.
+ ///
+ public bool[] MAdd(RedisKey key, RedisValue[] items)
{
- return _db.Execute(BF.LOADCHUNK, key, iterator, data);
+ if (items == null)
+ throw new ArgumentNullException(nameof(items));
+
+ List args = new List { key };
+
+ foreach (var item in items)
+ {
+ args.Add(item);
+ }
+
+ return ResponseParser.ToBooleanArray(_db.Execute(BF.MADD, args));
}
+ ///
+ /// Checks whether one or more items may exist in the filter or not.
+ ///
+ /// The name of the filter.
+ /// One or more items to check.
+ /// An array of booleans, for each item means the item may exist in the filter,
+ /// and means the item may exist in the filter.
+ ///
+ public bool[] MExists(RedisKey key, RedisValue[] items)
+ {
+ if (items == null)
+ throw new ArgumentNullException(nameof(items));
+
+ List args = new List { key };
+
+ foreach (var item in items)
+ {
+ args.Add(item);
+ }
+
+ return ResponseParser.ToBooleanArray(_db.Execute(BF.MEXISTS, args));
+
+ }
+
+ ///
+ /// Creates a new Bloom Filter.
+ ///
+ /// The key under which the filter is found.
+ /// The desired probability for false positives (value between 0 to 1).
+ /// The number of entries intended to be added to the filter.
+ /// (Optional) When capacity is reached, an additional sub-filter is
+ /// created in size of the last sub-filter multiplied by expansion.
+ /// (Optional) toprevent the filter
+ /// from creating additional sub-filters if initial capacity is reached.
+ /// if executed correctly, otherwise.
+ ///
+ public bool Reserve(RedisKey key, double errorRate, long capacity,
+ int? expansion = null, bool nonscaling = false)
+ {
+ List args = new List { key, errorRate, capacity };
+
+ if (expansion != null)
+ {
+ args.Add(expansion);
+ }
+
+ if (nonscaling)
+ {
+ args.Add(BloomArgs.NONSCALING);
+ }
+
+ return ResponseParser.ParseOKtoBoolean(_db.Execute(BF.RESERVE, args));
+ }
+
+ ///
+ /// Restores a filter previosly saved using SCANDUMP.
+ ///
+ /// Name of the filter.
+ /// Iterator value; either 0 or the iterator from a previous invocation of this command.
+ /// Tuple of iterator and data.
+ ///
+ public Tuple? ScanDump(RedisKey key, long iterator)
+ {
+ return ResponseParser.ToScanDumpTuple(_db.Execute(BF.SCANDUMP, key, iterator));
+ }
}
}
diff --git a/src/NRedisStack.Core/Bloom/DataTypes/BloomInformation.cs b/src/NRedisStack.Core/Bloom/DataTypes/BloomInformation.cs
new file mode 100644
index 00000000..a54a0643
--- /dev/null
+++ b/src/NRedisStack.Core/Bloom/DataTypes/BloomInformation.cs
@@ -0,0 +1,24 @@
+namespace NRedisStack.Core.Bloom.DataTypes
+{
+ ///
+ /// This class represents the response for BF.INFO command.
+ /// This object has Read-only properties and cannot be generated outside a BF.INFO response.
+ ///
+ public class BloomInformation
+ {
+ public long Capacity { get; private set; }
+ public long Size { get; private set; }
+ public long NumberOfFilters { get; private set; }
+ public long NumberOfItemsInserted { get; private set; }
+ public long ExpansionRate { get; private set; }
+
+ internal BloomInformation(long capacity, long size, long numberOfFilters, long numberOfItemsInserted, long expansionRate)
+ {
+ Capacity = capacity;
+ Size = size;
+ NumberOfFilters = numberOfFilters;
+ NumberOfItemsInserted = numberOfItemsInserted;
+ ExpansionRate = expansionRate;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/NRedisStack.Core/Json/JsonCommands.cs b/src/NRedisStack.Core/Json/JsonCommands.cs
index df054510..63ac9ab8 100644
--- a/src/NRedisStack.Core/Json/JsonCommands.cs
+++ b/src/NRedisStack.Core/Json/JsonCommands.cs
@@ -35,11 +35,15 @@ public RedisResult Set(RedisKey key, RedisValue path, RedisValue json, When when
}
}
- public RedisResult Get(RedisKey key, RedisValue? indent = null,
- RedisValue? newLine = null, RedisValue? space = null, RedisValue? path = null)
+ public RedisResult Get(RedisKey key,
+ RedisValue? indent = null,
+ RedisValue? newLine = null,
+ RedisValue? space = null,
+ RedisValue? path = null)
{
- List args = new List();
- args.Add(key);
+
+ List args = new List(){key};
+
if (indent != null)
{
args.Add(JsonArgs.INDENT);
diff --git a/src/NRedisStack.Core/TimeSeries/TimeSeriesClientResponseParser.cs b/src/NRedisStack.Core/ResponseParser.cs
similarity index 53%
rename from src/NRedisStack.Core/TimeSeries/TimeSeriesClientResponseParser.cs
rename to src/NRedisStack.Core/ResponseParser.cs
index b885d42b..346b6c05 100644
--- a/src/NRedisStack.Core/TimeSeries/TimeSeriesClientResponseParser.cs
+++ b/src/NRedisStack.Core/ResponseParser.cs
@@ -4,54 +4,101 @@
using NRedisStack.Core.DataTypes;
using NRedisStack.Core.Extensions;
using StackExchange.Redis;
+using NRedisStack.Core.Bloom.DataTypes;
namespace NRedisStack.Core
{
public static class ResponseParser
{
- public static bool ParseBoolean(RedisResult result)
+
+ //TODO: See if I can change the code to remove the warnings
+ public static bool ParseOKtoBoolean(RedisResult result)
+ {
+ return result.ToString() == "OK";
+ }
+
+ public static bool[] ToBooleanArray(RedisResult result)
+ {
+ RedisResult[] redisResults = (RedisResult[])result;
+ bool[] boolArr = new bool[redisResults.Length];
+ for (int i = 0; i < redisResults.Length; i++)
+ {
+ boolArr[i] = redisResults[i].ToString() == "1";
+ }
+
+ return boolArr;
+ }
+
+ public static RedisResult[] ToArray(RedisResult result)
{
- return (string)result == "OK";
+ return (RedisResult[])result;
}
- public static long ParseLong(RedisResult result)
+ public static long ToLong(RedisResult result)
{
if (result.Type == ResultType.None) return 0;
return (long)result;
}
- public static TimeStamp ParseTimeStamp(RedisResult result)
+ public static TimeStamp ToTimeStamp(RedisResult result)
{
if (result.Type == ResultType.None) return null;
return new TimeStamp((long)result);
}
- public static IReadOnlyList ParseTimeStampArray(RedisResult result)
+ public static IReadOnlyList ToTimeStampArray(RedisResult result)
{
RedisResult[] redisResults = (RedisResult[])result;
var list = new List(redisResults.Length);
if (redisResults.Length == 0) return list;
- Array.ForEach(redisResults, timestamp => list.Add(ParseTimeStamp(timestamp)));
+ Array.ForEach(redisResults, timestamp => list.Add(ToTimeStamp(timestamp)));
return list;
}
- public static TimeSeriesTuple ParseTimeSeriesTuple(RedisResult result)
+ public static TimeSeriesTuple? ToTimeSeriesTuple(RedisResult result)
{
- RedisResult[] redisResults = (RedisResult[])result;
+ RedisResult[]? redisResults = (RedisResult[]?)result;
+ if (redisResults.Length == 0) return null;
+ return new TimeSeriesTuple(ToTimeStamp(redisResults[0]), (double)redisResults[1]);
+ }
+
+ public static Tuple? ToScanDumpTuple(RedisResult result)
+ {
+ RedisResult[]? redisResults = (RedisResult[]?)result;
+ if (redisResults == null || redisResults.Length == 0) return null;
+ return new Tuple((long)redisResults[0], (Byte[])redisResults[1]);
+ }
+
+ public static HashEntry? ToHashEntry(RedisResult result)
+ {
+ RedisValue[]? redisResults = (RedisValue[]?)result;
if (redisResults.Length == 0) return null;
- return new TimeSeriesTuple(ParseTimeStamp(redisResults[0]), (double)redisResults[1]);
+ return new HashEntry(redisResults[0], redisResults[1]);
+
}
- public static IReadOnlyList ParseTimeSeriesTupleArray(RedisResult result)
+ public static HashEntry[]? ToHashEntryArray(RedisResult result)
+ {
+ RedisValue[]? redisResults = (RedisValue[]?)result;
+
+ var hash = new HashEntry[redisResults.Length / 2];
+ if (redisResults.Length == 0) return hash;
+
+ for (int i = 0; i < redisResults.Length - 1; i += 2)
+ hash[i / 2] = new HashEntry(redisResults[i], redisResults[i + 1]);
+ return hash;
+ }
+
+ public static IReadOnlyList ToTimeSeriesTupleArray(RedisResult result)
{
RedisResult[] redisResults = (RedisResult[])result;
var list = new List(redisResults.Length);
if (redisResults.Length == 0) return list;
- Array.ForEach(redisResults, tuple => list.Add(ParseTimeSeriesTuple(tuple)));
+ Array.ForEach(redisResults, tuple => list.Add(ToTimeSeriesTuple(tuple)));
return list;
}
- public static IReadOnlyList ParseLabelArray(RedisResult result)
+ public static IReadOnlyList ToLabelArray(RedisResult result)
{
RedisResult[] redisResults = (RedisResult[])result;
var list = new List(redisResults.Length);
@@ -73,8 +120,8 @@ public static IReadOnlyList ParseLabelArray(RedisResult result)
{
RedisResult[] MRangeTuple = (RedisResult[])MRangeValue;
string key = (string)MRangeTuple[0];
- IReadOnlyList labels = ParseLabelArray(MRangeTuple[1]);
- TimeSeriesTuple value = ParseTimeSeriesTuple(MRangeTuple[2]);
+ IReadOnlyList labels = ToLabelArray(MRangeTuple[1]);
+ TimeSeriesTuple value = ToTimeSeriesTuple(MRangeTuple[2]);
list.Add((key, labels, value));
});
return list;
@@ -89,14 +136,14 @@ public static IReadOnlyList ParseLabelArray(RedisResult result)
{
RedisResult[] MRangeTuple = (RedisResult[])MRangeValue;
string key = (string)MRangeTuple[0];
- IReadOnlyList labels = ParseLabelArray(MRangeTuple[1]);
- IReadOnlyList values = ParseTimeSeriesTupleArray(MRangeTuple[2]);
+ IReadOnlyList labels = ToLabelArray(MRangeTuple[1]);
+ IReadOnlyList values = ToTimeSeriesTupleArray(MRangeTuple[2]);
list.Add((key, labels, values));
});
return list;
}
- public static TimeSeriesRule ParseRule(RedisResult result)
+ public static TimeSeriesRule ToRule(RedisResult result)
{
RedisResult[] redisResults = (RedisResult[])result;
string destKey = (string)redisResults[0];
@@ -105,37 +152,74 @@ public static TimeSeriesRule ParseRule(RedisResult result)
return new TimeSeriesRule(destKey, bucketTime, aggregation);
}
- public static IReadOnlyList ParseRuleArray(RedisResult result)
+ public static IReadOnlyList ToRuleArray(RedisResult result)
{
RedisResult[] redisResults = (RedisResult[])result;
var list = new List();
if (redisResults.Length == 0) return list;
- Array.ForEach(redisResults, rule => list.Add(ParseRule(rule)));
+ Array.ForEach(redisResults, rule => list.Add(ToRule(rule)));
return list;
}
- public static TsDuplicatePolicy? ParsePolicy(RedisResult result)
+ public static TsDuplicatePolicy? ToPolicy(RedisResult result)
{
- var policyStatus = (string) result;
- if (String.IsNullOrEmpty(policyStatus) || policyStatus == "(nil)") {
+ var policyStatus = (string)result;
+ if (String.IsNullOrEmpty(policyStatus) || policyStatus == "(nil)")
+ {
return null;
}
return DuplicatePolicyExtensions.AsPolicy(policyStatus.ToUpper());
}
- public static TimeSeriesInformation ParseInfo(RedisResult result)
+ public static BloomInformation? ToBloomInfo(RedisResult result) //TODO: Think about a different implementation, because if the output of BF.INFO changes or even just the names of the labels then the parsing will not work
+ {
+ long capacity, size, numberOfFilters, numberOfItemsInserted, expansionRate;
+ capacity = size = numberOfFilters = numberOfItemsInserted = expansionRate = -1;
+ RedisResult[]? redisResults = (RedisResult[]?)result;
+
+ if (redisResults == null) return null;
+
+ for (int i = 0; i < redisResults.Length; ++i)
+ {
+ string? label = redisResults[i++].ToString();
+ switch (label)
+ {
+ case "Capacity":
+ capacity = (long)redisResults[i];
+ break;
+ case "Size":
+ size = (long)redisResults[i];
+ break;
+ case "Number of filters":
+ numberOfFilters = (long)redisResults[i];
+ break;
+ case "Number of items inserted":
+ numberOfItemsInserted = (long)redisResults[i];
+ break;
+ case "Expansion rate":
+ expansionRate = (long)redisResults[i];
+ break;
+ }
+ }
+
+ return new BloomInformation(capacity, size, numberOfFilters, numberOfItemsInserted, expansionRate);
+ }
+
+ public static TimeSeriesInformation ToTimeSeriesInfo(RedisResult result)
{
- long totalSamples = -1, memoryUsage = -1, retentionTime = -1, chunkSize=-1, chunkCount = -1;
+ long totalSamples = -1, memoryUsage = -1, retentionTime = -1, chunkSize = -1, chunkCount = -1;
TimeStamp firstTimestamp = null, lastTimestamp = null;
IReadOnlyList labels = null;
- IReadOnlyList rules = null;
+ IReadOnlyList rules = null;
string sourceKey = null;
TsDuplicatePolicy? duplicatePolicy = null;
RedisResult[] redisResults = (RedisResult[])result;
- for(int i=0; i v1.4
- duplicatePolicy = ParsePolicy(redisResults[i]);
+ duplicatePolicy = ToPolicy(redisResults[i]);
break;
}
}
@@ -182,7 +266,7 @@ public static TimeSeriesInformation ParseInfo(RedisResult result)
lastTimestamp, retentionTime, chunkCount, chunkSize, labels, sourceKey, rules, duplicatePolicy);
}
- public static IReadOnlyList ParseStringArray(RedisResult result)
+ public static IReadOnlyList ToStringArray(RedisResult result)
{
RedisResult[] redisResults = (RedisResult[])result;
var list = new List();
@@ -191,4 +275,4 @@ public static IReadOnlyList ParseStringArray(RedisResult result)
return list;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/NRedisStack.Core/TimeSeries/TimeSeriesCommands.cs b/src/NRedisStack.Core/TimeSeries/TimeSeriesCommands.cs
index 0064ba1c..19a1ecec 100644
--- a/src/NRedisStack.Core/TimeSeries/TimeSeriesCommands.cs
+++ b/src/NRedisStack.Core/TimeSeries/TimeSeriesCommands.cs
@@ -17,18 +17,18 @@ public TimeSeriesCommands(IDatabase db)
public bool Create(string key, long? retentionTime = null, IReadOnlyCollection labels = null, bool? uncompressed = null, long? chunkSizeBytes = null, TsDuplicatePolicy? duplicatePolicy = null)
{
var args = TimeSeriesAux.BuildTsCreateArgs(key, retentionTime, labels, uncompressed, chunkSizeBytes, duplicatePolicy);
- return ResponseParser.ParseBoolean(_db.Execute(TS.CREATE, args));
+ return ResponseParser.ParseOKtoBoolean(_db.Execute(TS.CREATE, args));
}
public TimeSeriesInformation Info(string key)
{
- return ResponseParser.ParseInfo(_db.Execute(TS.INFO, key));
+ return ResponseParser.ToTimeSeriesInfo(_db.Execute(TS.INFO, key));
}
public bool TimeSeriesAlter(string key, long? retentionTime = null, IReadOnlyCollection labels = null)
{
var args = TimeSeriesAux.BuildTsAlterArgs(key, retentionTime, labels);
- return ResponseParser.ParseBoolean(_db.Execute(TS.ALTER, args));
+ return ResponseParser.ParseOKtoBoolean(_db.Execute(TS.ALTER, args));
}
}
diff --git a/tests/NRedisStack.Tests/Bloom/BloomTests.cs b/tests/NRedisStack.Tests/Bloom/BloomTests.cs
index 30664f47..e34ec997 100644
--- a/tests/NRedisStack.Tests/Bloom/BloomTests.cs
+++ b/tests/NRedisStack.Tests/Bloom/BloomTests.cs
@@ -3,7 +3,6 @@
using NRedisStack.Core.RedisStackCommands;
using Moq;
-
namespace NRedisStack.Tests.Bloom;
public class BloomTests : AbstractNRedisStackTest, IDisposable
@@ -18,16 +17,28 @@ public void Dispose()
}
[Fact]
- public void TestBfAddWhenExist()
+ public void TestReserveBasic()
{
IDatabase db = redisFixture.Redis.GetDatabase();
- Assert.True((db.BF().Add(key, "item1")).ToString() == "1"); // first time
- Assert.True(db.BF().Add(key, "item1").ToString() == "0"); // second time
+ db.BF().Reserve(key, 0.001, 100L);
+
+ Assert.True((db.BF().Add(key, "item1")));
+ Assert.True(db.BF().Exists(key, "item1"));
+ Assert.False(db.BF().Exists(key, "item2"));
}
[Fact]
- public void TestBfAddExists()
+ public void TestAddWhenExist()
+ {
+ IDatabase db = redisFixture.Redis.GetDatabase();
+
+ Assert.True((db.BF().Add(key, "item1"))); // first time
+ Assert.False(db.BF().Add(key, "item1")); // second time
+ }
+
+ [Fact]
+ public void TestAddExists()
{
IDatabase db = redisFixture.Redis.GetDatabase();
@@ -36,10 +47,50 @@ public void TestBfAddExists()
}
[Fact]
- public void TestBfInsert()
+ public void TestAddExistsMulti()
+ {
+ IDatabase db = redisFixture.Redis.GetDatabase();
+ var items = new RedisValue[]{"foo", "bar", "baz"};
+ var items2 = new RedisValue[]{"newElement", "bar", "baz"};
+
+ var result = db.BF().MAdd(key, items);
+ Assert.Equal(new bool[] {true, true, true}, result);
+
+ result = db.BF().MAdd(key, items2);
+ Assert.Equal(new bool[] {true, false, false}, result);
+ }
+
+ [Fact]
+ public void TestExample() {
+ IDatabase db = redisFixture.Redis.GetDatabase();
+
+ // Simple bloom filter using default module settings
+ db.BF().Add("simpleBloom", "Mark");
+ // Does "Mark" now exist?
+ db.BF().Exists("simpleBloom", "Mark"); // true
+ db.BF().Exists("simpleBloom", "Farnsworth"); // False
+
+ // If you have a long list of items to check/add, you can use the
+ // "multi" methods
+ var items = new RedisValue[]{"foo", "bar", "baz", "bat", "bag"};
+ db.BF().MAdd("simpleBloom", items);
+
+ // Check if they exist:
+ var allItems = new RedisValue[]{"foo", "bar", "baz", "bat", "Mark", "nonexist"};
+ var rv = db.BF().MExists("simpleBloom", allItems);
+ // All items except the last one will be 'true'
+ Assert.Equal(new bool[] {true, true, true, true, true, false}, rv);
+
+ // Reserve a "customized" bloom filter
+ db.BF().Reserve("specialBloom", 0.0001, 10000);
+ db.BF().Add("specialBloom", "foo");
+ }
+
+ [Fact]
+ public void TestInsert()
{
IDatabase db = redisFixture.Redis.GetDatabase();
- RedisValue[] items = new RedisValue[] { "item1" , "item2", "item3"};
+ RedisValue[] items = new RedisValue[] { "item1", "item2", "item3" };
db.BF().Insert("key", items);
@@ -47,4 +98,50 @@ public void TestBfInsert()
Assert.True(db.BF().Exists("key", "item2"));
Assert.True(db.BF().Exists("key", "item3"));
}
+
+ [Fact]
+ public void TestExistsNonExist()
+ {
+ IDatabase db = redisFixture.Redis.GetDatabase();
+
+ RedisValue item = new RedisValue("item");
+ Assert.False(db.BF().Exists("NonExistKey", item));
+ }
+
+ [Fact]
+ public void TestInfo() //TODO: think again about the returned value of BF.INFO, maybe creating a new returned type
+ {
+ IDatabase db = redisFixture.Redis.GetDatabase();
+ db.BF().Add(key, "item");
+ var info = db.BF().Info(key);
+
+ Assert.NotNull(info);
+ Assert.Equal(info.NumberOfItemsInserted, (long)1);
+
+ Assert.Throws( () => db.BF().Info("notExistKey"));
+ }
+
+ [Fact]
+ public void TestScanDumpAndLoadChunk() //TODO: Fininsh this Test
+ {
+ IDatabase db = redisFixture.Redis.GetDatabase();
+ db.Execute("FLUSHALL");
+
+ db.BF().Reserve("bloom-dump",0.1, 10);
+ db.BF().Add("bloom-dump", "a");
+
+ long iterator = 0;
+ while(true)
+ {
+ var chunkData = db.BF().ScanDump("bloom-dump", iterator);
+ iterator = chunkData.Item1;
+ if(iterator == 0) break;
+ Assert.True(db.BF().LoadChunk("bloom-load", iterator, chunkData.Item2));
+ }
+
+ // check for properties
+ Assert.Equal(db.BF().Info("bloom-dump").NumberOfItemsInserted, db.BF().Info("bloom-load").NumberOfItemsInserted);
+ // check for existing items
+ Assert.True(db.BF().Exists("bloom-load", "a"));
+ }
}
\ No newline at end of file
diff --git a/tests/NRedisStack.Tests/Json/JsonTests.cs b/tests/NRedisStack.Tests/Json/JsonTests.cs
index a78ae22c..53b4af20 100644
--- a/tests/NRedisStack.Tests/Json/JsonTests.cs
+++ b/tests/NRedisStack.Tests/Json/JsonTests.cs
@@ -17,13 +17,13 @@ public void Dispose()
redisFixture.Redis.GetDatabase().KeyDelete(key);
}
- [Fact]
- public void TestJsonSet()
- {
- var obj = new Person { Name = "Shachar", Age = 23 };
- _mock.Object.JSON().Set("Person:Shachar", "$", obj, When.Exists);
- _mock.Verify(x => x.Execute("JSON.SET", "Person:Shachar", "$", "{\"Name\":\"Shachar\",\"Age\":23}", "XX"));
- }
+ // [Fact]
+ // public void TestJsonSet()
+ // {
+ // var obj = new Person { Name = "Shachar", Age = 23 };
+ // _mock.Object.JSON().Set("Person:Shachar", "$", obj, When.Exists);
+ // _mock.Verify(x => x.Execute("JSON.SET", "Person:Shachar", "$", "{\"Name\":\"Shachar\",\"Age\":23}", "XX"));
+ // }
[Fact]
public void TestJsonSetNotExist()
@@ -33,6 +33,8 @@ public void TestJsonSetNotExist()
_mock.Verify(x => x.Execute("JSON.SET", "Person:Shachar", "$", "{\"Name\":\"Shachar\",\"Age\":23}", "NX"));
}
+ //TODO: understand why this 2 tests are not pass what we do
+ //"dotnet test" but they pass when we do "dotnet test --filter ..."
[Fact]
public void TestSimpleJsonGet()
{
@@ -41,7 +43,11 @@ public void TestSimpleJsonGet()
db.JSON().Set(key, "$", obj);
string expected = "{\"Name\":\"Shachar\",\"Age\":23}";
- Assert.Equal(db.JSON().Get(key).ToString(), expected);
+ var result = db.JSON().Get(key).ToString();
+ if(result == null)
+ throw new ArgumentNullException(nameof(result));
+
+ Assert.Equal(result, expected);
}
[Fact]
@@ -52,7 +58,10 @@ public void TestJsonGet()
db.JSON().Set(key, "$", obj);
- string expected = "[222111\"Shachar\"222]";
- Assert.Equal(db.JSON().Get(key, "111", "222", "333", "$.Name").ToString(), expected);
+ var expected = "[222111\"Shachar\"222]";
+ var result = db.JSON().Get(key, "111", "222", "333", "$.Name");
+ // if(result == null)
+ // throw new ArgumentNullException(nameof(result));
+ Assert.Equal(result.ToString(), expected);
}
}
\ No newline at end of file