From aa83a954f37106aaa1e91b3e71fc2b888a7f073c Mon Sep 17 00:00:00 2001 From: mk3008 Date: Sun, 26 Nov 2023 13:20:49 +0900 Subject: [PATCH 1/2] #284 Simplified the description of relation join expressions Enabled to write in the same way as the Where clause. --- src/Carbunql/Building/FromClauseExtension.cs | 55 +-------- src/Carbunql/Building/RelationExtension.cs | 108 ++++++++++++++++++ src/Carbunql/Building/WhereClauseExtension.cs | 1 - test/Carbunql.Building.Test/JoinTest.cs | 38 ++++++ 4 files changed, 147 insertions(+), 55 deletions(-) create mode 100644 src/Carbunql/Building/RelationExtension.cs diff --git a/src/Carbunql/Building/FromClauseExtension.cs b/src/Carbunql/Building/FromClauseExtension.cs index e7fa5822..482730ad 100644 --- a/src/Carbunql/Building/FromClauseExtension.cs +++ b/src/Carbunql/Building/FromClauseExtension.cs @@ -1,7 +1,5 @@ using Carbunql.Clauses; using Carbunql.Tables; -using Carbunql.Values; -using System.Linq.Expressions; namespace Carbunql.Building; @@ -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 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 builder) - { - source.Condition = builder(source); - return source.Table; - } -} \ No newline at end of file +} diff --git a/src/Carbunql/Building/RelationExtension.cs b/src/Carbunql/Building/RelationExtension.cs new file mode 100644 index 00000000..d75734ac --- /dev/null +++ b/src/Carbunql/Building/RelationExtension.cs @@ -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 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 builder) + { + source.Condition = builder(source); + return source.Table; + } + + public static SelectableTable On(this Relation source, Action 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 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; + } +} \ No newline at end of file diff --git a/src/Carbunql/Building/WhereClauseExtension.cs b/src/Carbunql/Building/WhereClauseExtension.cs index 2f1f2772..fcf40d7d 100644 --- a/src/Carbunql/Building/WhereClauseExtension.cs +++ b/src/Carbunql/Building/WhereClauseExtension.cs @@ -1,7 +1,6 @@ using Carbunql.Analysis.Parser; using Carbunql.Clauses; using Carbunql.Values; -using System.Linq.Expressions; namespace Carbunql.Building; diff --git a/test/Carbunql.Building.Test/JoinTest.cs b/test/Carbunql.Building.Test/JoinTest.cs index cad9cf89..5dadde12 100644 --- a/test/Carbunql.Building.Test/JoinTest.cs +++ b/test/Carbunql.Building.Test/JoinTest.cs @@ -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); + } } \ No newline at end of file From c5bcc7885204f5db0648cf7d39478654ee1456a0 Mon Sep 17 00:00:00 2001 From: mk3008 Date: Sun, 26 Nov 2023 13:21:32 +0900 Subject: [PATCH 2/2] version 0.5.5 --- src/Carbunql/Carbunql.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Carbunql/Carbunql.csproj b/src/Carbunql/Carbunql.csproj index 30cb0536..c58ea2a1 100644 --- a/src/Carbunql/Carbunql.csproj +++ b/src/Carbunql/Carbunql.csproj @@ -7,7 +7,7 @@ mk3008net A lightweight library for parsing and building select queries. SQL can be rebuilt dynamically. - 0.5.4 + 0.5.5 mk3008net https://github.com/mk3008/Carbunql README.md