Here is the failed unit test, it ** throws Aerospike.Client.AerospikeException : Error 4, Parameter error** when client.Operate( …) is called.
If the condition is Exp.BinExists(binName) alone, it works. As soon as put it in Exp.And(), even just the only parameter, it begins to fail.
Exp.NE line alone as condition will also throw the same exception.
Thanks for the help in advance.
[Fact]
public void TestNestedMap()
{
AerospikeClient client = new AerospikeClient("127.0.0.1", 3000);
Key key = new Key("test", "NestedMapOps", "key1");
string binName = "NestedMap";
string outKey = "Out";
string innerKey = "Inner";
Value value = Value.Get(99);
try
{
var writeOps = GetNestedWriteOperationsForField<int>(binName, outKey, innerKey, value).ToArray();
var recordWrite = client.Operate(null, key, writeOps);
}
catch (AerospikeException ae) when (ae.Result == ResultCode.KEY_EXISTS_ERROR)
{
//ignore
}
var recordRead = client.Operate(null, key, GetNestedReadOperationsForField(binName, outKey, innerKey)); // throws Aerospike.Client.AerospikeException : Error 4, Parameter error
Assert.NotNull(recordRead);
Assert.Equal(99, recordRead.GetInt(binName));
}
private static IEnumerable<Operation> GetNestedWriteOperationsForField<TValue>(string binName, string outerKey, string innerKey, Value value)
{
//create an empty innder map first as needed, otherwise AE exception
yield return MapOperation.Put(new MapPolicy(MapOrder.UNORDERED, MapWriteMode.CREATE_ONLY), binName,
Value.Get(outerKey), Value.Get(new Dictionary<string, TValue> { }));
yield return MapOperation.Increment(MapPolicy.Default, binName, new StringValue(innerKey), value, CTX.MapKey(Value.Get(outerKey)));
}
private static Operation GetNestedReadOperationsForField(string binName, string outerKey, string innerKey)
{
Exp condition = Exp.And(
Exp.BinExists(binName),
Exp.NE(MapExp.GetByKey(MapReturnType.VALUE, Exp.Type.MAP, Exp.Val(outerKey), Exp.Bin(binName, Exp.Type.MAP)), Exp.Nil())
);
Exp work = MapExp.GetByKey(MapReturnType.VALUE, Exp.Type.INT, Exp.Val(innerKey), Exp.Bin(binName, Exp.Type.MAP), CTX.MapKey(Value.Get(outerKey))); //Good
Exp conditionedWork = Exp.Cond(condition, work, Exp.Val(0));
return ExpOperation.Read(binName, Exp.Build(conditionedWork), ExpReadFlags.EVAL_NO_FAIL);
}