Skip to content

Commit

Permalink
Merge pull request #285 from mk3008/284-i-want-to-easily-write-table-…
Browse files Browse the repository at this point in the history
…join-conditions

284 i want to easily write table join conditions
  • Loading branch information
mk3008 authored Nov 26, 2023
2 parents 912f507 + c5bcc78 commit cac3e86
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 56 deletions.
55 changes: 1 addition & 54 deletions src/Carbunql/Building/FromClauseExtension.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Carbunql.Clauses;
using Carbunql.Tables;
using Carbunql.Values;
using System.Linq.Expressions;

namespace Carbunql.Building;

Expand Down Expand Up @@ -185,55 +183,4 @@ public static Relation Join(this FromClause source, SelectableTable table, strin
source.Relations.Add(r);
return r;
}

public static Relation As(this Relation source, string Alias)
{
source.Table.SetAlias(Alias);
return source;
}

public static SelectableTable On(this Relation source, FromClause from, string column)
{
return source.On(from.Root, new[] { column });
}

public static SelectableTable On(this Relation source, SelectableTable sourceTable, string column)
{
return source.On(sourceTable, new[] { column });
}

public static SelectableTable On(this Relation source, SelectableTable sourceTable, IEnumerable<string> columns)
{
return source.On(r =>
{
ColumnValue? root = null;
ColumnValue? prev = null;

foreach (var column in columns)
{
var lv = new ColumnValue(sourceTable.Alias, column);
var rv = new ColumnValue(r.Table.Alias, column);
lv.AddOperatableValue("=", rv);

if (prev == null)
{
root = lv;
}
else
{
prev.AddOperatableValue("and", lv);
}
prev = rv;
}

if (root == null) throw new ArgumentNullException(nameof(columns));
return root;
});
}

public static SelectableTable On(this Relation source, Func<Relation, ValueBase> builder)
{
source.Condition = builder(source);
return source.Table;
}
}
}
108 changes: 108 additions & 0 deletions src/Carbunql/Building/RelationExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using Carbunql.Analysis.Parser;
using Carbunql.Clauses;
using Carbunql.Values;

namespace Carbunql.Building;

public static class RelationExtension
{
public static Relation As(this Relation source, string Alias)
{
source.Table.SetAlias(Alias);
return source;
}

public static SelectableTable On(this Relation source, FromClause from, string column)
{
return source.On(from.Root, new[] { column });
}

public static SelectableTable On(this Relation source, SelectableTable sourceTable, string column)
{
return source.On(sourceTable, new[] { column });
}

public static SelectableTable On(this Relation source, SelectableTable sourceTable, IEnumerable<string> columns)
{
return source.On(r =>
{
ColumnValue? root = null;
ColumnValue? prev = null;

foreach (var column in columns)
{
var lv = new ColumnValue(sourceTable.Alias, column);
var rv = new ColumnValue(r.Table.Alias, column);
lv.AddOperatableValue("=", rv);

if (prev == null)
{
root = lv;
}
else
{
prev.AddOperatableValue("and", lv);
}
prev = rv;
}

if (root == null) throw new ArgumentNullException(nameof(columns));
return root;
});
}

public static SelectableTable On(this Relation source, Func<Relation, ValueBase> builder)
{
source.Condition = builder(source);
return source.Table;
}

public static SelectableTable On(this Relation source, Action<Relation> builder)
{
builder(source);
return source.Table;
}

public static ValueBase Condition(this Relation source, string table, string column)
{
var v = new ColumnValue(table, column);
return source.Condition(v);
}

public static ValueBase Condition(this Relation source, FromClause table, string column)
{
var v = new ColumnValue(table, column);
return source.Condition(v);
}

public static ValueBase Condition(this Relation source, SelectableTable table, string column)
{
var v = new ColumnValue(table, column);
return source.Condition(v);
}

public static ValueBase Where(this Relation source, string text)
{
var v = ValueParser.Parse(text);
return source.Condition(v);
}

public static ValueBase Condition(this Relation source, Func<ValueBase> builder)
{
var v = builder();
return source.Condition(v);
}

public static ValueBase Condition(this Relation source, ValueBase value)
{
if (source.Condition == null)
{
source.Condition = value;
}
else
{
source.Condition.And(value);
}
return value;
}
}
1 change: 0 additions & 1 deletion src/Carbunql/Building/WhereClauseExtension.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Carbunql.Analysis.Parser;
using Carbunql.Clauses;
using Carbunql.Values;
using System.Linq.Expressions;

namespace Carbunql.Building;

Expand Down
2 changes: 1 addition & 1 deletion src/Carbunql/Carbunql.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Title></Title>
<Copyright>mk3008net</Copyright>
<Description>A lightweight library for parsing and building select queries. SQL can be rebuilt dynamically.</Description>
<Version>0.5.4</Version>
<Version>0.5.5</Version>
<Authors>mk3008net</Authors>
<PackageProjectUrl>https://github.com/mk3008/Carbunql</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down
38 changes: 38 additions & 0 deletions test/Carbunql.Building.Test/JoinTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,42 @@ public void Custom()
Assert.Equal(">=", lst[24].Text);
Assert.Equal("10", lst[25].Text);
}

[Fact]
public void ShorthandExpression()
{
var sq = new SelectQuery();
var (f, a) = sq.From("table_a").As("a");
var b = f.InnerJoin("table_b").As("b").On(r =>
{
r.Condition(f.Root, "id").Equal(r.Table, "a_id");
r.Condition(r.Table, "value").Expression(">=", new LiteralValue("10"));
});

sq.Select(f.Root, "a_id");

Monitor.Log(sq);

var lst = sq.GetTokens().ToList();

Assert.Equal(26, lst.Count());

Assert.Equal("on", lst[12].Text);

Assert.Equal("a", lst[13].Text);
Assert.Equal(".", lst[14].Text);
Assert.Equal("id", lst[15].Text);
Assert.Equal("=", lst[16].Text);
Assert.Equal("b", lst[17].Text);
Assert.Equal(".", lst[18].Text);
Assert.Equal("a_id", lst[19].Text);

Assert.Equal("and", lst[20].Text);

Assert.Equal("b", lst[21].Text);
Assert.Equal(".", lst[22].Text);
Assert.Equal("value", lst[23].Text);
Assert.Equal(">=", lst[24].Text);
Assert.Equal("10", lst[25].Text);
}
}

0 comments on commit cac3e86

Please sign in to comment.