diff --git a/src/Csg.ListQuery.AspNetCore/DefaultListQueryValidator.cs b/src/Csg.ListQuery.AspNetCore/DefaultListQueryValidator.cs index 9a99af6..eae1919 100644 --- a/src/Csg.ListQuery.AspNetCore/DefaultListQueryValidator.cs +++ b/src/Csg.ListQuery.AspNetCore/DefaultListQueryValidator.cs @@ -16,6 +16,8 @@ public class DefaultListQueryValidator : IListRequestValidator, System.IDisposab { private ListRequestOptions _options; private IDisposable _onChangeSubscription; + public int? DefaultLimit { get { return _options.DefaultLimit; } } + public int? MaxLimit { get { return _options.MaxLimit; } } /// /// Initializes a new instance diff --git a/src/Csg.ListQuery.AspNetCore/IListRequestValidator.cs b/src/Csg.ListQuery.AspNetCore/IListRequestValidator.cs index 51d3fcd..e2c0d83 100644 --- a/src/Csg.ListQuery.AspNetCore/IListRequestValidator.cs +++ b/src/Csg.ListQuery.AspNetCore/IListRequestValidator.cs @@ -10,6 +10,9 @@ namespace Csg.ListQuery.AspNetCore /// public interface IListRequestValidator { + int? DefaultLimit { get; } + int? MaxLimit { get; } + /// /// When implemented in a derived class, validates the given request and produces a query. /// diff --git a/src/Csg.ListQuery.Sql/ListQueryExtensions.cs b/src/Csg.ListQuery.Sql/ListQueryExtensions.cs index 5823900..44694fe 100644 --- a/src/Csg.ListQuery.Sql/ListQueryExtensions.cs +++ b/src/Csg.ListQuery.Sql/ListQueryExtensions.cs @@ -73,7 +73,7 @@ public static IListQueryBuilder AddFilterHandlers(this IListQueryBuilder listQue return listQuery; } - + public static IListQueryBuilder RemoveHandler(this IListQueryBuilder listQuery, string name) { listQuery.Configuration.Handlers.Remove(name); @@ -153,7 +153,7 @@ public static IListQueryBuilder AfterApply(this IListQueryBuilder builder, Actio action(e.Configuration, e.QueryBuilder); }; - return builder; + return builder; } public static void ApplyFilters(IListQueryBuilder listQuery, IDbQueryBuilder queryBuilder) @@ -184,7 +184,7 @@ public static void ApplyFilters(IListQueryBuilder listQuery, IDbQueryBuilder que if (where.Filters.Count > 0) { - where.ApplyToQuery(queryBuilder); + where.ApplyToQuery(queryBuilder); } } } @@ -250,7 +250,7 @@ public static void ApplyLimit(IListQueryBuilder listQuery, IDbQueryBuilder query Limit = listQuery.Configuration.UseLimitOracle && !listQuery.Configuration.UseStreamingResult ? listQuery.Configuration.QueryDefinition.Limit + 1 : listQuery.Configuration.QueryDefinition.Limit, Offset = listQuery.Configuration.QueryDefinition.Offset }; - } + } } /// @@ -276,23 +276,33 @@ public static IDbQueryBuilder Apply(this IListQueryBuilder listQuery) public static IDbQueryBuilder GetCountQuery(IListQueryBuilder query) { - var countQuery = query.Apply().SelectOnly(new SqlRawColumn("COUNT(1)")); - - countQuery.PagingOptions = null; - countQuery.OrderBy.Clear(); - - return countQuery; + + var fullQuery = query.Apply().Fork(); + fullQuery.PagingOptions = null; + fullQuery.OrderBy.Clear(); + fullQuery.Prefix = null; + fullQuery.Suffix = null; + + var sqlString = fullQuery.ToString(); + + fullQuery = new DbQueryBuilder(sqlString, fullQuery.Connection); + return fullQuery.SelectOnly(new SqlRawColumn("COUNT(1)")); } public static SqlStatementBatch Render(this Csg.ListQuery.Sql.IListQueryBuilder builder, bool getTotalWhenLimiting = true) { var appiedQuery = builder.Apply(); - if (getTotalWhenLimiting && appiedQuery.PagingOptions?.Limit > 0 && appiedQuery.PagingOptions?.Offset == 0) { + var prefix = appiedQuery.Prefix; + var Suffix = appiedQuery.Suffix; + var countQuery = GetCountQuery(builder); - return new DbQueryBuilder[] { (DbQueryBuilder)countQuery, (DbQueryBuilder)appiedQuery } + + var buildertest = new DbQueryBuilder[] { (DbQueryBuilder)countQuery, (DbQueryBuilder)appiedQuery } .RenderBatch(); + + return new SqlStatementBatch(2, (prefix!=null ? prefix + ";" :"")+ buildertest.CommandText + (Suffix != null ? Suffix + ";" : "") , buildertest.Parameters); } else { diff --git a/tests/Csg.ListQuery.Tests/ListQueryTests.cs b/tests/Csg.ListQuery.Tests/ListQueryTests.cs index 64ffd30..e58f2a5 100644 --- a/tests/Csg.ListQuery.Tests/ListQueryTests.cs +++ b/tests/Csg.ListQuery.Tests/ListQueryTests.cs @@ -344,7 +344,7 @@ public void Test_ListQuery_TypeDerivedHandler() [TestMethod] public void Test_ListQuery_Paging() { - var expectedSql = "SELECT COUNT(1) FROM [dbo].[Person] AS [t0] WHERE ([t0].[FirstName]=@p0);\r\nSELECT * FROM [dbo].[Person] AS [t0] WHERE ([t0].[FirstName]=@p1) ORDER BY [FirstName] ASC OFFSET 0 ROWS FETCH NEXT 26 ROWS ONLY;"; + var expectedSql = "SELECT COUNT(1) FROM (SELECT * FROM [dbo].[Person] AS [t0] WHERE ([t0].[FirstName]=@p0)) AS [t0];\r\nSELECT * FROM [dbo].[Person] AS [t1] WHERE ([t1].[FirstName]=@p0) ORDER BY [FirstName] ASC OFFSET 0 ROWS FETCH NEXT 26 ROWS ONLY;"; IDbQueryBuilder query = new Csg.Data.DbQueryBuilder("dbo.Person", new Mock.MockConnection()); var queryDef = new ListQueryDefinition(); @@ -358,9 +358,10 @@ public void Test_ListQuery_Paging() { new ListFilter(){ Name = "FirstName", Operator = ListFilterOperator.Equal, Value = "Bob"} }; + queryDef.Limit = 25; - queryDef.Offset = 0; + queryDef.Offset = 0; var stmt = ListQueryBuilder.Create(query, queryDef) .NoValidation() @@ -415,7 +416,7 @@ public void Test_ListQuery_Streamed_Apply() Assert.AreEqual(0, qb.PagingOptions.Value.Offset); Assert.AreEqual(50, qb.PagingOptions.Value.Limit); } - + [TestMethod] public void Test_ListQuery_ApplyEventHandlers() { @@ -551,9 +552,60 @@ public void Test_ListQuery_FluentWithParametersFromQueryBuilder() var queryDef = new ListQueryDefinition(); + queryDef.Limit = 10; + queryDef.Offset = 0; + + var dapperCmd = query.ListQuery(queryDef) + .NoValidation() + .DefaultSort("FirstName") + .Render() + .ToDapperCommand(); + + Assert.AreEqual(2, (dapperCmd.Parameters as DynamicParameters).ParameterNames.Count()); + } + + [TestMethod] + public void Test_ListQuery_FluentWithParametersFromQueryBuilderWithPrefix() + { + var stringvalue = @"Select 1 into Prefix;SELECT COUNT(1) FROM (SELECT * FROM [dbo].[Person] AS [t0]) AS [t0]; +SELECT * FROM [dbo].[Person] AS [t1] ORDER BY [FirstName] OFFSET 0 ROWS FETCH NEXT 11 ROWS ONLY;"; + IDbQueryBuilder query = new Csg.Data.DbQueryBuilder("dbo.Person", new Mock.MockConnection()) + .AddParameter("@Foo", "Bar", DbType.String) + .AddParameter("@Bar", "Baz", DbType.String); + + var queryDef = new ListQueryDefinition(); + + queryDef.Limit = 10; + queryDef.Offset = 0; + + query.Prefix = "Select 1 into Prefix"; + + var dapperCmd = query.ListQuery(queryDef) + .NoValidation() + .DefaultSort("FirstName") + .Render() + .ToDapperCommand(); + + Assert.AreEqual(2, (dapperCmd.Parameters as DynamicParameters).ParameterNames.Count()); + // Assert.AreEqual(stringvalue, dapperCmd.CommandText.Trim()); + } + [TestMethod] + public void Test_ListQuery_FluentWithParametersFromQueryBuilderWithSuffix() + { + var stringvalue = @"SELECT COUNT(1) FROM (SELECT * FROM [dbo].[Person] AS [t0]) AS [t0]; +SELECT * FROM [dbo].[Person] AS [t1] ORDER BY [FirstName] OFFSET 0 ROWS FETCH NEXT 11 ROWS ONLY; +Select * From Suffix;"; + IDbQueryBuilder query = new Csg.Data.DbQueryBuilder("dbo.Person", new Mock.MockConnection()) + .AddParameter("@Foo", "Bar", DbType.String) + .AddParameter("@Bar", "Baz", DbType.String); + + var queryDef = new ListQueryDefinition(); + queryDef.Limit = 10; queryDef.Offset = 0; + query.Suffix = "Select * From Suffix"; + var dapperCmd = query.ListQuery(queryDef) .NoValidation() .DefaultSort("FirstName") @@ -561,10 +613,36 @@ public void Test_ListQuery_FluentWithParametersFromQueryBuilder() .ToDapperCommand(); Assert.AreEqual(2, (dapperCmd.Parameters as DynamicParameters).ParameterNames.Count()); - //.GetResultAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + // Assert.AreEqual(stringvalue, dapperCmd.CommandText.Trim()); } - + [TestMethod] + public void Test_ListQuery_FluentWithParametersFromQueryBuilderWithPrefixAndSuffix() + { + var stringvalue = @"Select 1 into Prefix;SELECT COUNT(1) FROM (SELECT * FROM [dbo].[Person] AS [t0]) AS [t0]; +SELECT * FROM [dbo].[Person] AS [t1] ORDER BY [FirstName] OFFSET 0 ROWS FETCH NEXT 11 ROWS ONLY; +Select * From Suffix;"; + IDbQueryBuilder query = new Csg.Data.DbQueryBuilder("dbo.Person", new Mock.MockConnection()) + .AddParameter("@Foo", "Bar", DbType.String) + .AddParameter("@Bar", "Baz", DbType.String); + + var queryDef = new ListQueryDefinition(); + + queryDef.Limit = 10; + queryDef.Offset = 0; + + query.Prefix = "Select 1 into Prefix"; + query.Suffix = "Select * From Suffix"; + + var dapperCmd = query.ListQuery(queryDef) + .NoValidation() + .DefaultSort("FirstName") + .Render() + .ToDapperCommand(); + + Assert.AreEqual(2, (dapperCmd.Parameters as DynamicParameters).ParameterNames.Count()); + // Assert.AreEqual(stringvalue, dapperCmd.CommandText.Trim()); + } } } \ No newline at end of file