Skip to content

Commit

Permalink
Add conditional extension methods for SelectQuery
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
mk3008 committed Sep 5, 2024
1 parent 5ebe9a6 commit 572ba56
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/Carbunql/Fluent/SelectQueryParameterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, SelectQuery> func)
{
var prm = new QueryParameter(name, value);
query.Parameters.Add(prm);
return func(prm.ParameterName);
}
}
42 changes: 42 additions & 0 deletions src/Carbunql/Fluent/SelectQueryWhereExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,48 @@ public static class SelectQueryWhereExtensions
{
internal static char[] ParameterSymbols = { '@', ':', '$' };

/// <summary>
/// Conditionally applies the specified function to the query if the condition is true.
/// </summary>
/// <param name="query">The query to apply the function to.</param>
/// <param name="condition">The condition to evaluate.</param>
/// <param name="func">The function to apply if the condition is true.</param>
/// <returns>The modified query if the condition is true; otherwise, the original query.</returns>
public static SelectQuery If(this SelectQuery query, bool condition, Func<SelectQuery, SelectQuery> func)
{
return condition
? func(query)
: query;
}

/// <summary>
/// Applies the specified function to the query if the value is not null.
/// </summary>
/// <param name="query">The query to apply the function to.</param>
/// <param name="value">The value to check for null.</param>
/// <param name="func">The function to apply if the value is not null.</param>
/// <returns>The modified query if the value is not null; otherwise, the original query.</returns>
public static SelectQuery IfNotNull(this SelectQuery query, object? value, Func<SelectQuery, SelectQuery> func)
{
return value != null
? func(query)
: query;
}

/// <summary>
/// Applies the specified function to the query if the string value is not null or empty.
/// </summary>
/// <param name="query">The query to apply the function to.</param>
/// <param name="value">The string value to check for null or emptiness.</param>
/// <param name="func">The function to apply if the string value is not null or empty.</param>
/// <returns>The modified query if the string value is not null or empty; otherwise, the original query.</returns>
public static SelectQuery IfNotNullOrEmpty(this SelectQuery query, string? value, Func<SelectQuery, SelectQuery> func)
{
return !string.IsNullOrEmpty(value)
? func(query)
: query;
}

private static (string, string) GenerateComparison(string operatorSymbol, object? value)
{
if (value == null)
Expand Down
149 changes: 149 additions & 0 deletions test/Carbunql.Building.Test/QuerySourceFilterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 572ba56

Please sign in to comment.