Skip to content

Commit

Permalink
#253 add JoinTableParserTest
Browse files Browse the repository at this point in the history
Fixed an issue where From clause parsing did not work.
  • Loading branch information
mk3008 committed Nov 5, 2023
1 parent 7075408 commit 89fc037
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 3 deletions.
33 changes: 30 additions & 3 deletions src/QueryBuilderByLinq/Analysis/FromTableInfoParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,41 @@ public static class FromTableInfoParser
if (lambda == null) return null;

var body = lambda.GetBody<MethodCallExpression>();
if (body == null || body.Method.Name != nameof(Sql.FromTable)) return null;
if (body == null) return null;

// no relation pattern.
var operand = method.GetArgument<UnaryExpression>(2).GetOperand<LambdaExpression>();
if (operand == null) return null;

//name
if (operand.Parameters.Count != 2) return null;
var parameter = operand.Parameters[1];

if (body.Method.Name == nameof(Sql.FromTable))
{
return ParseCore3ArgumentsFromTable(body, parameter);
}
else if (body.Method.Name == nameof(Sql.InnerJoinTable) || body.Method.Name == nameof(Sql.LeftJoinTable) || body.Method.Name == nameof(Sql.CrossJoinTable))
{
/*
has relation pattern.
'body' is relation conditions.
'parameter' is relation alias.
*/

//query
lambda = method.GetArgument<UnaryExpression>(2).GetOperand<LambdaExpression>();
if (lambda == null || lambda.Parameters.Count != 2) return null;

var prm = lambda.Parameters[0];
return new FromTableInfo(prm.ToTypeTable(), prm.Name!);
}

return null;
}

private static FromTableInfo? ParseCore3ArgumentsFromTable(MethodCallExpression body, ParameterExpression parameter)
{
if (body.Method.Name != nameof(Sql.FromTable)) throw new InvalidProgramException();

var alias = parameter.Name!;

//table
Expand Down
89 changes: 89 additions & 0 deletions test/QueryBuilderByLinq.Test/Analysis/JoinTableInfoParserTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using Carbunql;
using QueryBuilderByLinq.Analysis;
using Xunit.Abstractions;
using static QueryBuilderByLinq.Sql;

namespace QueryBuilderByLinq.Test.Analysis;

public class JoinTableInfoParserTest
{
private readonly QueryCommandMonitor Monitor;

public JoinTableInfoParserTest(ITestOutputHelper output)
{
Monitor = new QueryCommandMonitor(output);
Output = output;
}

private ITestOutputHelper Output { get; set; }

[Fact]
public void NoRelationTest()
{
var query = from a in FromTable<sale>()
select a;

Monitor.Log(query);

var joins = JoinTableInfoParser.Parse(query.Expression);

Assert.Empty(joins);
}

[Fact]
public void InnerJoinTest()
{
var query = from s in FromTable<sale>()
from a in InnerJoinTable<article>(x => s.article_id == x.article_id)
select a;

Monitor.Log(query);

var from = FromTableInfoParser.Parse(query.Expression);
Assert.Equal("sale", from?.ToSelectable().ToText());
Assert.Equal("s", from?.Alias);

var joins = JoinTableInfoParser.Parse(query.Expression);

Assert.Empty(joins);
}

[Fact]
public void LeftJoinTest()
{
var query = from s in FromTable<sale>()
from a in LeftJoinTable<article>(x => s.article_id == x.article_id)
select a;

Monitor.Log(query);

var from = FromTableInfoParser.Parse(query.Expression);
Assert.Equal("sale", from?.ToSelectable().ToText());
Assert.Equal("s", from?.Alias);

var joins = JoinTableInfoParser.Parse(query.Expression);

Assert.Empty(joins);
}

[Fact]
public void CrossJoinTest()
{
var query = from s in FromTable<sale>()
from a in CrossJoinTable<article>()
select a;

Monitor.Log(query);

var from = FromTableInfoParser.Parse(query.Expression);
Assert.Equal("sale", from?.ToSelectable().ToText());
Assert.Equal("s", from?.Alias);

var joins = JoinTableInfoParser.Parse(query.Expression);

Assert.Empty(joins);
}

public record struct sale(int sales_id, int article_id, int quantity);
public record struct article(int article_id, string article_name, int price);
}

0 comments on commit 89fc037

Please sign in to comment.