Skip to content

Commit

Permalink
Add parameter in BsonExpression
Browse files Browse the repository at this point in the history
  • Loading branch information
mbdavid committed Feb 14, 2018
1 parent b358b88 commit 1412387
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 49 deletions.
7 changes: 6 additions & 1 deletion LiteDB.Demo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ class Program

static void Main(string[] args)
{
var e = BsonExpression.Parse(new StringScanner("_id=1 and name='John'"), true);
var e = BsonExpression.Create("arr[@p1]");

e.Parameters["p1"] = 0;


var r = e.Execute(new BsonDocument { ["a"] = 1 }).First();

//var r = e.Execute(new BsonDocument()).First();

Expand Down
22 changes: 21 additions & 1 deletion LiteDB.Tests/Document/BsonExpression_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@

namespace LiteDB.Tests.Document
{
/// <summary>
/// BsonExpression unit test from external text file
/// File format:
/// "#" new comment used in next tests
/// "{" new document to be used in next tests
/// ">" indicate new expression to test
/// "~" expect expression formatted
/// "@" expect parameter value
/// "=" expect result (support multilines per test)
/// </summary>

[TestClass]
public class BsonExpression_Tests
{
Expand All @@ -26,6 +37,9 @@ public class BsonExpression_Tests
[TestMethod]
public void BsonExpression_Method() => this.RunTest("Method.txt");

[TestMethod]
public void BsonExpression_Parameter() => this.RunTest("Parameter.txt");

public void RunTest(string filename)
{
var tests = this.ReadTests("LiteDB.Tests.Document.ExprTests." + filename);
Expand All @@ -42,6 +56,8 @@ public void RunTest(string filename)

if (test.Results.Count == 0) continue;

test.Parameters.CopyTo(expr.Parameters);

// test result
var doc = JsonSerializer.Deserialize(test.JsonDocument ?? "{}") as BsonDocument;

Expand All @@ -60,7 +76,6 @@ public void RunTest(string filename)
{
Assert.Fail($"ERROR in {test.Expression}: {ex.Message}");
}

}
}

Expand Down Expand Up @@ -92,6 +107,10 @@ public List<ExprTest> ReadTests(string name)
{
test.Formatted = s.Scan(@"~\s*([\s\S]*?)\n", 1).Trim();
}
else if (s.Match(@"\@\w+")) // expected parameter
{
test.Parameters[s.Scan(@"\@(\w+)\s+", 1)] = JsonSerializer.Deserialize(s.Scan(@"([\s\S]*?)\n", 1).Trim());
}
else if (s.Match(@"\#")) // comment in test
{
comment = s.Scan(@"\#\s*([\s\S]*?)\n", 1).Trim();
Expand Down Expand Up @@ -120,6 +139,7 @@ public class ExprTest
public string Expression { get; set; }
public string Formatted { get; set; }
public List<BsonValue> Results { get; set; } = new List<BsonValue>();
public BsonDocument Parameters { get; set; } = new BsonDocument();
public string Comment { get; set; }
}
}
4 changes: 0 additions & 4 deletions LiteDB.Tests/Document/ExprTests/Format.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
# BsonExpression Unit Test
# "{" new document to be used in next tests
# ">" indicate new expression to test
# "~" expected expression formatted
# "=" expected result (support multilines per test)

# Expression format
> _id
Expand Down
4 changes: 0 additions & 4 deletions LiteDB.Tests/Document/ExprTests/Method.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
# BsonExpression Unit Test
# "{" new document to be used in next tests
# ">" indicate new expression to test
# "~" expected expression formatted
# "=" expected result (support multilines per test)

# String functions
> "Lite" + "DB" + "v" + 5
Expand Down
4 changes: 0 additions & 4 deletions LiteDB.Tests/Document/ExprTests/Operator.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
# BsonExpression Unit Test
# "{" new document to be used in next tests
# ">" indicate new expression to test
# "~" expected expression formatted
# "=" expected result (support multilines per test)

# Operators order
{ a: 1, b: 2, c: 3 }
Expand Down
23 changes: 23 additions & 0 deletions LiteDB.Tests/Document/ExprTests/Parameter.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# BsonExpression Unit Test

# Simple parameter call
> @p1
@p1 10
= 10

# Arithmetic
> @p1 + 25
@p1 15
= 40

# Method call
> UPPER(@p1 + @p2)
@p1 "lite"
@p2 "db"
= "LITEDB"

# Inside path filter
{ arr: [1, 2, 3, 4, 5 ] }
> SUM(arr[@ >= @p1])
@p1 4
= 9
4 changes: 0 additions & 4 deletions LiteDB.Tests/Document/ExprTests/Path.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
# BsonExpression Unit Test
# "{" new document to be used in next tests
# ">" indicate new expression to test
# "~" expected expression formatted
# "=" expected result (support multilines per test)

# Simple path navigation
{ a: 1, b: null, c: true, d:[1,2], e:{d:4} }
Expand Down
2 changes: 2 additions & 0 deletions LiteDB.Tests/LiteDB.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@
<None Remove="Document\ExprTests\Format.txt" />
<None Remove="Document\ExprTests\Method.txt" />
<None Remove="Document\ExprTests\Operator.txt" />
<None Remove="Document\ExprTests\Parameter.txt" />
<None Remove="Document\Path.txt" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Document\ExprTests\Format.txt" />
<EmbeddedResource Include="Document\ExprTests\Parameter.txt" />
<EmbeddedResource Include="Document\ExprTests\Operator.txt" />
<EmbeddedResource Include="Document\ExprTests\Method.txt" />
<EmbeddedResource Include="Document\ExprTests\Path.txt" />
Expand Down
15 changes: 10 additions & 5 deletions LiteDB/Document/Expression/BsonExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public class BsonExpression
/// </summary>
internal bool IsConstant { get; set; }

/// <summary>
/// Get/Set parameter values that will be used on expression execution
/// </summary>
public BsonDocument Parameters { get; private set; } = new BsonDocument();

/// <summary>
/// In conditional/or/and expressions, indicate Left side
/// </summary>
Expand Down Expand Up @@ -65,7 +70,7 @@ public class BsonExpression
/// <summary>
/// Compiled Expression into a function to be executed
/// </summary>
private Func<BsonDocument, BsonValue, IEnumerable<BsonValue>> _func;
private Func<BsonDocument, BsonValue, BsonDocument, IEnumerable<BsonValue>> _func;

/// <summary>
/// Only internal ctor (from BsonParserExpression)
Expand Down Expand Up @@ -96,7 +101,7 @@ public IEnumerable<BsonValue> Execute(BsonDocument root, BsonValue current, bool
else
{
var index = 0;
var values = _func(root, current ?? root);
var values = _func(root, current ?? root, this.Parameters);

foreach (var value in values)
{
Expand Down Expand Up @@ -136,15 +141,15 @@ public static List<BsonExpression> Parse(StringScanner s, bool onlyTerms)
{
var root = Expression.Parameter(typeof(BsonDocument), "root");
var current = Expression.Parameter(typeof(BsonValue), "current");
var parameters = Expression.Parameter(typeof(BsonDocument), "parameters");

var exprList = BsonExpressionParser.ParseFullExpression(s, root, current, true, onlyTerms);
var exprList = BsonExpressionParser.ParseFullExpression(s, root, current, parameters, true, onlyTerms);

foreach(var expr in exprList)
{
var lambda = System.Linq.Expressions.Expression.Lambda<Func<BsonDocument, BsonValue, IEnumerable<BsonValue>>>(expr.Expression, root, current);
var lambda = System.Linq.Expressions.Expression.Lambda<Func<BsonDocument, BsonValue, BsonDocument, IEnumerable<BsonValue>>>(expr.Expression, root, current, parameters);

expr._func = lambda.Compile();

}

return exprList;
Expand Down
5 changes: 4 additions & 1 deletion LiteDB/Document/Expression/Parser/BsonExpressionOperators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ public static IEnumerable<BsonValue> MEMBER_PATH(IEnumerable<BsonValue> values,
/// <summary>
/// Returns all values from array according index. If index are MaxValue, return all values
/// </summary>
public static IEnumerable<BsonValue> ARRAY_PATH(IEnumerable<BsonValue> values, int index, BsonExpression expr, BsonDocument root)
public static IEnumerable<BsonValue> ARRAY_PATH(IEnumerable<BsonValue> values, int index, BsonExpression expr, BsonDocument root, BsonDocument parameters)
{
foreach (var value in values)
{
Expand All @@ -245,6 +245,9 @@ public static IEnumerable<BsonValue> ARRAY_PATH(IEnumerable<BsonValue> values, i
// [<expr>] - index are an expression
if (expr.Type != BsonExpressionType.Empty)
{
// update parameters in expression
parameters.CopyTo(expr.Parameters);

foreach (var item in arr)
{
// execute for each child value and except a first bool value (returns if true)
Expand Down
Loading

0 comments on commit 1412387

Please sign in to comment.