From f2d019bea290fd5f35915c78c7dfa3f2c3bcb29c Mon Sep 17 00:00:00 2001
From: HCricle <15218450198@163.com>
Date: Tue, 8 Nov 2022 16:35:18 +0800
Subject: [PATCH 1/6] Support `SelectDatePart` in mysql and sqlite
---
Program/Program.cs | 3 +-
QueryBuilder.Tests/SelectTests.cs | 8 +++
QueryBuilder/Clauses/ColumnClause.cs | 21 +++++++
QueryBuilder/Compilers/Compiler.Conditions.cs | 9 +++
QueryBuilder/Compilers/Compiler.cs | 12 ++++
QueryBuilder/Compilers/SqliteCompiler.cs | 22 +++++++
QueryBuilder/Query.Select.cs | 61 +++++++++++++++++++
7 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/Program/Program.cs b/Program/Program.cs
index 9b4c2845..b1a1db77 100644
--- a/Program/Program.cs
+++ b/Program/Program.cs
@@ -37,8 +37,7 @@ static void Main(string[] args)
using (var db = SqlLiteQueryFactory())
{
var query = db.Query("accounts")
- .Where("balance", ">", 0)
- .GroupBy("balance")
+ .SelectDatePart("year", "created_at", "created_at_day")
.Limit(10);
var accounts = query.Clone().Get();
diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs
index 3f3c28ba..a272b610 100644
--- a/QueryBuilder.Tests/SelectTests.cs
+++ b/QueryBuilder.Tests/SelectTests.cs
@@ -930,6 +930,14 @@ public void SelectWithExists_OmitSelectIsFalse()
var sqlServer = compiler.Compile(q).ToString();
Assert.Equal("SELECT * FROM [Posts] WHERE EXISTS (SELECT [Id] FROM [Comments] WHERE [Comments].[PostId] = [Posts].[Id])", sqlServer.ToString());
}
+ [Fact]
+ public void SelectWithDatePart()
+ {
+ var q = new Query().From("users as u").SelectDatePart("day","date","date_day");
+ var c = Compile(q);
+ Assert.Equal("SELECT (DAY(`date`)) AS `date_day` FROM `users` AS `u`", c[EngineCodes.MySql]);
+ Assert.Equal("SELECT (strftime('%d', \"date\")) AS \"date_day\" FROM \"users\" AS \"u\"", c[EngineCodes.Sqlite]);
+ }
}
}
diff --git a/QueryBuilder/Clauses/ColumnClause.cs b/QueryBuilder/Clauses/ColumnClause.cs
index dd51a85e..9318e889 100644
--- a/QueryBuilder/Clauses/ColumnClause.cs
+++ b/QueryBuilder/Clauses/ColumnClause.cs
@@ -29,6 +29,27 @@ public override AbstractClause Clone()
};
}
}
+ ///
+ /// Represents date column clause calculated using query.
+ ///
+ public class DateQueryColumn : Column
+ {
+ public string Column { get; set; }
+
+ public string Part { get; set; }
+
+ public override AbstractClause Clone()
+ {
+ return new DateQueryColumn
+ {
+ Engine = Engine,
+ Name=Name,
+ Column = Column,
+ Component = Component,
+ Part = Part,
+ };
+ }
+ }
///
/// Represents column clause calculated using query.
diff --git a/QueryBuilder/Compilers/Compiler.Conditions.cs b/QueryBuilder/Compilers/Compiler.Conditions.cs
index 6615c246..05093821 100644
--- a/QueryBuilder/Compilers/Compiler.Conditions.cs
+++ b/QueryBuilder/Compilers/Compiler.Conditions.cs
@@ -158,6 +158,15 @@ protected virtual string CompileBasicStringCondition(SqlResult ctx, BasicStringC
}
+ protected virtual string CompileBasicDateSelect(SqlResult ctx,DateQueryColumn x)
+ {
+ var column = Wrap(x.Column);
+
+ var sql = $"{x.Part.ToUpperInvariant()}({column})";
+
+ return sql;
+ }
+
protected virtual string CompileBasicDateCondition(SqlResult ctx, BasicDateCondition x)
{
var column = Wrap(x.Column);
diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs
index aa15c789..4ab8ae2c 100644
--- a/QueryBuilder/Compilers/Compiler.cs
+++ b/QueryBuilder/Compilers/Compiler.cs
@@ -531,7 +531,19 @@ public virtual string CompileColumn(SqlResult ctx, AbstractColumn column)
return "(" + subCtx.RawSql + $"){alias}";
}
+ if (column is DateQueryColumn dateQueryColumn)
+ {
+ var alias = "";
+ if (!string.IsNullOrWhiteSpace(dateQueryColumn.Name))
+ {
+ alias = $" {ColumnAsKeyword}{WrapValue(dateQueryColumn.Name)}";
+ }
+
+ var subCtx = CompileBasicDateSelect(ctx,dateQueryColumn);
+
+ return "(" + subCtx + $"){alias}";
+ }
if (column is AggregatedColumn aggregatedColumn)
{
string agg = aggregatedColumn.Aggregate.ToUpperInvariant();
diff --git a/QueryBuilder/Compilers/SqliteCompiler.cs b/QueryBuilder/Compilers/SqliteCompiler.cs
index 1401dd35..b95993c7 100644
--- a/QueryBuilder/Compilers/SqliteCompiler.cs
+++ b/QueryBuilder/Compilers/SqliteCompiler.cs
@@ -19,7 +19,29 @@ public override string CompileFalse()
{
return "0";
}
+ protected override string CompileBasicDateSelect(SqlResult ctx, DateQueryColumn x)
+ {
+ var column = Wrap(x.Column);
+ var formatMap = new Dictionary {
+ { "date", "%Y-%m-%d" },
+ { "time", "%H:%M:%S" },
+ { "year", "%Y" },
+ { "month", "%m" },
+ { "day", "%d" },
+ { "hour", "%H" },
+ { "minute", "%M" },
+ };
+
+ if (!formatMap.ContainsKey(x.Part))
+ {
+ return column;
+ }
+
+ var sql = $"strftime('{formatMap[x.Part]}', {column})";
+
+ return sql;
+ }
public override string CompileLimit(SqlResult ctx)
{
var limit = ctx.Query.GetLimit(EngineCode);
diff --git a/QueryBuilder/Query.Select.cs b/QueryBuilder/Query.Select.cs
index 9502c024..f7bf8d1e 100644
--- a/QueryBuilder/Query.Select.cs
+++ b/QueryBuilder/Query.Select.cs
@@ -117,5 +117,66 @@ public Query SelectMax(string column, Func filter = null)
{
return SelectAggregate("max", column, filter);
}
+
+ #region date
+ public Query SelectDatePart(string part, string column,string alias)
+ {
+ return AddComponent("select", new DateQueryColumn
+ {
+ Name = alias,
+ Part = part?.ToLowerInvariant(),
+ Column=column
+ });
+ }
+ public Query SelectNotDatePart(string part, string column, string alias)
+ {
+ return Not().SelectDatePart(part, column, alias);
+ }
+
+ public Query OrSelectDatePart(string part, string column, string alias)
+ {
+ return Or().SelectDatePart(part, column, alias);
+ }
+
+ public Query OrSelectNotDatePart(string part, string column, string alias)
+ {
+ return Or().Not().SelectDatePart(part, column, alias);
+ }
+
+ public Query SelectDate(string column, string alias)
+ {
+ return SelectDatePart("date", column, alias);
+ }
+ public Query SelectNotDate(string column, string alias)
+ {
+ return Not().SelectDate(column, alias);
+ }
+ public Query OrSelectDate(string column, string alias)
+ {
+ return Or().SelectDate(column, alias);
+ }
+ public Query OrSelectNotDate(string column, string alias)
+ {
+ return Or().Not().SelectDate(column, alias);
+ }
+
+ public Query SelectTime(string column, string alias)
+ {
+ return SelectDatePart("time", column, alias);
+ }
+ public Query SelectNotTime(string column, string alias)
+ {
+ return Not().SelectTime(column, alias);
+ }
+ public Query OrSelectTime(string column, string alias)
+ {
+ return Or().SelectTime(column, alias);
+ }
+ public Query OrSelectNotTime(string column, string alias)
+ {
+ return Or().Not().SelectTime(column, alias);
+ }
+ #endregion
+
}
}
From e39ab5e3995e11841334b6f6683c9061ce88f416 Mon Sep 17 00:00:00 2001
From: HCricle <15218450198@163.com>
Date: Tue, 8 Nov 2022 17:22:14 +0800
Subject: [PATCH 2/6] Support fiebird, oracle, postgres, sqlite, sqlservice
---
Program/Program.cs | 3 +-
QueryBuilder.Tests/SelectTests.cs | 4 +++
QueryBuilder/Compilers/FirebirdCompiler.cs | 22 ++++++++++++
QueryBuilder/Compilers/OracleCompiler.cs | 27 ++++++++++++++
QueryBuilder/Compilers/PostgresCompiler.cs | 22 ++++++++++++
QueryBuilder/Compilers/SqlServerCompiler.cs | 17 +++++++++
QueryBuilder/Query.Select.cs | 39 ---------------------
7 files changed, 94 insertions(+), 40 deletions(-)
diff --git a/Program/Program.cs b/Program/Program.cs
index b1a1db77..9b4c2845 100644
--- a/Program/Program.cs
+++ b/Program/Program.cs
@@ -37,7 +37,8 @@ static void Main(string[] args)
using (var db = SqlLiteQueryFactory())
{
var query = db.Query("accounts")
- .SelectDatePart("year", "created_at", "created_at_day")
+ .Where("balance", ">", 0)
+ .GroupBy("balance")
.Limit(10);
var accounts = query.Clone().Get();
diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs
index a272b610..7291502d 100644
--- a/QueryBuilder.Tests/SelectTests.cs
+++ b/QueryBuilder.Tests/SelectTests.cs
@@ -938,6 +938,10 @@ public void SelectWithDatePart()
Assert.Equal("SELECT (DAY(`date`)) AS `date_day` FROM `users` AS `u`", c[EngineCodes.MySql]);
Assert.Equal("SELECT (strftime('%d', \"date\")) AS \"date_day\" FROM \"users\" AS \"u\"", c[EngineCodes.Sqlite]);
+ Assert.Equal("SELECT (DAY(`date`)) AS `date_day` FROM `users` AS `u`", c[EngineCodes.MySql]);
+ Assert.Equal("SELECT (EXTRACT(DAY FROM \"DATE\")) AS \"DATE_DAY\" FROM \"USERS\" AS \"U\"", c[EngineCodes.Firebird]);
+ Assert.Equal("SELECT (DATEPART(DAY, [date])) AS [date_day] FROM [users] AS [u]", c[EngineCodes.SqlServer]);
+ Assert.Equal("SELECT (EXTRACT(DAY FROM \"date\")) \"date_day\" FROM \"users\" \"u\"", c[EngineCodes.Oracle]);
}
}
}
diff --git a/QueryBuilder/Compilers/FirebirdCompiler.cs b/QueryBuilder/Compilers/FirebirdCompiler.cs
index 61ab9547..e16bda9b 100644
--- a/QueryBuilder/Compilers/FirebirdCompiler.cs
+++ b/QueryBuilder/Compilers/FirebirdCompiler.cs
@@ -73,6 +73,28 @@ protected override string CompileColumns(SqlResult ctx)
return compiled;
}
+ protected override string CompileBasicDateSelect(SqlResult ctx, DateQueryColumn x)
+ {
+ var column = Wrap(x.Column);
+
+ string left;
+
+ if (x.Part == "time")
+ {
+ left = $"CAST({column} as TIME)";
+ }
+ else if (x.Part == "date")
+ {
+ left = $"CAST({column} as DATE)";
+ }
+ else
+ {
+ left = $"EXTRACT({x.Part.ToUpperInvariant()} FROM {column})";
+ }
+
+ return left;
+ }
+
protected override string CompileBasicDateCondition(SqlResult ctx, BasicDateCondition condition)
{
var column = Wrap(condition.Column);
diff --git a/QueryBuilder/Compilers/OracleCompiler.cs b/QueryBuilder/Compilers/OracleCompiler.cs
index 610ec20d..60c055b6 100644
--- a/QueryBuilder/Compilers/OracleCompiler.cs
+++ b/QueryBuilder/Compilers/OracleCompiler.cs
@@ -99,7 +99,34 @@ internal void ApplyLegacyLimit(SqlResult ctx)
ctx.RawSql = newSql;
}
+ protected override string CompileBasicDateSelect(SqlResult ctx, DateQueryColumn x)
+ {
+ var column = Wrap(x.Column);
+ string sql;
+ switch (x.Part)
+ {
+ case "date": // assume YY-MM-DD format
+ sql = $"TO_CHAR({column}, 'YY-MM-DD')";
+ break;
+ case "time":
+ sql = $"TO_CHAR({column}, 'HH24:MI:SS')";
+ break;
+ case "year":
+ case "month":
+ case "day":
+ case "hour":
+ case "minute":
+ case "second":
+ sql = $"EXTRACT({x.Part.ToUpperInvariant()} FROM {column})";
+ break;
+ default:
+ sql = column;
+ break;
+ }
+
+ return sql;
+ }
protected override string CompileBasicDateCondition(SqlResult ctx, BasicDateCondition condition)
{
diff --git a/QueryBuilder/Compilers/PostgresCompiler.cs b/QueryBuilder/Compilers/PostgresCompiler.cs
index 3b45d0e6..3c29de66 100644
--- a/QueryBuilder/Compilers/PostgresCompiler.cs
+++ b/QueryBuilder/Compilers/PostgresCompiler.cs
@@ -66,6 +66,28 @@ protected override string CompileBasicStringCondition(SqlResult ctx, BasicString
}
+ protected override string CompileBasicDateSelect(SqlResult ctx, DateQueryColumn x)
+ {
+
+ var column = Wrap(x.Column);
+
+ string left;
+
+ if (x.Part == "time")
+ {
+ left = $"{column}::time";
+ }
+ else if (x.Part == "date")
+ {
+ left = $"{column}::date";
+ }
+ else
+ {
+ left = $"DATE_PART('{x.Part.ToUpperInvariant()}', {column})";
+ }
+
+ return left;
+ }
protected override string CompileBasicDateCondition(SqlResult ctx, BasicDateCondition condition)
{
diff --git a/QueryBuilder/Compilers/SqlServerCompiler.cs b/QueryBuilder/Compilers/SqlServerCompiler.cs
index 0202f0f1..416ac9b0 100644
--- a/QueryBuilder/Compilers/SqlServerCompiler.cs
+++ b/QueryBuilder/Compilers/SqlServerCompiler.cs
@@ -144,7 +144,24 @@ public override string CompileFalse()
{
return "cast(0 as bit)";
}
+ protected override string CompileBasicDateSelect(SqlResult ctx, DateQueryColumn x)
+ {
+ var column = Wrap(x.Column);
+ var part = x.Part.ToUpperInvariant();
+
+ string left;
+ if (part == "TIME" || part == "DATE")
+ {
+ left = $"CAST({column} AS {part.ToUpperInvariant()})";
+ }
+ else
+ {
+ left = $"DATEPART({part.ToUpperInvariant()}, {column})";
+ }
+
+ return left;
+ }
protected override string CompileBasicDateCondition(SqlResult ctx, BasicDateCondition condition)
{
var column = Wrap(condition.Column);
diff --git a/QueryBuilder/Query.Select.cs b/QueryBuilder/Query.Select.cs
index f7bf8d1e..3f5289b2 100644
--- a/QueryBuilder/Query.Select.cs
+++ b/QueryBuilder/Query.Select.cs
@@ -128,54 +128,15 @@ public Query SelectDatePart(string part, string column,string alias)
Column=column
});
}
- public Query SelectNotDatePart(string part, string column, string alias)
- {
- return Not().SelectDatePart(part, column, alias);
- }
-
- public Query OrSelectDatePart(string part, string column, string alias)
- {
- return Or().SelectDatePart(part, column, alias);
- }
-
- public Query OrSelectNotDatePart(string part, string column, string alias)
- {
- return Or().Not().SelectDatePart(part, column, alias);
- }
public Query SelectDate(string column, string alias)
{
return SelectDatePart("date", column, alias);
}
- public Query SelectNotDate(string column, string alias)
- {
- return Not().SelectDate(column, alias);
- }
- public Query OrSelectDate(string column, string alias)
- {
- return Or().SelectDate(column, alias);
- }
- public Query OrSelectNotDate(string column, string alias)
- {
- return Or().Not().SelectDate(column, alias);
- }
-
public Query SelectTime(string column, string alias)
{
return SelectDatePart("time", column, alias);
}
- public Query SelectNotTime(string column, string alias)
- {
- return Not().SelectTime(column, alias);
- }
- public Query OrSelectTime(string column, string alias)
- {
- return Or().SelectTime(column, alias);
- }
- public Query OrSelectNotTime(string column, string alias)
- {
- return Or().Not().SelectTime(column, alias);
- }
#endregion
}
From 272b220e6adf144ae9abb7d3431564e780e31903 Mon Sep 17 00:00:00 2001
From: HCricle <15218450198@163.com>
Date: Tue, 8 Nov 2022 17:31:37 +0800
Subject: [PATCH 3/6] brackets
---
QueryBuilder.Tests/SelectTests.cs | 12 ++++++------
QueryBuilder/Compilers/Compiler.cs | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs
index 7291502d..7048a551 100644
--- a/QueryBuilder.Tests/SelectTests.cs
+++ b/QueryBuilder.Tests/SelectTests.cs
@@ -936,12 +936,12 @@ public void SelectWithDatePart()
var q = new Query().From("users as u").SelectDatePart("day","date","date_day");
var c = Compile(q);
- Assert.Equal("SELECT (DAY(`date`)) AS `date_day` FROM `users` AS `u`", c[EngineCodes.MySql]);
- Assert.Equal("SELECT (strftime('%d', \"date\")) AS \"date_day\" FROM \"users\" AS \"u\"", c[EngineCodes.Sqlite]);
- Assert.Equal("SELECT (DAY(`date`)) AS `date_day` FROM `users` AS `u`", c[EngineCodes.MySql]);
- Assert.Equal("SELECT (EXTRACT(DAY FROM \"DATE\")) AS \"DATE_DAY\" FROM \"USERS\" AS \"U\"", c[EngineCodes.Firebird]);
- Assert.Equal("SELECT (DATEPART(DAY, [date])) AS [date_day] FROM [users] AS [u]", c[EngineCodes.SqlServer]);
- Assert.Equal("SELECT (EXTRACT(DAY FROM \"date\")) \"date_day\" FROM \"users\" \"u\"", c[EngineCodes.Oracle]);
+ Assert.Equal("SELECT DAY(`date`) AS `date_day` FROM `users` AS `u`", c[EngineCodes.MySql]);
+ Assert.Equal("SELECT strftime('%d', \"date\") AS \"date_day\" FROM \"users\" AS \"u\"", c[EngineCodes.Sqlite]);
+ Assert.Equal("SELECT DAY(`date`) AS `date_day` FROM `users` AS `u`", c[EngineCodes.MySql]);
+ Assert.Equal("SELECT EXTRACT(DAY FROM \"DATE\") AS \"DATE_DAY\" FROM \"USERS\" AS \"U\"", c[EngineCodes.Firebird]);
+ Assert.Equal("SELECT DATEPART(DAY, [date]) AS [date_day] FROM [users] AS [u]", c[EngineCodes.SqlServer]);
+ Assert.Equal("SELECT EXTRACT(DAY FROM \"date\") \"date_day\" FROM \"users\" \"u\"", c[EngineCodes.Oracle]);
}
}
}
diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs
index 4ab8ae2c..06aacaae 100644
--- a/QueryBuilder/Compilers/Compiler.cs
+++ b/QueryBuilder/Compilers/Compiler.cs
@@ -542,7 +542,7 @@ public virtual string CompileColumn(SqlResult ctx, AbstractColumn column)
var subCtx = CompileBasicDateSelect(ctx,dateQueryColumn);
- return "(" + subCtx + $"){alias}";
+ return subCtx + $"{alias}";
}
if (column is AggregatedColumn aggregatedColumn)
{
From 50c39e21f19d7bfc52eaffc310ccff5d9ba57577 Mon Sep 17 00:00:00 2001
From: HCricle <15218450198@163.com>
Date: Tue, 8 Nov 2022 17:36:35 +0800
Subject: [PATCH 4/6] move CompileBasicDateSelect out Conditions file
---
QueryBuilder/Compilers/Compiler.Conditions.cs | 9 ---------
QueryBuilder/Compilers/Compiler.cs | 10 ++++++++++
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/QueryBuilder/Compilers/Compiler.Conditions.cs b/QueryBuilder/Compilers/Compiler.Conditions.cs
index 05093821..6615c246 100644
--- a/QueryBuilder/Compilers/Compiler.Conditions.cs
+++ b/QueryBuilder/Compilers/Compiler.Conditions.cs
@@ -158,15 +158,6 @@ protected virtual string CompileBasicStringCondition(SqlResult ctx, BasicStringC
}
- protected virtual string CompileBasicDateSelect(SqlResult ctx,DateQueryColumn x)
- {
- var column = Wrap(x.Column);
-
- var sql = $"{x.Part.ToUpperInvariant()}({column})";
-
- return sql;
- }
-
protected virtual string CompileBasicDateCondition(SqlResult ctx, BasicDateCondition x)
{
var column = Wrap(x.Column);
diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs
index 06aacaae..73c82c00 100644
--- a/QueryBuilder/Compilers/Compiler.cs
+++ b/QueryBuilder/Compilers/Compiler.cs
@@ -227,6 +227,16 @@ protected virtual SqlResult CompileSelectQuery(Query query)
return ctx;
}
+
+ protected virtual string CompileBasicDateSelect(SqlResult ctx, DateQueryColumn x)
+ {
+ var column = Wrap(x.Column);
+
+ var sql = $"{x.Part.ToUpperInvariant()}({column})";
+
+ return sql;
+ }
+
protected virtual SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc)
{
var ctx = new SqlResult();
From 02058e65a6843c4034cc50b958667f79e3397059 Mon Sep 17 00:00:00 2001
From: HCricle <15218450198@163.com>
Date: Thu, 10 Nov 2022 10:12:57 +0800
Subject: [PATCH 5/6] Support OrderByDatePart, GroupByDatePart
---
QueryBuilder/Clauses/OrderClause.cs | 16 ++++++++
QueryBuilder/Compilers/Compiler.cs | 8 ++++
QueryBuilder/Query.cs | 57 +++++++++++++++++++++++++++++
3 files changed, 81 insertions(+)
diff --git a/QueryBuilder/Clauses/OrderClause.cs b/QueryBuilder/Clauses/OrderClause.cs
index 69af772e..9a07f6ec 100644
--- a/QueryBuilder/Clauses/OrderClause.cs
+++ b/QueryBuilder/Clauses/OrderClause.cs
@@ -4,7 +4,23 @@ public abstract class AbstractOrderBy : AbstractClause
{
}
+ public class DateOrderBy : OrderBy
+ {
+ public string Part { get; set; }
+ ///
+ public override AbstractClause Clone()
+ {
+ return new DateOrderBy
+ {
+ Engine = Engine,
+ Component = Component,
+ Column = Column,
+ Part= Part,
+ Ascending = Ascending
+ };
+ }
+ }
public class OrderBy : AbstractOrderBy
{
public string Column { get; set; }
diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs
index 73c82c00..bcca64db 100644
--- a/QueryBuilder/Compilers/Compiler.cs
+++ b/QueryBuilder/Compilers/Compiler.cs
@@ -823,6 +823,14 @@ public virtual string CompileOrders(SqlResult ctx)
ctx.Bindings.AddRange(raw.Bindings);
return WrapIdentifiers(raw.Expression);
}
+ if (x is DateOrderBy dateOrderBy)
+ {
+ var direct = dateOrderBy.Ascending ? "" : " DESC";
+
+ var sql = CompileBasicDateSelect(ctx, new DateQueryColumn { Column = dateOrderBy.Column, Part = dateOrderBy.Part });
+
+ return Wrap(sql) + direct;
+ }
var direction = (x as OrderBy).Ascending ? "" : " DESC";
diff --git a/QueryBuilder/Query.cs b/QueryBuilder/Query.cs
index 8435eca6..56abb3e6 100755
--- a/QueryBuilder/Query.cs
+++ b/QueryBuilder/Query.cs
@@ -335,7 +335,64 @@ public Query GroupByRaw(string expression, params object[] bindings)
return this;
}
+ #region date
+ public Query OrderByDatePart(string part, string column)
+ {
+ return AddComponent("order", new DateOrderBy
+ {
+ Part = part?.ToLowerInvariant(),
+ Column = column,
+ Ascending = true
+ });
+ }
+
+ public Query OrderByDate(string column)
+ {
+ return OrderByDatePart("date", column);
+ }
+ public Query OrderByTime(string column)
+ {
+ return OrderByDatePart("time", column);
+ }
+
+ public Query OrderByDatePartDesc(string part, string column)
+ {
+ return AddComponent("order", new DateOrderBy
+ {
+ Part = part?.ToLowerInvariant(),
+ Column = column,
+ Ascending = true
+ });
+ }
+
+ public Query OrderByDateDesc(string column)
+ {
+ return OrderByDatePartDesc("date", column);
+ }
+ public Query OrderByTimeDesc(string column)
+ {
+ return OrderByDatePartDesc("time", column);
+ }
+
+ public Query GroupByDatePart(string part, string column)
+ {
+ return AddComponent("group", new DateQueryColumn
+ {
+ Part = part?.ToLowerInvariant(),
+ Column = column
+ });
+ }
+
+ public Query GroupByDate(string column)
+ {
+ return OrderByDatePart("date", column);
+ }
+ public Query GroupByTime(string column)
+ {
+ return OrderByDatePart("time", column);
+ }
+ #endregion
public override Query NewQuery()
{
return new Query();
From 961cf596e78e6ca89b6c945f85bb3b95a09054d3 Mon Sep 17 00:00:00 2001
From: HCricle <15218450198@163.com>
Date: Thu, 10 Nov 2022 10:31:43 +0800
Subject: [PATCH 6/6] add sqlserver test, fix wrap in date part select
---
QueryBuilder.Tests/SqlServer/SqlServerTests.cs | 15 +++++++++++++++
QueryBuilder/Compilers/Compiler.cs | 2 +-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/QueryBuilder.Tests/SqlServer/SqlServerTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerTests.cs
index 3adb84f5..3f8dcf6d 100644
--- a/QueryBuilder.Tests/SqlServer/SqlServerTests.cs
+++ b/QueryBuilder.Tests/SqlServer/SqlServerTests.cs
@@ -58,5 +58,20 @@ public void OffsetSqlServer_Should_Be_Incremented_By_One(int offset)
"SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] >= " +
(offset + 1), c.ToString());
}
+
+ [Fact]
+ public void SqlServerOrderByTimePart()
+ {
+ var query = new Query("table").OrderByDatePart("year","field");
+ var result = compiler.Compile(query);
+ Assert.Equal("SELECT * FROM [table] ORDER BY DATEPART(YEAR, [field])", result.Sql);
+ }
+ [Fact]
+ public void SqlServerGroupByTimePart()
+ {
+ var query = new Query("table").GroupByDatePart("year", "field").SelectDatePart("year","field","meow");
+ var result = compiler.Compile(query);
+ Assert.Equal("SELECT DATEPART(YEAR, [field]) AS [meow] FROM [table] GROUP BY DATEPART(YEAR, [field])", result.Sql);
+ }
}
}
diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs
index bcca64db..05e54f33 100644
--- a/QueryBuilder/Compilers/Compiler.cs
+++ b/QueryBuilder/Compilers/Compiler.cs
@@ -829,7 +829,7 @@ public virtual string CompileOrders(SqlResult ctx)
var sql = CompileBasicDateSelect(ctx, new DateQueryColumn { Column = dateOrderBy.Column, Part = dateOrderBy.Part });
- return Wrap(sql) + direct;
+ return sql + direct;
}
var direction = (x as OrderBy).Ascending ? "" : " DESC";