From 572ba564b832dec21857da038944dee60f62875a Mon Sep 17 00:00:00 2001 From: mk3008 Date: Thu, 5 Sep 2024 22:11:29 +0900 Subject: [PATCH] Add conditional extension methods for SelectQuery - Implemented `If` method to apply a function to `SelectQuery` if a boolean condition is true. - Added `IfNotNull` method to apply a function when the provided object is not null. - Introduced `IfNotNullOrEmpty` method to apply a function when a string is not null or empty. These methods improve readability and allow for cleaner conditional query modifications. --- .../Fluent/SelectQueryParameterExtensions.cs | 14 ++ .../Fluent/SelectQueryWhereExtensions.cs | 42 +++++ .../QuerySourceFilterTest.cs | 149 ++++++++++++++++++ 3 files changed, 205 insertions(+) diff --git a/src/Carbunql/Fluent/SelectQueryParameterExtensions.cs b/src/Carbunql/Fluent/SelectQueryParameterExtensions.cs index c7d8ea8f..b9e0f3ce 100644 --- a/src/Carbunql/Fluent/SelectQueryParameterExtensions.cs +++ b/src/Carbunql/Fluent/SelectQueryParameterExtensions.cs @@ -8,4 +8,18 @@ public static SelectQuery AddParameter(this SelectQuery query, string name, obje query.Parameters.Add(prm); return query; } + + public static SelectQuery FluentParameter(this SelectQuery query, string name, object? value) + { + var prm = new QueryParameter(name, value); + query.Parameters.Add(prm); + return query; + } + + public static SelectQuery FluentParameter(this SelectQuery query, string name, object? value, Func func) + { + var prm = new QueryParameter(name, value); + query.Parameters.Add(prm); + return func(prm.ParameterName); + } } diff --git a/src/Carbunql/Fluent/SelectQueryWhereExtensions.cs b/src/Carbunql/Fluent/SelectQueryWhereExtensions.cs index 5d707c50..d408d4b6 100644 --- a/src/Carbunql/Fluent/SelectQueryWhereExtensions.cs +++ b/src/Carbunql/Fluent/SelectQueryWhereExtensions.cs @@ -7,6 +7,48 @@ public static class SelectQueryWhereExtensions { internal static char[] ParameterSymbols = { '@', ':', '$' }; + /// + /// Conditionally applies the specified function to the query if the condition is true. + /// + /// The query to apply the function to. + /// The condition to evaluate. + /// The function to apply if the condition is true. + /// The modified query if the condition is true; otherwise, the original query. + public static SelectQuery If(this SelectQuery query, bool condition, Func func) + { + return condition + ? func(query) + : query; + } + + /// + /// Applies the specified function to the query if the value is not null. + /// + /// The query to apply the function to. + /// The value to check for null. + /// The function to apply if the value is not null. + /// The modified query if the value is not null; otherwise, the original query. + public static SelectQuery IfNotNull(this SelectQuery query, object? value, Func func) + { + return value != null + ? func(query) + : query; + } + + /// + /// Applies the specified function to the query if the string value is not null or empty. + /// + /// The query to apply the function to. + /// The string value to check for null or emptiness. + /// The function to apply if the string value is not null or empty. + /// The modified query if the string value is not null or empty; otherwise, the original query. + public static SelectQuery IfNotNullOrEmpty(this SelectQuery query, string? value, Func func) + { + return !string.IsNullOrEmpty(value) + ? func(query) + : query; + } + private static (string, string) GenerateComparison(string operatorSymbol, object? value) { if (value == null) diff --git a/test/Carbunql.Building.Test/QuerySourceFilterTest.cs b/test/Carbunql.Building.Test/QuerySourceFilterTest.cs index 27637fae..fe86caf3 100644 --- a/test/Carbunql.Building.Test/QuerySourceFilterTest.cs +++ b/test/Carbunql.Building.Test/QuerySourceFilterTest.cs @@ -1271,4 +1271,153 @@ sale AS s Assert.Equal(expect, query.ToText(), true, true, true); } + + [Fact] + public void IfTest() + { + var sql = """ + select + s.unit_price * s.amount as price + from + sale as s + """; + + int? price = null; + + var query = SelectQuery.Parse(sql) + .If(price != null, x => x.Equal(nameof(price), price)); + + Monitor.Log(query, exportTokens: false); + + var expect = """ + SELECT + s.unit_price * s.amount AS price + FROM + sale AS s + """; + + Assert.Equal(expect, query.ToText(), true, true, true); + + price = 10; + + query = SelectQuery.Parse(sql) + .If(price != null, x => x.Equal(nameof(price), price)); + + Monitor.Log(query, exportTokens: false); + + expect = """ + SELECT + s.unit_price * s.amount AS price + FROM + sale AS s + WHERE + s.unit_price * s.amount = 10 + """; + + Assert.Equal(expect, query.ToText(), true, true, true); + } + + [Fact] + public void IfNotNullTest() + { + var sql = """ + select + s.unit_price * s.amount as price + from + sale as s + """; + + int? price = null; + + var query = SelectQuery.Parse(sql) + .IfNotNull(price, x => x.Equal(nameof(price), price)); + + Monitor.Log(query, exportTokens: false); + + var expect = """ + SELECT + s.unit_price * s.amount AS price + FROM + sale AS s + """; + + Assert.Equal(expect, query.ToText(), true, true, true); + + price = 10; + + query = SelectQuery.Parse(sql) + .IfNotNull(price, x => x.Equal(nameof(price), price)); + + Monitor.Log(query, exportTokens: false); + + expect = """ + SELECT + s.unit_price * s.amount AS price + FROM + sale AS s + WHERE + s.unit_price * s.amount = 10 + """; + + Assert.Equal(expect, query.ToText(), true, true, true); + } + + [Fact] + public void IfNotNullOrEmptyTest() + { + var sql = """ + select + s.product_name + from + sale as s + """; + + string? product_name = null; + + var query = SelectQuery.Parse(sql) + .IfNotNullOrEmpty(product_name, x => + { + x.FluentParameter(":product_name" + , product_name + , name => x.Equal(nameof(product_name), name) + ); + return x; + }); + + Monitor.Log(query, exportTokens: false); + + var expect = """ + SELECT + s.product_name + FROM + sale AS s + """; + + Assert.Equal(expect, query.ToText(), true, true, true); + + product_name = "test"; + + query = SelectQuery.Parse(sql) + .IfNotNullOrEmpty(product_name, x => + { + x.FluentParameter(":product_name" + , product_name + , name => x.Equal(nameof(product_name), name) + ); + return x; + }); + + Monitor.Log(query, exportTokens: false); + + expect = """ + SELECT + s.product_name + FROM + sale AS s + WHERE + s.product_name = :product_name + """; + + Assert.Equal(expect, query.ToText(), true, true, true); + } }