From 9519fc7ac67f2c62d1ac7bd19a944ae0eb76402a Mon Sep 17 00:00:00 2001 From: faddiv Date: Fri, 29 Nov 2024 16:10:38 +0100 Subject: [PATCH 01/27] Basic Fixes and Add user secrets for db connection. --- QueryBuilder.Tests/MySqlExecutionTest.cs | 24 ++++++++++++-------- QueryBuilder.Tests/ParameterTypeTests.cs | 4 ++-- QueryBuilder.Tests/QueryBuilder.Tests.csproj | 5 +++- QueryBuilder/Compilers/Compiler.cs | 8 +++---- QueryBuilder/Compilers/SqlServerCompiler.cs | 2 +- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/QueryBuilder.Tests/MySqlExecutionTest.cs b/QueryBuilder.Tests/MySqlExecutionTest.cs index 07df93c8..4a86fd86 100644 --- a/QueryBuilder.Tests/MySqlExecutionTest.cs +++ b/QueryBuilder.Tests/MySqlExecutionTest.cs @@ -6,6 +6,7 @@ using System.Linq; using static SqlKata.Expressions; using System.Collections.Generic; +using Microsoft.Extensions.Configuration; namespace SqlKata.Tests { @@ -213,12 +214,12 @@ public void BasicSelectFilter() // 2020 {"2020-01-01", 10}, {"2020-05-01", 20}, - + // 2021 {"2021-01-01", 40}, {"2021-02-01", 10}, {"2021-04-01", -10}, - + // 2022 {"2022-01-01", 80}, {"2022-02-01", -30}, @@ -249,14 +250,19 @@ public void BasicSelectFilter() db.Drop("Transaction"); } - QueryFactory DB() + private static string GetConnectionString() { - var host = System.Environment.GetEnvironmentVariable("SQLKATA_MYSQL_HOST"); - var user = System.Environment.GetEnvironmentVariable("SQLKATA_MYSQL_USER"); - var dbName = System.Environment.GetEnvironmentVariable("SQLKATA_MYSQL_DB"); - var cs = $"server={host};user={user};database={dbName}"; + var config = new ConfigurationBuilder() + .AddUserSecrets(typeof(MySqlExecutionTest).Assembly) + .Build(); + return config.GetConnectionString("MySqlExecutionTest"); + } - var connection = new MySqlConnection(cs); + private static Lazy ConnectionString { get; } = new(GetConnectionString); + + QueryFactory DB() + { + var connection = new MySqlConnection(ConnectionString.Value); var db = new QueryFactory(connection, new MySqlCompiler()); @@ -266,4 +272,4 @@ QueryFactory DB() } -} \ No newline at end of file +} diff --git a/QueryBuilder.Tests/ParameterTypeTests.cs b/QueryBuilder.Tests/ParameterTypeTests.cs index 095a6e53..37c9fc26 100644 --- a/QueryBuilder.Tests/ParameterTypeTests.cs +++ b/QueryBuilder.Tests/ParameterTypeTests.cs @@ -22,9 +22,9 @@ public class ParameterTypeGenerator : IEnumerable private readonly List _data = new List { new object[] {"1", 1}, - new object[] {Convert.ToSingle("10.5", CultureInfo.InvariantCulture).ToString(), 10.5}, + new object[] {"10.5", 10.5}, new object[] {"-2", -2}, - new object[] {Convert.ToSingle("-2.8", CultureInfo.InvariantCulture).ToString(), -2.8}, + new object[] {"-2.8", -2.8}, new object[] {"cast(1 as bit)", true}, new object[] {"cast(0 as bit)", false}, new object[] {"'2018-10-28 19:22:00'", new DateTime(2018, 10, 28, 19, 22, 0)}, diff --git a/QueryBuilder.Tests/QueryBuilder.Tests.csproj b/QueryBuilder.Tests/QueryBuilder.Tests.csproj index 92829215..90203dfd 100755 --- a/QueryBuilder.Tests/QueryBuilder.Tests.csproj +++ b/QueryBuilder.Tests/QueryBuilder.Tests.csproj @@ -1,12 +1,15 @@ - net6.0 Library false SqlKata.Tests + net8.0 + c675ce13-c233-4a60-9fcc-dadf8f5238ca + + diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs index 6bb208ea..0fea1a28 100644 --- a/QueryBuilder/Compilers/Compiler.cs +++ b/QueryBuilder/Compilers/Compiler.cs @@ -32,13 +32,13 @@ protected Compiler() /// /// Whether the compiler supports the `SELECT ... FILTER` syntax /// - /// + /// public virtual bool SupportsFilterClause { get; set; } = false; /// /// If true the compiler will remove the SELECT clause for the query used inside WHERE EXISTS /// - /// + /// public virtual bool OmitSelectInsideExists { get; set; } = true; protected virtual string SingleRowDummyTableName { get => null; } @@ -229,7 +229,7 @@ protected virtual SqlResult CompileSelectQuery(Query query) protected virtual SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) { - var ctx = new SqlResult(); + var ctx = new SqlResult(parameterPlaceholder, EscapeCharacter); var row = "SELECT " + string.Join(", ", adHoc.Columns.Select(col => $"{parameterPlaceholder} AS {Wrap(col)}")); @@ -295,7 +295,7 @@ protected virtual SqlResult CompileDeleteQuery(Query query) } else { - // check if we have alias + // check if we have alias if (fromClause is FromClause && !string.IsNullOrEmpty(fromClause.Alias)) { ctx.RawSql = $"DELETE {Wrap(fromClause.Alias)} FROM {table} {joins}{where}"; diff --git a/QueryBuilder/Compilers/SqlServerCompiler.cs b/QueryBuilder/Compilers/SqlServerCompiler.cs index a1b7da55..98b488bf 100644 --- a/QueryBuilder/Compilers/SqlServerCompiler.cs +++ b/QueryBuilder/Compilers/SqlServerCompiler.cs @@ -173,7 +173,7 @@ protected override string CompileBasicDateCondition(SqlResult ctx, BasicDateCond protected override SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) { - var ctx = new SqlResult(); + var ctx = new SqlResult(parameterPlaceholder, EscapeCharacter); var colNames = string.Join(", ", adHoc.Columns.Select(Wrap)); From 4e748e1a117342c4d4ae817dc2bb3c3c62d8616e Mon Sep 17 00:00:00 2001 From: faddiv Date: Fri, 29 Nov 2024 20:37:13 +0100 Subject: [PATCH 02/27] Testing improvement: Eliminate direct testing of CompileLimit --- QueryBuilder.Tests/MySql/MySqlLimitTests.cs | 16 +++---- .../Oracle/OracleLegacyLimitTests.cs | 20 ++++---- QueryBuilder.Tests/Oracle/OracleLimitTests.cs | 30 +++++++----- .../PostgreSql/PostgreSqlLimitTests.cs | 28 +++++++---- .../SqlServer/SqlServerLegacyLimitTests.cs | 47 ++++++++++++++----- .../SqlServer/SqlServerLimitTests.cs | 18 ++++--- QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs | 28 +++++++---- 7 files changed, 121 insertions(+), 66 deletions(-) diff --git a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs index 3e22c19a..9d5f0874 100644 --- a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs +++ b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs @@ -17,18 +17,18 @@ public MySqlLimitTests() public void WithNoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult("?", "\\") {Query = query}; + var ctx = compiler.Compile(query); - Assert.Null(compiler.CompileLimit(ctx)); + Assert.Equal("SELECT * FROM `Table`", ctx.RawSql); } [Fact] public void WithNoOffset() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult("?", "\\") {Query = query}; + var ctx = compiler.Compile(query); - Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx)); + Assert.Equal("SELECT * FROM `Table` LIMIT ?", ctx.RawSql); Assert.Equal(10, ctx.Bindings[0]); } @@ -36,9 +36,9 @@ public void WithNoOffset() public void WithNoLimit() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; + var ctx = compiler.Compile(query); - Assert.Equal("LIMIT 18446744073709551615 OFFSET ?", compiler.CompileLimit(ctx)); + Assert.Equal("SELECT * FROM `Table` LIMIT 18446744073709551615 OFFSET ?", ctx.RawSql); Assert.Equal(20L, ctx.Bindings[0]); Assert.Single(ctx.Bindings); } @@ -47,9 +47,9 @@ public void WithNoLimit() public void WithLimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; + var ctx = compiler.Compile(query); - Assert.Equal("LIMIT ? OFFSET ?", compiler.CompileLimit(ctx)); + Assert.Equal("SELECT * FROM `Table` LIMIT ? OFFSET ?", ctx.RawSql); Assert.Equal(5, ctx.Bindings[0]); Assert.Equal(20L, ctx.Bindings[1]); Assert.Equal(2, ctx.Bindings.Count); diff --git a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs index 47a233dd..299c71ef 100644 --- a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs @@ -21,13 +21,12 @@ public void WithNoLimitNorOffset() { // Arrange: var query = new Query(TableName); - var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder }; // Act: - compiler.ApplyLegacyLimit(ctx); + var ctx = compiler.Compile(query); // Assert: - Assert.Equal(SqlPlaceholder, ctx.RawSql); + Assert.Equal("SELECT * FROM \"Table\"", ctx.RawSql); } [Fact] @@ -35,13 +34,12 @@ public void WithNoOffset() { // Arrange: var query = new Query(TableName).Limit(10); - var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder }; // Act: - compiler.ApplyLegacyLimit(ctx); + var ctx = compiler.Compile(query); // Assert: - Assert.Matches($"SELECT \\* FROM \\({SqlPlaceholder}\\) WHERE ROWNUM <= ?", ctx.RawSql); + Assert.Equal("SELECT * FROM (SELECT * FROM \"Table\") WHERE ROWNUM <= ?", ctx.RawSql); Assert.Equal(10, ctx.Bindings[0]); Assert.Single(ctx.Bindings); } @@ -51,13 +49,12 @@ public void WithNoLimit() { // Arrange: var query = new Query(TableName).Offset(20); - var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder }; // Act: - compiler.ApplyLegacyLimit(ctx); + var ctx = compiler.Compile(query); // Assert: - Assert.Equal("SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM (GENERATED_SQL) \"results_wrapper\") WHERE \"row_num\" > ?", ctx.RawSql); + Assert.Equal("SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM (SELECT * FROM \"Table\") \"results_wrapper\") WHERE \"row_num\" > ?", ctx.RawSql); Assert.Equal(20L, ctx.Bindings[0]); Assert.Single(ctx.Bindings); } @@ -67,13 +64,12 @@ public void WithLimitAndOffset() { // Arrange: var query = new Query(TableName).Limit(5).Offset(20); - var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder }; // Act: - compiler.ApplyLegacyLimit(ctx); + var ctx = compiler.Compile(query); // Assert: - Assert.Equal("SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM (GENERATED_SQL) \"results_wrapper\" WHERE ROWNUM <= ?) WHERE \"row_num\" > ?", ctx.RawSql); + Assert.Equal("SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM (SELECT * FROM \"Table\") \"results_wrapper\" WHERE ROWNUM <= ?) WHERE \"row_num\" > ?", ctx.RawSql); Assert.Equal(25L, ctx.Bindings[0]); Assert.Equal(20L, ctx.Bindings[1]); Assert.Equal(2, ctx.Bindings.Count); diff --git a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs index 9701705c..0a8ca969 100644 --- a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs @@ -21,10 +21,12 @@ public void NoLimitNorOffset() { // Arrange: var query = new Query(TableName); - var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder }; - // Act & Assert: - Assert.Null(compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\"", ctx.RawSql); } [Fact] @@ -32,10 +34,12 @@ public void LimitOnly() { // Arrange: var query = new Query(TableName).Limit(10); - var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder }; - // Act & Assert: - Assert.EndsWith("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\" ORDER BY (SELECT 0 FROM DUAL) OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", ctx.RawSql); Assert.Equal(2, ctx.Bindings.Count); Assert.Equal(0L, ctx.Bindings[0]); Assert.Equal(10, ctx.Bindings[1]); @@ -46,11 +50,12 @@ public void OffsetOnly() { // Arrange: var query = new Query(TableName).Offset(20); - var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder }; - // Act & Assert: - Assert.EndsWith("OFFSET ? ROWS", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + // Assert: + Assert.Equal("SELECT * FROM \"Table\" ORDER BY (SELECT 0 FROM DUAL) OFFSET ? ROWS", ctx.RawSql); Assert.Single(ctx.Bindings); Assert.Equal(20L, ctx.Bindings[0]); } @@ -60,11 +65,12 @@ public void LimitAndOffset() { // Arrange: var query = new Query(TableName).Limit(5).Offset(20); - var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder }; - // Act & Assert: - Assert.EndsWith("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + // Assert: + Assert.Equal("SELECT * FROM \"Table\" ORDER BY (SELECT 0 FROM DUAL) OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", ctx.RawSql); Assert.Equal(2, ctx.Bindings.Count); Assert.Equal(20L, ctx.Bindings[0]); Assert.Equal(5, ctx.Bindings[1]); diff --git a/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs b/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs index 169fb99d..41859e6e 100644 --- a/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs +++ b/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs @@ -17,18 +17,24 @@ public PostgreSqlLimitTests() public void WithNoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\"", ctx.RawSql); } [Fact] public void WithNoOffset() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\" LIMIT ?", ctx.RawSql); Assert.Equal(10, ctx.Bindings[0]); } @@ -36,9 +42,12 @@ public void WithNoOffset() public void WithNoLimit() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Equal("OFFSET ?", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\" OFFSET ?", ctx.RawSql); Assert.Equal(20L, ctx.Bindings[0]); Assert.Single(ctx.Bindings); } @@ -47,9 +56,12 @@ public void WithNoLimit() public void WithLimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Equal("LIMIT ? OFFSET ?", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\" LIMIT ? OFFSET ?", ctx.RawSql); Assert.Equal(5, ctx.Bindings[0]); Assert.Equal(20L, ctx.Bindings[1]); Assert.Equal(2, ctx.Bindings.Count); diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs index 1cc58060..20e013bd 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs @@ -18,36 +18,53 @@ public SqlServerLegacyLimitTests() public void NoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM [Table]", ctx.RawSql); } [Fact] public void LimitOnly() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT TOP (?) * FROM [Table]", ctx.RawSql); } [Fact] public void OffsetOnly() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Table]) AS [results_wrapper] WHERE [row_num] >= ?", ctx.RawSql); + Assert.Single(ctx.Bindings); + Assert.Equal(21L, ctx.Bindings[0]); } [Fact] public void LimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Table]) AS [results_wrapper] WHERE [row_num] BETWEEN ? AND ?", ctx.RawSql); + Assert.Collection(ctx.Bindings, + e => Assert.Equal(21L, e), + e => Assert.Equal(25L, e)); } [Fact] @@ -55,7 +72,9 @@ public void ShouldEmulateOrderByIfNoOrderByProvided() { var query = new Query("Table").Limit(5).Offset(20); - Assert.Contains("ORDER BY (SELECT 0)", compiler.Compile(query).ToString()); + var ctx = compiler.Compile(query); + + Assert.Contains("ORDER BY (SELECT 0)", ctx.ToString()); } [Fact] @@ -63,7 +82,9 @@ public void ShouldKeepTheOrdersAsIsIfNoPaginationProvided() { var query = new Query("Table").OrderBy("Id"); - Assert.Contains("ORDER BY [Id]", compiler.Compile(query).ToString()); + var ctx = compiler.Compile(query); + + Assert.Contains("ORDER BY [Id]", ctx.ToString()); } [Fact] @@ -71,8 +92,10 @@ public void ShouldKeepTheOrdersAsIsIfPaginationProvided() { var query = new Query("Table").Offset(10).Limit(20).OrderBy("Id"); - Assert.Contains("ORDER BY [Id]", compiler.Compile(query).ToString()); - Assert.DoesNotContain("(SELECT 0)", compiler.Compile(query).ToString()); + var sqlResult = compiler.Compile(query); + + Assert.Contains("ORDER BY [Id]", sqlResult.ToString()); + Assert.DoesNotContain("(SELECT 0)", sqlResult.ToString()); } } } diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs index e6fa416b..44e67b89 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs @@ -51,10 +51,10 @@ public void OffsetOnly() public void LimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.EndsWith("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", compiler.CompileLimit(ctx)); + var ctx = compiler.Compile(query); + Assert.Equal("SELECT * FROM [Table] ORDER BY (SELECT 0) OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", ctx.RawSql); Assert.Equal(2, ctx.Bindings.Count); Assert.Equal(20L, ctx.Bindings[0]); Assert.Equal(5, ctx.Bindings[1]); @@ -65,7 +65,9 @@ public void ShouldEmulateOrderByIfNoOrderByProvided() { var query = new Query("Table").Limit(5).Offset(20); - Assert.Contains("ORDER BY (SELECT 0)", compiler.Compile(query).ToString()); + var sqlResult = compiler.Compile(query); + + Assert.Contains("ORDER BY (SELECT 0)", sqlResult.ToString()); } [Fact] @@ -73,7 +75,9 @@ public void ShouldKeepTheOrdersAsIsIfNoPaginationProvided() { var query = new Query("Table").OrderBy("Id"); - Assert.Contains("ORDER BY [Id]", compiler.Compile(query).ToString()); + var sqlResult = compiler.Compile(query); + + Assert.Contains("ORDER BY [Id]", sqlResult.ToString()); } [Fact] @@ -81,8 +85,10 @@ public void ShouldKeepTheOrdersAsIsIfPaginationProvided() { var query = new Query("Table").Offset(10).Limit(20).OrderBy("Id"); - Assert.Contains("ORDER BY [Id]", compiler.Compile(query).ToString()); - Assert.DoesNotContain("(SELECT 0)", compiler.Compile(query).ToString()); + var sqlResult = compiler.Compile(query); + + Assert.Contains("ORDER BY [Id]", sqlResult.ToString()); + Assert.DoesNotContain("(SELECT 0)", sqlResult.ToString()); } } } diff --git a/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs b/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs index 837a6654..421bca27 100644 --- a/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs +++ b/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs @@ -17,18 +17,24 @@ public SqliteLimitTests() public void WithNoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult("?", "\\") { Query = query }; - Assert.Null(compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\"", ctx.RawSql); } [Fact] public void WithNoOffset() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult("?", "\\") { Query = query }; - Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\" LIMIT ?", ctx.RawSql); Assert.Equal(10, ctx.Bindings[0]); } @@ -36,9 +42,12 @@ public void WithNoOffset() public void WithNoLimit() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult("?", "\\") { Query = query }; - Assert.Equal("LIMIT -1 OFFSET ?", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\" LIMIT -1 OFFSET ?", ctx.RawSql); Assert.Equal(20L, ctx.Bindings[0]); Assert.Single(ctx.Bindings); } @@ -47,9 +56,12 @@ public void WithNoLimit() public void WithLimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult("?", "\\") { Query = query }; - Assert.Equal("LIMIT ? OFFSET ?", compiler.CompileLimit(ctx)); + // Act + var ctx = compiler.Compile(query); + + // Assert: + Assert.Equal("SELECT * FROM \"Table\" LIMIT ? OFFSET ?", ctx.RawSql); Assert.Equal(5, ctx.Bindings[0]); Assert.Equal(20L, ctx.Bindings[1]); Assert.Equal(2, ctx.Bindings.Count); From 7d23e22015983daac9cf4c1c721f80de1413a4dc Mon Sep 17 00:00:00 2001 From: faddiv Date: Sat, 30 Nov 2024 12:48:24 +0100 Subject: [PATCH 03/27] Improved Delete tests --- QueryBuilder.Tests/DeleteTests.cs | 74 ++++++++++++++----- .../Infrastructure/TestCompilersContainer.cs | 4 +- .../Infrastructure/TestSupport.cs | 6 ++ 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/QueryBuilder.Tests/DeleteTests.cs b/QueryBuilder.Tests/DeleteTests.cs index 14fd4043..c9765bd7 100644 --- a/QueryBuilder.Tests/DeleteTests.cs +++ b/QueryBuilder.Tests/DeleteTests.cs @@ -1,49 +1,87 @@ using SqlKata.Compilers; -using SqlKata.Extensions; using SqlKata.Tests.Infrastructure; -using System; -using System.Linq; using Xunit; namespace SqlKata.Tests { public class DeleteTests : TestSupport { - [Fact] - public void BasicDelete() + [Theory] + [InlineData(EngineCodes.SqlServer, "DELETE FROM [Posts]")] + [InlineData(EngineCodes.Oracle, "DELETE FROM \"Posts\"")] + [InlineData(EngineCodes.PostgreSql, "DELETE FROM \"Posts\"")] + [InlineData(EngineCodes.MySql, "DELETE FROM `Posts`")] + [InlineData(EngineCodes.Firebird, "DELETE FROM \"POSTS\"")] + [InlineData(EngineCodes.Sqlite, "DELETE FROM \"Posts\"")] + public void BasicDelete(string engine, string query) { var q = new Query("Posts").AsDelete(); - var c = Compile(q); + var c = CompileFor(engine, q); - Assert.Equal("DELETE FROM [Posts]", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void DeleteWithJoin() + [Theory] + [InlineData(EngineCodes.SqlServer, + "DELETE [Posts] FROM [Posts] \n" + + "INNER JOIN [Authors] ON [Authors].[Id] = [Posts].[AuthorId] WHERE [Authors].[Id] = 5")] + [InlineData(EngineCodes.Oracle, + "DELETE \"Posts\" FROM \"Posts\" \n" + + "INNER JOIN \"Authors\" ON \"Authors\".\"Id\" = \"Posts\".\"AuthorId\" WHERE \"Authors\".\"Id\" = 5")] + [InlineData(EngineCodes.PostgreSql, + "DELETE \"Posts\" FROM \"Posts\" \n" + + "INNER JOIN \"Authors\" ON \"Authors\".\"Id\" = \"Posts\".\"AuthorId\" WHERE \"Authors\".\"Id\" = 5")] + [InlineData(EngineCodes.MySql, + "DELETE `Posts` FROM `Posts` \n" + + "INNER JOIN `Authors` ON `Authors`.`Id` = `Posts`.`AuthorId` WHERE `Authors`.`Id` = 5")] + [InlineData(EngineCodes.Firebird, + "DELETE \"POSTS\" FROM \"POSTS\" \n" + + "INNER JOIN \"AUTHORS\" ON \"AUTHORS\".\"ID\" = \"POSTS\".\"AUTHORID\" WHERE \"AUTHORS\".\"ID\" = 5")] + [InlineData(EngineCodes.Sqlite, + "DELETE \"Posts\" FROM \"Posts\" \n" + + "INNER JOIN \"Authors\" ON \"Authors\".\"Id\" = \"Posts\".\"AuthorId\" WHERE \"Authors\".\"Id\" = 5")] + public void DeleteWithJoin(string engine, string query) { var q = new Query("Posts") .Join("Authors", "Authors.Id", "Posts.AuthorId") .Where("Authors.Id", 5) .AsDelete(); - var c = Compile(q); + var c = CompileFor(engine, q); - Assert.Equal("DELETE [Posts] FROM [Posts] \nINNER JOIN [Authors] ON [Authors].[Id] = [Posts].[AuthorId] WHERE [Authors].[Id] = 5", c[EngineCodes.SqlServer]); - Assert.Equal("DELETE `Posts` FROM `Posts` \nINNER JOIN `Authors` ON `Authors`.`Id` = `Posts`.`AuthorId` WHERE `Authors`.`Id` = 5", c[EngineCodes.MySql]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void DeleteWithJoinAndAlias() + [Theory] + [InlineData(EngineCodes.SqlServer, + "DELETE [P] FROM [Posts] AS [P] \n" + + "INNER JOIN [Authors] AS [A] ON [A].[Id] = [P].[AuthorId] WHERE [A].[Id] = 5")] + [InlineData(EngineCodes.Oracle, + "DELETE \"P\" FROM \"Posts\" \"P\" \n" + + "INNER JOIN \"Authors\" \"A\" ON \"A\".\"Id\" = \"P\".\"AuthorId\" WHERE \"A\".\"Id\" = 5")] + [InlineData(EngineCodes.PostgreSql, + "DELETE \"P\" FROM \"Posts\" AS \"P\" \n" + + "INNER JOIN \"Authors\" AS \"A\" ON \"A\".\"Id\" = \"P\".\"AuthorId\" WHERE \"A\".\"Id\" = 5")] + [InlineData(EngineCodes.MySql, + "DELETE `P` FROM `Posts` AS `P` \n" + + "INNER JOIN `Authors` AS `A` ON `A`.`Id` = `P`.`AuthorId` WHERE `A`.`Id` = 5")] + [InlineData(EngineCodes.Firebird, + "DELETE \"P\" FROM \"POSTS\" AS \"P\" \n" + + "INNER JOIN \"AUTHORS\" AS \"A\" ON \"A\".\"ID\" = \"P\".\"AUTHORID\" WHERE \"A\".\"ID\" = 5")] + [InlineData(EngineCodes.Sqlite, + "DELETE \"P\" FROM \"Posts\" AS \"P\" \n" + + "INNER JOIN \"Authors\" AS \"A\" ON \"A\".\"Id\" = \"P\".\"AuthorId\" WHERE \"A\".\"Id\" = 5")] + public void DeleteWithJoinAndAlias(string engine, string query) { var q = new Query("Posts as P") - .Join("Authors", "Authors.Id", "P.AuthorId") - .Where("Authors.Id", 5) + .Join("Authors as A", "A.Id", "P.AuthorId") + .Where("A.Id", 5) .AsDelete(); - var c = Compile(q); + var c = CompileFor(engine, q); - Assert.Equal("DELETE [P] FROM [Posts] AS [P] \nINNER JOIN [Authors] ON [Authors].[Id] = [P].[AuthorId] WHERE [Authors].[Id] = 5", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } } } diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs b/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs index 2312a192..3b00e8c3 100644 --- a/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs +++ b/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs @@ -38,12 +38,12 @@ public IEnumerable KnownEngineCodes /// public Compiler Get(string engineCode) { - if (!Compilers.ContainsKey(engineCode)) + if (!Compilers.TryGetValue(engineCode, out var compiler)) { throw new InvalidOperationException(string.Format(Messages.ERR_INVALID_ENGINECODE, engineCode)); } - return Compilers[engineCode]; + return compiler; } /// diff --git a/QueryBuilder.Tests/Infrastructure/TestSupport.cs b/QueryBuilder.Tests/Infrastructure/TestSupport.cs index 78d912cc..d2fc2905 100644 --- a/QueryBuilder.Tests/Infrastructure/TestSupport.cs +++ b/QueryBuilder.Tests/Infrastructure/TestSupport.cs @@ -16,5 +16,11 @@ protected IReadOnlyDictionary Compile(Query query) { return Compilers.Compile(query).ToDictionary(s => s.Key, v => v.Value.ToString()); } + + protected SqlResult CompileFor(string engine, Query query) + { + return Compilers.CompileFor(engine, query); + } + } } From d3355a163069f44f96d50cfd2d947601acf9d015 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sat, 30 Nov 2024 13:10:22 +0100 Subject: [PATCH 04/27] Improved ExecutionTests --- QueryBuilder.Tests/ExecutionTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/QueryBuilder.Tests/ExecutionTests.cs b/QueryBuilder.Tests/ExecutionTests.cs index 5d41e7fd..a726a1c9 100644 --- a/QueryBuilder.Tests/ExecutionTests.cs +++ b/QueryBuilder.Tests/ExecutionTests.cs @@ -7,7 +7,7 @@ namespace SqlKata.Tests public class ExecutionTests { [Fact] - public void ShouldThrowException() + public void Get_WhenWasNotCalledOnXQuery_ShouldThrowException() { Assert.Throws(() => { @@ -23,8 +23,8 @@ public void TimeoutShouldBeCarriedToNewCreatedFactory() var newFactory = QueryExtensions.CreateQueryFactory(db.Query()); Assert.Equal(db.QueryTimeout, newFactory.QueryTimeout); } - - [Fact(Skip = "timeout over cloned xQuery is not supported yet")] + + [Fact] public void TimeoutShouldBeCarriedToNewCreatedFactoryAfterClone() { var db = new QueryFactory(); From e9df38e39492a3b358aea237754b4399fead4646 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sat, 30 Nov 2024 15:16:02 +0100 Subject: [PATCH 05/27] Refactor DefineTest --- QueryBuilder.Tests/DefineTest.cs | 476 +++++++++++++++---------------- 1 file changed, 236 insertions(+), 240 deletions(-) diff --git a/QueryBuilder.Tests/DefineTest.cs b/QueryBuilder.Tests/DefineTest.cs index 0b5ff292..13ee3e82 100644 --- a/QueryBuilder.Tests/DefineTest.cs +++ b/QueryBuilder.Tests/DefineTest.cs @@ -10,24 +10,25 @@ namespace SqlKata.Tests /// public class DefineTest : TestSupport { - - [Fact] - public void Test_Define_Where() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Products] WHERE [ProductName] = 'Anto'")] + public void Test_Define_Where(string engine, string sqlText) { var query = new Query("Products") - .Define("@name", "Anto") - .Where("ProductName", Variable("@name")); - - var c = Compile(query); + .Define("@name", "Anto") + .Where("ProductName", Variable("@name")); - Assert.Equal("SELECT * FROM [Products] WHERE [ProductName] = 'Anto'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Test_Define_SubQuery() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT * FROM [Products] WHERE [unitprice] > (SELECT AVG([unitprice]) AS [avg] FROM [Products] WHERE [UnitsInStock] > 10) AND [UnitsOnOrder] > 5")] + public void Test_Define_SubQuery(string engine, string sqlText) { - var subquery = new Query("Products") .AsAverage("unitprice") .Define("@UnitsInSt", 10) @@ -37,142 +38,134 @@ public void Test_Define_SubQuery() .Where("unitprice", ">", subquery) .Where("UnitsOnOrder", ">", 5); - var c = Compile(query); - - Assert.Equal("SELECT * FROM [Products] WHERE [unitprice] > (SELECT AVG([unitprice]) AS [avg] FROM [Products] WHERE [UnitsInStock] > 10) AND [UnitsOnOrder] > 5", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Test_Define_WhereEnds() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ProductId], [ProductName] FROM [Products] WHERE LOWER([ProductName]) like '%coffee'", + false)] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ProductId], [ProductName] FROM [Products] WHERE [ProductName] like '%Coffee'", + true)] + public void Test_Define_WhereEnds(string engine, string sqlText, bool caseSensitive) { - - var query1 = new Query("Products") - .Select("ProductId") - .Define("@product", "Coffee") - .WhereEnds("ProductName", Variable("@product")); - - - var query2 = new Query("Products") + var query = new Query("Products") .Select("ProductId", "ProductName") .Define("@product", "Coffee") - .WhereEnds("ProductName", Variable("@product"), true); - - var c1 = Compile(query1); - var c2 = Compile(query2); - - Assert.Equal("SELECT [ProductId] FROM [Products] WHERE LOWER([ProductName]) like '%coffee'", c1[EngineCodes.SqlServer]); + .WhereEnds("ProductName", Variable("@product"), caseSensitive); - Assert.Equal("SELECT [ProductId], [ProductName] FROM [Products] WHERE [ProductName] like '%Coffee'", c2[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void Test_Define_WhereStarts() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE LOWER([QuantityPerUnit]) like '12%'", + false)] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE [QuantityPerUnit] like '12%'", + true)] + public void Test_Define_WhereStarts(string engine, string sqlText, bool caseSensitive) { + var query = new Query("Products") + .Select("ProductId", "QuantityPerUnit") + .Define("@perUnit", "12") + .WhereStarts("QuantityPerUnit", Variable("@perUnit"), caseSensitive); + var c = CompileFor(engine, query); - var query1 = new Query("Products") - .Select("ProductId", "QuantityPerUnit") - .Define("@perUnit", "12") - .WhereStarts("QuantityPerUnit", Variable("@perUnit")); - - - var query2 = new Query("Products") - .Select("ProductId", "QuantityPerUnit") - .Define("@perUnit", "12") - .WhereStarts("QuantityPerUnit", Variable("@perUnit"), true); - - var c1 = Compile(query1); - var c2 = Compile(query2); - - Assert.Equal("SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE LOWER([QuantityPerUnit]) like '12%'", c1[EngineCodes.SqlServer]); - Assert.Equal("SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE [QuantityPerUnit] like '12%'", c2[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void Test_Define_WhereContains() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE LOWER([QuantityPerUnit]) like '%500%'", + false)] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE [QuantityPerUnit] like '%500%'", + true)] + public void Test_Define_WhereContains(string engine, string sqlText, bool caseSensitive) { - - var query1 = new Query("Products") - .Define("@perUnit", "500") - .Select("ProductId", "QuantityPerUnit") - .WhereContains("QuantityPerUnit", Variable("@perUnit")); - - - var query2 = new Query("Products") + var query = new Query("Products") .Define("@perUnit", "500") .Select("ProductId", "QuantityPerUnit") - .WhereContains("QuantityPerUnit", Variable("@perUnit"), true); - - var c1 = Compile(query1); - var c2 = Compile(query2); + .WhereContains("QuantityPerUnit", Variable("@perUnit"), caseSensitive); - Assert.Equal("SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE LOWER([QuantityPerUnit]) like '%500%'", c1[EngineCodes.SqlServer]); - Assert.Equal("SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE [QuantityPerUnit] like '%500%'", c2[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void Test_Define_WhereLike() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ProductId], [ProductName], [SupplierID] FROM [Products] WHERE LOWER([SupplierID]) like '20'", + false)] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ProductId], [ProductName], [SupplierID] FROM [Products] WHERE [SupplierID] like '20'", + true)] + public void Test_Define_WhereLike(string engine, string sqlText, bool caseSensitive) { - var query1 = new Query("Products") - .Select("ProductId", "ProductName", "SupplierID") - .Define("@id", "20") - .WhereLike("SupplierID", Variable("@id")); - - - var query2 = new Query("Products") + var query = new Query("Products") .Select("ProductId", "ProductName", "SupplierID") .Define("@id", "20") - .WhereLike("SupplierID", Variable("@id"), true); - - var c1 = Compile(query1); - var c2 = Compile(query2); + .WhereLike("SupplierID", Variable("@id"), caseSensitive); - Assert.Equal("SELECT [ProductId], [ProductName], [SupplierID] FROM [Products] WHERE LOWER([SupplierID]) like '20'", c1[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal("SELECT [ProductId], [ProductName], [SupplierID] FROM [Products] WHERE [SupplierID] like '20'", c2[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void Test_Define_WhereInSubquery() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT [ShipperID], [CompanyName] FROM [Shippers] WHERE [ShipperID] IN (SELECT [ShipVia] FROM [Orders] WHERE [ShipVia] = 3)")] + public void Test_Define_WhereInSubquery(string engine, string sqlText) { - var subquery = new Query("Orders") - .Define("@shipId", 3) - .Select("ShipVia").Where("ShipVia", Variable("@shipId")); + .Define("@shipId", 3) + .Select("ShipVia").Where("ShipVia", Variable("@shipId")); var query1 = new Query("Shippers") - .Select("ShipperID", "CompanyName") - .WhereIn("ShipperID", subquery); + .Select("ShipperID", "CompanyName") + .WhereIn("ShipperID", subquery); - var c1 = Compile(query1); + var c1 = CompileFor(engine, query1); - Assert.Equal("SELECT [ShipperID], [CompanyName] FROM [Shippers] WHERE [ShipperID] IN (SELECT [ShipVia] FROM [Orders] WHERE [ShipVia] = 3)", c1[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c1.ToString()); } - [Fact] - public void Test_Define_Having() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] HAVING [Id] = 1")] + public void Test_Define_Having(string engine, string sqlText) { - var c = Compile(new Query("Table") + var query = new Query("Table") .Define("@foo", 1) - .Having("Id", "=", Variable("@foo"))); + .Having("Id", "=", Variable("@foo")); + + var c1 = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [Table] HAVING [Id] = 1", c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c1.ToString()); } - /* - [Fact] - public void Test_Define_HavingRaw() + [Theory(Skip = "Not implemented")] + [InlineData(EngineCodes.SqlServer, "SELECT [Employees].[LastName], COUNT(Orders.OrderID) AS NumberOfOrders FROM [Orders] \nINNER JOIN [Employees] ON [Employees].[EmployeeID] = [Orders].[EmployeeID] GROUP BY [LastName] HAVING COUNT(Orders.OrderID) > 80")] + public void Test_Define_HavingRaw(string engine, string sqlText) { var query1 = new Query("Orders") .Define("@count", 80) @@ -182,87 +175,88 @@ public void Test_Define_HavingRaw() .GroupBy("LastName") .HavingRaw("COUNT(Orders.OrderID) > @count"); - var c = Compile(query1); + var c = CompileFor(engine, query1); - Assert.Equal("SELECT [Employees].[LastName], COUNT(Orders.OrderID) AS NumberOfOrders FROM [Orders] \nINNER JOIN [Employees] ON [Employees].[EmployeeID] = [Orders].[EmployeeID] GROUP BY [LastName] HAVING COUNT(Orders.OrderID) > 80", c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - */ - [Fact] - public void Test_Define_HavingStarts() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like 'u%'")] + public void Test_Define_HavingStarts(string engine, string sqlText) { - var query = new Query("Customers") - .Define("@label", "U") - .SelectRaw("COUNT(CustomerID)") - .Select("Country") - .GroupBy("Country") - .HavingStarts("Country", Variable("@label")); - - var c = Compile(query); + .Define("@label", "U") + .SelectRaw("COUNT(CustomerID)") + .Select("Country") + .GroupBy("Country") + .HavingStarts("Country", Variable("@label")); - Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like 'u%'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal( + sqlText, + c.ToString()); } - - - [Fact] - public void Test_Define_Having_Ends() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d'")] + public void Test_Define_Having_Ends(string engine, string sqlText) { var query = new Query("Customers") - .Define("@label", "d") - .SelectRaw("COUNT(CustomerID)") - .Select("Country") - .GroupBy("Country") - .HavingEnds("Country", Variable("@label")); + .Define("@label", "d") + .SelectRaw("COUNT(CustomerID)") + .Select("Country") + .GroupBy("Country") + .HavingEnds("Country", Variable("@label")); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d'", c[EngineCodes.SqlServer]); + Assert.Equal( + sqlText, + c.ToString()); } - - [Fact] - public void Test_Define_Having_Contains() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d%'")] + public void Test_Define_Having_Contains(string engine, string sqlText) { - - var query = new Query("Customers") - .Define("@label", "d") - .SelectRaw("COUNT(CustomerID)") - .Select("Country") - .GroupBy("Country") - .HavingContains("Country", Variable("@label")); - - var c = Compile(query); + .Define("@label", "d") + .SelectRaw("COUNT(CustomerID)") + .Select("Country") + .GroupBy("Country") + .HavingContains("Country", Variable("@label")); - Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d%'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void Test_Define_NestedCondition() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT COUNT(*) AS [count] FROM [Orders] WHERE ([ShipRegion] != NULL)")] + public void Test_Define_NestedCondition(string engine, string sqlText) { var query = new Query("Orders") - .Define("@shipReg", null) - .Define("@one", 1) - .Where(q => - q.Where("ShipRegion", "!=", Variable("@shipReg")) - // .WhereRaw("1 = @one") + .Define("@shipReg", null) + .Define("@one", 1) + .Where(q => + q.Where("ShipRegion", "!=", Variable("@shipReg")) + // .WhereRaw("1 = @one") ).AsCount(); - var c = Compile(query); - - Assert.Equal("SELECT COUNT(*) AS [count] FROM [Orders] WHERE ([ShipRegion] != NULL)", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Test_Define_WhereDate() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Orders] WHERE CAST([RequiredDate] AS DATE) = '1996-08-01'")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Orders\" WHERE \"RequiredDate\"::date = '1996-08-01'")] + [InlineData(EngineCodes.Sqlite, "SELECT * FROM \"Orders\" WHERE strftime('%Y-%m-%d', \"RequiredDate\") = cast('1996-08-01' as text)")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"ORDERS\" WHERE CAST(\"REQUIREDDATE\" as DATE) = '1996-08-01'")] + public void Test_Define_WhereDate(string engine, string sqlText) { var dateObj = new System.DateTime(year: 1996, month: 8, day: 1); @@ -270,73 +264,74 @@ public void Test_Define_WhereDate() .Define("@d", dateObj) .WhereDate("RequiredDate", Variable("@d")); + var c = CompileFor(engine, query); - var query2 = new Query("Orders") + Assert.Equal(sqlText, c.ToString()); + } + + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Orders] WHERE DATEPART(YEAR, [RequiredDate]) = 1996")] + public void Test_Define_WhereDatePart(string engine, string sqlText) + { + var query = new Query("Orders") .Define("@d", 1996) .WhereDatePart("year", "RequiredDate", "=", Variable("@d")); - var query3 = new Query("Orders") - .Define("@d", "00:00:00") - .WhereTime("RequiredDate", "!=", Variable("@d")); - - var c = Compile(query); - var c2 = Compile(query2); - var c3 = Compile(query3); - - Assert.Equal("SELECT * FROM [Orders] WHERE CAST([RequiredDate] AS DATE) = '1996-08-01'", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM \"Orders\" WHERE \"RequiredDate\"::date = '1996-08-01'", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT * FROM \"Orders\" WHERE strftime('%Y-%m-%d', \"RequiredDate\") = cast('1996-08-01' as text)", c[EngineCodes.Sqlite]); - Assert.Equal("SELECT * FROM \"ORDERS\" WHERE CAST(\"REQUIREDDATE\" as DATE) = '1996-08-01'", c[EngineCodes.Firebird]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); + } + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Orders] WHERE CAST([RequiredDate] AS TIME) != '00:00:00'")] + public void Test_Define_WhereTime(string engine, string sqlText) + { + var query = new Query("Orders") + .Define("@d", "00:00:00") + .WhereTime("RequiredDate", "!=", Variable("@d")); - Assert.Equal("SELECT * FROM [Orders] WHERE DATEPART(YEAR, [RequiredDate]) = 1996", c2[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM [Orders] WHERE CAST([RequiredDate] AS TIME) != '00:00:00'", c3[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void Test_Define_WhereExists() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Customers] WHERE EXISTS (SELECT 1 FROM [Orders] WHERE [ShipPostalCode] = '8200')")] + public void Test_Define_WhereExists(string engine, string sqlText) { var query = new Query("Customers") .WhereExists(q => q.From("Orders") - .Define("@postal", "8200") - .Where("ShipPostalCode", Variable("@postal")) - ); - - var c = Compile(query); - Assert.Equal("SELECT * FROM [Customers] WHERE EXISTS (SELECT 1 FROM [Orders] WHERE [ShipPostalCode] = '8200')", c[EngineCodes.SqlServer]); - } + .Define("@postal", "8200") + .Where("ShipPostalCode", Variable("@postal")) + ); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); + } - [Fact] - public void Test_Define_With() + [Theory] + [InlineData(EngineCodes.SqlServer, "WITH [prodCTE] AS (SELECT [Categories].[CategoryName], [Products].[UnitPrice] FROM [Products] \nINNER JOIN [Categories] ON [Categories].[CategoryID] = [Products].[CategoryID] WHERE [Products].[UnitPrice] > 10)\nSELECT * FROM [prodCTE]")] + public void Test_Define_With(string engine, string sqlText) { - var query = new Query("Products") - .Define("@unit", 10) - .Join("Categories", "Categories.CategoryID", "Products.CategoryID") - .Select("Categories.CategoryName", "Products.UnitPrice") - .Where("Products.UnitPrice", ">", Variable("@unit")); + .Define("@unit", 10) + .Join("Categories", "Categories.CategoryID", "Products.CategoryID") + .Select("Categories.CategoryName", "Products.UnitPrice") + .Where("Products.UnitPrice", ">", Variable("@unit")); var queryCTe = new Query("prodCTE") - .With("prodCTE", query); - - var c = Compile(queryCTe); + .With("prodCTE", query); + var c = CompileFor(engine, queryCTe); - Assert.Equal("WITH [prodCTE] AS (SELECT [Categories].[CategoryName], [Products].[UnitPrice] FROM [Products] \nINNER JOIN [Categories] ON [Categories].[CategoryID] = [Products].[CategoryID] WHERE [Products].[UnitPrice] > 10)\nSELECT * FROM [prodCTE]", c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - - - /* - [Fact] - public void Test_Define_WithRaw() + [Theory(Skip = "not implemented")] + [InlineData(EngineCodes.SqlServer, "WITH [prodCTE] AS (SELECT c.CategoryName, p.UnitPrice FROM Products p INNER JOIN Categories c ON c.CategoryID = p.CategoryID WHERE p.UnitPrice > 10 AND 2 = 2)\nSELECT [CategoryName], [UnitPrice] FROM [prodCTE]")] + public void Test_Define_WithRaw(string engine, string sqlText) { - //WithRaw var query = new Query("prodCTE") .Define("@unit", 10) @@ -344,72 +339,74 @@ public void Test_Define_WithRaw() .Select("CategoryName", "UnitPrice") .WithRaw("prodCTE", "SELECT c.CategoryName, p.UnitPrice FROM Products p INNER JOIN Categories c ON c.CategoryID = p.CategoryID WHERE p.UnitPrice > @unit AND 2 = @foo"); - var c = Compile(query); - - Assert.Equal("WITH [prodCTE] AS (SELECT c.CategoryName, p.UnitPrice FROM Products p INNER JOIN Categories c ON c.CategoryID = p.CategoryID WHERE p.UnitPrice > 10 AND 2 = 2)\nSELECT [CategoryName], [UnitPrice] FROM [prodCTE]", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - */ - // - [Fact] - public void Test_Define_Union() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') UNION SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] + public void Test_Define_Union(string engine, string sqlText) { var q1 = new Query("Suppliers") - .Define("@foo", "Beirut") - .Select("City") - .Where("City", Variable("@foo")); + .Define("@foo", "Beirut") + .Select("City") + .Where("City", Variable("@foo")); var q2 = new Query("Customers") - .Define("@city", "Z") - .Select("City") - .Union(q1) - .WhereNotLike("City", Variable("@city")); + .Define("@city", "Z") + .Select("City") + .Union(q1) + .WhereNotLike("City", Variable("@city")); - var c = Compile(q2); - Assert.Equal("SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') UNION SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'", c[EngineCodes.SqlServer]); - } + var c = CompileFor(engine, q2); + Assert.Equal(sqlText, c.ToString()); + } - [Fact] - public void Test_Define_Except() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') EXCEPT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] + public void Test_Define_Except(string engine, string sqlText) { var q1 = new Query("Suppliers") - .Define("@foo", "Beirut") - .Select("City") - .Where("City", Variable("@foo")); + .Define("@foo", "Beirut") + .Select("City") + .Where("City", Variable("@foo")); var q2 = new Query("Customers") - .Define("@city", "Z") - .Select("City") - .Except(q1) - .WhereNotLike("City", Variable("@city")); + .Define("@city", "Z") + .Select("City") + .Except(q1) + .WhereNotLike("City", Variable("@city")); + + var c = CompileFor(engine, q2); - var c = Compile(q2); - Assert.Equal("SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') EXCEPT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'", c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Test_Define_Intersect() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') INTERSECT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] + public void Test_Define_Intersect(string engine, string sqlText) { var q1 = new Query("Suppliers") - .Define("@foo", "Beirut") - .Select("City") - .Where("City", Variable("@foo")); + .Define("@foo", "Beirut") + .Select("City") + .Where("City", Variable("@foo")); var q2 = new Query("Customers") - .Define("@city", "Z") - .Select("City") - .Intersect(q1) - .WhereNotLike("City", Variable("@city")); + .Define("@city", "Z") + .Select("City") + .Intersect(q1) + .WhereNotLike("City", Variable("@city")); + + var c = CompileFor(engine, q2); - var c = Compile(q2); - Assert.Equal("SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') INTERSECT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'", c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - /* - [Fact] - public void Test_Define_CombineRaw() + [Theory(Skip = "not implemented")] + [InlineData(EngineCodes.SqlServer, "SELECT [City] FROM [Customers] UNION ALL SELECT City FROM Suppliers WHERE 1 = 1 AND 2 = 2")] + public void Test_Define_CombineRaw(string engine, string sqlText) { var query = new Query("Customers") @@ -418,10 +415,9 @@ public void Test_Define_CombineRaw() .Select("City") .CombineRaw("UNION ALL SELECT City FROM Suppliers WHERE 1 = @foo AND 2 = @faa"); - var c = Compile(query); - Assert.Equal("SELECT [City] FROM [Customers] UNION ALL SELECT City FROM Suppliers WHERE 1 = 1 AND 2 = 2", c[EngineCodes.SqlServer]); - } - */ + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); + } } } From 3631797ae5dc09777795b9fa8951d940a038f531 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sat, 30 Nov 2024 22:02:15 +0100 Subject: [PATCH 06/27] Improved GeneralTests part 1 --- QueryBuilder.Tests/GeneralTests.cs | 110 ++++++++++++++++++----------- 1 file changed, 67 insertions(+), 43 deletions(-) diff --git a/QueryBuilder.Tests/GeneralTests.cs b/QueryBuilder.Tests/GeneralTests.cs index 63fb3d3f..d8767fe0 100644 --- a/QueryBuilder.Tests/GeneralTests.cs +++ b/QueryBuilder.Tests/GeneralTests.cs @@ -9,20 +9,29 @@ namespace SqlKata.Tests { public class GeneralTests : TestSupport { - [Fact] - public void ColumnsEscaping() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [mycol[isthis]]] FROM [users]")] + public void ColumnsEscaping(string engine, string sqlText) { - var q = new Query().From("users") + var query = new Query().From("users") .Select("mycol[isthis]"); - var c = Compile(q); + var c = CompileFor(engine, query); - Assert.Equal("SELECT [mycol[isthis]]] FROM [users]", c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void InnerScopeEngineWithinCTE() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "WITH [series] AS (SELECT * FROM [table] WHERE sqlsrv = 1)\nSELECT * FROM [series]")] + [InlineData( + EngineCodes.PostgreSql, + "WITH \"series\" AS (SELECT * FROM \"table\" WHERE postgres = true)\nSELECT * FROM \"series\"")] + [InlineData( + EngineCodes.Firebird, + "WITH \"SERIES\" AS (SELECT * FROM \"TABLE\" WHERE firebird = 1)\nSELECT * FROM \"SERIES\"")] + public void InnerScopeEngineWithinCTE(string engine, string sqlText) { var series = new Query("table") .ForPostgreSql(q => q.WhereRaw("postgres = true")) @@ -30,18 +39,22 @@ public void InnerScopeEngineWithinCTE() .ForFirebird(q => q.WhereRaw("firebird = 1")); var query = new Query("series").With("series", series); - var c = Compile(query); - - Assert.Equal("WITH [series] AS (SELECT * FROM [table] WHERE sqlsrv = 1)\nSELECT * FROM [series]", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal("WITH \"series\" AS (SELECT * FROM \"table\" WHERE postgres = true)\nSELECT * FROM \"series\"", - c[EngineCodes.PostgreSql]); - Assert.Equal("WITH \"SERIES\" AS (SELECT * FROM \"TABLE\" WHERE firebird = 1)\nSELECT * FROM \"SERIES\"", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InnerScopeEngineWithinSubQuery() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT * FROM (SELECT * FROM [table] WHERE sqlsrv = 1) AS [series]")] + [InlineData( + EngineCodes.PostgreSql, + "SELECT * FROM (SELECT * FROM \"table\" WHERE postgres = true) AS \"series\"")] + [InlineData( + EngineCodes.Firebird, + "SELECT * FROM (SELECT * FROM \"TABLE\" WHERE firebird = 1) AS \"SERIES\"")] + public void InnerScopeEngineWithinSubQuery(string engine, string sqlText) { var series = new Query("table") .ForPostgreSql(q => q.WhereRaw("postgres = true")) @@ -49,12 +62,9 @@ public void InnerScopeEngineWithinSubQuery() .ForFirebird(q => q.WhereRaw("firebird = 1")); var query = new Query("series").From(series.As("series")); - var c = Compile(query); - - Assert.Equal("SELECT * FROM (SELECT * FROM [table] WHERE sqlsrv = 1) AS [series]", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM (SELECT * FROM \"table\" WHERE postgres = true) AS \"series\"", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT * FROM (SELECT * FROM \"TABLE\" WHERE firebird = 1) AS \"SERIES\"", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -99,8 +109,20 @@ public void Custom_compiler_with_empty_identifier_overrides_should_remove_identi Assert.Equal("Table", wrappedValue); } - [Fact] - public void Should_Equal_AfterMultipleCompile() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT * FROM (SELECT [Id], [Name], ROW_NUMBER() OVER (ORDER BY [Name]) AS [row_num] FROM [Table]) AS [results_wrapper] WHERE [row_num] BETWEEN 2 AND 21")] + [InlineData( + EngineCodes.MySql, + "SELECT `Id`, `Name` FROM `Table` ORDER BY `Name` LIMIT 20 OFFSET 1")] + [InlineData( + EngineCodes.PostgreSql, + "SELECT \"Id\", \"Name\" FROM \"Table\" ORDER BY \"Name\" LIMIT 20 OFFSET 1")] + [InlineData( + EngineCodes.Firebird, + "SELECT \"ID\", \"NAME\" FROM \"TABLE\" ORDER BY \"NAME\" ROWS 2 TO 21")] + public void Should_Equal_AfterMultipleCompile(string engine, string sqlText) { var query = new Query() .Select("Id", "Name") @@ -109,33 +131,35 @@ public void Should_Equal_AfterMultipleCompile() .Limit(20) .Offset(1); - var first = Compile(query); - Assert.Equal( - "SELECT * FROM (SELECT [Id], [Name], ROW_NUMBER() OVER (ORDER BY [Name]) AS [row_num] FROM [Table]) AS [results_wrapper] WHERE [row_num] BETWEEN 2 AND 21", - first[EngineCodes.SqlServer]); - Assert.Equal("SELECT `Id`, `Name` FROM `Table` ORDER BY `Name` LIMIT 20 OFFSET 1", first[EngineCodes.MySql]); - Assert.Equal("SELECT \"Id\", \"Name\" FROM \"Table\" ORDER BY \"Name\" LIMIT 20 OFFSET 1", first[EngineCodes.PostgreSql]); - Assert.Equal("SELECT \"ID\", \"NAME\" FROM \"TABLE\" ORDER BY \"NAME\" ROWS 2 TO 21", first[EngineCodes.Firebird]); + var first = CompileFor(engine, query); - var second = Compile(query); + Assert.Equal(sqlText, first.ToString()); - Assert.Equal(first[EngineCodes.SqlServer], second[EngineCodes.SqlServer]); - Assert.Equal(first[EngineCodes.MySql], second[EngineCodes.MySql]); - Assert.Equal(first[EngineCodes.PostgreSql], second[EngineCodes.PostgreSql]); - Assert.Equal(first[EngineCodes.Firebird], second[EngineCodes.Firebird]); + var second = CompileFor(engine, query); + + Assert.Equal(sqlText, second.ToString()); } - [Fact] - public void Raw_WrapIdentifiers() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT [Id], [Name], [Age] FROM [Users]")] + [InlineData( + EngineCodes.MySql, + "SELECT `Id`, `Name`, `Age` FROM `Users`")] + [InlineData( + EngineCodes.PostgreSql, + "SELECT \"Id\", \"Name\", \"Age\" FROM \"Users\"")] + [InlineData( + EngineCodes.Firebird, + "SELECT \"Id\", \"Name\", \"Age\" FROM \"USERS\"")] + public void Raw_WrapIdentifiers(string engine, string sqlText) { var query = new Query("Users").SelectRaw("[Id], [Name], {Age}"); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT [Id], [Name], [Age] FROM [Users]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT `Id`, `Name`, `Age` FROM `Users`", c[EngineCodes.MySql]); - Assert.Equal("SELECT \"Id\", \"Name\", \"Age\" FROM \"Users\"", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT \"Id\", \"Name\", \"Age\" FROM \"USERS\"", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } [Fact] From 0ba9bf3582f1e7bad5af39e71bb21b090f4bef01 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 1 Dec 2024 10:42:44 +0100 Subject: [PATCH 07/27] Improved GeneralTests part 2 --- QueryBuilder.Tests/GeneralTests.cs | 232 ++++++++++++++--------------- 1 file changed, 113 insertions(+), 119 deletions(-) diff --git a/QueryBuilder.Tests/GeneralTests.cs b/QueryBuilder.Tests/GeneralTests.cs index d8767fe0..bfc156e5 100644 --- a/QueryBuilder.Tests/GeneralTests.cs +++ b/QueryBuilder.Tests/GeneralTests.cs @@ -110,19 +110,13 @@ public void Custom_compiler_with_empty_identifier_overrides_should_remove_identi } [Theory] - [InlineData( - EngineCodes.SqlServer, - "SELECT * FROM (SELECT [Id], [Name], ROW_NUMBER() OVER (ORDER BY [Name]) AS [row_num] FROM [Table]) AS [results_wrapper] WHERE [row_num] BETWEEN 2 AND 21")] - [InlineData( - EngineCodes.MySql, - "SELECT `Id`, `Name` FROM `Table` ORDER BY `Name` LIMIT 20 OFFSET 1")] - [InlineData( - EngineCodes.PostgreSql, - "SELECT \"Id\", \"Name\" FROM \"Table\" ORDER BY \"Name\" LIMIT 20 OFFSET 1")] - [InlineData( - EngineCodes.Firebird, - "SELECT \"ID\", \"NAME\" FROM \"TABLE\" ORDER BY \"NAME\" ROWS 2 TO 21")] - public void Should_Equal_AfterMultipleCompile(string engine, string sqlText) + [InlineData(EngineCodes.Firebird)] + [InlineData(EngineCodes.MySql)] + [InlineData(EngineCodes.Oracle)] + [InlineData(EngineCodes.PostgreSql)] + [InlineData(EngineCodes.Sqlite)] + [InlineData(EngineCodes.SqlServer)] + public void Should_Equal_AfterMultipleCompile(string engine) { var query = new Query() .Select("Id", "Name") @@ -132,27 +126,16 @@ public void Should_Equal_AfterMultipleCompile(string engine, string sqlText) .Offset(1); var first = CompileFor(engine, query); - - Assert.Equal(sqlText, first.ToString()); - var second = CompileFor(engine, query); - Assert.Equal(sqlText, second.ToString()); + Assert.Equal(first.ToString(), second.ToString()); } [Theory] - [InlineData( - EngineCodes.SqlServer, - "SELECT [Id], [Name], [Age] FROM [Users]")] - [InlineData( - EngineCodes.MySql, - "SELECT `Id`, `Name`, `Age` FROM `Users`")] - [InlineData( - EngineCodes.PostgreSql, - "SELECT \"Id\", \"Name\", \"Age\" FROM \"Users\"")] - [InlineData( - EngineCodes.Firebird, - "SELECT \"Id\", \"Name\", \"Age\" FROM \"USERS\"")] + [InlineData(EngineCodes.SqlServer, "SELECT [Id], [Name], [Age] FROM [Users]")] + [InlineData(EngineCodes.MySql, "SELECT `Id`, `Name`, `Age` FROM `Users`")] + [InlineData(EngineCodes.PostgreSql, "SELECT \"Id\", \"Name\", \"Age\" FROM \"Users\"")] + [InlineData(EngineCodes.Firebird, "SELECT \"Id\", \"Name\", \"Age\" FROM \"USERS\"")] public void Raw_WrapIdentifiers(string engine, string sqlText) { var query = new Query("Users").SelectRaw("[Id], [Name], {Age}"); @@ -162,14 +145,15 @@ public void Raw_WrapIdentifiers(string engine, string sqlText) Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Raw_WrapIdentifiers_Escaped() + [Theory] + [InlineData(EngineCodes.PostgreSql, "SELECT '{1,2,3}'::int[] FROM \"Users\"")] + public void Raw_WrapIdentifiers_Escaped(string engine, string sqlText) { var query = new Query("Users").SelectRaw("'\\{1,2,3\\}'::int\\[\\]"); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT '{1,2,3}'::int[] FROM \"Users\"", c[EngineCodes.PostgreSql]); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -177,7 +161,6 @@ public void WrapWithSpace() { var compiler = new SqlServerCompiler(); - Assert.Equal("[My Table] AS [Table]", compiler.Wrap("My Table as Table")); } @@ -186,7 +169,6 @@ public void WrapWithDotes() { var compiler = new SqlServerCompiler(); - Assert.Equal("[My Schema].[My Table] AS [Table]", compiler.Wrap("My Schema.My Table as Table")); } @@ -195,53 +177,55 @@ public void WrapWithMultipleSpaces() { var compiler = new SqlServerCompiler(); - Assert.Equal("[My Table One] AS [Table One]", compiler.Wrap("My Table One as Table One")); } - [Fact] - public void CompilerSpecificFrom() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [mssql]")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"pgsql\"")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `mysql`")] + public void CompilerSpecificFrom(string engine, string sqlText) { var query = new Query() .ForSqlServer(q => q.From("mssql")) .ForPostgreSql(q => q.From("pgsql")) .ForMySql(q => q.From("mysql")); - var engines = new[] { EngineCodes.SqlServer, EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); - Assert.Equal("SELECT * FROM [mssql]", c[EngineCodes.SqlServer].RawSql); - Assert.Equal("SELECT * FROM \"pgsql\"", c[EngineCodes.PostgreSql].RawSql); - Assert.Equal("SELECT * FROM `mysql`", c[EngineCodes.MySql].RawSql); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void CompilerSpecificFromRaw() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [mssql]")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"pgsql\"")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `mysql`")] + public void CompilerSpecificFromRaw(string engine, string sqlText) { var query = new Query() .ForSqlServer(q => q.FromRaw("[mssql]")) .ForPostgreSql(q => q.FromRaw("[pgsql]")) .ForMySql(q => q.FromRaw("[mysql]")); - var engines = new[] { EngineCodes.SqlServer, EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); - Assert.Equal("SELECT * FROM [mssql]", c[EngineCodes.SqlServer].RawSql); - Assert.Equal("SELECT * FROM \"pgsql\"", c[EngineCodes.PostgreSql].RawSql); - Assert.Equal("SELECT * FROM `mysql`", c[EngineCodes.MySql].RawSql); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void CompilerSpecificFromMixed() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [mssql]")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"pgsql\"")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `mysql`")] + public void CompilerSpecificFromMixed(string engine, string sqlText) { var query = new Query() .ForSqlServer(q => q.From("mssql")) .ForPostgreSql(q => q.FromRaw("[pgsql]")) .ForMySql(q => q.From("mysql")); - var engines = new[] { EngineCodes.SqlServer, EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); - Assert.Equal("SELECT * FROM [mssql]", c[EngineCodes.SqlServer].RawSql); - Assert.Equal("SELECT * FROM \"pgsql\"", c[EngineCodes.PostgreSql].RawSql); - Assert.Equal("SELECT * FROM `mysql`", c[EngineCodes.MySql].RawSql); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -269,7 +253,7 @@ public void AddOrReplace_Works(string table, string engine) var query = new Query(); if (table != null) query.From(table); - query.AddOrReplaceComponent("from", new FromClause() { Table = "updated", Engine = engine }); + query.AddOrReplaceComponent("from", new FromClause { Table = "updated", Engine = engine }); var froms = query.Clauses.OfType(); Assert.Single(froms); @@ -300,6 +284,7 @@ public void AddOrReplace_Throws_MoreThanOne() .Where("c", "d"); Action act = () => query.AddOrReplaceComponent("where", new BasicCondition()); + Assert.Throws(act); } @@ -311,24 +296,25 @@ public void OneLimitPerEngine() .ForSqlServer(q => q.Limit(10)); var limits = query.GetComponents("limit", EngineCodes.SqlServer); + Assert.Single(limits); Assert.Equal(10, limits.Single().Limit); } - [Fact] - public void CompilerSpecificLimit() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT TOP (5) * FROM [mytable]")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"mytable\" LIMIT 10")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `mytable`")] + public void CompilerSpecificLimit(string engine, string sqlText) { var query = new Query("mytable") .ForSqlServer(q => q.Limit(5)) .ForPostgreSql(q => q.Limit(10)); - var engines = new[] { EngineCodes.SqlServer, EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); + var c = CompileFor(engine, query); Assert.Equal(2, query.GetComponents("limit").Count); - Assert.Equal("SELECT TOP (5) * FROM [mytable]", c[EngineCodes.SqlServer].ToString()); - Assert.Equal("SELECT * FROM \"mytable\" LIMIT 10", c[EngineCodes.PostgreSql].ToString()); - Assert.Equal("SELECT * FROM `mytable`", c[EngineCodes.MySql].ToString()); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -343,24 +329,24 @@ public void OneOffsetPerEngine() Assert.Equal(10, limits.Single().Offset); } - [Fact] - public void CompilerSpecificOffset() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [mytable]")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"mytable\" OFFSET 10")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `mytable` LIMIT 18446744073709551615 OFFSET 5")] + public void CompilerSpecificOffset(string engine, string sqlText) { var query = new Query("mytable") .ForMySql(q => q.Offset(5)) .ForPostgreSql(q => q.Offset(10)); - var engines = new[] { EngineCodes.SqlServer, EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); + var c = CompileFor(engine, query); Assert.Equal(2, query.GetComponents("offset").Count); - Assert.Equal("SELECT * FROM `mytable` LIMIT 18446744073709551615 OFFSET 5", c[EngineCodes.MySql].ToString()); - Assert.Equal("SELECT * FROM \"mytable\" OFFSET 10", c[EngineCodes.PostgreSql].ToString()); - Assert.Equal("SELECT * FROM [mytable]", c[EngineCodes.SqlServer].ToString()); + Assert.Equal(sqlText, c.ToString()); } [Fact] - public void Limit_Takes_Generic_If_Needed() + public void Offset_Takes_Generic_If_Needed() { var query = new Query("mytable") .Limit(5) @@ -375,7 +361,7 @@ public void Limit_Takes_Generic_If_Needed() } [Fact] - public void Offset_Takes_Generic_If_Needed() + public void Limit_Takes_Generic_If_Needed() { var query = new Query("mytable") .Limit(5) @@ -421,8 +407,11 @@ public void Can_Change_Generic_Offset_After_SpecificLimit() Assert.Equal("SELECT * FROM \"mytable\" LIMIT 20 OFFSET 7", c[EngineCodes.PostgreSql].ToString()); } - [Fact] - public void Where_Nested() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "SELECT * FROM [table] WHERE ([a] = 1 OR [a] = 2)")] + public void Where_Nested(string engine, string sqlText) { var query = new Query("table") .Where(q => q.Where("a", 1).OrWhere("a", 2)); @@ -431,9 +420,9 @@ public void Where_Nested() EngineCodes.SqlServer, }; - var c = Compilers.Compile(engines, query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [table] WHERE ([a] = 1 OR [a] = 2)", c[EngineCodes.SqlServer].ToString()); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -474,8 +463,26 @@ public void AdHoc_Throws_WhenFieldValuesOutNumberColumns() => new object[] { 4, 5, 6 }, })); - [Fact] - public void AdHoc_SingletonRow() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "WITH [rows] AS (SELECT [a] FROM (VALUES (1)) AS tbl ([a]))\nSELECT * FROM [rows]")] + [InlineData( + EngineCodes.PostgreSql, + "WITH \"rows\" AS (SELECT 1 AS \"a\")\nSELECT * FROM \"rows\"")] + [InlineData( + EngineCodes.MySql, + "WITH `rows` AS (SELECT 1 AS `a`)\nSELECT * FROM `rows`")] + [InlineData( + EngineCodes.Sqlite, + "WITH \"rows\" AS (SELECT 1 AS \"a\")\nSELECT * FROM \"rows\"")] + [InlineData( + EngineCodes.Firebird, + "WITH \"ROWS\" AS (SELECT 1 AS \"A\" FROM RDB$DATABASE)\nSELECT * FROM \"ROWS\"")] + [InlineData( + EngineCodes.Oracle, + "WITH \"rows\" AS (SELECT 1 AS \"a\" FROM DUAL)\nSELECT * FROM \"rows\"")] + public void AdHoc_SingletonRow(string engine, string sqlText) { var query = new Query("rows").With("rows", new[] { "a" }, @@ -483,14 +490,9 @@ public void AdHoc_SingletonRow() new object[] { 1 }, }); - var c = Compilers.Compile(query); + var c = CompileFor(engine, query); - Assert.Equal("WITH [rows] AS (SELECT [a] FROM (VALUES (1)) AS tbl ([a]))\nSELECT * FROM [rows]", c[EngineCodes.SqlServer].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\")\nSELECT * FROM \"rows\"", c[EngineCodes.PostgreSql].ToString()); - Assert.Equal("WITH `rows` AS (SELECT 1 AS `a`)\nSELECT * FROM `rows`", c[EngineCodes.MySql].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\")\nSELECT * FROM \"rows\"", c[EngineCodes.Sqlite].ToString()); - Assert.Equal("WITH \"ROWS\" AS (SELECT 1 AS \"A\" FROM RDB$DATABASE)\nSELECT * FROM \"ROWS\"", c[EngineCodes.Firebird].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\" FROM DUAL)\nSELECT * FROM \"rows\"", c[EngineCodes.Oracle].ToString()); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -570,60 +572,52 @@ public void UnsafeLiteral_Update() Assert.Equal("UPDATE [Table] SET [Count] = Count + 1", c[EngineCodes.SqlServer].ToString()); } - [Fact] - public void Passing_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [Col] = cast(1 as bit)")] + public void Passing_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse(string engine, string sqlText) { var query = new Query("Table").Where("Col", true); - var engines = new[] { - EngineCodes.SqlServer, - }; - - var c = Compilers.Compile(engines, query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [Table] WHERE [Col] = cast(1 as bit)", c[EngineCodes.SqlServer].ToString()); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Passing_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [Col] = cast(0 as bit)")] + public void Passing_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse(string engine, string sqlText) { var query = new Query("Table").Where("Col", false); - var engines = new[] { - EngineCodes.SqlServer, - }; - - var c = Compilers.Compile(engines, query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [Table] WHERE [Col] = cast(0 as bit)", c[EngineCodes.SqlServer].ToString()); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Passing_Negative_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [Col] != cast(1 as bit)")] + public void Passing_Negative_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse( + string engine, + string sqlText) { var query = new Query("Table").Where("Col", "!=", true); - var engines = new[] { - EngineCodes.SqlServer, - }; - - var c = Compilers.Compile(engines, query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [Table] WHERE [Col] != cast(1 as bit)", c[EngineCodes.SqlServer].ToString()); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Passing_Negative_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [Col] != cast(0 as bit)")] + public void Passing_Negative_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse( + string engine, + string sqlText) { var query = new Query("Table").Where("Col", "!=", false); - var engines = new[] { - EngineCodes.SqlServer, - }; - - var c = Compilers.Compile(engines, query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [Table] WHERE [Col] != cast(0 as bit)", c[EngineCodes.SqlServer].ToString()); + Assert.Equal(sqlText, c.ToString()); } } } From 8a7996eaf6f1ce5ff57784b20b70512eeb1ea632 Mon Sep 17 00:00:00 2001 From: Viktor Faddi Date: Sun, 1 Dec 2024 21:07:11 +0100 Subject: [PATCH 08/27] Imporved InsertTests part 1 --- QueryBuilder.Tests/InsertTests.cs | 98 ++++++++++++------------------- 1 file changed, 37 insertions(+), 61 deletions(-) diff --git a/QueryBuilder.Tests/InsertTests.cs b/QueryBuilder.Tests/InsertTests.cs index 926e18b2..b2d936b4 100644 --- a/QueryBuilder.Tests/InsertTests.cs +++ b/QueryBuilder.Tests/InsertTests.cs @@ -29,8 +29,10 @@ public Account(string name, string currency = null, string created_at = null, st public string color { get; set; } } - [Fact] - public void InsertObject() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')")] + public void InsertObject(string engine, string sqlText) { var query = new Query("Table") .AsInsert( @@ -40,19 +42,16 @@ public void InsertObject() Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); - var c = Compile(query); - - Assert.Equal( - "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InsertFromSubQueryWithCte() + [Theory] + [InlineData(EngineCodes.SqlServer, "WITH [old_cards] AS (SELECT * FROM [all_cars] WHERE [year] < 2000)\nINSERT INTO [expensive_cars] ([name], [model], [year]) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [old_cars] WHERE [price] > 100) AS [results_wrapper] WHERE [row_num] BETWEEN 11 AND 20")] + [InlineData(EngineCodes.MySql, "WITH `old_cards` AS (SELECT * FROM `all_cars` WHERE `year` < 2000)\nINSERT INTO `expensive_cars` (`name`, `model`, `year`) SELECT * FROM `old_cars` WHERE `price` > 100 LIMIT 10 OFFSET 10")] + [InlineData(EngineCodes.PostgreSql, "WITH \"old_cards\" AS (SELECT * FROM \"all_cars\" WHERE \"year\" < 2000)\nINSERT INTO \"expensive_cars\" (\"name\", \"model\", \"year\") SELECT * FROM \"old_cars\" WHERE \"price\" > 100 LIMIT 10 OFFSET 10")] + public void InsertFromSubQueryWithCte(string engine, string sqlText) { var query = new Query("expensive_cars") .With("old_cards", new Query("all_cars").Where("year", "<", 2000)) @@ -60,23 +59,15 @@ public void InsertFromSubQueryWithCte() new[] { "name", "model", "year" }, new Query("old_cars").Where("price", ">", 100).ForPage(2, 10)); - var c = Compile(query); - - Assert.Equal( - "WITH [old_cards] AS (SELECT * FROM [all_cars] WHERE [year] < 2000)\nINSERT INTO [expensive_cars] ([name], [model], [year]) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [old_cars] WHERE [price] > 100) AS [results_wrapper] WHERE [row_num] BETWEEN 11 AND 20", - c[EngineCodes.SqlServer]); - - Assert.Equal( - "WITH `old_cards` AS (SELECT * FROM `all_cars` WHERE `year` < 2000)\nINSERT INTO `expensive_cars` (`name`, `model`, `year`) SELECT * FROM `old_cars` WHERE `price` > 100 LIMIT 10 OFFSET 10", - c[EngineCodes.MySql]); + var c = CompileFor(engine, query); - Assert.Equal( - "WITH \"old_cards\" AS (SELECT * FROM \"all_cars\" WHERE \"year\" < 2000)\nINSERT INTO \"expensive_cars\" (\"name\", \"model\", \"year\") SELECT * FROM \"old_cars\" WHERE \"price\" > 100 LIMIT 10 OFFSET 10", - c[EngineCodes.PostgreSql]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InsertMultiRecords() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [expensive_cars] ([name], [brand], [year]) VALUES ('Chiron', 'Bugatti', NULL), ('Huayra', 'Pagani', 2012), ('Reventon roadster', 'Lamborghini', 2009)")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"EXPENSIVE_CARS\" (\"NAME\", \"BRAND\", \"YEAR\") SELECT 'Chiron', 'Bugatti', NULL FROM RDB$DATABASE UNION ALL SELECT 'Huayra', 'Pagani', 2012 FROM RDB$DATABASE UNION ALL SELECT 'Reventon roadster', 'Lamborghini', 2009 FROM RDB$DATABASE")] + public void InsertMultiRecords(string engine, string sqlText) { var query = new Query("expensive_cars") .AsInsert( @@ -88,54 +79,39 @@ public void InsertMultiRecords() new object[] { "Reventon roadster", "Lamborghini", 2009 } }); - var c = Compile(query); - - Assert.Equal( - "INSERT INTO [expensive_cars] ([name], [brand], [year]) VALUES ('Chiron', 'Bugatti', NULL), ('Huayra', 'Pagani', 2012), ('Reventon roadster', 'Lamborghini', 2009)", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO \"EXPENSIVE_CARS\" (\"NAME\", \"BRAND\", \"YEAR\") SELECT 'Chiron', 'Bugatti', NULL FROM RDB$DATABASE UNION ALL SELECT 'Huayra', 'Pagani', 2012 FROM RDB$DATABASE UNION ALL SELECT 'Reventon roadster', 'Lamborghini', 2009 FROM RDB$DATABASE", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InsertWithNullValues() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [Books] ([Id], [Author], [ISBN], [Date]) VALUES (1, 'Author 1', '123456', NULL)")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"BOOKS\" (\"ID\", \"AUTHOR\", \"ISBN\", \"DATE\") VALUES (1, 'Author 1', '123456', NULL)")] + public void InsertWithNullValues(string engine, string sqlText) { var query = new Query("Books") .AsInsert( new[] { "Id", "Author", "ISBN", "Date" }, new object[] { 1, "Author 1", "123456", null }); - var c = Compile(query); - - Assert.Equal("INSERT INTO [Books] ([Id], [Author], [ISBN], [Date]) VALUES (1, 'Author 1', '123456', NULL)", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - - Assert.Equal( - "INSERT INTO \"BOOKS\" (\"ID\", \"AUTHOR\", \"ISBN\", \"DATE\") VALUES (1, 'Author 1', '123456', NULL)", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InsertWithEmptyString() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [Books] ([Id], [Author], [ISBN], [Description]) VALUES (1, 'Author 1', '123456', '')")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"BOOKS\" (\"ID\", \"AUTHOR\", \"ISBN\", \"DESCRIPTION\") VALUES (1, 'Author 1', '123456', '')")] + public void InsertWithEmptyString(string engine, string sqlText) { var query = new Query("Books") .AsInsert( new[] { "Id", "Author", "ISBN", "Description" }, new object[] { 1, "Author 1", "123456", "" }); - var c = Compile(query); - - Assert.Equal( - "INSERT INTO [Books] ([Id], [Author], [ISBN], [Description]) VALUES (1, 'Author 1', '123456', '')", - c[EngineCodes.SqlServer]); - + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO \"BOOKS\" (\"ID\", \"AUTHOR\", \"ISBN\", \"DESCRIPTION\") VALUES (1, 'Author 1', '123456', '')", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -151,13 +127,13 @@ public void InsertWithByteArray() fauxImagebytes }); - var c = Compilers.Compile(query); - Assert.All(c.Values, a => Assert.Equal(2, a.NamedBindings.Count)); - - var exemplar = c[EngineCodes.SqlServer]; + var c = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (?, ?)", exemplar.RawSql); - Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (@p0, @p1)", exemplar.Sql); + Assert.Equal(2, c.NamedBindings.Count); + Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (?, ?)", c.RawSql); + Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (@p0, @p1)", c.Sql); + Assert.Equal(1, c.NamedBindings["@p0"]); + Assert.Equal(fauxImagebytes, c.NamedBindings["@p1"]); } [Fact] From 8e97da45dd20345a43dd635eb35fa6cc704af6b8 Mon Sep 17 00:00:00 2001 From: Viktor Faddi Date: Wed, 4 Dec 2024 17:42:17 +0100 Subject: [PATCH 09/27] Imporved InsertTests part 2 --- QueryBuilder.Tests/InsertTests.cs | 91 ++++++++++++------------------- 1 file changed, 35 insertions(+), 56 deletions(-) diff --git a/QueryBuilder.Tests/InsertTests.cs b/QueryBuilder.Tests/InsertTests.cs index b2d936b4..5c8fa5d0 100644 --- a/QueryBuilder.Tests/InsertTests.cs +++ b/QueryBuilder.Tests/InsertTests.cs @@ -136,25 +136,22 @@ public void InsertWithByteArray() Assert.Equal(fauxImagebytes, c.NamedBindings["@p1"]); } - [Fact] - public void InsertWithIgnoreAndColumnProperties() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [Account] ([name], [currency_id]) VALUES ('popular', 'US')")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"ACCOUNT\" (\"NAME\", \"CURRENCY_ID\") VALUES ('popular', 'US')")] + public void InsertWithIgnoreAndColumnProperties(string engine, string sqlText) { var account = new Account(name: $"popular", color: $"blue", currency: "US"); var query = new Query("Account").AsInsert(account); - var c = Compile(query); - - Assert.Equal( - "INSERT INTO [Account] ([name], [currency_id]) VALUES ('popular', 'US')", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO \"ACCOUNT\" (\"NAME\", \"CURRENCY_ID\") VALUES ('popular', 'US')", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InsertFromRaw() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO Table.With.Dots ([Name], [Age]) VALUES ('The User', '2018-01-01')")] + public void InsertFromRaw(string engine, string sqlText) { var query = new Query() .FromRaw("Table.With.Dots") @@ -165,11 +162,9 @@ public void InsertFromRaw() Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO Table.With.Dots ([Name], [Age]) VALUES ('The User', '2018-01-01')", - c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -190,8 +185,10 @@ public void InsertFromQueryShouldFail() }); } - [Fact] - public void InsertKeyValuePairs() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')")] + public void InsertKeyValuePairs(string engine, string sqlText) { var dictionaryUser = new Dictionary { @@ -203,19 +200,15 @@ public void InsertKeyValuePairs() var query = new Query("Table") .AsInsert(dictionaryUser); - var c = Compile(query); - - Assert.Equal( - "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InsertDictionary() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')")] + public void InsertDictionary(string engine, string sqlText) { var dictionaryUser = new Dictionary { { "Name", "The User" }, @@ -225,19 +218,15 @@ public void InsertDictionary() var query = new Query("Table") .AsInsert(dictionaryUser); - var c = Compile(query); - - Assert.Equal( - "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InsertReadOnlyDictionary() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')")] + public void InsertReadOnlyDictionary(string engine, string sqlText) { var dictionaryUser = new ReadOnlyDictionary( new Dictionary @@ -249,19 +238,15 @@ public void InsertReadOnlyDictionary() var query = new Query("Table") .AsInsert(dictionaryUser); - var c = Compile(query); - - Assert.Equal( - "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void InsertExpandoObject() + [Theory] + [InlineData(EngineCodes.SqlServer, "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')")] + [InlineData(EngineCodes.Firebird, "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')")] + public void InsertExpandoObject(string engine, string sqlText) { dynamic expandoUser = new ExpandoObject(); expandoUser.Name = "The User"; @@ -270,15 +255,9 @@ public void InsertExpandoObject() var query = new Query("Table") .AsInsert(expandoUser); - var c = Compile(query); - - Assert.Equal( - "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } } } From 8b9d26d4f4b20df0d68aa928f6ec2c6b13e383c9 Mon Sep 17 00:00:00 2001 From: Viktor Faddi Date: Wed, 4 Dec 2024 17:47:34 +0100 Subject: [PATCH 10/27] Move MySql and SqlLite execution tests into subdir. --- .../{ => MySql}/MySqlExecutionTest.cs | 13 ++++++------- .../{ => Sqlite}/SQLiteExecutionTest.cs | 19 ++++++++----------- 2 files changed, 14 insertions(+), 18 deletions(-) rename QueryBuilder.Tests/{ => MySql}/MySqlExecutionTest.cs (99%) rename QueryBuilder.Tests/{ => Sqlite}/SQLiteExecutionTest.cs (98%) diff --git a/QueryBuilder.Tests/MySqlExecutionTest.cs b/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs similarity index 99% rename from QueryBuilder.Tests/MySqlExecutionTest.cs rename to QueryBuilder.Tests/MySql/MySqlExecutionTest.cs index 4a86fd86..8f30f8b1 100644 --- a/QueryBuilder.Tests/MySqlExecutionTest.cs +++ b/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs @@ -1,14 +1,13 @@ -using SqlKata.Compilers; -using Xunit; -using SqlKata.Execution; -using MySql.Data.MySqlClient; using System; -using System.Linq; -using static SqlKata.Expressions; using System.Collections.Generic; +using System.Linq; using Microsoft.Extensions.Configuration; +using MySql.Data.MySqlClient; +using SqlKata.Compilers; +using SqlKata.Execution; +using Xunit; -namespace SqlKata.Tests +namespace SqlKata.Tests.MySql { public class MySqlExecutionTest { diff --git a/QueryBuilder.Tests/SQLiteExecutionTest.cs b/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs similarity index 98% rename from QueryBuilder.Tests/SQLiteExecutionTest.cs rename to QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs index 8c4d43f5..8a536ad0 100644 --- a/QueryBuilder.Tests/SQLiteExecutionTest.cs +++ b/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs @@ -1,14 +1,11 @@ -using SqlKata.Compilers; -using Xunit; -using SqlKata.Execution; -using MySql.Data.MySqlClient; -using System; -using System.Linq; -using static SqlKata.Expressions; using System.Collections.Generic; +using System.Linq; using Microsoft.Data.Sqlite; +using SqlKata.Compilers; +using SqlKata.Execution; +using Xunit; -namespace SqlKata.Tests +namespace SqlKata.Tests.Sqlite { public class SqliteExecutionTest { @@ -222,12 +219,12 @@ public void BasicSelectFilter() // 2020 {"2020-01-01", 10}, {"2020-05-01", 20}, - + // 2021 {"2021-01-01", 40}, {"2021-02-01", 10}, {"2021-04-01", -10}, - + // 2022 {"2022-01-01", 80}, {"2022-02-01", -30}, @@ -272,4 +269,4 @@ QueryFactory DB() } -} \ No newline at end of file +} From 67ab7ad079478cbf7c84fefa74a4670e4046814a Mon Sep 17 00:00:00 2001 From: Viktor Faddi Date: Wed, 4 Dec 2024 17:53:49 +0100 Subject: [PATCH 11/27] Move QueryFactoryExtensions into infra --- .../{ => Infrastructure}/QueryFactoryExtension.cs | 5 +++-- QueryBuilder.Tests/MySql/MySqlExecutionTest.cs | 1 + QueryBuilder.Tests/ParameterTypeTests.cs | 1 - QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) rename QueryBuilder.Tests/{ => Infrastructure}/QueryFactoryExtension.cs (92%) diff --git a/QueryBuilder.Tests/QueryFactoryExtension.cs b/QueryBuilder.Tests/Infrastructure/QueryFactoryExtension.cs similarity index 92% rename from QueryBuilder.Tests/QueryFactoryExtension.cs rename to QueryBuilder.Tests/Infrastructure/QueryFactoryExtension.cs index 9f87bfce..0b993217 100644 --- a/QueryBuilder.Tests/QueryFactoryExtension.cs +++ b/QueryBuilder.Tests/Infrastructure/QueryFactoryExtension.cs @@ -1,7 +1,8 @@ - using System.Collections.Generic; using SqlKata.Execution; +namespace SqlKata.Tests.Infrastructure; + static class QueryFactoryExtensions { public static QueryFactory Create(this QueryFactory db, string table, IEnumerable cols) @@ -16,4 +17,4 @@ public static QueryFactory Drop(this QueryFactory db, string table) db.Statement($"DROP TABLE IF EXISTS `{table}`;"); return db; } -} \ No newline at end of file +} diff --git a/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs b/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs index 8f30f8b1..93a84360 100644 --- a/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs +++ b/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs @@ -5,6 +5,7 @@ using MySql.Data.MySqlClient; using SqlKata.Compilers; using SqlKata.Execution; +using SqlKata.Tests.Infrastructure; using Xunit; namespace SqlKata.Tests.MySql diff --git a/QueryBuilder.Tests/ParameterTypeTests.cs b/QueryBuilder.Tests/ParameterTypeTests.cs index 37c9fc26..819ce7cd 100644 --- a/QueryBuilder.Tests/ParameterTypeTests.cs +++ b/QueryBuilder.Tests/ParameterTypeTests.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using SqlKata.Compilers; using Xunit; using System.Collections; diff --git a/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs b/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs index 8a536ad0..d70812c8 100644 --- a/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs +++ b/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs @@ -3,6 +3,7 @@ using Microsoft.Data.Sqlite; using SqlKata.Compilers; using SqlKata.Execution; +using SqlKata.Tests.Infrastructure; using Xunit; namespace SqlKata.Tests.Sqlite From 047ec4da73cf27e73b95ebdad51fd2afc8ff1d97 Mon Sep 17 00:00:00 2001 From: Viktor Faddi Date: Wed, 4 Dec 2024 19:50:49 +0100 Subject: [PATCH 12/27] Imporved SelectTests part 1 --- QueryBuilder.Tests/SelectTests.cs | 506 ++++++++++++++---------------- 1 file changed, 239 insertions(+), 267 deletions(-) diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs index 647187b9..6804ade8 100644 --- a/QueryBuilder.Tests/SelectTests.cs +++ b/QueryBuilder.Tests/SelectTests.cs @@ -9,90 +9,103 @@ namespace SqlKata.Tests { public class SelectTests : TestSupport { - [Fact] - public void BasicSelect() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [id], [name] FROM [users]")] + [InlineData(EngineCodes.MySql, "SELECT `id`, `name` FROM `users`")] + [InlineData(EngineCodes.PostgreSql, "SELECT \"id\", \"name\" FROM \"users\"")] + [InlineData(EngineCodes.Firebird, "SELECT \"ID\", \"NAME\" FROM \"USERS\"")] + [InlineData(EngineCodes.Oracle, "SELECT \"id\", \"name\" FROM \"users\"")] + public void BasicSelect(string engine, string sqlText) { - var q = new Query().From("users").Select("id", "name"); - var c = Compile(q); + var query = new Query().From("users").Select("id", "name"); - Assert.Equal("SELECT [id], [name] FROM [users]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT `id`, `name` FROM `users`", c[EngineCodes.MySql]); - Assert.Equal("SELECT \"id\", \"name\" FROM \"users\"", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT \"ID\", \"NAME\" FROM \"USERS\"", c[EngineCodes.Firebird]); - Assert.Equal("SELECT \"id\", \"name\" FROM \"users\"", c[EngineCodes.Oracle]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void BasicSelectEnumerable() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [id], [name] FROM [users]")] + [InlineData(EngineCodes.MySql, "SELECT `id`, `name` FROM `users`")] + [InlineData(EngineCodes.PostgreSql, "SELECT \"id\", \"name\" FROM \"users\"")] + [InlineData(EngineCodes.Firebird, "SELECT \"ID\", \"NAME\" FROM \"USERS\"")] + [InlineData(EngineCodes.Oracle, "SELECT \"id\", \"name\" FROM \"users\"")] + public void BasicSelectEnumerable(string engine, string sqlText) { - var q = new Query().From("users").Select(new List() { "id", "name" }); - var c = Compile(q); + var query = new Query().From("users").Select(new List() { "id", "name" }); + + var c = CompileFor(engine, query); - Assert.Equal("SELECT [id], [name] FROM [users]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT `id`, `name` FROM `users`", c[EngineCodes.MySql]); - Assert.Equal("SELECT \"id\", \"name\" FROM \"users\"", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT \"ID\", \"NAME\" FROM \"USERS\"", c[EngineCodes.Firebird]); - Assert.Equal("SELECT \"id\", \"name\" FROM \"users\"", c[EngineCodes.Oracle]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void BasicSelectWhereBindingIsEmptyOrNull() - { - var q = new Query() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [id], [name] FROM [users] WHERE [author] = '' OR [author] IS NULL")] + [InlineData(EngineCodes.MySql, "SELECT `id`, `name` FROM `users` WHERE `author` = '' OR `author` IS NULL")] + [InlineData(EngineCodes.PostgreSql, "SELECT \"id\", \"name\" FROM \"users\" WHERE \"author\" = '' OR \"author\" IS NULL")] + [InlineData(EngineCodes.Firebird, "SELECT \"ID\", \"NAME\" FROM \"USERS\" WHERE \"AUTHOR\" = '' OR \"AUTHOR\" IS NULL")] + [InlineData(EngineCodes.Oracle, "SELECT \"id\", \"name\" FROM \"users\" WHERE \"author\" = '' OR \"author\" IS NULL")] + public void BasicSelectWhereBindingIsEmptyOrNull(string engine, string sqlText) + { + var query = new Query() .From("users") .Select("id", "name") .Where("author", "") .OrWhere("author", null); - var c = Compile(q); + var c = CompileFor(engine, query); - Assert.Equal("SELECT [id], [name] FROM [users] WHERE [author] = '' OR [author] IS NULL", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT `id`, `name` FROM `users` WHERE `author` = '' OR `author` IS NULL", c[EngineCodes.MySql]); - Assert.Equal("SELECT \"id\", \"name\" FROM \"users\" WHERE \"author\" = '' OR \"author\" IS NULL", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT \"ID\", \"NAME\" FROM \"USERS\" WHERE \"AUTHOR\" = '' OR \"AUTHOR\" IS NULL", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void BasicSelectWithAlias() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [id], [name] FROM [users] AS [u]")] + [InlineData(EngineCodes.MySql, "SELECT `id`, `name` FROM `users` AS `u`")] + [InlineData(EngineCodes.PostgreSql, "SELECT \"id\", \"name\" FROM \"users\" AS \"u\"")] + [InlineData(EngineCodes.Firebird, "SELECT \"ID\", \"NAME\" FROM \"USERS\" AS \"U\"")] + [InlineData(EngineCodes.Oracle, "SELECT \"id\", \"name\" FROM \"users\" \"u\"")] + public void BasicSelectWithAlias(string engine, string sqlText) { - var q = new Query().From("users as u").Select("id", "name"); - var c = Compile(q); + var query = new Query().From("users as u").Select("id", "name"); - Assert.Equal("SELECT [id], [name] FROM [users] AS [u]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT `id`, `name` FROM `users` AS `u`", c[EngineCodes.MySql]); - Assert.Equal("SELECT \"id\", \"name\" FROM \"users\" AS \"u\"", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT \"ID\", \"NAME\" FROM \"USERS\" AS \"U\"", c[EngineCodes.Firebird]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void ExpandedSelect() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [users].[id], [users].[name], [users].[age] FROM [users]")] + [InlineData(EngineCodes.MySql, "SELECT `users`.`id`, `users`.`name`, `users`.`age` FROM `users`")] + public void ExpandedSelect(string engine, string sqlText) { - var q = new Query().From("users").Select("users.{id,name, age}"); - var c = Compile(q); + var query = new Query().From("users").Select("users.{id,name, age}"); + + var c = CompileFor(engine, query); - Assert.Equal("SELECT [users].[id], [users].[name], [users].[age] FROM [users]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT `users`.`id`, `users`.`name`, `users`.`age` FROM `users`", c[EngineCodes.MySql]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void ExpandedSelectMultiline() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [users].[id], [users].[name] AS [Name], [users].[age] FROM [users]")] + [InlineData(EngineCodes.MySql, "SELECT `users`.`id`, `users`.`name` AS `Name`, `users`.`age` FROM `users`")] + public void ExpandedSelectMultiline(string engine, string sqlText) { - var q = new Query().From("users").Select(@"users.{ + var query = new Query().From("users").Select(@"users.{ id, name as Name, age }"); - var c = Compile(q); - Assert.Equal("SELECT [users].[id], [users].[name] AS [Name], [users].[age] FROM [users]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT `users`.`id`, `users`.`name` AS `Name`, `users`.`age` FROM `users`", c[EngineCodes.MySql]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } [Fact] public void ExpandedSelectWithSchema() { - var q = new Query().From("users").Select("dbo.users.{id,name, age}"); - var c = Compile(q); + var query = new Query().From("users").Select("dbo.users.{id,name, age}"); + var c = Compile(query); Assert.Equal("SELECT [dbo].[users].[id], [dbo].[users].[name], [dbo].[users].[age] FROM [users]", c[EngineCodes.SqlServer]); } @@ -100,121 +113,121 @@ public void ExpandedSelectWithSchema() [Fact] public void ExpandedSelectMultilineWithSchema() { - var q = new Query().From("users").Select(@"dbo.users.{ + var query = new Query().From("users").Select(@"dbo.users.{ id, name as Name, age }"); - var c = Compile(q); + var c = Compile(query); Assert.Equal("SELECT [dbo].[users].[id], [dbo].[users].[name] AS [Name], [dbo].[users].[age] FROM [users]", c[EngineCodes.SqlServer]); } - [Fact] - public void NestedEmptyWhereAtFirstCondition() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [table] WHERE [id] = 1")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"TABLE\" WHERE \"ID\" = 1")] + public void NestedEmptyWhereAtFirstCondition(string engine, string sqlText) { var query = new Query("table") .Where(q => new Query()) .Where("id", 1); - var c = Compile(query); - - Assert.Equal("SELECT * FROM [table] WHERE [id] = 1", c[EngineCodes.SqlServer]); - + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM \"TABLE\" WHERE \"ID\" = 1", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void WhereTrue() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [IsActive] = cast(1 as bit)")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `Table` WHERE `IsActive` = true")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"IsActive\" = true")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"TABLE\" WHERE \"ISACTIVE\" = 1")] + public void WhereTrue(string engine, string sqlText) { var query = new Query("Table").WhereTrue("IsActive"); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [Table] WHERE [IsActive] = cast(1 as bit)", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM `Table` WHERE `IsActive` = true", c[EngineCodes.MySql]); - Assert.Equal("SELECT * FROM \"Table\" WHERE \"IsActive\" = true", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT * FROM \"TABLE\" WHERE \"ISACTIVE\" = 1", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void WhereFalse() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [IsActive] = cast(0 as bit)")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `Table` WHERE `IsActive` = false")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"IsActive\" = false")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"TABLE\" WHERE \"ISACTIVE\" = 0")] + public void WhereFalse(string engine, string sqlText) { var query = new Query("Table").WhereFalse("IsActive"); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [Table] WHERE [IsActive] = cast(0 as bit)", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM `Table` WHERE `IsActive` = false", c[EngineCodes.MySql]); - Assert.Equal("SELECT * FROM \"Table\" WHERE \"IsActive\" = false", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT * FROM \"TABLE\" WHERE \"ISACTIVE\" = 0", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void OrWhereFalse() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] = cast(0 as bit)")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"MyCol\" = 'abc' OR \"IsActive\" = false")] + public void OrWhereFalse(string engine, string sqlText) { var query = new Query("Table").Where("MyCol", "abc").OrWhereFalse("IsActive"); - var c = Compile(query); - - Assert.Equal("SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] = cast(0 as bit)", c[EngineCodes.SqlServer]); - - Assert.Equal("SELECT * FROM \"Table\" WHERE \"MyCol\" = 'abc' OR \"IsActive\" = false", c[EngineCodes.PostgreSql]); + var c = CompileFor(engine, query); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void OrWhereTrue() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] = cast(1 as bit)")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"MyCol\" = 'abc' OR \"IsActive\" = true")] + public void OrWhereTrue(string engine, string sqlText) { var query = new Query("Table").Where("MyCol", "abc").OrWhereTrue("IsActive"); - var c = Compile(query); - - Assert.Equal("SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] = cast(1 as bit)", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM \"Table\" WHERE \"MyCol\" = 'abc' OR \"IsActive\" = true", c[EngineCodes.PostgreSql]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void OrWhereNull() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] IS NULL")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"MyCol\" = 'abc' OR \"IsActive\" IS NULL")] + public void OrWhereNull(string engine, string sqlText) { var query = new Query("Table").Where("MyCol", "abc").OrWhereNull("IsActive"); - var c = Compile(query); - - Assert.Equal("SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] IS NULL", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM \"Table\" WHERE \"MyCol\" = 'abc' OR \"IsActive\" IS NULL", c[EngineCodes.PostgreSql]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void WhereSub() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE (SELECT COUNT(*) AS [count] FROM [Table2] WHERE [Table2].[Column] = [Table].[MyCol]) = 1")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE (SELECT COUNT(*) AS \"count\" FROM \"Table2\" WHERE \"Table2\".\"Column\" = \"Table\".\"MyCol\") = 1")] + public void WhereSub(string engine, string sqlText) { var subQuery = new Query("Table2").WhereColumns("Table2.Column", "=", "Table.MyCol").AsCount(); var query = new Query("Table").WhereSub(subQuery, 1); - var c = Compile(query); - - Assert.Equal("SELECT * FROM [Table] WHERE (SELECT COUNT(*) AS [count] FROM [Table2] WHERE [Table2].[Column] = [Table].[MyCol]) = 1", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM \"Table\" WHERE (SELECT COUNT(*) AS \"count\" FROM \"Table2\" WHERE \"Table2\".\"Column\" = \"Table\".\"MyCol\") = 1", c[EngineCodes.PostgreSql]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void OrWhereSub() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [MyCol] IS NULL OR (SELECT COUNT(*) AS [count] FROM [Table2] WHERE [Table2].[Column] = [Table].[MyCol]) < 1")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"MyCol\" IS NULL OR (SELECT COUNT(*) AS \"count\" FROM \"Table2\" WHERE \"Table2\".\"Column\" = \"Table\".\"MyCol\") < 1")] + public void OrWhereSub(string engine, string sqlText) { var subQuery = new Query("Table2").WhereColumns("Table2.Column", "=", "Table.MyCol").AsCount(); var query = new Query("Table").WhereNull("MyCol").OrWhereSub(subQuery, "<", 1); - var c = Compile(query); - - Assert.Equal("SELECT * FROM [Table] WHERE [MyCol] IS NULL OR (SELECT COUNT(*) AS [count] FROM [Table2] WHERE [Table2].[Column] = [Table].[MyCol]) < 1", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM \"Table\" WHERE \"MyCol\" IS NULL OR (SELECT COUNT(*) AS \"count\" FROM \"Table2\" WHERE \"Table2\".\"Column\" = \"Table\".\"MyCol\") < 1", c[EngineCodes.PostgreSql]); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -237,126 +250,116 @@ public void UsingJsonArray() Assert.Equal("SELECT * FROM \"Table\" WHERE \"Json\"->'address'->>'country' in (1,2,3,4)", c[EngineCodes.PostgreSql]); } - [Fact] - public void Union() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] UNION SELECT * FROM [Laptops]")] + [InlineData(EngineCodes.Sqlite, "SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\"")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\"")] + public void Union(string engine, string sqlText) { var laptops = new Query("Laptops"); var mobiles = new Query("Phones").Union(laptops); - var c = Compile(mobiles); + var c = CompileFor(engine, mobiles); - Assert.Equal("SELECT * FROM [Phones] UNION SELECT * FROM [Laptops]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\"", c[EngineCodes.Sqlite]); - Assert.Equal("SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\"", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void UnionWithBindings() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] WHERE [Type] = 'A'")] + [InlineData(EngineCodes.Sqlite, "SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `Phones` UNION SELECT * FROM `Laptops` WHERE `Type` = 'A'")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\" WHERE \"TYPE\" = 'A'")] + public void UnionWithBindings(string engine, string sqlText) { var laptops = new Query("Laptops").Where("Type", "A"); var mobiles = new Query("Phones").Union(laptops); - var c = Compile(mobiles); + var c = CompileFor(engine, mobiles); - Assert.Equal("SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] WHERE [Type] = 'A'", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'", c[EngineCodes.Sqlite]); - Assert.Equal("SELECT * FROM `Phones` UNION SELECT * FROM `Laptops` WHERE `Type` = 'A'", c[EngineCodes.MySql]); - Assert.Equal("SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\" WHERE \"TYPE\" = 'A'", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void RawUnionWithBindings() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] WHERE [Type] = 'A'")] + [InlineData(EngineCodes.Sqlite, "SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `Phones` UNION SELECT * FROM `Laptops` WHERE `Type` = 'A'")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] // Is this good? + public void RawUnionWithBindings(string engine, string sqlText) { var mobiles = new Query("Phones").UnionRaw("UNION SELECT * FROM [Laptops] WHERE [Type] = ?", "A"); - var c = Compile(mobiles); + var c = CompileFor(engine, mobiles); - Assert.Equal("SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] WHERE [Type] = 'A'", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM `Phones` UNION SELECT * FROM `Laptops` WHERE `Type` = 'A'", c[EngineCodes.MySql]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void MultipleUnion() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] UNION SELECT * FROM [Tablets]")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\" UNION SELECT * FROM \"TABLETS\"")] + public void MultipleUnion(string engine, string sqlText) { var laptops = new Query("Laptops"); var tablets = new Query("Tablets"); var mobiles = new Query("Phones").Union(laptops).Union(tablets); - var c = Compile(mobiles); - - Assert.Equal("SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] UNION SELECT * FROM [Tablets]", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, mobiles); + Assert.Equal(sqlText, c.ToString()); - Assert.Equal("SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\" UNION SELECT * FROM \"TABLETS\"", - c[EngineCodes.Firebird]); } - [Fact] - public void MultipleUnionWithBindings() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] WHERE [Price] > 1000 UNION SELECT * FROM [Tablets] WHERE [Price] > 2000")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" > 1000 UNION SELECT * FROM \"TABLETS\" WHERE \"PRICE\" > 2000")] + public void MultipleUnionWithBindings(string engine, string sqlText) { var laptops = new Query("Laptops").Where("Price", ">", 1000); var tablets = new Query("Tablets").Where("Price", ">", 2000); var mobiles = new Query("Phones").Where("Price", "<", 3000).Union(laptops).Union(tablets); - var c = Compile(mobiles); - - Assert.Equal( - "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] WHERE [Price] > 1000 UNION SELECT * FROM [Tablets] WHERE [Price] > 2000", - c[EngineCodes.SqlServer]); - + var c = CompileFor(engine, mobiles); - Assert.Equal( - "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" > 1000 UNION SELECT * FROM \"TABLETS\" WHERE \"PRICE\" > 2000", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void MultipleUnionWithBindingsAndPagination() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] WHERE [Price] > 1000 UNION ALL SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Tablets] WHERE [Price] > 2000) AS [results_wrapper] WHERE [row_num] BETWEEN 16 AND 30")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" > 1000 UNION ALL SELECT * FROM \"TABLETS\" WHERE \"PRICE\" > 2000 ROWS 16 TO 30")] + public void MultipleUnionWithBindingsAndPagination(string engine, string sqlText) { var laptops = new Query("Laptops").Where("Price", ">", 1000); var tablets = new Query("Tablets").Where("Price", ">", 2000).ForPage(2); var mobiles = new Query("Phones").Where("Price", "<", 3000).Union(laptops).UnionAll(tablets); + var c = CompileFor(engine, mobiles); - var c = Compile(mobiles); - - Assert.Equal( - "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] WHERE [Price] > 1000 UNION ALL SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Tablets] WHERE [Price] > 2000) AS [results_wrapper] WHERE [row_num] BETWEEN 16 AND 30", - c[EngineCodes.SqlServer]); - - - Assert.Equal( - "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" > 1000 UNION ALL SELECT * FROM \"TABLETS\" WHERE \"PRICE\" > 2000 ROWS 16 TO 30", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UnionWithCallbacks() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] UNION ALL SELECT * FROM [Tablets]")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" UNION ALL SELECT * FROM \"TABLETS\"")] + public void UnionWithCallbacks(string engine, string sqlText) { var mobiles = new Query("Phones") .Where("Price", "<", 3000) .Union(q => q.From("Laptops")) .UnionAll(q => q.From("Tablets")); - var c = Compile(mobiles); - - Assert.Equal( - "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] UNION ALL SELECT * FROM [Tablets]", - c[EngineCodes.SqlServer]); - + var c = CompileFor(engine, mobiles); - Assert.Equal( - "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" UNION ALL SELECT * FROM \"TABLETS\"", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UnionWithDifferentEngine() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] WHERE [Price] < 300 EXCEPT SELECT * FROM [Phones] WHERE NOT ([Os] = 'iOS') UNION ALL SELECT * FROM [Tablets] WHERE [Price] < 100")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `Phones` WHERE `Price` < 300 INTERSECT ALL SELECT * FROM `Watches` WHERE `Os` = 'Android' UNION ALL SELECT * FROM `Tablets` WHERE `Price` < 100")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Phones\" WHERE \"Price\" < 300 UNION SELECT * FROM \"Laptops\" WHERE \"Price\" < 800 UNION ALL SELECT * FROM \"Tablets\" WHERE \"Price\" < 100")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 300 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" < 800 UNION ALL SELECT * FROM \"TABLETS\" WHERE \"PRICE\" < 100")] + public void UnionWithDifferentEngine(string engine, string sqlText) { var mobiles = new Query("Phones") .Where("Price", "<", 300) @@ -366,23 +369,9 @@ public void UnionWithDifferentEngine() .ForFirebird(scope => scope.Union(q => q.From("Laptops").Where("Price", "<", 800))) .UnionAll(q => q.From("Tablets").Where("Price", "<", 100)); - var c = Compile(mobiles); - - Assert.Equal( - "SELECT * FROM [Phones] WHERE [Price] < 300 EXCEPT SELECT * FROM [Phones] WHERE NOT ([Os] = 'iOS') UNION ALL SELECT * FROM [Tablets] WHERE [Price] < 100", - c[EngineCodes.SqlServer]); - - Assert.Equal( - "SELECT * FROM `Phones` WHERE `Price` < 300 INTERSECT ALL SELECT * FROM `Watches` WHERE `Os` = 'Android' UNION ALL SELECT * FROM `Tablets` WHERE `Price` < 100", - c[EngineCodes.MySql]); + var c = CompileFor(engine, mobiles); - Assert.Equal( - "SELECT * FROM \"Phones\" WHERE \"Price\" < 300 UNION SELECT * FROM \"Laptops\" WHERE \"Price\" < 800 UNION ALL SELECT * FROM \"Tablets\" WHERE \"Price\" < 100", - c[EngineCodes.PostgreSql]); - - Assert.Equal( - "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 300 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" < 800 UNION ALL SELECT * FROM \"TABLETS\" WHERE \"PRICE\" < 100", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -395,17 +384,17 @@ public void CombineRaw() Assert.Equal("SELECT * FROM [Mobiles] UNION ALL SELECT * FROM Devices", c[EngineCodes.SqlServer]); } - [Fact] - public void CombineRawWithPlaceholders() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Mobiles] UNION ALL SELECT * FROM [Devices]")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `Mobiles` UNION ALL SELECT * FROM `Devices`")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"MOBILES\" UNION ALL SELECT * FROM \"Devices\"")] + public void CombineRawWithPlaceholders(string engine, string sqlText) { var query = new Query("Mobiles").CombineRaw("UNION ALL SELECT * FROM {Devices}"); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [Mobiles] UNION ALL SELECT * FROM [Devices]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM `Mobiles` UNION ALL SELECT * FROM `Devices`", c[EngineCodes.MySql]); - - Assert.Equal("SELECT * FROM \"MOBILES\" UNION ALL SELECT * FROM \"Devices\"", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -462,8 +451,12 @@ public void MultipleCte() c[EngineCodes.SqlServer]); } - [Fact] - public void CteAndBindings() + [Theory] + [InlineData(EngineCodes.SqlServer, "WITH [range] AS (SELECT [Number] FROM [Sequence] WHERE [Number] < 78)\nSELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Races] WHERE [Id] > 55 AND [Value] BETWEEN 18 AND 24) AS [results_wrapper] WHERE [row_num] BETWEEN 21 AND 45")] + [InlineData(EngineCodes.MySql, "WITH `range` AS (SELECT `Id` FROM `seqtbl` WHERE `Id` < 33)\nSELECT * FROM `Races` WHERE `RaceAuthor` IN (SELECT `Name` FROM `Users` WHERE `Status` = 'Available') AND `Id` > 55 AND `Value` BETWEEN 18 AND 24")] + [InlineData(EngineCodes.PostgreSql, "WITH \"range\" AS (SELECT \"d\" FROM generate_series(1, 33) as d)\nSELECT * FROM \"Races\" WHERE \"Name\" = '3778' AND \"Id\" > 55 AND \"Value\" BETWEEN 18 AND 24")] + [InlineData(EngineCodes.Firebird, "WITH \"RANGE\" AS (SELECT \"D\" FROM generate_series(1, 33) as d)\nSELECT * FROM \"RACES\" WHERE \"NAME\" = '3778' AND \"ID\" > 55 AND \"VALUE\" BETWEEN 18 AND 24")] + public void CteAndBindings(string engine, string sqlText) { var query = new Query("Races") .For("mysql", s => @@ -491,28 +484,18 @@ public void CteAndBindings() .Where("Id", ">", 55) .WhereBetween("Value", 18, 24); - var c = Compile(query); - - Assert.Equal( - "WITH [range] AS (SELECT [Number] FROM [Sequence] WHERE [Number] < 78)\nSELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Races] WHERE [Id] > 55 AND [Value] BETWEEN 18 AND 24) AS [results_wrapper] WHERE [row_num] BETWEEN 21 AND 45", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "WITH `range` AS (SELECT `Id` FROM `seqtbl` WHERE `Id` < 33)\nSELECT * FROM `Races` WHERE `RaceAuthor` IN (SELECT `Name` FROM `Users` WHERE `Status` = 'Available') AND `Id` > 55 AND `Value` BETWEEN 18 AND 24", - c[EngineCodes.MySql]); - - Assert.Equal( - "WITH \"range\" AS (SELECT \"d\" FROM generate_series(1, 33) as d)\nSELECT * FROM \"Races\" WHERE \"Name\" = '3778' AND \"Id\" > 55 AND \"Value\" BETWEEN 18 AND 24", - c[EngineCodes.PostgreSql]); - - Assert.Equal( - "WITH \"RANGE\" AS (SELECT \"D\" FROM generate_series(1, 33) as d)\nSELECT * FROM \"RACES\" WHERE \"NAME\" = '3778' AND \"ID\" > 55 AND \"VALUE\" BETWEEN 18 AND 24", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } // test for issue #50 - [Fact] - public void CascadedCteAndBindings() + [Theory] + [InlineData(EngineCodes.SqlServer, "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2)\nSELECT * FROM [cte2] WHERE [Column3] = 5")] + [InlineData(EngineCodes.MySql, "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2)\nSELECT * FROM `cte2` WHERE `Column3` = 5")] + [InlineData(EngineCodes.PostgreSql, "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2)\nSELECT * FROM \"cte2\" WHERE \"Column3\" = 5")] + [InlineData(EngineCodes.Firebird, "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2)\nSELECT * FROM \"CTE2\" WHERE \"COLUMN3\" = 5")] + public void CascadedCteAndBindings(string engine, string sqlText) { var cte1 = new Query("Table1"); cte1.Select("Column1", "Column2"); @@ -530,20 +513,18 @@ public void CascadedCteAndBindings() mainQuery.From("cte2"); mainQuery.Where("Column3", 5); - var c = Compile(mainQuery); + var c = CompileFor(engine, mainQuery); - Assert.Equal("WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2)\nSELECT * FROM [cte2] WHERE [Column3] = 5", c[EngineCodes.SqlServer]); - - Assert.Equal("WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2)\nSELECT * FROM `cte2` WHERE `Column3` = 5", c[EngineCodes.MySql]); - - Assert.Equal("WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2)\nSELECT * FROM \"cte2\" WHERE \"Column3\" = 5", c[EngineCodes.PostgreSql]); - - Assert.Equal("WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2)\nSELECT * FROM \"CTE2\" WHERE \"COLUMN3\" = 5", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } // test for issue #50 - [Fact] - public void CascadedAndMultiReferencedCteAndBindings() + [Theory] + [InlineData(EngineCodes.SqlServer, "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2),\n[cte3] AS (SELECT [Column3_3], [Column3_4] FROM [Table3] \nINNER JOIN [cte1] ON ([Column1] = [Column3_3]) WHERE [Column3_4] = 33)\nSELECT * FROM [cte2] WHERE [Column3] = 5")] + [InlineData(EngineCodes.MySql, "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2),\n`cte3` AS (SELECT `Column3_3`, `Column3_4` FROM `Table3` \nINNER JOIN `cte1` ON (`Column1` = `Column3_3`) WHERE `Column3_4` = 33)\nSELECT * FROM `cte2` WHERE `Column3` = 5")] + [InlineData(EngineCodes.PostgreSql, "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2),\n\"cte3\" AS (SELECT \"Column3_3\", \"Column3_4\" FROM \"Table3\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3_3\") WHERE \"Column3_4\" = 33)\nSELECT * FROM \"cte2\" WHERE \"Column3\" = 5")] + [InlineData(EngineCodes.Firebird, "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2),\n\"CTE3\" AS (SELECT \"COLUMN3_3\", \"COLUMN3_4\" FROM \"TABLE3\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3_3\") WHERE \"COLUMN3_4\" = 33)\nSELECT * FROM \"CTE2\" WHERE \"COLUMN3\" = 5")] + public void CascadedAndMultiReferencedCteAndBindings(string engine, string sqlText) { var cte1 = new Query("Table1"); cte1.Select("Column1", "Column2"); @@ -568,20 +549,18 @@ public void CascadedAndMultiReferencedCteAndBindings() mainQuery.From("cte2"); mainQuery.Where("Column3", 5); - var c = Compile(mainQuery); + var c = CompileFor(engine, mainQuery); - Assert.Equal("WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2),\n[cte3] AS (SELECT [Column3_3], [Column3_4] FROM [Table3] \nINNER JOIN [cte1] ON ([Column1] = [Column3_3]) WHERE [Column3_4] = 33)\nSELECT * FROM [cte2] WHERE [Column3] = 5", c[EngineCodes.SqlServer]); - - Assert.Equal("WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2),\n`cte3` AS (SELECT `Column3_3`, `Column3_4` FROM `Table3` \nINNER JOIN `cte1` ON (`Column1` = `Column3_3`) WHERE `Column3_4` = 33)\nSELECT * FROM `cte2` WHERE `Column3` = 5", c[EngineCodes.MySql]); - - Assert.Equal("WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2),\n\"cte3\" AS (SELECT \"Column3_3\", \"Column3_4\" FROM \"Table3\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3_3\") WHERE \"Column3_4\" = 33)\nSELECT * FROM \"cte2\" WHERE \"Column3\" = 5", c[EngineCodes.PostgreSql]); - - Assert.Equal("WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2),\n\"CTE3\" AS (SELECT \"COLUMN3_3\", \"COLUMN3_4\" FROM \"TABLE3\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3_3\") WHERE \"COLUMN3_4\" = 33)\nSELECT * FROM \"CTE2\" WHERE \"COLUMN3\" = 5", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } // test for issue #50 - [Fact] - public void MultipleCtesAndBindings() + [Theory] + [InlineData(EngineCodes.SqlServer, "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2),\n[cte3] AS (SELECT [Column3_3], [Column3_4] FROM [Table3] \nINNER JOIN [cte1] ON ([Column1] = [Column3_3]) WHERE [Column3_4] = 33)\nSELECT * FROM [cte3] WHERE [Column3_4] = 5")] + [InlineData(EngineCodes.MySql, "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2),\n`cte3` AS (SELECT `Column3_3`, `Column3_4` FROM `Table3` \nINNER JOIN `cte1` ON (`Column1` = `Column3_3`) WHERE `Column3_4` = 33)\nSELECT * FROM `cte3` WHERE `Column3_4` = 5")] + [InlineData(EngineCodes.PostgreSql, "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2),\n\"cte3\" AS (SELECT \"Column3_3\", \"Column3_4\" FROM \"Table3\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3_3\") WHERE \"Column3_4\" = 33)\nSELECT * FROM \"cte3\" WHERE \"Column3_4\" = 5")] + [InlineData(EngineCodes.Firebird, "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2),\n\"CTE3\" AS (SELECT \"COLUMN3_3\", \"COLUMN3_4\" FROM \"TABLE3\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3_3\") WHERE \"COLUMN3_4\" = 33)\nSELECT * FROM \"CTE3\" WHERE \"COLUMN3_4\" = 5")] + public void MultipleCtesAndBindings(string engine, string sqlText) { var cte1 = new Query("Table1"); cte1.Select("Column1", "Column2"); @@ -605,58 +584,51 @@ public void MultipleCtesAndBindings() mainQuery.From("cte3"); mainQuery.Where("Column3_4", 5); - var c = Compile(mainQuery); + var c = CompileFor(engine, mainQuery); - Assert.Equal("WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2),\n[cte3] AS (SELECT [Column3_3], [Column3_4] FROM [Table3] \nINNER JOIN [cte1] ON ([Column1] = [Column3_3]) WHERE [Column3_4] = 33)\nSELECT * FROM [cte3] WHERE [Column3_4] = 5", c[EngineCodes.SqlServer]); - - Assert.Equal("WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2),\n`cte3` AS (SELECT `Column3_3`, `Column3_4` FROM `Table3` \nINNER JOIN `cte1` ON (`Column1` = `Column3_3`) WHERE `Column3_4` = 33)\nSELECT * FROM `cte3` WHERE `Column3_4` = 5", c[EngineCodes.MySql]); - - Assert.Equal("WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2),\n\"cte3\" AS (SELECT \"Column3_3\", \"Column3_4\" FROM \"Table3\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3_3\") WHERE \"Column3_4\" = 33)\nSELECT * FROM \"cte3\" WHERE \"Column3_4\" = 5", c[EngineCodes.PostgreSql]); - - Assert.Equal("WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2),\n\"CTE3\" AS (SELECT \"COLUMN3_3\", \"COLUMN3_4\" FROM \"TABLE3\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3_3\") WHERE \"COLUMN3_4\" = 33)\nSELECT * FROM \"CTE3\" WHERE \"COLUMN3_4\" = 5", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - - [Fact] - public void Limit() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT TOP (10) [id], [name] FROM [users]")] + [InlineData(EngineCodes.MySql, "SELECT `id`, `name` FROM `users` LIMIT 10")] + [InlineData(EngineCodes.PostgreSql, "SELECT \"id\", \"name\" FROM \"users\" LIMIT 10")] + [InlineData(EngineCodes.Firebird, "SELECT FIRST 10 \"ID\", \"NAME\" FROM \"USERS\"")] + public void Limit(string engine, string sqlText) { - var q = new Query().From("users").Select("id", "name").Limit(10); - var c = Compile(q); + var query = new Query().From("users").Select("id", "name").Limit(10); + + var c = CompileFor(engine, query); - // Assert.Equal(c[EngineCodes.SqlServer], "SELECT * FROM (SELECT [id], [name],ROW_NUMBER() OVER (SELECT 0) AS [row_num] FROM [users]) AS [temp_table] WHERE [row_num] >= 10"); - Assert.Equal("SELECT TOP (10) [id], [name] FROM [users]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT `id`, `name` FROM `users` LIMIT 10", c[EngineCodes.MySql]); - Assert.Equal("SELECT \"id\", \"name\" FROM \"users\" LIMIT 10", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT FIRST 10 \"ID\", \"NAME\" FROM \"USERS\"", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void Offset() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] >= 11")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `users` LIMIT 18446744073709551615 OFFSET 10")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"users\" OFFSET 10")] + [InlineData(EngineCodes.Firebird, "SELECT SKIP 10 * FROM \"USERS\"")] + public void Offset(string engine, string sqlText) { - var q = new Query().From("users").Offset(10); - var c = Compile(q); + var query = new Query().From("users").Offset(10); - Assert.Equal( - "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] >= 11", - c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM `users` LIMIT 18446744073709551615 OFFSET 10", c[EngineCodes.MySql]); - Assert.Equal("SELECT * FROM \"users\" OFFSET 10", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT SKIP 10 * FROM \"USERS\"", c[EngineCodes.Firebird]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void LimitOffset() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] BETWEEN 11 AND 15")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `users` LIMIT 5 OFFSET 10")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"users\" LIMIT 5 OFFSET 10")] + [InlineData(EngineCodes.Firebird, "SELECT * FROM \"USERS\" ROWS 11 TO 15")] + public void LimitOffset(string engine, string sqlText) { - var q = new Query().From("users").Offset(10).Limit(5); + var query = new Query().From("users").Offset(10).Limit(5); - var c = Compile(q); + var c = CompileFor(engine, query); - Assert.Equal( - "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] BETWEEN 11 AND 15", - c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM `users` LIMIT 5 OFFSET 10", c[EngineCodes.MySql]); - Assert.Equal("SELECT * FROM \"users\" LIMIT 5 OFFSET 10", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT * FROM \"USERS\" ROWS 11 TO 15", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } [Fact] From d009e7577965a2ab23ec36dfe9d97b4fcf4284b5 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 8 Dec 2024 16:13:38 +0100 Subject: [PATCH 13/27] Imporved SelectTests part 2 --- QueryBuilder.Tests/SelectTests.cs | 189 +++++++++++++++++------------- 1 file changed, 106 insertions(+), 83 deletions(-) diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs index 6804ade8..9c7b852f 100644 --- a/QueryBuilder.Tests/SelectTests.cs +++ b/QueryBuilder.Tests/SelectTests.cs @@ -631,17 +631,16 @@ public void LimitOffset(string engine, string sqlText) Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void BasicJoin() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [users] \nINNER JOIN [countries] ON [countries].[id] = [users].[country_id]")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `users` \nINNER JOIN `countries` ON `countries`.`id` = `users`.`country_id`")] + public void BasicJoin(string engine, string sqlText) { - var q = new Query().From("users").Join("countries", "countries.id", "users.country_id"); + var query = new Query().From("users").Join("countries", "countries.id", "users.country_id"); - var c = Compile(q); + var c = CompileFor(engine, query); - Assert.Equal("SELECT * FROM [users] \nINNER JOIN [countries] ON [countries].[id] = [users].[country_id]", - c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM `users` \nINNER JOIN `countries` ON `countries`.`id` = `users`.`country_id`", - c[EngineCodes.MySql]); + Assert.Equal(sqlText, c.ToString()); } [Theory] @@ -671,7 +670,6 @@ public void JoinTypes(string given, string output) c[EngineCodes.Firebird]); } - [Fact] public void OrWhereRawEscaped() { var query = new Query("Table").WhereRaw("[MyCol] = ANY(?::int\\[\\])", "{1,2,3}"); @@ -681,127 +679,151 @@ public void OrWhereRawEscaped() Assert.Equal("SELECT * FROM \"Table\" WHERE \"MyCol\" = ANY('{1,2,3}'::int[])", c[EngineCodes.PostgreSql]); } - [Fact] - public void Having() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING [Column1] > 1")] + public void Having(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .Having("Column1", ">", 1); - var c = Compile(q); - Assert.Equal("SELECT * FROM [Table1] HAVING [Column1] > 1", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void MultipleHaving() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING [Column1] > 1 AND [Column2] = 1")] + public void MultipleHaving(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .Having("Column1", ">", 1) .Having("Column2", "=", 1); - var c = Compile(q); - Assert.Equal("SELECT * FROM [Table1] HAVING [Column1] > 1 AND [Column2] = 1", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void MultipleOrHaving() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING [Column1] > 1 OR [Column2] = 1")] + public void MultipleOrHaving(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .Having("Column1", ">", 1) .OrHaving("Column2", "=", 1); - var c = Compile(q); - Assert.Equal("SELECT * FROM [Table1] HAVING [Column1] > 1 OR [Column2] = 1", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void ShouldUseILikeOnPostgresWhenNonCaseSensitive() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%upper word%'")] + [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table1\" WHERE \"Column1\" ilike '%Upper Word%'")] + public void ShouldUseILikeOnPostgresWhenNonCaseSensitive(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .WhereLike("Column1", "%Upper Word%", false); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%upper word%'", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT * FROM \"Table1\" WHERE \"Column1\" ilike '%Upper Word%'", c[EngineCodes.PostgreSql]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void EscapedWhereLike() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like 'teststring\\%' ESCAPE '\\'")] + public void EscapedWhereLike(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .WhereLike("Column1", @"TestString\%", false, @"\"); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] WHERE LOWER([Column1]) like 'teststring\%' ESCAPE '\'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void EscapedWhereStarts() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like 'teststring\\%%' ESCAPE '\\'")] + public void EscapedWhereStarts(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .WhereStarts("Column1", @"TestString\%", false, @"\"); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] WHERE LOWER([Column1]) like 'teststring\%%' ESCAPE '\'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void EscapedWhereEnds() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%teststring\\%' ESCAPE '\\'")] + public void EscapedWhereEnds(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .WhereEnds("Column1", @"TestString\%", false, @"\"); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%teststring\%' ESCAPE '\'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void EscapedWhereContains() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%teststring\\%%' ESCAPE '\\'")] + public void EscapedWhereContains(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .WhereContains("Column1", @"TestString\%", false, @"\"); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%teststring\%%' ESCAPE '\'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void EscapedHavingLike() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING LOWER([Column1]) like 'teststring\\%' ESCAPE '\\'")] + public void EscapedHavingLike(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .HavingLike("Column1", @"TestString\%", false, @"\"); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] HAVING LOWER([Column1]) like 'teststring\%' ESCAPE '\'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void EscapedHavingStarts() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING LOWER([Column1]) like 'teststring\\%%' ESCAPE '\\'")] + public void EscapedHavingStarts(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .HavingStarts("Column1", @"TestString\%", false, @"\"); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] HAVING LOWER([Column1]) like 'teststring\%%' ESCAPE '\'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void EscapedHavingEnds() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING LOWER([Column1]) like '%teststring\\%' ESCAPE '\\'")] + public void EscapedHavingEnds(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .HavingEnds("Column1", @"TestString\%", false, @"\"); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] HAVING LOWER([Column1]) like '%teststring\%' ESCAPE '\'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void EscapedHavingContains() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING LOWER([Column1]) like '%teststring\\%%' ESCAPE '\\'")] + public void EscapedHavingContains(string engine, string sqlText) { - var q = new Query("Table1") + var query = new Query("Table1") .HavingContains("Column1", @"TestString\%", false, @"\"); - var c = Compile(q); - Assert.Equal(@"SELECT * FROM [Table1] HAVING LOWER([Column1]) like '%teststring\%%' ESCAPE '\'", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -888,29 +910,31 @@ public void BasicSelectAggregateWithAlias() Assert.Equal("SELECT [Title], SUM([ViewCount]) AS [TotalViews] FROM [Posts]", sqlServer.ToString()); } - [Fact] - public void SelectWithFilter() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM(CASE WHEN [Published_Month] = 'Jan' THEN [ViewCount] END) AS [Published_Jan], SUM(CASE WHEN [Published_Month] = 'Feb' THEN [ViewCount] END) AS [Published_Feb] FROM [Posts]")] + [InlineData(EngineCodes.PostgreSql, "SELECT \"Title\", SUM(\"ViewCount\") FILTER (WHERE \"Published_Month\" = 'Jan') AS \"Published_Jan\", SUM(\"ViewCount\") FILTER (WHERE \"Published_Month\" = 'Feb') AS \"Published_Feb\" FROM \"Posts\"")] + public void SelectWithFilter(string engine, string sqlText) { - var q = new Query("Posts").Select("Title") + var query = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount as Published_Jan", q => q.Where("Published_Month", "Jan")) .SelectAggregate("sum", "ViewCount as Published_Feb", q => q.Where("Published_Month", "Feb")); - var pgSql = Compilers.CompileFor(EngineCodes.PostgreSql, q); - Assert.Equal("SELECT \"Title\", SUM(\"ViewCount\") FILTER (WHERE \"Published_Month\" = 'Jan') AS \"Published_Jan\", SUM(\"ViewCount\") FILTER (WHERE \"Published_Month\" = 'Feb') AS \"Published_Feb\" FROM \"Posts\"", pgSql.ToString()); + var c = CompileFor(engine, query); - var sqlServer = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT [Title], SUM(CASE WHEN [Published_Month] = 'Jan' THEN [ViewCount] END) AS [Published_Jan], SUM(CASE WHEN [Published_Month] = 'Feb' THEN [ViewCount] END) AS [Published_Feb] FROM [Posts]", sqlServer.ToString()); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void SelectWithExists() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Posts] WHERE EXISTS (SELECT 1 FROM [Comments] WHERE [Comments].[PostId] = [Posts].[Id])")] + public void SelectWithExists(string engine, string sqlText) { - var q = new Query("Posts").WhereExists( + var query = new Query("Posts").WhereExists( new Query("Comments").WhereColumns("Comments.PostId", "=", "Posts.Id") ); - var sqlServer = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT * FROM [Posts] WHERE EXISTS (SELECT 1 FROM [Comments] WHERE [Comments].[PostId] = [Posts].[Id])", sqlServer.ToString()); + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -929,6 +953,5 @@ 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()); } - } } From 1b3d430b7c00318f6b94a38fbfb2f9224957a780 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 22 Dec 2024 11:32:41 +0100 Subject: [PATCH 14/27] Imporved SelectTests part 3 --- .../Infrastructure/TestSupport.cs | 23 ++ QueryBuilder.Tests/SelectTests.cs | 280 +++++++++++------- 2 files changed, 199 insertions(+), 104 deletions(-) diff --git a/QueryBuilder.Tests/Infrastructure/TestSupport.cs b/QueryBuilder.Tests/Infrastructure/TestSupport.cs index d2fc2905..a5a3ba26 100644 --- a/QueryBuilder.Tests/Infrastructure/TestSupport.cs +++ b/QueryBuilder.Tests/Infrastructure/TestSupport.cs @@ -1,5 +1,7 @@ +using System; using System.Collections.Generic; using System.Linq; +using SqlKata.Compilers; namespace SqlKata.Tests.Infrastructure { @@ -22,5 +24,26 @@ protected SqlResult CompileFor(string engine, Query query) return Compilers.CompileFor(engine, query); } + protected SqlResult CompileFor(string engine, Query query, Action action) + { + var compiler = CreateCompiler(engine); + action(compiler); + + return compiler.Compile(query); + } + + private static Compiler CreateCompiler(string engine) + { + return engine switch + { + EngineCodes.Firebird => new FirebirdCompiler(), + EngineCodes.MySql => new MySqlCompiler(), + EngineCodes.Oracle => new OracleCompiler(), + EngineCodes.PostgreSql => new PostgresCompiler(), + EngineCodes.Sqlite => new SqliteCompiler(), + EngineCodes.SqlServer => new SqlServerCompiler(), + _ => throw new ArgumentException($"Unsupported engine type: {engine}", nameof(engine)), + }; + } } } diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs index 9c7b852f..0e107e0c 100644 --- a/QueryBuilder.Tests/SelectTests.cs +++ b/QueryBuilder.Tests/SelectTests.cs @@ -42,9 +42,12 @@ public void BasicSelectEnumerable(string engine, string sqlText) [Theory] [InlineData(EngineCodes.SqlServer, "SELECT [id], [name] FROM [users] WHERE [author] = '' OR [author] IS NULL")] [InlineData(EngineCodes.MySql, "SELECT `id`, `name` FROM `users` WHERE `author` = '' OR `author` IS NULL")] - [InlineData(EngineCodes.PostgreSql, "SELECT \"id\", \"name\" FROM \"users\" WHERE \"author\" = '' OR \"author\" IS NULL")] - [InlineData(EngineCodes.Firebird, "SELECT \"ID\", \"NAME\" FROM \"USERS\" WHERE \"AUTHOR\" = '' OR \"AUTHOR\" IS NULL")] - [InlineData(EngineCodes.Oracle, "SELECT \"id\", \"name\" FROM \"users\" WHERE \"author\" = '' OR \"author\" IS NULL")] + [InlineData(EngineCodes.PostgreSql, + "SELECT \"id\", \"name\" FROM \"users\" WHERE \"author\" = '' OR \"author\" IS NULL")] + [InlineData(EngineCodes.Firebird, + "SELECT \"ID\", \"NAME\" FROM \"USERS\" WHERE \"AUTHOR\" = '' OR \"AUTHOR\" IS NULL")] + [InlineData(EngineCodes.Oracle, + "SELECT \"id\", \"name\" FROM \"users\" WHERE \"author\" = '' OR \"author\" IS NULL")] public void BasicSelectWhereBindingIsEmptyOrNull(string engine, string sqlText) { var query = new Query() @@ -107,7 +110,8 @@ public void ExpandedSelectWithSchema() var query = new Query().From("users").Select("dbo.users.{id,name, age}"); var c = Compile(query); - Assert.Equal("SELECT [dbo].[users].[id], [dbo].[users].[name], [dbo].[users].[age] FROM [users]", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT [dbo].[users].[id], [dbo].[users].[name], [dbo].[users].[age] FROM [users]", + c[EngineCodes.SqlServer]); } [Fact] @@ -120,7 +124,8 @@ public void ExpandedSelectMultilineWithSchema() }"); var c = Compile(query); - Assert.Equal("SELECT [dbo].[users].[id], [dbo].[users].[name] AS [Name], [dbo].[users].[age] FROM [users]", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT [dbo].[users].[id], [dbo].[users].[name] AS [Name], [dbo].[users].[age] FROM [users]", + c[EngineCodes.SqlServer]); } [Theory] @@ -129,7 +134,7 @@ public void ExpandedSelectMultilineWithSchema() public void NestedEmptyWhereAtFirstCondition(string engine, string sqlText) { var query = new Query("table") - .Where(q => new Query()) + .Where(_ => new Query()) .Where("id", 1); var c = CompileFor(engine, query); @@ -166,7 +171,8 @@ public void WhereFalse(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] = cast(0 as bit)")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] = cast(0 as bit)")] [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"MyCol\" = 'abc' OR \"IsActive\" = false")] public void OrWhereFalse(string engine, string sqlText) { @@ -178,7 +184,8 @@ public void OrWhereFalse(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] = cast(1 as bit)")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table] WHERE [MyCol] = 'abc' OR [IsActive] = cast(1 as bit)")] [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"MyCol\" = 'abc' OR \"IsActive\" = true")] public void OrWhereTrue(string engine, string sqlText) { @@ -187,7 +194,6 @@ public void OrWhereTrue(string engine, string sqlText) var c = CompileFor(engine, query); Assert.Equal(sqlText, c.ToString()); - } [Theory] @@ -203,8 +209,10 @@ public void OrWhereNull(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE (SELECT COUNT(*) AS [count] FROM [Table2] WHERE [Table2].[Column] = [Table].[MyCol]) = 1")] - [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE (SELECT COUNT(*) AS \"count\" FROM \"Table2\" WHERE \"Table2\".\"Column\" = \"Table\".\"MyCol\") = 1")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table] WHERE (SELECT COUNT(*) AS [count] FROM [Table2] WHERE [Table2].[Column] = [Table].[MyCol]) = 1")] + [InlineData(EngineCodes.PostgreSql, + "SELECT * FROM \"Table\" WHERE (SELECT COUNT(*) AS \"count\" FROM \"Table2\" WHERE \"Table2\".\"Column\" = \"Table\".\"MyCol\") = 1")] public void WhereSub(string engine, string sqlText) { var subQuery = new Query("Table2").WhereColumns("Table2.Column", "=", "Table.MyCol").AsCount(); @@ -217,8 +225,10 @@ public void WhereSub(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table] WHERE [MyCol] IS NULL OR (SELECT COUNT(*) AS [count] FROM [Table2] WHERE [Table2].[Column] = [Table].[MyCol]) < 1")] - [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Table\" WHERE \"MyCol\" IS NULL OR (SELECT COUNT(*) AS \"count\" FROM \"Table2\" WHERE \"Table2\".\"Column\" = \"Table\".\"MyCol\") < 1")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table] WHERE [MyCol] IS NULL OR (SELECT COUNT(*) AS [count] FROM [Table2] WHERE [Table2].[Column] = [Table].[MyCol]) < 1")] + [InlineData(EngineCodes.PostgreSql, + "SELECT * FROM \"Table\" WHERE \"MyCol\" IS NULL OR (SELECT COUNT(*) AS \"count\" FROM \"Table2\" WHERE \"Table2\".\"Column\" = \"Table\".\"MyCol\") < 1")] public void OrWhereSub(string engine, string sqlText) { var subQuery = new Query("Table2").WhereColumns("Table2.Column", "=", "Table.MyCol").AsCount(); @@ -247,7 +257,8 @@ public void UsingJsonArray() var c = Compile(query); - Assert.Equal("SELECT * FROM \"Table\" WHERE \"Json\"->'address'->>'country' in (1,2,3,4)", c[EngineCodes.PostgreSql]); + Assert.Equal("SELECT * FROM \"Table\" WHERE \"Json\"->'address'->>'country' in (1,2,3,4)", + c[EngineCodes.PostgreSql]); } [Theory] @@ -266,9 +277,11 @@ public void Union(string engine, string sqlText) [Theory] [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] WHERE [Type] = 'A'")] - [InlineData(EngineCodes.Sqlite, "SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] + [InlineData(EngineCodes.Sqlite, + "SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] [InlineData(EngineCodes.MySql, "SELECT * FROM `Phones` UNION SELECT * FROM `Laptops` WHERE `Type` = 'A'")] - [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\" WHERE \"TYPE\" = 'A'")] + [InlineData(EngineCodes.Firebird, + "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\" WHERE \"TYPE\" = 'A'")] public void UnionWithBindings(string engine, string sqlText) { var laptops = new Query("Laptops").Where("Type", "A"); @@ -281,9 +294,11 @@ public void UnionWithBindings(string engine, string sqlText) [Theory] [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] WHERE [Type] = 'A'")] - [InlineData(EngineCodes.Sqlite, "SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] + [InlineData(EngineCodes.Sqlite, + "SELECT * FROM \"Phones\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] [InlineData(EngineCodes.MySql, "SELECT * FROM `Phones` UNION SELECT * FROM `Laptops` WHERE `Type` = 'A'")] - [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] // Is this good? + [InlineData(EngineCodes.Firebird, + "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"Laptops\" WHERE \"Type\" = 'A'")] // Is this good? public void RawUnionWithBindings(string engine, string sqlText) { var mobiles = new Query("Phones").UnionRaw("UNION SELECT * FROM [Laptops] WHERE [Type] = ?", "A"); @@ -294,8 +309,10 @@ public void RawUnionWithBindings(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] UNION SELECT * FROM [Tablets]")] - [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\" UNION SELECT * FROM \"TABLETS\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Phones] UNION SELECT * FROM [Laptops] UNION SELECT * FROM [Tablets]")] + [InlineData(EngineCodes.Firebird, + "SELECT * FROM \"PHONES\" UNION SELECT * FROM \"LAPTOPS\" UNION SELECT * FROM \"TABLETS\"")] public void MultipleUnion(string engine, string sqlText) { var laptops = new Query("Laptops"); @@ -306,12 +323,13 @@ public void MultipleUnion(string engine, string sqlText) var c = CompileFor(engine, mobiles); Assert.Equal(sqlText, c.ToString()); - } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] WHERE [Price] > 1000 UNION SELECT * FROM [Tablets] WHERE [Price] > 2000")] - [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" > 1000 UNION SELECT * FROM \"TABLETS\" WHERE \"PRICE\" > 2000")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] WHERE [Price] > 1000 UNION SELECT * FROM [Tablets] WHERE [Price] > 2000")] + [InlineData(EngineCodes.Firebird, + "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" > 1000 UNION SELECT * FROM \"TABLETS\" WHERE \"PRICE\" > 2000")] public void MultipleUnionWithBindings(string engine, string sqlText) { var laptops = new Query("Laptops").Where("Price", ">", 1000); @@ -325,8 +343,10 @@ public void MultipleUnionWithBindings(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] WHERE [Price] > 1000 UNION ALL SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Tablets] WHERE [Price] > 2000) AS [results_wrapper] WHERE [row_num] BETWEEN 16 AND 30")] - [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" > 1000 UNION ALL SELECT * FROM \"TABLETS\" WHERE \"PRICE\" > 2000 ROWS 16 TO 30")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] WHERE [Price] > 1000 UNION ALL SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Tablets] WHERE [Price] > 2000) AS [results_wrapper] WHERE [row_num] BETWEEN 16 AND 30")] + [InlineData(EngineCodes.Firebird, + "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" > 1000 UNION ALL SELECT * FROM \"TABLETS\" WHERE \"PRICE\" > 2000 ROWS 16 TO 30")] public void MultipleUnionWithBindingsAndPagination(string engine, string sqlText) { var laptops = new Query("Laptops").Where("Price", ">", 1000); @@ -340,8 +360,10 @@ public void MultipleUnionWithBindingsAndPagination(string engine, string sqlText } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] UNION ALL SELECT * FROM [Tablets]")] - [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" UNION ALL SELECT * FROM \"TABLETS\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Phones] WHERE [Price] < 3000 UNION SELECT * FROM [Laptops] UNION ALL SELECT * FROM [Tablets]")] + [InlineData(EngineCodes.Firebird, + "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 3000 UNION SELECT * FROM \"LAPTOPS\" UNION ALL SELECT * FROM \"TABLETS\"")] public void UnionWithCallbacks(string engine, string sqlText) { var mobiles = new Query("Phones") @@ -355,10 +377,14 @@ public void UnionWithCallbacks(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Phones] WHERE [Price] < 300 EXCEPT SELECT * FROM [Phones] WHERE NOT ([Os] = 'iOS') UNION ALL SELECT * FROM [Tablets] WHERE [Price] < 100")] - [InlineData(EngineCodes.MySql, "SELECT * FROM `Phones` WHERE `Price` < 300 INTERSECT ALL SELECT * FROM `Watches` WHERE `Os` = 'Android' UNION ALL SELECT * FROM `Tablets` WHERE `Price` < 100")] - [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Phones\" WHERE \"Price\" < 300 UNION SELECT * FROM \"Laptops\" WHERE \"Price\" < 800 UNION ALL SELECT * FROM \"Tablets\" WHERE \"Price\" < 100")] - [InlineData(EngineCodes.Firebird, "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 300 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" < 800 UNION ALL SELECT * FROM \"TABLETS\" WHERE \"PRICE\" < 100")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Phones] WHERE [Price] < 300 EXCEPT SELECT * FROM [Phones] WHERE NOT ([Os] = 'iOS') UNION ALL SELECT * FROM [Tablets] WHERE [Price] < 100")] + [InlineData(EngineCodes.MySql, + "SELECT * FROM `Phones` WHERE `Price` < 300 INTERSECT ALL SELECT * FROM `Watches` WHERE `Os` = 'Android' UNION ALL SELECT * FROM `Tablets` WHERE `Price` < 100")] + [InlineData(EngineCodes.PostgreSql, + "SELECT * FROM \"Phones\" WHERE \"Price\" < 300 UNION SELECT * FROM \"Laptops\" WHERE \"Price\" < 800 UNION ALL SELECT * FROM \"Tablets\" WHERE \"Price\" < 100")] + [InlineData(EngineCodes.Firebird, + "SELECT * FROM \"PHONES\" WHERE \"PRICE\" < 300 UNION SELECT * FROM \"LAPTOPS\" WHERE \"PRICE\" < 800 UNION ALL SELECT * FROM \"TABLETS\" WHERE \"PRICE\" < 100")] public void UnionWithDifferentEngine(string engine, string sqlText) { var mobiles = new Query("Phones") @@ -401,7 +427,7 @@ public void CombineRawWithPlaceholders(string engine, string sqlText) public void NestedEmptyWhere() { // Empty nested where should be ignored - var query = new Query("A").Where(q => new Query().Where(q2 => new Query().Where(q3 => new Query()))); + var query = new Query("A").Where(_ => new Query().Where(_ => new Query().Where(_ => new Query()))); var c = Compile(query); @@ -411,7 +437,7 @@ public void NestedEmptyWhere() [Fact] public void NestedQuery() { - var query = new Query("A").Where(q => new Query("B")); + var query = new Query("A").Where(_ => new Query("B")); var c = Compile(query); @@ -424,7 +450,7 @@ public void NestedQueryAfterNestedJoin() // in this test, i am testing the compiler dynamic caching functionality var query = new Query("users") .Join("countries", j => j.On("countries.id", "users.country_id")) - .Where(q => new Query()); + .Where(_ => new Query()); var c = Compile(query); @@ -452,10 +478,14 @@ public void MultipleCte() } [Theory] - [InlineData(EngineCodes.SqlServer, "WITH [range] AS (SELECT [Number] FROM [Sequence] WHERE [Number] < 78)\nSELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Races] WHERE [Id] > 55 AND [Value] BETWEEN 18 AND 24) AS [results_wrapper] WHERE [row_num] BETWEEN 21 AND 45")] - [InlineData(EngineCodes.MySql, "WITH `range` AS (SELECT `Id` FROM `seqtbl` WHERE `Id` < 33)\nSELECT * FROM `Races` WHERE `RaceAuthor` IN (SELECT `Name` FROM `Users` WHERE `Status` = 'Available') AND `Id` > 55 AND `Value` BETWEEN 18 AND 24")] - [InlineData(EngineCodes.PostgreSql, "WITH \"range\" AS (SELECT \"d\" FROM generate_series(1, 33) as d)\nSELECT * FROM \"Races\" WHERE \"Name\" = '3778' AND \"Id\" > 55 AND \"Value\" BETWEEN 18 AND 24")] - [InlineData(EngineCodes.Firebird, "WITH \"RANGE\" AS (SELECT \"D\" FROM generate_series(1, 33) as d)\nSELECT * FROM \"RACES\" WHERE \"NAME\" = '3778' AND \"ID\" > 55 AND \"VALUE\" BETWEEN 18 AND 24")] + [InlineData(EngineCodes.SqlServer, + "WITH [range] AS (SELECT [Number] FROM [Sequence] WHERE [Number] < 78)\nSELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Races] WHERE [Id] > 55 AND [Value] BETWEEN 18 AND 24) AS [results_wrapper] WHERE [row_num] BETWEEN 21 AND 45")] + [InlineData(EngineCodes.MySql, + "WITH `range` AS (SELECT `Id` FROM `seqtbl` WHERE `Id` < 33)\nSELECT * FROM `Races` WHERE `RaceAuthor` IN (SELECT `Name` FROM `Users` WHERE `Status` = 'Available') AND `Id` > 55 AND `Value` BETWEEN 18 AND 24")] + [InlineData(EngineCodes.PostgreSql, + "WITH \"range\" AS (SELECT \"d\" FROM generate_series(1, 33) as d)\nSELECT * FROM \"Races\" WHERE \"Name\" = '3778' AND \"Id\" > 55 AND \"Value\" BETWEEN 18 AND 24")] + [InlineData(EngineCodes.Firebird, + "WITH \"RANGE\" AS (SELECT \"D\" FROM generate_series(1, 33) as d)\nSELECT * FROM \"RACES\" WHERE \"NAME\" = '3778' AND \"ID\" > 55 AND \"VALUE\" BETWEEN 18 AND 24")] public void CteAndBindings(string engine, string sqlText) { var query = new Query("Races") @@ -491,10 +521,14 @@ public void CteAndBindings(string engine, string sqlText) // test for issue #50 [Theory] - [InlineData(EngineCodes.SqlServer, "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2)\nSELECT * FROM [cte2] WHERE [Column3] = 5")] - [InlineData(EngineCodes.MySql, "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2)\nSELECT * FROM `cte2` WHERE `Column3` = 5")] - [InlineData(EngineCodes.PostgreSql, "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2)\nSELECT * FROM \"cte2\" WHERE \"Column3\" = 5")] - [InlineData(EngineCodes.Firebird, "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2)\nSELECT * FROM \"CTE2\" WHERE \"COLUMN3\" = 5")] + [InlineData(EngineCodes.SqlServer, + "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2)\nSELECT * FROM [cte2] WHERE [Column3] = 5")] + [InlineData(EngineCodes.MySql, + "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2)\nSELECT * FROM `cte2` WHERE `Column3` = 5")] + [InlineData(EngineCodes.PostgreSql, + "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2)\nSELECT * FROM \"cte2\" WHERE \"Column3\" = 5")] + [InlineData(EngineCodes.Firebird, + "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2)\nSELECT * FROM \"CTE2\" WHERE \"COLUMN3\" = 5")] public void CascadedCteAndBindings(string engine, string sqlText) { var cte1 = new Query("Table1"); @@ -520,10 +554,14 @@ public void CascadedCteAndBindings(string engine, string sqlText) // test for issue #50 [Theory] - [InlineData(EngineCodes.SqlServer, "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2),\n[cte3] AS (SELECT [Column3_3], [Column3_4] FROM [Table3] \nINNER JOIN [cte1] ON ([Column1] = [Column3_3]) WHERE [Column3_4] = 33)\nSELECT * FROM [cte2] WHERE [Column3] = 5")] - [InlineData(EngineCodes.MySql, "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2),\n`cte3` AS (SELECT `Column3_3`, `Column3_4` FROM `Table3` \nINNER JOIN `cte1` ON (`Column1` = `Column3_3`) WHERE `Column3_4` = 33)\nSELECT * FROM `cte2` WHERE `Column3` = 5")] - [InlineData(EngineCodes.PostgreSql, "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2),\n\"cte3\" AS (SELECT \"Column3_3\", \"Column3_4\" FROM \"Table3\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3_3\") WHERE \"Column3_4\" = 33)\nSELECT * FROM \"cte2\" WHERE \"Column3\" = 5")] - [InlineData(EngineCodes.Firebird, "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2),\n\"CTE3\" AS (SELECT \"COLUMN3_3\", \"COLUMN3_4\" FROM \"TABLE3\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3_3\") WHERE \"COLUMN3_4\" = 33)\nSELECT * FROM \"CTE2\" WHERE \"COLUMN3\" = 5")] + [InlineData(EngineCodes.SqlServer, + "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2),\n[cte3] AS (SELECT [Column3_3], [Column3_4] FROM [Table3] \nINNER JOIN [cte1] ON ([Column1] = [Column3_3]) WHERE [Column3_4] = 33)\nSELECT * FROM [cte2] WHERE [Column3] = 5")] + [InlineData(EngineCodes.MySql, + "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2),\n`cte3` AS (SELECT `Column3_3`, `Column3_4` FROM `Table3` \nINNER JOIN `cte1` ON (`Column1` = `Column3_3`) WHERE `Column3_4` = 33)\nSELECT * FROM `cte2` WHERE `Column3` = 5")] + [InlineData(EngineCodes.PostgreSql, + "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2),\n\"cte3\" AS (SELECT \"Column3_3\", \"Column3_4\" FROM \"Table3\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3_3\") WHERE \"Column3_4\" = 33)\nSELECT * FROM \"cte2\" WHERE \"Column3\" = 5")] + [InlineData(EngineCodes.Firebird, + "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2),\n\"CTE3\" AS (SELECT \"COLUMN3_3\", \"COLUMN3_4\" FROM \"TABLE3\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3_3\") WHERE \"COLUMN3_4\" = 33)\nSELECT * FROM \"CTE2\" WHERE \"COLUMN3\" = 5")] public void CascadedAndMultiReferencedCteAndBindings(string engine, string sqlText) { var cte1 = new Query("Table1"); @@ -556,10 +594,14 @@ public void CascadedAndMultiReferencedCteAndBindings(string engine, string sqlTe // test for issue #50 [Theory] - [InlineData(EngineCodes.SqlServer, "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2),\n[cte3] AS (SELECT [Column3_3], [Column3_4] FROM [Table3] \nINNER JOIN [cte1] ON ([Column1] = [Column3_3]) WHERE [Column3_4] = 33)\nSELECT * FROM [cte3] WHERE [Column3_4] = 5")] - [InlineData(EngineCodes.MySql, "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2),\n`cte3` AS (SELECT `Column3_3`, `Column3_4` FROM `Table3` \nINNER JOIN `cte1` ON (`Column1` = `Column3_3`) WHERE `Column3_4` = 33)\nSELECT * FROM `cte3` WHERE `Column3_4` = 5")] - [InlineData(EngineCodes.PostgreSql, "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2),\n\"cte3\" AS (SELECT \"Column3_3\", \"Column3_4\" FROM \"Table3\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3_3\") WHERE \"Column3_4\" = 33)\nSELECT * FROM \"cte3\" WHERE \"Column3_4\" = 5")] - [InlineData(EngineCodes.Firebird, "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2),\n\"CTE3\" AS (SELECT \"COLUMN3_3\", \"COLUMN3_4\" FROM \"TABLE3\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3_3\") WHERE \"COLUMN3_4\" = 33)\nSELECT * FROM \"CTE3\" WHERE \"COLUMN3_4\" = 5")] + [InlineData(EngineCodes.SqlServer, + "WITH [cte1] AS (SELECT [Column1], [Column2] FROM [Table1] WHERE [Column2] = 1),\n[cte2] AS (SELECT [Column3], [Column4] FROM [Table2] \nINNER JOIN [cte1] ON ([Column1] = [Column3]) WHERE [Column4] = 2),\n[cte3] AS (SELECT [Column3_3], [Column3_4] FROM [Table3] \nINNER JOIN [cte1] ON ([Column1] = [Column3_3]) WHERE [Column3_4] = 33)\nSELECT * FROM [cte3] WHERE [Column3_4] = 5")] + [InlineData(EngineCodes.MySql, + "WITH `cte1` AS (SELECT `Column1`, `Column2` FROM `Table1` WHERE `Column2` = 1),\n`cte2` AS (SELECT `Column3`, `Column4` FROM `Table2` \nINNER JOIN `cte1` ON (`Column1` = `Column3`) WHERE `Column4` = 2),\n`cte3` AS (SELECT `Column3_3`, `Column3_4` FROM `Table3` \nINNER JOIN `cte1` ON (`Column1` = `Column3_3`) WHERE `Column3_4` = 33)\nSELECT * FROM `cte3` WHERE `Column3_4` = 5")] + [InlineData(EngineCodes.PostgreSql, + "WITH \"cte1\" AS (SELECT \"Column1\", \"Column2\" FROM \"Table1\" WHERE \"Column2\" = 1),\n\"cte2\" AS (SELECT \"Column3\", \"Column4\" FROM \"Table2\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3\") WHERE \"Column4\" = 2),\n\"cte3\" AS (SELECT \"Column3_3\", \"Column3_4\" FROM \"Table3\" \nINNER JOIN \"cte1\" ON (\"Column1\" = \"Column3_3\") WHERE \"Column3_4\" = 33)\nSELECT * FROM \"cte3\" WHERE \"Column3_4\" = 5")] + [InlineData(EngineCodes.Firebird, + "WITH \"CTE1\" AS (SELECT \"COLUMN1\", \"COLUMN2\" FROM \"TABLE1\" WHERE \"COLUMN2\" = 1),\n\"CTE2\" AS (SELECT \"COLUMN3\", \"COLUMN4\" FROM \"TABLE2\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3\") WHERE \"COLUMN4\" = 2),\n\"CTE3\" AS (SELECT \"COLUMN3_3\", \"COLUMN3_4\" FROM \"TABLE3\" \nINNER JOIN \"CTE1\" ON (\"COLUMN1\" = \"COLUMN3_3\") WHERE \"COLUMN3_4\" = 33)\nSELECT * FROM \"CTE3\" WHERE \"COLUMN3_4\" = 5")] public void MultipleCtesAndBindings(string engine, string sqlText) { var cte1 = new Query("Table1"); @@ -604,7 +646,8 @@ public void Limit(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] >= 11")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] >= 11")] [InlineData(EngineCodes.MySql, "SELECT * FROM `users` LIMIT 18446744073709551615 OFFSET 10")] [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"users\" OFFSET 10")] [InlineData(EngineCodes.Firebird, "SELECT SKIP 10 * FROM \"USERS\"")] @@ -618,7 +661,8 @@ public void Offset(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] BETWEEN 11 AND 15")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [users]) AS [results_wrapper] WHERE [row_num] BETWEEN 11 AND 15")] [InlineData(EngineCodes.MySql, "SELECT * FROM `users` LIMIT 5 OFFSET 10")] [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"users\" LIMIT 5 OFFSET 10")] [InlineData(EngineCodes.Firebird, "SELECT * FROM \"USERS\" ROWS 11 TO 15")] @@ -632,8 +676,10 @@ public void LimitOffset(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [users] \nINNER JOIN [countries] ON [countries].[id] = [users].[country_id]")] - [InlineData(EngineCodes.MySql, "SELECT * FROM `users` \nINNER JOIN `countries` ON `countries`.`id` = `users`.`country_id`")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [users] \nINNER JOIN [countries] ON [countries].[id] = [users].[country_id]")] + [InlineData(EngineCodes.MySql, + "SELECT * FROM `users` \nINNER JOIN `countries` ON `countries`.`id` = `users`.`country_id`")] public void BasicJoin(string engine, string sqlText) { var query = new Query().From("users").Join("countries", "countries.id", "users.country_id"); @@ -670,6 +716,7 @@ public void JoinTypes(string given, string output) c[EngineCodes.Firebird]); } + [Fact] public void OrWhereRawEscaped() { var query = new Query("Table").WhereRaw("[MyCol] = ANY(?::int\\[\\])", "{1,2,3}"); @@ -723,7 +770,7 @@ public void MultipleOrHaving(string engine, string sqlText) public void ShouldUseILikeOnPostgresWhenNonCaseSensitive(string engine, string sqlText) { var query = new Query("Table1") - .WhereLike("Column1", "%Upper Word%", false); + .WhereLike("Column1", "%Upper Word%", caseSensitive: false); var c = CompileFor(engine, query); @@ -731,7 +778,8 @@ public void ShouldUseILikeOnPostgresWhenNonCaseSensitive(string engine, string s } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like 'teststring\\%' ESCAPE '\\'")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table1] WHERE LOWER([Column1]) like 'teststring\\%' ESCAPE '\\'")] public void EscapedWhereLike(string engine, string sqlText) { var query = new Query("Table1") @@ -743,7 +791,8 @@ public void EscapedWhereLike(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like 'teststring\\%%' ESCAPE '\\'")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table1] WHERE LOWER([Column1]) like 'teststring\\%%' ESCAPE '\\'")] public void EscapedWhereStarts(string engine, string sqlText) { var query = new Query("Table1") @@ -755,7 +804,8 @@ public void EscapedWhereStarts(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%teststring\\%' ESCAPE '\\'")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%teststring\\%' ESCAPE '\\'")] public void EscapedWhereEnds(string engine, string sqlText) { var query = new Query("Table1") @@ -767,7 +817,8 @@ public void EscapedWhereEnds(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%teststring\\%%' ESCAPE '\\'")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table1] WHERE LOWER([Column1]) like '%teststring\\%%' ESCAPE '\\'")] public void EscapedWhereContains(string engine, string sqlText) { var query = new Query("Table1") @@ -779,7 +830,8 @@ public void EscapedWhereContains(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING LOWER([Column1]) like 'teststring\\%' ESCAPE '\\'")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table1] HAVING LOWER([Column1]) like 'teststring\\%' ESCAPE '\\'")] public void EscapedHavingLike(string engine, string sqlText) { var query = new Query("Table1") @@ -791,7 +843,8 @@ public void EscapedHavingLike(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING LOWER([Column1]) like 'teststring\\%%' ESCAPE '\\'")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table1] HAVING LOWER([Column1]) like 'teststring\\%%' ESCAPE '\\'")] public void EscapedHavingStarts(string engine, string sqlText) { var query = new Query("Table1") @@ -803,7 +856,8 @@ public void EscapedHavingStarts(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING LOWER([Column1]) like '%teststring\\%' ESCAPE '\\'")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table1] HAVING LOWER([Column1]) like '%teststring\\%' ESCAPE '\\'")] public void EscapedHavingEnds(string engine, string sqlText) { var query = new Query("Table1") @@ -815,7 +869,8 @@ public void EscapedHavingEnds(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] HAVING LOWER([Column1]) like '%teststring\\%%' ESCAPE '\\'")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Table1] HAVING LOWER([Column1]) like '%teststring\\%%' ESCAPE '\\'")] public void EscapedHavingContains(string engine, string sqlText) { var query = new Query("Table1") @@ -831,7 +886,7 @@ public void EscapeClauseThrowsForMultipleCharacters() { Assert.ThrowsAny(() => { - var q = new Query("Table1") + _ = new Query("Table1") .HavingContains("Column1", @"TestString\%", false, @"\aa"); }); } @@ -846,73 +901,92 @@ public void BasicSelectRaw_WithNoTable() Assert.Equal("SELECT somefunction() as c1", c.ToString()); } - [Fact] - public void BasicSelect_WithNoTable() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [c1]")] + public void BasicSelect_WithNoTable(string engine, string sqlText) { var q = new Query().Select("c1"); - var c = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT [c1]", c.ToString()); + + var c = CompileFor(engine, q); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void BasicSelect_WithNoTableAndWhereClause() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [c1] WHERE [p] = 1")] + public void BasicSelect_WithNoTableAndWhereClause(string engine, string sqlText) { var q = new Query().Select("c1").Where("p", 1); - var c = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT [c1] WHERE [p] = 1", c.ToString()); + + var c = CompileFor(engine, q); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void BasicSelect_WithNoTableWhereRawClause() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [c1] WHERE 1 = 1")] + public void BasicSelect_WithNoTableWhereRawClause(string engine, string sqlText) { var q = new Query().Select("c1").WhereRaw("1 = 1"); - var c = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT [c1] WHERE 1 = 1", c.ToString()); + + var c = CompileFor(engine, q); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void BasicSelectAggregate() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM([ViewCount]) FROM [Posts]")] + public void BasicSelectAggregate(string engine, string sqlText) { var q = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount"); - var sqlServer = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT [Title], SUM([ViewCount]) FROM [Posts]", sqlServer.ToString()); + var c = CompileFor(engine, q); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void SelectAggregateShouldIgnoreEmptyFilter() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM([ViewCount]) FROM [Posts]")] + public void SelectAggregateShouldIgnoreEmptyFilter(string engine, string sqlText) { var q = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount", q => q); - var sqlServer = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT [Title], SUM([ViewCount]) FROM [Posts]", sqlServer.ToString()); + var c = CompileFor(engine, q); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void SelectAggregateShouldIgnoreEmptyQueryFilter() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM([ViewCount]) FROM [Posts]")] + public void SelectAggregateShouldIgnoreEmptyQueryFilter(string engine, string sqlText) { var q = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount", new Query()); - var sqlServer = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT [Title], SUM([ViewCount]) FROM [Posts]", sqlServer.ToString()); + var c = CompileFor(engine, q); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void BasicSelectAggregateWithAlias() + [Theory] + [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM([ViewCount]) AS [TotalViews] FROM [Posts]")] + public void BasicSelectAggregateWithAlias(string engine, string sqlText) { var q = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount as TotalViews"); - var sqlServer = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT [Title], SUM([ViewCount]) AS [TotalViews] FROM [Posts]", sqlServer.ToString()); + var c = CompileFor(engine, q); + + Assert.Equal(sqlText, c.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM(CASE WHEN [Published_Month] = 'Jan' THEN [ViewCount] END) AS [Published_Jan], SUM(CASE WHEN [Published_Month] = 'Feb' THEN [ViewCount] END) AS [Published_Feb] FROM [Posts]")] - [InlineData(EngineCodes.PostgreSql, "SELECT \"Title\", SUM(\"ViewCount\") FILTER (WHERE \"Published_Month\" = 'Jan') AS \"Published_Jan\", SUM(\"ViewCount\") FILTER (WHERE \"Published_Month\" = 'Feb') AS \"Published_Feb\" FROM \"Posts\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT [Title], SUM(CASE WHEN [Published_Month] = 'Jan' THEN [ViewCount] END) AS [Published_Jan], SUM(CASE WHEN [Published_Month] = 'Feb' THEN [ViewCount] END) AS [Published_Feb] FROM [Posts]")] + [InlineData(EngineCodes.PostgreSql, + "SELECT \"Title\", SUM(\"ViewCount\") FILTER (WHERE \"Published_Month\" = 'Jan') AS \"Published_Jan\", SUM(\"ViewCount\") FILTER (WHERE \"Published_Month\" = 'Feb') AS \"Published_Feb\" FROM \"Posts\"")] public void SelectWithFilter(string engine, string sqlText) { var query = new Query("Posts").Select("Title") @@ -925,7 +999,8 @@ public void SelectWithFilter(string engine, string sqlText) } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Posts] WHERE EXISTS (SELECT 1 FROM [Comments] WHERE [Comments].[PostId] = [Posts].[Id])")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Posts] WHERE EXISTS (SELECT 1 FROM [Comments] WHERE [Comments].[PostId] = [Posts].[Id])")] public void SelectWithExists(string engine, string sqlText) { var query = new Query("Posts").WhereExists( @@ -937,21 +1012,18 @@ public void SelectWithExists(string engine, string sqlText) Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void SelectWithExists_OmitSelectIsFalse() + [Theory] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Posts] WHERE EXISTS (SELECT [Id] FROM [Comments] WHERE [Comments].[PostId] = [Posts].[Id])")] + public void SelectWithExists_OmitSelectIsFalse(string engine, string sqlText) { var q = new Query("Posts").WhereExists( new Query("Comments").Select("Id").WhereColumns("Comments.PostId", "=", "Posts.Id") ); + var c = CompileFor(engine, q, compiler1 => { compiler1.OmitSelectInsideExists = false; }); - var compiler = new SqlServerCompiler - { - OmitSelectInsideExists = false, - }; - - var sqlServer = compiler.Compile(q).ToString(); - Assert.Equal("SELECT * FROM [Posts] WHERE EXISTS (SELECT [Id] FROM [Comments] WHERE [Comments].[PostId] = [Posts].[Id])", sqlServer.ToString()); + Assert.Equal(sqlText, c.ToString()); } } } From 1496dbd3bea1dcf21ac88358f5e33da54197e399 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 22 Dec 2024 12:34:58 +0100 Subject: [PATCH 15/27] Improved UpdateTests --- QueryBuilder.Tests/UpdateTests.cs | 233 ++++++++++++------------------ 1 file changed, 96 insertions(+), 137 deletions(-) diff --git a/QueryBuilder.Tests/UpdateTests.cs b/QueryBuilder.Tests/UpdateTests.cs index bf3dd7d9..c57765e8 100644 --- a/QueryBuilder.Tests/UpdateTests.cs +++ b/QueryBuilder.Tests/UpdateTests.cs @@ -55,8 +55,10 @@ public OrderProductComposite(string orderid, string productid, int quantity) public string Foo { get; set; } } - [Fact] - public void UpdateObject() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'")] + [InlineData(EngineCodes.Firebird, "UPDATE \"TABLE\" SET \"NAME\" = 'The User', \"AGE\" = '2018-01-01'")] + public void UpdateObject(string engine, string sqlText) { var query = new Query("Table").AsUpdate(new { @@ -64,122 +66,107 @@ public void UpdateObject() Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal( - "UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'", - c[EngineCodes.SqlServer]); - - Assert.Equal( - "UPDATE \"TABLE\" SET \"NAME\" = 'The User', \"AGE\" = '2018-01-01'", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UpdateWithNullValues() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Books] SET [Author] = 'Author 1', [Date] = NULL, [Version] = NULL WHERE [Id] = 1")] + [InlineData(EngineCodes.Firebird, "UPDATE \"BOOKS\" SET \"AUTHOR\" = 'Author 1', \"DATE\" = NULL, \"VERSION\" = NULL WHERE \"ID\" = 1")] + public void UpdateWithNullValues(string engine, string sqlText) { var query = new Query("Books").Where("Id", 1).AsUpdate( new[] { "Author", "Date", "Version" }, new object[] { "Author 1", null, null } ); - var c = Compile(query); - - Assert.Equal( - "UPDATE [Books] SET [Author] = 'Author 1', [Date] = NULL, [Version] = NULL WHERE [Id] = 1", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "UPDATE \"BOOKS\" SET \"AUTHOR\" = 'Author 1', \"DATE\" = NULL, \"VERSION\" = NULL WHERE \"ID\" = 1", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UpdateWithEmptyString() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Books] SET [Author] = 'Author 1', [Description] = '' WHERE [Id] = 1")] + [InlineData(EngineCodes.Firebird, "UPDATE \"BOOKS\" SET \"AUTHOR\" = 'Author 1', \"DESCRIPTION\" = '' WHERE \"ID\" = 1")] + public void UpdateWithEmptyString(string engine, string sqlText) { var query = new Query("Books").Where("Id", 1).AsUpdate( new[] { "Author", "Description" }, new object[] { "Author 1", "" } ); - var c = Compile(query); - - Assert.Equal("UPDATE [Books] SET [Author] = 'Author 1', [Description] = '' WHERE [Id] = 1", c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal("UPDATE \"BOOKS\" SET \"AUTHOR\" = 'Author 1', \"DESCRIPTION\" = '' WHERE \"ID\" = 1", c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UpdateWithCte() + [Theory] + [InlineData(EngineCodes.SqlServer, + "WITH [OldBooks] AS (SELECT * FROM [Books] WHERE [Date] < '2024-05-24')\nUPDATE [Books] SET [Price] = '150' WHERE [Price] > 100")] + public void UpdateWithCte(string engine, string sqlText) { - var now = DateTime.UtcNow.ToString("yyyy-MM-dd"); - var query = new Query("Books") - .With("OldBooks", q => q.From("Books").Where("Date", "<", now)) + .With("OldBooks", q => q.From("Books").Where("Date", "<", "2024-05-24")) .Where("Price", ">", 100) .AsUpdate(new Dictionary { {"Price", "150"} }); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal( - $"WITH [OldBooks] AS (SELECT * FROM [Books] WHERE [Date] < '{now}')\nUPDATE [Books] SET [Price] = '150' WHERE [Price] > 100", - c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UpdateWithIgnoreAndColumnProperties() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Book] SET [Name] = 'SqlKataBook', [Author] = 'Kata', [Price] = 100")] + [InlineData(EngineCodes.Firebird, "UPDATE \"BOOK\" SET \"NAME\" = 'SqlKataBook', \"AUTHOR\" = 'Kata', \"PRICE\" = 100")] + public void UpdateWithIgnoreAndColumnProperties(string engine, string sqlText) { var book = new Book(name: $"SqlKataBook", author: "Kata", color: $"red", price: 100m); var query = new Query("Book").AsUpdate(book); - var c = Compile(query); - - Assert.Equal( - "UPDATE [Book] SET [Name] = 'SqlKataBook', [Author] = 'Kata', [Price] = 100", - c[EngineCodes.SqlServer]); + var c = CompileFor(engine, query); - Assert.Equal( - "UPDATE \"BOOK\" SET \"NAME\" = 'SqlKataBook', \"AUTHOR\" = 'Kata', \"PRICE\" = 100", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UpdateWithKeyAttribute() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [OrderProductComposite] SET [OrdId] = 'ORD01', [ProductId] = 'PROD02', [Quantity] = 20, [Faa] = 'baz' WHERE [OrdId] = 'ORD01' AND [ProductId] = 'PROD02'")] + [InlineData(EngineCodes.Firebird, "UPDATE \"ORDERPRODUCTCOMPOSITE\" SET \"ORDID\" = 'ORD01', \"PRODUCTID\" = 'PROD02', \"QUANTITY\" = 20, \"FAA\" = 'baz' WHERE \"ORDID\" = 'ORD01' AND \"PRODUCTID\" = 'PROD02'")] + public void UpdateWithKeyAttribute(string engine, string sqlText) { var order = new OrderProductComposite("ORD01", "PROD02", 20); var query = new Query("OrderProductComposite").AsUpdate(order); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal( - "UPDATE [OrderProductComposite] SET [OrdId] = 'ORD01', [ProductId] = 'PROD02', [Quantity] = 20, [Faa] = 'baz' WHERE [OrdId] = 'ORD01' AND [ProductId] = 'PROD02'", - c[EngineCodes.SqlServer]); - - Assert.Equal( - "UPDATE \"ORDERPRODUCTCOMPOSITE\" SET \"ORDID\" = 'ORD01', \"PRODUCTID\" = 'PROD02', \"QUANTITY\" = 20, \"FAA\" = 'baz' WHERE \"ORDID\" = 'ORD01' AND \"PRODUCTID\" = 'PROD02'", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UpdateFromRaw() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE Table.With.Dots SET [Name] = 'The User'")] + public void UpdateFromRaw(string engine, string sqlText) { var query = new Query().FromRaw("Table.With.Dots").AsUpdate(new { Name = "The User", }); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal( - "UPDATE Table.With.Dots SET [Name] = 'The User'", - c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UpdateFromQueryShouldFail() + [Theory] + [InlineData(EngineCodes.Firebird)] + [InlineData(EngineCodes.MySql)] + [InlineData(EngineCodes.Oracle)] + [InlineData(EngineCodes.PostgreSql)] + [InlineData(EngineCodes.Sqlite)] + [InlineData(EngineCodes.SqlServer)] + public void UpdateFromQueryShouldFail(string engine) { var query = new Query().From(new Query("InnerTable")).AsUpdate(new { @@ -188,12 +175,13 @@ public void UpdateFromQueryShouldFail() Assert.Throws(() => { - Compile(query); + _ = CompileFor(engine, query); }); } - [Fact] - public void update_should_compile_literal_without_parameters_holders() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [MyTable] SET [Name] = ?, [Address] = @address")] + public void update_should_compile_literal_without_parameters_holders(string engine, string sqlText) { var query = new Query("MyTable").AsUpdate(new { @@ -201,16 +189,16 @@ public void update_should_compile_literal_without_parameters_holders() Address = new UnsafeLiteral("@address") }); - var compiler = new SqlServerCompiler(); - var result = compiler.Compile(query); + var c = CompileFor(engine, query); - Assert.Equal( - "UPDATE [MyTable] SET [Name] = ?, [Address] = @address", - result.RawSql); + Assert.Equal(sqlText, c.RawSql); + Assert.Single(c.NamedBindings); + Assert.Equal("The User", c.NamedBindings.First().Value); } - [Fact] - public void UpdateUsingKeyValuePairs() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'")] + public void UpdateUsingKeyValuePairs(string engine, string sqlText) { var dictionaryUser = new Dictionary { @@ -222,53 +210,14 @@ public void UpdateUsingKeyValuePairs() var query = new Query("Table") .AsUpdate(dictionaryUser); - var c = Compile(query); - - Assert.Equal( - "UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'", - c[EngineCodes.SqlServer]); - } - - [Fact] - public void UpdateUsingDictionary() - { - var dictionaryUser = new Dictionary { - { "Name", "The User" }, - { "Age", new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc) }, - }; - - var query = new Query("Table") - .AsUpdate(dictionaryUser); - - var c = Compile(query); - - Assert.Equal( - "UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'", - c[EngineCodes.SqlServer]); - } - - [Fact] - public void UpdateUsingReadOnlyDictionary() - { - var dictionaryUser = new ReadOnlyDictionary( - new Dictionary - { - { "Name", "The User" }, - { "Age", new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc) }, - }); - - var query = new Query("Table") - .AsUpdate(dictionaryUser); - - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal( - "UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'", - c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void UpdateUsingExpandoObject() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'")] + public void UpdateUsingExpandoObject(string engine, string sqlText) { dynamic expandoUser = new ExpandoObject(); expandoUser.Name = "The User"; @@ -277,43 +226,53 @@ public void UpdateUsingExpandoObject() var query = new Query("Table") .AsUpdate(expandoUser); - var c = Compile(query); + var c = CompileFor(engine, query); - Assert.Equal( - "UPDATE [Table] SET [Name] = 'The User', [Age] = '2018-01-01'", - c[EngineCodes.SqlServer]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void IncrementUpdate() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Table] SET [Total] = [Total] + 1")] + public void IncrementUpdate(string engine, string sqlText) { var query = new Query("Table").AsIncrement("Total"); - var c = Compile(query); - Assert.Equal("UPDATE [Table] SET [Total] = [Total] + 1", c[EngineCodes.SqlServer]); + + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void IncrementUpdateWithValue() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Table] SET [Total] = [Total] + 2")] + public void IncrementUpdateWithValue(string engine, string sqlText) { var query = new Query("Table").AsIncrement("Total", 2); - var c = Compile(query); - Assert.Equal("UPDATE [Table] SET [Total] = [Total] + 2", c[EngineCodes.SqlServer]); + + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void IncrementUpdateWithWheres() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Table] SET [Total] = [Total] + 2 WHERE [Name] = 'A'")] + public void IncrementUpdateWithWheres(string engine, string sqlText) { var query = new Query("Table").Where("Name", "A").AsIncrement("Total", 2); - var c = Compile(query); - Assert.Equal("UPDATE [Table] SET [Total] = [Total] + 2 WHERE [Name] = 'A'", c[EngineCodes.SqlServer]); + + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void DecrementUpdate() + [Theory] + [InlineData(EngineCodes.SqlServer, "UPDATE [Table] SET [Total] = [Total] - 2 WHERE [Name] = 'A'")] + public void DecrementUpdate(string engine, string sqlText) { var query = new Query("Table").Where("Name", "A").AsDecrement("Total", 2); - var c = Compile(query); - Assert.Equal("UPDATE [Table] SET [Total] = [Total] - 2 WHERE [Name] = 'A'", c[EngineCodes.SqlServer]); + + var c = CompileFor(engine, query); + + Assert.Equal(sqlText, c.ToString()); } } } From 132e8b92118918fc7724b76df11c40ef60791ce5 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 22 Dec 2024 12:45:10 +0100 Subject: [PATCH 16/27] Improved WhereTests --- .../Infrastructure/TestSupport.cs | 9 +++++++-- QueryBuilder.Tests/UpdateTests.cs | 1 - QueryBuilder.Tests/WhereTests.cs | 20 +++++++++++-------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/QueryBuilder.Tests/Infrastructure/TestSupport.cs b/QueryBuilder.Tests/Infrastructure/TestSupport.cs index a5a3ba26..e05b8121 100644 --- a/QueryBuilder.Tests/Infrastructure/TestSupport.cs +++ b/QueryBuilder.Tests/Infrastructure/TestSupport.cs @@ -21,7 +21,9 @@ protected IReadOnlyDictionary Compile(Query query) protected SqlResult CompileFor(string engine, Query query) { - return Compilers.CompileFor(engine, query); + var compiler = CreateCompiler(engine); + + return compiler.Compile(query); } protected SqlResult CompileFor(string engine, Query query, Action action) @@ -41,7 +43,10 @@ private static Compiler CreateCompiler(string engine) EngineCodes.Oracle => new OracleCompiler(), EngineCodes.PostgreSql => new PostgresCompiler(), EngineCodes.Sqlite => new SqliteCompiler(), - EngineCodes.SqlServer => new SqlServerCompiler(), + EngineCodes.SqlServer => new SqlServerCompiler() + { + UseLegacyPagination = true + }, _ => throw new ArgumentException($"Unsupported engine type: {engine}", nameof(engine)), }; } diff --git a/QueryBuilder.Tests/UpdateTests.cs b/QueryBuilder.Tests/UpdateTests.cs index c57765e8..82162bec 100644 --- a/QueryBuilder.Tests/UpdateTests.cs +++ b/QueryBuilder.Tests/UpdateTests.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Dynamic; using System.Linq; using SqlKata.Compilers; diff --git a/QueryBuilder.Tests/WhereTests.cs b/QueryBuilder.Tests/WhereTests.cs index 0c1254b2..b5e49875 100644 --- a/QueryBuilder.Tests/WhereTests.cs +++ b/QueryBuilder.Tests/WhereTests.cs @@ -6,28 +6,32 @@ namespace SqlKata.Tests { public class WhereTests : TestSupport { - [Fact] - public void GroupedWhereFilters() + [Theory] + [InlineData(EngineCodes.PostgreSql, + """SELECT * FROM "Table1" WHERE ("Column1" = 10 OR "Column2" = 20) AND "Column3" = 30""")] + public void GroupedWhereFilters(string engine, string sqlText) { var q = new Query("Table1") .Where(q => q.Or().Where("Column1", 10).Or().Where("Column2", 20)) .Where("Column3", 30); - var c = Compile(q); + var c = CompileFor(engine, q); - Assert.Equal(@"SELECT * FROM ""Table1"" WHERE (""Column1"" = 10 OR ""Column2"" = 20) AND ""Column3"" = 30", c[EngineCodes.PostgreSql]); + Assert.Equal(sqlText, c.ToString()); } - [Fact] - public void GroupedHavingFilters() + [Theory] + [InlineData(EngineCodes.PostgreSql, + """SELECT * FROM "Table1" HAVING (SUM("Column1") = 10 OR SUM("Column2") = 20) AND SUM("Column3") = 30""")] + public void GroupedHavingFilters(string engine, string sqlText) { var q = new Query("Table1") .Having(q => q.Or().HavingRaw("SUM([Column1]) = ?", 10).Or().HavingRaw("SUM([Column2]) = ?", 20)) .HavingRaw("SUM([Column3]) = ?", 30); - var c = Compile(q); + var c = CompileFor(engine, q); - Assert.Equal(@"SELECT * FROM ""Table1"" HAVING (SUM(""Column1"") = 10 OR SUM(""Column2"") = 20) AND SUM(""Column3"") = 30", c[EngineCodes.PostgreSql]); + Assert.Equal(sqlText, c.ToString()); } } } From 1de8e2d8e23031023e7c6ecb0d0f1b2774e4bb58 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 22 Dec 2024 13:21:10 +0100 Subject: [PATCH 17/27] Organize code. --- QueryBuilder.Tests/GeneralTests.cs | 1 + .../Infrastructure/TestCompiler.cs | 58 ------------------- .../TestCompilers/TestCompiler.cs | 20 +++++++ .../TestEmptyIdentifiersCompiler.cs | 7 +++ .../TestCompilers/TestFirebirdCompiler.cs | 13 +++++ .../TestCompilers/TestMySqlCompiler.cs | 13 +++++ .../TestCompilers/TestPostgresCompiler.cs | 13 +++++ .../TestCompilers/TestSqlServerCompiler.cs | 13 +++++ 8 files changed, 80 insertions(+), 58 deletions(-) delete mode 100644 QueryBuilder.Tests/Infrastructure/TestCompiler.cs create mode 100644 QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs create mode 100644 QueryBuilder.Tests/Infrastructure/TestCompilers/TestEmptyIdentifiersCompiler.cs create mode 100644 QueryBuilder.Tests/Infrastructure/TestCompilers/TestFirebirdCompiler.cs create mode 100644 QueryBuilder.Tests/Infrastructure/TestCompilers/TestMySqlCompiler.cs create mode 100644 QueryBuilder.Tests/Infrastructure/TestCompilers/TestPostgresCompiler.cs create mode 100644 QueryBuilder.Tests/Infrastructure/TestCompilers/TestSqlServerCompiler.cs diff --git a/QueryBuilder.Tests/GeneralTests.cs b/QueryBuilder.Tests/GeneralTests.cs index bfc156e5..9851f4b2 100644 --- a/QueryBuilder.Tests/GeneralTests.cs +++ b/QueryBuilder.Tests/GeneralTests.cs @@ -3,6 +3,7 @@ using SqlKata.Tests.Infrastructure; using System; using System.Linq; +using SqlKata.Tests.Infrastructure.TestCompilers; using Xunit; namespace SqlKata.Tests diff --git a/QueryBuilder.Tests/Infrastructure/TestCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompiler.cs deleted file mode 100644 index aded9fd1..00000000 --- a/QueryBuilder.Tests/Infrastructure/TestCompiler.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Reflection; -using SqlKata.Compilers; - -namespace SqlKata.Tests.Infrastructure -{ - /// - /// A test class to expose private methods - /// - class TestCompiler : Compiler - { - public override string EngineCode { get; } = "test"; - - public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) - { - return FindCompilerMethodInfo(clauseType, methodName); - } - } - - class TestSqlServerCompiler : SqlServerCompiler - { - public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) - { - return FindCompilerMethodInfo(clauseType, methodName); - } - } - - class TestMySqlCompiler : MySqlCompiler - { - public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) - { - return FindCompilerMethodInfo(clauseType, methodName); - } - } - - class TestPostgresCompiler : PostgresCompiler - { - public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) - { - return FindCompilerMethodInfo(clauseType, methodName); - } - } - - class TestFirebirdCompiler : FirebirdCompiler - { - public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) - { - return FindCompilerMethodInfo(clauseType, methodName); - } - } - - class TestEmptyIdentifiersCompiler : TestCompiler - { - protected override string OpeningIdentifier { get; set; } = ""; - protected override string ClosingIdentifier { get; set; } = ""; - } -} - diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs new file mode 100644 index 00000000..0c3afd7a --- /dev/null +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs @@ -0,0 +1,20 @@ +using System; +using System.Reflection; +using SqlKata.Compilers; + +namespace SqlKata.Tests.Infrastructure.TestCompilers +{ + /// + /// A test class to expose private methods + /// + class TestCompiler : Compiler + { + public override string EngineCode { get; } = "test"; + + public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) + { + return FindCompilerMethodInfo(clauseType, methodName); + } + } +} + diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestEmptyIdentifiersCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestEmptyIdentifiersCompiler.cs new file mode 100644 index 00000000..c18dd7b2 --- /dev/null +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestEmptyIdentifiersCompiler.cs @@ -0,0 +1,7 @@ +namespace SqlKata.Tests.Infrastructure.TestCompilers; + +class TestEmptyIdentifiersCompiler : TestCompiler +{ + protected override string OpeningIdentifier { get; set; } = ""; + protected override string ClosingIdentifier { get; set; } = ""; +} diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestFirebirdCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestFirebirdCompiler.cs new file mode 100644 index 00000000..b246a1a4 --- /dev/null +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestFirebirdCompiler.cs @@ -0,0 +1,13 @@ +using System; +using System.Reflection; +using SqlKata.Compilers; + +namespace SqlKata.Tests.Infrastructure.TestCompilers; + +class TestFirebirdCompiler : FirebirdCompiler +{ + public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) + { + return FindCompilerMethodInfo(clauseType, methodName); + } +} diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestMySqlCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestMySqlCompiler.cs new file mode 100644 index 00000000..08898dca --- /dev/null +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestMySqlCompiler.cs @@ -0,0 +1,13 @@ +using System; +using System.Reflection; +using SqlKata.Compilers; + +namespace SqlKata.Tests.Infrastructure.TestCompilers; + +class TestMySqlCompiler : MySqlCompiler +{ + public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) + { + return FindCompilerMethodInfo(clauseType, methodName); + } +} diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestPostgresCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestPostgresCompiler.cs new file mode 100644 index 00000000..38644095 --- /dev/null +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestPostgresCompiler.cs @@ -0,0 +1,13 @@ +using System; +using System.Reflection; +using SqlKata.Compilers; + +namespace SqlKata.Tests.Infrastructure.TestCompilers; + +class TestPostgresCompiler : PostgresCompiler +{ + public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) + { + return FindCompilerMethodInfo(clauseType, methodName); + } +} diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestSqlServerCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestSqlServerCompiler.cs new file mode 100644 index 00000000..706fee6e --- /dev/null +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestSqlServerCompiler.cs @@ -0,0 +1,13 @@ +using System; +using System.Reflection; +using SqlKata.Compilers; + +namespace SqlKata.Tests.Infrastructure.TestCompilers; + +class TestSqlServerCompiler : SqlServerCompiler +{ + public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) + { + return FindCompilerMethodInfo(clauseType, methodName); + } +} From 21bf41fd8a152a6076c73fa76f3be477095d88c9 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 22 Dec 2024 19:23:13 +0100 Subject: [PATCH 18/27] Improve WhiteListing coverage. --- .../Infrastructure/TestSupport.cs | 21 ++-- QueryBuilder.Tests/OperatorWhitelistTests.cs | 103 +++++++----------- QueryBuilder.Tests/SelectTests.cs | 5 +- 3 files changed, 60 insertions(+), 69 deletions(-) diff --git a/QueryBuilder.Tests/Infrastructure/TestSupport.cs b/QueryBuilder.Tests/Infrastructure/TestSupport.cs index e05b8121..4020c1fc 100644 --- a/QueryBuilder.Tests/Infrastructure/TestSupport.cs +++ b/QueryBuilder.Tests/Infrastructure/TestSupport.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using SqlKata.Compilers; +using SqlKata.Tests.Infrastructure.TestCompilers; namespace SqlKata.Tests.Infrastructure { @@ -19,19 +20,24 @@ protected IReadOnlyDictionary Compile(Query query) return Compilers.Compile(query).ToDictionary(s => s.Key, v => v.Value.ToString()); } - protected SqlResult CompileFor(string engine, Query query) + protected SqlResult CompileFor(string engine, Query query, Func configuration = null) { var compiler = CreateCompiler(engine); + if (configuration != null) + { + compiler = configuration(compiler); + } return compiler.Compile(query); } - protected SqlResult CompileFor(string engine, Query query, Action action) + protected SqlResult CompileFor(string engine, Query query, Action configuration) { - var compiler = CreateCompiler(engine); - action(compiler); - - return compiler.Compile(query); + return CompileFor(engine, query, compiler => + { + configuration(compiler); + return compiler; + }); } private static Compiler CreateCompiler(string engine) @@ -43,10 +49,11 @@ private static Compiler CreateCompiler(string engine) EngineCodes.Oracle => new OracleCompiler(), EngineCodes.PostgreSql => new PostgresCompiler(), EngineCodes.Sqlite => new SqliteCompiler(), - EngineCodes.SqlServer => new SqlServerCompiler() + EngineCodes.SqlServer => new SqlServerCompiler { UseLegacyPagination = true }, + EngineCodes.Generic => new TestCompiler(), _ => throw new ArgumentException($"Unsupported engine type: {engine}", nameof(engine)), }; } diff --git a/QueryBuilder.Tests/OperatorWhitelistTests.cs b/QueryBuilder.Tests/OperatorWhitelistTests.cs index 55c3aafc..79116f42 100644 --- a/QueryBuilder.Tests/OperatorWhitelistTests.cs +++ b/QueryBuilder.Tests/OperatorWhitelistTests.cs @@ -1,34 +1,37 @@ using System; using SqlKata.Compilers; +using SqlKata.Tests.Infrastructure; +using SqlKata.Tests.Infrastructure.TestCompilers; using Xunit; namespace SqlKata.Tests { - public class OperatorWhitelistTests + public class OperatorWhitelistTests : TestSupport { - - public OperatorWhitelistTests() + public static TheoryData AllowedOperators = new() { - - } + "=", "<", ">", "<=", ">=", "<>", "!=", "<=>", + "like", "not like", + "ilike", "not ilike", + "like binary", "not like binary", + "rlike", "not rlike", + "regexp", "not regexp", + "similar to", "not similar to" + }; [Theory] [InlineData("!!")] [InlineData("~!")] [InlineData("*=")] + [InlineData("")] public void DenyInvalidOperatorsInWhere(string op) { - var compiler = new SqlServerCompiler(); + var compiler = new TestCompiler(); Assert.Throws(() => { - compiler.Compile(new Query("Table").Where("Id", op, 1)); - compiler.Compile(new Query("Table").OrWhere("Id", op, 1)); - compiler.Compile(new Query("Table").WhereNot("Id", op, 1)); - compiler.Compile(new Query("Table").OrWhereNot("Id", op, 1)); - - compiler.Compile(new Query("Table").WhereColumns("Col1", op, "Col2")); - compiler.Compile(new Query("Table").OrWhereColumns("Col1", op, "Col2")); + var query = new Query("Table").Where("Id", op, 1); + compiler.Compile(query); }); } @@ -36,51 +39,37 @@ public void DenyInvalidOperatorsInWhere(string op) [InlineData("!!")] [InlineData("~!")] [InlineData("*=")] + [InlineData("")] public void DenyInvalidOperatorsInHaving(string op) { - var compiler = new SqlServerCompiler(); + var compiler = new TestCompiler(); Assert.Throws(() => { - compiler.Compile(new Query("Table").Having("Id", op, 1)); - compiler.Compile(new Query("Table").OrHaving("Id", op, 1)); - compiler.Compile(new Query("Table").HavingNot("Id", op, 1)); - compiler.Compile(new Query("Table").OrHavingNot("Id", op, 1)); - - compiler.Compile(new Query("Table").HavingColumns("Col1", op, "Col2")); - compiler.Compile(new Query("Table").OrHavingColumns("Col1", op, "Col2")); + var query = new Query("Table").Having("Id", op, 1); + compiler.Compile(query); }); } - [Theory] - [InlineData("=")] - [InlineData("!=")] - [InlineData("ilike")] + [MemberData(nameof(AllowedOperators))] public void AllowValidOperatorsInWhere(string op) { - new Query("Table").Where("Id", op, 1); - new Query("Table").OrWhere("Id", op, 1); - new Query("Table").WhereNot("Id", op, 1); - new Query("Table").OrWhereNot("Id", op, 1); + var query = new Query("Table").Where("Id", op, 1); + + var result = CompileFor(EngineCodes.Generic, query); - new Query("Table").WhereColumns("Col1", op, "Col2"); - new Query("Table").OrWhereColumns("Col1", op, "Col2"); + Assert.Equal($"""SELECT * FROM "Table" WHERE "Id" {op} 1""", result.ToString()); } [Theory] - [InlineData("=")] - [InlineData("!=")] - [InlineData("ilike")] + [MemberData(nameof(AllowedOperators))] public void AllowValidOperatorsInHaving(string op) { - new Query("Table").Having("Id", op, 1); - new Query("Table").OrHaving("Id", op, 1); - new Query("Table").HavingNot("Id", op, 1); - new Query("Table").OrHavingNot("Id", op, 1); + var query = new Query("Table").Having("Id", op, 1); + var result = CompileFor(EngineCodes.Generic, query); - new Query("Table").HavingColumns("Col1", op, "Col2"); - new Query("Table").OrHavingColumns("Col1", op, "Col2"); + Assert.Equal($"""SELECT * FROM "Table" HAVING "Id" {op} 1""", result.ToString()); } [Theory] @@ -93,46 +82,38 @@ public void AllowValidOperatorsInHaving(string op) [InlineData("!~*")] public void ShouldNotThrowAfterWhiteListing(string op) { - var compiler = new SqlServerCompiler().Whitelist(op); + var query = new Query("Table").Where("Id", op, 1); - var query = new Query("Table"); + var result = CompileFor( + EngineCodes.Generic, + query, + compiler => compiler.Whitelist(op)); - compiler.Compile(query.Clone().Where("Id", op, 1)); - compiler.Compile(query.Clone().OrWhere("Id", op, 1)); - compiler.Compile(query.Clone().WhereNot("Id", op, 1)); - compiler.Compile(query.Clone().OrWhereNot("Id", op, 1)); + Assert.Equal($"""SELECT * FROM "Table" WHERE "Id" {op} 1""", result.ToString()); - compiler.Compile(query.Clone().WhereColumns("Col1", op, "Col2")); - compiler.Compile(query.Clone().OrWhereColumns("Col1", op, "Col2")); - - compiler.Compile(query.Clone().Having("Id", op, 1)); - compiler.Compile(query.Clone().OrHaving("Id", op, 1)); - compiler.Compile(query.Clone().HavingNot("Id", op, 1)); - compiler.Compile(query.Clone().OrHavingNot("Id", op, 1)); - - compiler.Compile(query.Clone().HavingColumns("Col1", op, "Col2")); - compiler.Compile(query.Clone().OrHavingColumns("Col1", op, "Col2")); } [Fact] public void ShouldAllowWhiteListedOperatorsInNestedWhere() { - var compiler = new SqlServerCompiler().Whitelist("!!"); - var query = new Query("Table") .Where(q => q.Where("A", "!!", "value")); - compiler.Compile(query); + var result = CompileFor(EngineCodes.Generic, query, compiler => compiler.Whitelist("!!")); + + Assert.Equal("""SELECT * FROM "Table" WHERE ("A" !! 'value')""", result.ToString()); } [Fact] public void ShouldNotConsiderWhereRawCondition() { - var compiler = new SqlServerCompiler(); - var query = new Query("Table") .WhereRaw("Col !! value"); + var result = CompileFor(EngineCodes.Generic, query); + + Assert.Equal("""SELECT * FROM "Table" WHERE Col !! value""", result.ToString()); + } } diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs index 0e107e0c..96ff17e0 100644 --- a/QueryBuilder.Tests/SelectTests.cs +++ b/QueryBuilder.Tests/SelectTests.cs @@ -1021,7 +1021,10 @@ public void SelectWithExists_OmitSelectIsFalse(string engine, string sqlText) new Query("Comments").Select("Id").WhereColumns("Comments.PostId", "=", "Posts.Id") ); - var c = CompileFor(engine, q, compiler1 => { compiler1.OmitSelectInsideExists = false; }); + var c = CompileFor(engine, q, compiler => + { + compiler.OmitSelectInsideExists = false; + }); Assert.Equal(sqlText, c.ToString()); } From 6f70580b61402fd80bc341294db61102b5627331 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 22 Dec 2024 20:39:11 +0100 Subject: [PATCH 19/27] Improve AggregateTests --- QueryBuilder.Tests/AggregateTests.cs | 171 ++++++++++++++++++++------- 1 file changed, 128 insertions(+), 43 deletions(-) diff --git a/QueryBuilder.Tests/AggregateTests.cs b/QueryBuilder.Tests/AggregateTests.cs index 68a69842..e2947797 100644 --- a/QueryBuilder.Tests/AggregateTests.cs +++ b/QueryBuilder.Tests/AggregateTests.cs @@ -6,87 +6,172 @@ namespace SqlKata.Tests { public class AggregateTests : TestSupport { - [Fact] - public void Count() + [Theory] + [InlineData(EngineCodes.Firebird, "SELECT COUNT(*) AS \"COUNT\" FROM \"A\"")] + [InlineData(EngineCodes.MySql, "SELECT COUNT(*) AS `count` FROM `A`")] + [InlineData(EngineCodes.Oracle, "SELECT COUNT(*) \"count\" FROM \"A\"")] + [InlineData(EngineCodes.PostgreSql, "SELECT COUNT(*) AS \"count\" FROM \"A\"")] + [InlineData(EngineCodes.Sqlite, "SELECT COUNT(*) AS \"count\" FROM \"A\"")] + [InlineData(EngineCodes.SqlServer, "SELECT COUNT(*) AS [count] FROM [A]")] + public void Count(string engine, string query) { - var query = new Query("A").AsCount(); + var q = new Query("A").AsCount(); - var c = Compile(query); + var c = CompileFor(engine, q); - Assert.Equal("SELECT COUNT(*) AS [count] FROM [A]", c[EngineCodes.SqlServer]); - Assert.Equal("SELECT COUNT(*) AS `count` FROM `A`", c[EngineCodes.MySql]); - Assert.Equal("SELECT COUNT(*) AS \"count\" FROM \"A\"", c[EngineCodes.PostgreSql]); - Assert.Equal("SELECT COUNT(*) AS \"COUNT\" FROM \"A\"", c[EngineCodes.Firebird]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void CountMultipleColumns() + [Theory] + [InlineData(EngineCodes.Firebird, + "SELECT COUNT(*) AS \"COUNT\" FROM (SELECT 1 FROM \"A\" WHERE \"COLUMNA\" IS NOT NULL AND \"COLUMNB\" IS NOT NULL) AS \"COUNTQUERY\"")] + [InlineData(EngineCodes.MySql, + "SELECT COUNT(*) AS `count` FROM (SELECT 1 FROM `A` WHERE `ColumnA` IS NOT NULL AND `ColumnB` IS NOT NULL) AS `countQuery`")] + [InlineData(EngineCodes.Oracle, + "SELECT COUNT(*) \"count\" FROM (SELECT 1 FROM \"A\" WHERE \"ColumnA\" IS NOT NULL AND \"ColumnB\" IS NOT NULL) \"countQuery\"")] + [InlineData(EngineCodes.PostgreSql, + "SELECT COUNT(*) AS \"count\" FROM (SELECT 1 FROM \"A\" WHERE \"ColumnA\" IS NOT NULL AND \"ColumnB\" IS NOT NULL) AS \"countQuery\"")] + [InlineData(EngineCodes.Sqlite, + "SELECT COUNT(*) AS \"count\" FROM (SELECT 1 FROM \"A\" WHERE \"ColumnA\" IS NOT NULL AND \"ColumnB\" IS NOT NULL) AS \"countQuery\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT COUNT(*) AS [count] FROM (SELECT 1 FROM [A] WHERE [ColumnA] IS NOT NULL AND [ColumnB] IS NOT NULL) AS [countQuery]")] + public void CountMultipleColumns(string engine, string query) { - var query = new Query("A").AsCount(new[] { "ColumnA", "ColumnB" }); + var q = new Query("A").AsCount(["ColumnA", "ColumnB"]); - var c = Compile(query); + var c = CompileFor(engine, q); - Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT 1 FROM [A] WHERE [ColumnA] IS NOT NULL AND [ColumnB] IS NOT NULL) AS [countQuery]", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void DistinctCount() + [Theory] + [InlineData(EngineCodes.Firebird, + "SELECT COUNT(*) AS \"COUNT\" FROM (SELECT DISTINCT * FROM \"A\") AS \"COUNTQUERY\"")] + [InlineData(EngineCodes.MySql, "SELECT COUNT(*) AS `count` FROM (SELECT DISTINCT * FROM `A`) AS `countQuery`")] + [InlineData(EngineCodes.Oracle, "SELECT COUNT(*) \"count\" FROM (SELECT DISTINCT * FROM \"A\") \"countQuery\"")] + [InlineData(EngineCodes.PostgreSql, + "SELECT COUNT(*) AS \"count\" FROM (SELECT DISTINCT * FROM \"A\") AS \"countQuery\"")] + [InlineData(EngineCodes.Sqlite, + "SELECT COUNT(*) AS \"count\" FROM (SELECT DISTINCT * FROM \"A\") AS \"countQuery\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT * FROM [A]) AS [countQuery]")] + public void DistinctCount(string engine, string query) { - var query = new Query("A").Distinct().AsCount(); + var q = new Query("A").Distinct().AsCount(); - var c = Compile(query); + var c = CompileFor(engine, q); - Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT * FROM [A]) AS [countQuery]", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void DistinctCountMultipleColumns() + [Theory] + [InlineData(EngineCodes.Firebird, + "SELECT COUNT(*) AS \"COUNT\" FROM (SELECT DISTINCT \"COLUMNA\", \"COLUMNB\" FROM \"A\") AS \"COUNTQUERY\"")] + [InlineData(EngineCodes.MySql, + "SELECT COUNT(*) AS `count` FROM (SELECT DISTINCT `ColumnA`, `ColumnB` FROM `A`) AS `countQuery`")] + [InlineData(EngineCodes.Oracle, + "SELECT COUNT(*) \"count\" FROM (SELECT DISTINCT \"ColumnA\", \"ColumnB\" FROM \"A\") \"countQuery\"")] + [InlineData(EngineCodes.PostgreSql, + "SELECT COUNT(*) AS \"count\" FROM (SELECT DISTINCT \"ColumnA\", \"ColumnB\" FROM \"A\") AS \"countQuery\"")] + [InlineData(EngineCodes.Sqlite, + "SELECT COUNT(*) AS \"count\" FROM (SELECT DISTINCT \"ColumnA\", \"ColumnB\" FROM \"A\") AS \"countQuery\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT [ColumnA], [ColumnB] FROM [A]) AS [countQuery]")] + public void DistinctCountMultipleColumns(string engine, string query) { - var query = new Query("A").Distinct().AsCount(new[] { "ColumnA", "ColumnB" }); + var q = new Query("A").Distinct().AsCount(new[] { "ColumnA", "ColumnB" }); - var c = Compile(query); + var c = CompileFor(engine, q); - Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT [ColumnA], [ColumnB] FROM [A]) AS [countQuery]", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void Average() + [Theory] + [InlineData(EngineCodes.Firebird, + "SELECT AVG(\"TTL\") AS \"AVG\" FROM \"A\"")] + [InlineData(EngineCodes.MySql, + "SELECT AVG(`TTL`) AS `avg` FROM `A`")] + [InlineData(EngineCodes.Oracle, + "SELECT AVG(\"TTL\") \"avg\" FROM \"A\"")] + [InlineData(EngineCodes.PostgreSql, + "SELECT AVG(\"TTL\") AS \"avg\" FROM \"A\"")] + [InlineData(EngineCodes.Sqlite, + "SELECT AVG(\"TTL\") AS \"avg\" FROM \"A\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT AVG([TTL]) AS [avg] FROM [A]")] + public void Average(string engine, string query) { - var query = new Query("A").AsAverage("TTL"); + var q = new Query("A").AsAverage("TTL"); - var c = Compile(query); + var c = CompileFor(engine, q); - Assert.Equal("SELECT AVG([TTL]) AS [avg] FROM [A]", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void Sum() + [Theory] + [InlineData(EngineCodes.Firebird, + "SELECT SUM(\"PACKETSDROPPED\") AS \"SUM\" FROM \"A\"")] + [InlineData(EngineCodes.MySql, + "SELECT SUM(`PacketsDropped`) AS `sum` FROM `A`")] + [InlineData(EngineCodes.Oracle, + "SELECT SUM(\"PacketsDropped\") \"sum\" FROM \"A\"")] + [InlineData(EngineCodes.PostgreSql, + "SELECT SUM(\"PacketsDropped\") AS \"sum\" FROM \"A\"")] + [InlineData(EngineCodes.Sqlite, + "SELECT SUM(\"PacketsDropped\") AS \"sum\" FROM \"A\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT SUM([PacketsDropped]) AS [sum] FROM [A]")] + public void Sum(string engine, string query) { - var query = new Query("A").AsSum("PacketsDropped"); + var q = new Query("A").AsSum("PacketsDropped"); - var c = Compile(query); + var c = CompileFor(engine, q); - Assert.Equal("SELECT SUM([PacketsDropped]) AS [sum] FROM [A]", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void Max() + [Theory] + [InlineData(EngineCodes.Firebird, + "SELECT MAX(\"LATENCYMS\") AS \"MAX\" FROM \"A\"")] + [InlineData(EngineCodes.MySql, + "SELECT MAX(`LatencyMs`) AS `max` FROM `A`")] + [InlineData(EngineCodes.Oracle, + "SELECT MAX(\"LatencyMs\") \"max\" FROM \"A\"")] + [InlineData(EngineCodes.PostgreSql, + "SELECT MAX(\"LatencyMs\") AS \"max\" FROM \"A\"")] + [InlineData(EngineCodes.Sqlite, + "SELECT MAX(\"LatencyMs\") AS \"max\" FROM \"A\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT MAX([LatencyMs]) AS [max] FROM [A]")] + public void Max(string engine, string query) { - var query = new Query("A").AsMax("LatencyMs"); + var q = new Query("A").AsMax("LatencyMs"); - var c = Compile(query); + var c = CompileFor(engine, q); - Assert.Equal("SELECT MAX([LatencyMs]) AS [max] FROM [A]", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } - [Fact] - public void Min() + [Theory] + [InlineData(EngineCodes.Firebird, + "SELECT MIN(\"LATENCYMS\") AS \"MIN\" FROM \"A\"")] + [InlineData(EngineCodes.MySql, + "SELECT MIN(`LatencyMs`) AS `min` FROM `A`")] + [InlineData(EngineCodes.Oracle, + "SELECT MIN(\"LatencyMs\") \"min\" FROM \"A\"")] + [InlineData(EngineCodes.PostgreSql, + "SELECT MIN(\"LatencyMs\") AS \"min\" FROM \"A\"")] + [InlineData(EngineCodes.Sqlite, + "SELECT MIN(\"LatencyMs\") AS \"min\" FROM \"A\"")] + [InlineData(EngineCodes.SqlServer, + "SELECT MIN([LatencyMs]) AS [min] FROM [A]")] + public void Min(string engine, string query) { - var query = new Query("A").AsMin("LatencyMs"); + var q = new Query("A").AsMin("LatencyMs"); - var c = Compile(query); + var c = CompileFor(engine, q); - Assert.Equal("SELECT MIN([LatencyMs]) AS [min] FROM [A]", c[EngineCodes.SqlServer]); + Assert.Equal(query, c.ToString()); } } } From b9553b6ad70ce5829c791af3af188c0ccaa35ee0 Mon Sep 17 00:00:00 2001 From: faddiv Date: Sun, 22 Dec 2024 21:58:41 +0100 Subject: [PATCH 20/27] UnsafeLiteral in conditions --- QueryBuilder.Tests/WhereTests.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/QueryBuilder.Tests/WhereTests.cs b/QueryBuilder.Tests/WhereTests.cs index b5e49875..041ee54b 100644 --- a/QueryBuilder.Tests/WhereTests.cs +++ b/QueryBuilder.Tests/WhereTests.cs @@ -33,5 +33,24 @@ public void GroupedHavingFilters(string engine, string sqlText) Assert.Equal(sqlText, c.ToString()); } + + [Theory] + [InlineData(EngineCodes.Firebird, """SELECT * FROM "TABLE1" WHERE "FIELD1" = Field2""")] + [InlineData(EngineCodes.MySql, "SELECT * FROM `Table1` WHERE `Field1` = Field2")] + [InlineData(EngineCodes.Oracle, """SELECT * FROM "Table1" WHERE "Field1" = Field2""")] + [InlineData(EngineCodes.PostgreSql, """SELECT * FROM "Table1" WHERE "Field1" = Field2""")] + [InlineData(EngineCodes.Sqlite, """SELECT * FROM "Table1" WHERE "Field1" = Field2""")] + [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Table1] WHERE [Field1] = Field2")] + public void UnsafeLiteralConditions(string engine, string sqlText) + { + var q = new Query("Table1") + .Where("Field1", new UnsafeLiteral("Field2")); + + var c = CompileFor(engine, q); + + Assert.Equal(sqlText, c.ToString()); + } + + } } From b9e3ed768e25c0eedd18a5283ab2d51ce759021c Mon Sep 17 00:00:00 2001 From: faddiv Date: Mon, 23 Dec 2024 10:52:13 +0100 Subject: [PATCH 21/27] Binding tests --- QueryBuilder.Tests/BindingsTests.cs | 202 ++++++++++++++++++ .../Infrastructure/TestSupport.cs | 10 + QueryBuilder.Tests/WhereTests.cs | 2 - 3 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 QueryBuilder.Tests/BindingsTests.cs diff --git a/QueryBuilder.Tests/BindingsTests.cs b/QueryBuilder.Tests/BindingsTests.cs new file mode 100644 index 00000000..dba6f38a --- /dev/null +++ b/QueryBuilder.Tests/BindingsTests.cs @@ -0,0 +1,202 @@ +using System.Linq; +using System.Text.RegularExpressions; +using SqlKata.Compilers; +using SqlKata.Tests.Infrastructure; +using Xunit; + +namespace SqlKata.Tests; + +public class BindingsTests : TestSupport +{ + private static readonly Regex _parameterExtractor = new(@"(@\w+\b)", RegexOptions.Compiled); + + [Fact] + public void BindingsAreAppliedFromWhere() + { + var q = new Query("Table") + .Where("Id", 1) + .Where("Name", "John"); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 1, + "John"); + } + + [Fact] + public void BindingsAreAppliedFromTake() + { + var q = new Query("Table") + .Take(10); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 10); + } + + [Fact] + public void BindingsAreAppliedFromSkip() + { + var q = new Query("Table") + .Skip(10); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 10L); + } + + [Fact] + public void BindingsAreAppliedFromTakeAndSkip() + { + var q = new Query("Table") + .Take(10) + .Skip(20); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 10, + 20L); + } + + [Fact] + public void BindingsAreAppliedFromOrderByRaw() + { + var q = new Query("Table") + .OrderByRaw("?, ?", 1, "John"); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 1, + "John"); + } + + [Fact] + public void BindingsAreAppliedFromHaving() + { + var q = new Query("Table") + .Having("Id", 1) + .Having("Name", "John"); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 1, + "John"); + } + + [Fact] + public void BindingsAreAppliedFromWith() + { + var q = new Query("Table") + .With("WithAlias", ["Id", "Name"], [[1, "First"], [2, "Second"]]); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 1, + "First", + 2, + "Second"); + } + + [Fact] + public void BindingsAreAppliedFromCombineRaw() + { + var q = new Query("Table") + .CombineRaw("UNION SELECT * FROM Table2 Id = ? AND Name = ?", 1, "John"); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 1, + "John"); + } + + [Fact] + public void BindingsAreAppliedFromHavingBetween() + { + var q = new Query("Table") + .HavingBetween("Id", 10, 20); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + 10, + 20); + } + + [Fact] + public void BindingsAreAppliedFromHavingContains() + { + // Contains is object but it works only with string. + var q = new Query("Table") + .HavingContains("Name", "John"); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + "%john%"); + } + + [Fact] + public void BindingsAreAppliedFromHavingEnds() + { + // Contains is object but it works only with string. + var q = new Query("Table") + .HavingEnds("Name", "John"); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + "%john"); + } + + [Fact] + public void BindingsAreAppliedFromHavingStarts() + { + var q = new Query("Table") + .HavingStarts("Name", "John"); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + "john%"); + } + + [Fact] + public void BindingsAreAppliedFromHavingLike() + { + var q = new Query("Table") + .HavingLike("Name", "John%Wick"); + + var result = CompileForGeneric(q); + + AssertBindingsAndNamedBindings(result, + "john%wick"); + } + + private static void AssertBindingsAndNamedBindings(SqlResult result, params object[] parameters) + { + Assert.Equal(parameters.Length, result.Bindings.Count); + foreach (var values in parameters.Zip(result.Bindings)) + { + Assert.Equal(values.First, values.Second); + } + + Assert.Equal(parameters.Length, result.NamedBindings.Count); + var parameterNames = _parameterExtractor + .Matches(result.Sql) + .Select(e => e.Value) + .ToArray(); + Assert.Equal(parameters.Length, parameterNames.Length); + foreach (var parameter in parameterNames.Zip(parameters)) + { + Assert.Equal(parameter.Second, result.NamedBindings[parameter.First]); + } + } +} diff --git a/QueryBuilder.Tests/Infrastructure/TestSupport.cs b/QueryBuilder.Tests/Infrastructure/TestSupport.cs index 4020c1fc..57c39e7c 100644 --- a/QueryBuilder.Tests/Infrastructure/TestSupport.cs +++ b/QueryBuilder.Tests/Infrastructure/TestSupport.cs @@ -20,6 +20,16 @@ protected IReadOnlyDictionary Compile(Query query) return Compilers.Compile(query).ToDictionary(s => s.Key, v => v.Value.ToString()); } + protected SqlResult CompileForGeneric(Query query, Func configuration = null) + { + return CompileFor(EngineCodes.Generic, query, configuration); + } + + protected SqlResult CompileForGeneric(Query query, Action configuration) + { + return CompileFor(EngineCodes.Generic, query, configuration); + } + protected SqlResult CompileFor(string engine, Query query, Func configuration = null) { var compiler = CreateCompiler(engine); diff --git a/QueryBuilder.Tests/WhereTests.cs b/QueryBuilder.Tests/WhereTests.cs index 041ee54b..051ee993 100644 --- a/QueryBuilder.Tests/WhereTests.cs +++ b/QueryBuilder.Tests/WhereTests.cs @@ -50,7 +50,5 @@ public void UnsafeLiteralConditions(string engine, string sqlText) Assert.Equal(sqlText, c.ToString()); } - - } } From 3c2616915e939d34b61fa425daec8119733d0857 Mon Sep 17 00:00:00 2001 From: faddiv Date: Tue, 24 Dec 2024 20:00:11 +0100 Subject: [PATCH 22/27] Eliminate old TestCompilersContainer --- QueryBuilder.Tests/AggregateTests.cs | 32 +- QueryBuilder.Tests/DefineTest.cs | 160 +++++---- QueryBuilder.Tests/DeleteTests.cs | 12 +- .../Firebird/FirebirdLimitTests.cs | 4 +- QueryBuilder.Tests/GeneralTests.cs | 203 +++++------ .../Infrastructure/TestCompilersContainer.cs | 109 ------ .../Infrastructure/TestSqlResultContainer.cs | 13 - .../Infrastructure/TestSupport.cs | 26 +- QueryBuilder.Tests/InfrastructureTests.cs | 54 --- QueryBuilder.Tests/InsertTests.cs | 58 ++-- QueryBuilder.Tests/MySql/MySqlLimitTests.cs | 4 +- .../Oracle/OracleDateConditionTests.cs | 4 +- .../Oracle/OracleInsertManyTests.cs | 4 +- .../Oracle/OracleLegacyLimitTests.cs | 5 +- QueryBuilder.Tests/Oracle/OracleLimitTests.cs | 4 +- QueryBuilder.Tests/ParameterTypeTests.cs | 4 +- .../PostgreSql/PostgreSqlLimitTests.cs | 4 +- QueryBuilder.Tests/SelectTests.cs | 325 +++++++++--------- .../SqlServer/NestedSelectTests.cs | 4 +- .../SqlServer/SqlServerLegacyLimitTests.cs | 5 +- .../SqlServer/SqlServerLimitTests.cs | 5 +- .../SqlServer/SqlServerTests.cs | 29 +- QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs | 4 +- QueryBuilder.Tests/UpdateTests.cs | 60 ++-- QueryBuilder.Tests/WhereTests.cs | 12 +- 25 files changed, 501 insertions(+), 643 deletions(-) delete mode 100644 QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs delete mode 100644 QueryBuilder.Tests/Infrastructure/TestSqlResultContainer.cs delete mode 100644 QueryBuilder.Tests/InfrastructureTests.cs diff --git a/QueryBuilder.Tests/AggregateTests.cs b/QueryBuilder.Tests/AggregateTests.cs index e2947797..7c0efbc8 100644 --- a/QueryBuilder.Tests/AggregateTests.cs +++ b/QueryBuilder.Tests/AggregateTests.cs @@ -17,9 +17,9 @@ public void Count(string engine, string query) { var q = new Query("A").AsCount(); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -39,9 +39,9 @@ public void CountMultipleColumns(string engine, string query) { var q = new Query("A").AsCount(["ColumnA", "ColumnB"]); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -59,9 +59,9 @@ public void DistinctCount(string engine, string query) { var q = new Query("A").Distinct().AsCount(); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -81,9 +81,9 @@ public void DistinctCountMultipleColumns(string engine, string query) { var q = new Query("A").Distinct().AsCount(new[] { "ColumnA", "ColumnB" }); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -103,9 +103,9 @@ public void Average(string engine, string query) { var q = new Query("A").AsAverage("TTL"); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -125,9 +125,9 @@ public void Sum(string engine, string query) { var q = new Query("A").AsSum("PacketsDropped"); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -147,9 +147,9 @@ public void Max(string engine, string query) { var q = new Query("A").AsMax("LatencyMs"); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -169,9 +169,9 @@ public void Min(string engine, string query) { var q = new Query("A").AsMin("LatencyMs"); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } } } diff --git a/QueryBuilder.Tests/DefineTest.cs b/QueryBuilder.Tests/DefineTest.cs index 13ee3e82..ee516220 100644 --- a/QueryBuilder.Tests/DefineTest.cs +++ b/QueryBuilder.Tests/DefineTest.cs @@ -18,9 +18,9 @@ public void Test_Define_Where(string engine, string sqlText) .Define("@name", "Anto") .Where("ProductName", Variable("@name")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -38,9 +38,9 @@ public void Test_Define_SubQuery(string engine, string sqlText) .Where("unitprice", ">", subquery) .Where("UnitsOnOrder", ">", 5); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } @@ -60,9 +60,9 @@ public void Test_Define_WhereEnds(string engine, string sqlText, bool caseSensit .Define("@product", "Coffee") .WhereEnds("ProductName", Variable("@product"), caseSensitive); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } @@ -82,9 +82,9 @@ public void Test_Define_WhereStarts(string engine, string sqlText, bool caseSens .Define("@perUnit", "12") .WhereStarts("QuantityPerUnit", Variable("@perUnit"), caseSensitive); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -103,9 +103,9 @@ public void Test_Define_WhereContains(string engine, string sqlText, bool caseSe .Select("ProductId", "QuantityPerUnit") .WhereContains("QuantityPerUnit", Variable("@perUnit"), caseSensitive); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -124,9 +124,9 @@ public void Test_Define_WhereLike(string engine, string sqlText, bool caseSensit .Define("@id", "20") .WhereLike("SupplierID", Variable("@id"), caseSensitive); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -140,14 +140,14 @@ public void Test_Define_WhereInSubquery(string engine, string sqlText) .Select("ShipVia").Where("ShipVia", Variable("@shipId")); - var query1 = new Query("Shippers") + var query = new Query("Shippers") .Select("ShipperID", "CompanyName") .WhereIn("ShipperID", subquery); - var c1 = CompileFor(engine, query1); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c1.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -158,31 +158,32 @@ public void Test_Define_Having(string engine, string sqlText) .Define("@foo", 1) .Having("Id", "=", Variable("@foo")); - var c1 = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c1.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory(Skip = "Not implemented")] - [InlineData(EngineCodes.SqlServer, "SELECT [Employees].[LastName], COUNT(Orders.OrderID) AS NumberOfOrders FROM [Orders] \nINNER JOIN [Employees] ON [Employees].[EmployeeID] = [Orders].[EmployeeID] GROUP BY [LastName] HAVING COUNT(Orders.OrderID) > 80")] + [InlineData(EngineCodes.SqlServer, + "SELECT [Employees].[LastName], COUNT(Orders.OrderID) AS NumberOfOrders FROM [Orders] \nINNER JOIN [Employees] ON [Employees].[EmployeeID] = [Orders].[EmployeeID] GROUP BY [LastName] HAVING COUNT(Orders.OrderID) > 80")] public void Test_Define_HavingRaw(string engine, string sqlText) { - var query1 = new Query("Orders") - .Define("@count", 80) - .Select("Employees.LastName") - .SelectRaw("COUNT(Orders.OrderID) AS NumberOfOrders") - .Join("Employees", "Employees.EmployeeID", "Orders.EmployeeID") - .GroupBy("LastName") - .HavingRaw("COUNT(Orders.OrderID) > @count"); - - var c = CompileFor(engine, query1); + var query = new Query("Orders") + .Define("@count", 80) + .Select("Employees.LastName") + .SelectRaw("COUNT(Orders.OrderID) AS NumberOfOrders") + .Join("Employees", "Employees.EmployeeID", "Orders.EmployeeID") + .GroupBy("LastName") + .HavingRaw("COUNT(Orders.OrderID) > @count"); - Assert.Equal(sqlText, c.ToString()); + var result = CompileFor(engine, query); + Assert.Equal(sqlText, result.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like 'u%'")] + [InlineData(EngineCodes.SqlServer, + "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like 'u%'")] public void Test_Define_HavingStarts(string engine, string sqlText) { var query = new Query("Customers") @@ -192,15 +193,16 @@ public void Test_Define_HavingStarts(string engine, string sqlText) .GroupBy("Country") .HavingStarts("Country", Variable("@label")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); Assert.Equal( sqlText, - c.ToString()); + result.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d'")] + [InlineData(EngineCodes.SqlServer, + "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d'")] public void Test_Define_Having_Ends(string engine, string sqlText) { var query = new Query("Customers") @@ -210,15 +212,16 @@ public void Test_Define_Having_Ends(string engine, string sqlText) .GroupBy("Country") .HavingEnds("Country", Variable("@label")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); Assert.Equal( sqlText, - c.ToString()); + result.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d%'")] + [InlineData(EngineCodes.SqlServer, + "SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d%'")] public void Test_Define_Having_Contains(string engine, string sqlText) { var query = new Query("Customers") @@ -228,9 +231,9 @@ public void Test_Define_Having_Contains(string engine, string sqlText) .GroupBy("Country") .HavingContains("Country", Variable("@label")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -245,17 +248,19 @@ public void Test_Define_NestedCondition(string engine, string sqlText) // .WhereRaw("1 = @one") ).AsCount(); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Orders] WHERE CAST([RequiredDate] AS DATE) = '1996-08-01'")] [InlineData(EngineCodes.PostgreSql, "SELECT * FROM \"Orders\" WHERE \"RequiredDate\"::date = '1996-08-01'")] - [InlineData(EngineCodes.Sqlite, "SELECT * FROM \"Orders\" WHERE strftime('%Y-%m-%d', \"RequiredDate\") = cast('1996-08-01' as text)")] - [InlineData(EngineCodes.Firebird, "SELECT * FROM \"ORDERS\" WHERE CAST(\"REQUIREDDATE\" as DATE) = '1996-08-01'")] + [InlineData(EngineCodes.Sqlite, + "SELECT * FROM \"Orders\" WHERE strftime('%Y-%m-%d', \"RequiredDate\") = cast('1996-08-01' as text)")] + [InlineData(EngineCodes.Firebird, + "SELECT * FROM \"ORDERS\" WHERE CAST(\"REQUIREDDATE\" as DATE) = '1996-08-01'")] public void Test_Define_WhereDate(string engine, string sqlText) { var dateObj = new System.DateTime(year: 1996, month: 8, day: 1); @@ -264,9 +269,9 @@ public void Test_Define_WhereDate(string engine, string sqlText) .Define("@d", dateObj) .WhereDate("RequiredDate", Variable("@d")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -277,9 +282,9 @@ public void Test_Define_WhereDatePart(string engine, string sqlText) .Define("@d", 1996) .WhereDatePart("year", "RequiredDate", "=", Variable("@d")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -290,13 +295,14 @@ public void Test_Define_WhereTime(string engine, string sqlText) .Define("@d", "00:00:00") .WhereTime("RequiredDate", "!=", Variable("@d")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT * FROM [Customers] WHERE EXISTS (SELECT 1 FROM [Orders] WHERE [ShipPostalCode] = '8200')")] + [InlineData(EngineCodes.SqlServer, + "SELECT * FROM [Customers] WHERE EXISTS (SELECT 1 FROM [Orders] WHERE [ShipPostalCode] = '8200')")] public void Test_Define_WhereExists(string engine, string sqlText) { var query = new Query("Customers") @@ -305,13 +311,14 @@ public void Test_Define_WhereExists(string engine, string sqlText) .Where("ShipPostalCode", Variable("@postal")) ); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "WITH [prodCTE] AS (SELECT [Categories].[CategoryName], [Products].[UnitPrice] FROM [Products] \nINNER JOIN [Categories] ON [Categories].[CategoryID] = [Products].[CategoryID] WHERE [Products].[UnitPrice] > 10)\nSELECT * FROM [prodCTE]")] + [InlineData(EngineCodes.SqlServer, + "WITH [prodCTE] AS (SELECT [Categories].[CategoryName], [Products].[UnitPrice] FROM [Products] \nINNER JOIN [Categories] ON [Categories].[CategoryID] = [Products].[CategoryID] WHERE [Products].[UnitPrice] > 10)\nSELECT * FROM [prodCTE]")] public void Test_Define_With(string engine, string sqlText) { var query = new Query("Products") @@ -323,13 +330,14 @@ public void Test_Define_With(string engine, string sqlText) var queryCTe = new Query("prodCTE") .With("prodCTE", query); - var c = CompileFor(engine, queryCTe); + var result = CompileFor(engine, queryCTe); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory(Skip = "not implemented")] - [InlineData(EngineCodes.SqlServer, "WITH [prodCTE] AS (SELECT c.CategoryName, p.UnitPrice FROM Products p INNER JOIN Categories c ON c.CategoryID = p.CategoryID WHERE p.UnitPrice > 10 AND 2 = 2)\nSELECT [CategoryName], [UnitPrice] FROM [prodCTE]")] + [InlineData(EngineCodes.SqlServer, + "WITH [prodCTE] AS (SELECT c.CategoryName, p.UnitPrice FROM Products p INNER JOIN Categories c ON c.CategoryID = p.CategoryID WHERE p.UnitPrice > 10 AND 2 = 2)\nSELECT [CategoryName], [UnitPrice] FROM [prodCTE]")] public void Test_Define_WithRaw(string engine, string sqlText) { //WithRaw @@ -337,15 +345,17 @@ public void Test_Define_WithRaw(string engine, string sqlText) .Define("@unit", 10) .Define("@foo", 2) .Select("CategoryName", "UnitPrice") - .WithRaw("prodCTE", "SELECT c.CategoryName, p.UnitPrice FROM Products p INNER JOIN Categories c ON c.CategoryID = p.CategoryID WHERE p.UnitPrice > @unit AND 2 = @foo"); + .WithRaw("prodCTE", + "SELECT c.CategoryName, p.UnitPrice FROM Products p INNER JOIN Categories c ON c.CategoryID = p.CategoryID WHERE p.UnitPrice > @unit AND 2 = @foo"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') UNION SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] + [InlineData(EngineCodes.SqlServer, + "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') UNION SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] public void Test_Define_Union(string engine, string sqlText) { var q1 = new Query("Suppliers") @@ -359,13 +369,14 @@ public void Test_Define_Union(string engine, string sqlText) .Union(q1) .WhereNotLike("City", Variable("@city")); - var c = CompileFor(engine, q2); + var result = CompileFor(engine, q2); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') EXCEPT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] + [InlineData(EngineCodes.SqlServer, + "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') EXCEPT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] public void Test_Define_Except(string engine, string sqlText) { var q1 = new Query("Suppliers") @@ -379,13 +390,14 @@ public void Test_Define_Except(string engine, string sqlText) .Except(q1) .WhereNotLike("City", Variable("@city")); - var c = CompileFor(engine, q2); + var result = CompileFor(engine, q2); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] - [InlineData(EngineCodes.SqlServer, "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') INTERSECT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] + [InlineData(EngineCodes.SqlServer, + "SELECT [City] FROM [Customers] WHERE NOT (LOWER([City]) like 'z') INTERSECT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'")] public void Test_Define_Intersect(string engine, string sqlText) { var q1 = new Query("Suppliers") @@ -399,25 +411,25 @@ public void Test_Define_Intersect(string engine, string sqlText) .Intersect(q1) .WhereNotLike("City", Variable("@city")); - var c = CompileFor(engine, q2); + var result = CompileFor(engine, q2); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory(Skip = "not implemented")] - [InlineData(EngineCodes.SqlServer, "SELECT [City] FROM [Customers] UNION ALL SELECT City FROM Suppliers WHERE 1 = 1 AND 2 = 2")] + [InlineData(EngineCodes.SqlServer, + "SELECT [City] FROM [Customers] UNION ALL SELECT City FROM Suppliers WHERE 1 = 1 AND 2 = 2")] public void Test_Define_CombineRaw(string engine, string sqlText) { - var query = new Query("Customers") - .Define("@foo", 1) - .Define("@faa", 2) - .Select("City") - .CombineRaw("UNION ALL SELECT City FROM Suppliers WHERE 1 = @foo AND 2 = @faa"); + .Define("@foo", 1) + .Define("@faa", 2) + .Select("City") + .CombineRaw("UNION ALL SELECT City FROM Suppliers WHERE 1 = @foo AND 2 = @faa"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } } } diff --git a/QueryBuilder.Tests/DeleteTests.cs b/QueryBuilder.Tests/DeleteTests.cs index c9765bd7..798da42a 100644 --- a/QueryBuilder.Tests/DeleteTests.cs +++ b/QueryBuilder.Tests/DeleteTests.cs @@ -17,9 +17,9 @@ public void BasicDelete(string engine, string query) { var q = new Query("Posts").AsDelete(); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -48,9 +48,9 @@ public void DeleteWithJoin(string engine, string query) .Where("Authors.Id", 5) .AsDelete(); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } [Theory] @@ -79,9 +79,9 @@ public void DeleteWithJoinAndAlias(string engine, string query) .Where("A.Id", 5) .AsDelete(); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(query, c.ToString()); + Assert.Equal(query, result.ToString()); } } } diff --git a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs index b449bae8..ca906073 100644 --- a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs +++ b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs @@ -6,11 +6,11 @@ namespace SqlKata.Tests.Firebird { public class FirebirdLimitTests : TestSupport { - private readonly FirebirdCompiler compiler; + private readonly Compiler compiler; public FirebirdLimitTests() { - compiler = Compilers.Get(EngineCodes.Firebird); + compiler = CreateCompiler(EngineCodes.Firebird); } [Fact] diff --git a/QueryBuilder.Tests/GeneralTests.cs b/QueryBuilder.Tests/GeneralTests.cs index 9851f4b2..d7750703 100644 --- a/QueryBuilder.Tests/GeneralTests.cs +++ b/QueryBuilder.Tests/GeneralTests.cs @@ -17,9 +17,9 @@ public void ColumnsEscaping(string engine, string sqlText) var query = new Query().From("users") .Select("mycol[isthis]"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -40,9 +40,9 @@ public void InnerScopeEngineWithinCTE(string engine, string sqlText) .ForFirebird(q => q.WhereRaw("firebird = 1")); var query = new Query("series").With("series", series); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -63,9 +63,9 @@ public void InnerScopeEngineWithinSubQuery(string engine, string sqlText) .ForFirebird(q => q.WhereRaw("firebird = 1")); var query = new Query("series").From(series.As("series")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -141,9 +141,9 @@ public void Raw_WrapIdentifiers(string engine, string sqlText) { var query = new Query("Users").SelectRaw("[Id], [Name], {Age}"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -152,9 +152,9 @@ public void Raw_WrapIdentifiers_Escaped(string engine, string sqlText) { var query = new Query("Users").SelectRaw("'\\{1,2,3\\}'::int\\[\\]"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -192,9 +192,9 @@ public void CompilerSpecificFrom(string engine, string sqlText) .ForPostgreSql(q => q.From("pgsql")) .ForMySql(q => q.From("mysql")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -208,9 +208,9 @@ public void CompilerSpecificFromRaw(string engine, string sqlText) .ForPostgreSql(q => q.FromRaw("[pgsql]")) .ForMySql(q => q.FromRaw("[mysql]")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -224,9 +224,9 @@ public void CompilerSpecificFromMixed(string engine, string sqlText) .ForPostgreSql(q => q.FromRaw("[pgsql]")) .ForMySql(q => q.From("mysql")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -235,13 +235,15 @@ public void OneFromPerEngine() var query = new Query("generic") .ForSqlServer(q => q.From("dnu")) .ForSqlServer(q => q.From("mssql")); - var engines = new[] { EngineCodes.SqlServer, EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); + + var c = CompileFor(EngineCodes.SqlServer, query); + var c2 = CompileFor(EngineCodes.PostgreSql, query); + var c3 = CompileFor(EngineCodes.MySql, query); Assert.Equal(2, query.Clauses.OfType().Count()); - Assert.Equal("SELECT * FROM [mssql]", c[EngineCodes.SqlServer].RawSql); - Assert.Equal("SELECT * FROM \"generic\"", c[EngineCodes.PostgreSql].RawSql); - Assert.Equal("SELECT * FROM `generic`", c[EngineCodes.MySql].RawSql); + Assert.Equal("SELECT * FROM [mssql]", c.RawSql); + Assert.Equal("SELECT * FROM \"generic\"", c2.RawSql); + Assert.Equal("SELECT * FROM `generic`", c3.RawSql); } [Theory] @@ -255,7 +257,7 @@ public void AddOrReplace_Works(string table, string engine) if (table != null) query.From(table); query.AddOrReplaceComponent("from", new FromClause { Table = "updated", Engine = engine }); - var froms = query.Clauses.OfType(); + var froms = query.Clauses.OfType().ToList(); Assert.Single(froms); Assert.Equal("updated", froms.Single().Table); @@ -312,10 +314,10 @@ public void CompilerSpecificLimit(string engine, string sqlText) .ForSqlServer(q => q.Limit(5)) .ForPostgreSql(q => q.Limit(10)); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); Assert.Equal(2, query.GetComponents("limit").Count); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -340,10 +342,10 @@ public void CompilerSpecificOffset(string engine, string sqlText) .ForMySql(q => q.Offset(5)) .ForPostgreSql(q => q.Offset(10)); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); Assert.Equal(2, query.GetComponents("offset").Count); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -354,11 +356,11 @@ public void Offset_Takes_Generic_If_Needed() .Offset(10) .ForPostgreSql(q => q.Offset(20)); - var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); + var c = CompileFor(EngineCodes.MySql, query); + var c2 = CompileFor(EngineCodes.PostgreSql, query); - Assert.Equal("SELECT * FROM `mytable` LIMIT 5 OFFSET 10", c[EngineCodes.MySql].ToString()); - Assert.Equal("SELECT * FROM \"mytable\" LIMIT 5 OFFSET 20", c[EngineCodes.PostgreSql].ToString()); + Assert.Equal("SELECT * FROM `mytable` LIMIT 5 OFFSET 10", c.ToString()); + Assert.Equal("SELECT * FROM \"mytable\" LIMIT 5 OFFSET 20", c2.ToString()); } [Fact] @@ -369,11 +371,11 @@ public void Limit_Takes_Generic_If_Needed() .Offset(10) .ForPostgreSql(q => q.Limit(20)); - var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); + var c = CompileFor(EngineCodes.MySql, query); + var c2 = CompileFor(EngineCodes.PostgreSql, query); - Assert.Equal("SELECT * FROM `mytable` LIMIT 5 OFFSET 10", c[EngineCodes.MySql].ToString()); - Assert.Equal("SELECT * FROM \"mytable\" LIMIT 20 OFFSET 10", c[EngineCodes.PostgreSql].ToString()); + Assert.Equal("SELECT * FROM `mytable` LIMIT 5 OFFSET 10", c.ToString()); + Assert.Equal("SELECT * FROM \"mytable\" LIMIT 20 OFFSET 10", c2.ToString()); } [Fact] @@ -385,11 +387,11 @@ public void Can_Change_Generic_Limit_After_SpecificOffset() .ForPostgreSql(q => q.Offset(20)) .Limit(7); - var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); + var c = CompileFor(EngineCodes.MySql, query); + var c2 = CompileFor(EngineCodes.PostgreSql, query); - Assert.Equal("SELECT * FROM `mytable` LIMIT 7 OFFSET 10", c[EngineCodes.MySql].ToString()); - Assert.Equal("SELECT * FROM \"mytable\" LIMIT 7 OFFSET 20", c[EngineCodes.PostgreSql].ToString()); + Assert.Equal("SELECT * FROM `mytable` LIMIT 7 OFFSET 10", c.ToString()); + Assert.Equal("SELECT * FROM \"mytable\" LIMIT 7 OFFSET 20", c2.ToString()); } [Fact] @@ -401,11 +403,11 @@ public void Can_Change_Generic_Offset_After_SpecificLimit() .ForPostgreSql(q => q.Limit(20)) .Offset(7); - var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql }; - var c = Compilers.Compile(engines, query); + var c = CompileFor(EngineCodes.MySql, query); + var c2 = CompileFor(EngineCodes.PostgreSql, query); - Assert.Equal("SELECT * FROM `mytable` LIMIT 5 OFFSET 7", c[EngineCodes.MySql].ToString()); - Assert.Equal("SELECT * FROM \"mytable\" LIMIT 20 OFFSET 7", c[EngineCodes.PostgreSql].ToString()); + Assert.Equal("SELECT * FROM `mytable` LIMIT 5 OFFSET 7", c.ToString()); + Assert.Equal("SELECT * FROM \"mytable\" LIMIT 20 OFFSET 7", c2.ToString()); } [Theory] @@ -415,15 +417,11 @@ public void Can_Change_Generic_Offset_After_SpecificLimit() public void Where_Nested(string engine, string sqlText) { var query = new Query("table") - .Where(q => q.Where("a", 1).OrWhere("a", 2)); + .Where(q => q.Where("a", 1).OrWhere("a", 2)); - var engines = new[] { - EngineCodes.SqlServer, - }; - - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -431,9 +429,10 @@ public void AdHoc_Throws_WhenNoColumnsProvided() => Assert.Throws(() => new Query("rows").With("rows", new string[0], - new object[][] { - new object[] {}, - new object[] {}, + new object[][] + { + new object[] { }, + new object[] { }, })); [Fact] @@ -441,7 +440,8 @@ public void AdHoc_Throws_WhenNoValueRowsProvided() => Assert.Throws(() => new Query("rows").With("rows", new[] { "a", "b", "c" }, - new object[][] { + new object[][] + { })); [Fact] @@ -449,7 +449,8 @@ public void AdHoc_Throws_WhenColumnsOutnumberFieldValues() => Assert.Throws(() => new Query("rows").With("rows", new[] { "a", "b", "c", "d" }, - new object[][] { + new object[][] + { new object[] { 1, 2, 3 }, new object[] { 4, 5, 6 }, })); @@ -459,7 +460,8 @@ public void AdHoc_Throws_WhenFieldValuesOutNumberColumns() => Assert.Throws(() => new Query("rows").With("rows", new[] { "a", "b" }, - new object[][] { + new object[][] + { new object[] { 1, 2, 3 }, new object[] { 4, 5, 6 }, })); @@ -487,33 +489,48 @@ public void AdHoc_SingletonRow(string engine, string sqlText) { var query = new Query("rows").With("rows", new[] { "a" }, - new object[][] { + new object[][] + { new object[] { 1 }, }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } - [Fact] - public void AdHoc_TwoRows() + [Theory] + [InlineData( + EngineCodes.SqlServer, + "WITH [rows] AS (SELECT [a], [b], [c] FROM (VALUES (1, 2, 3), (4, 5, 6)) AS tbl ([a], [b], [c]))\nSELECT * FROM [rows]")] + [InlineData( + EngineCodes.PostgreSql, + "WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\")\nSELECT * FROM \"rows\"")] + [InlineData( + EngineCodes.MySql, + "WITH `rows` AS (SELECT 1 AS `a`, 2 AS `b`, 3 AS `c` UNION ALL SELECT 4 AS `a`, 5 AS `b`, 6 AS `c`)\nSELECT * FROM `rows`")] + [InlineData( + EngineCodes.Sqlite, + "WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\")\nSELECT * FROM \"rows\"")] + [InlineData( + EngineCodes.Firebird, + "WITH \"ROWS\" AS (SELECT 1 AS \"A\", 2 AS \"B\", 3 AS \"C\" FROM RDB$DATABASE UNION ALL SELECT 4 AS \"A\", 5 AS \"B\", 6 AS \"C\" FROM RDB$DATABASE)\nSELECT * FROM \"ROWS\"")] + [InlineData( + EngineCodes.Oracle, + "WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" FROM DUAL UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\" FROM DUAL)\nSELECT * FROM \"rows\"")] + public void AdHoc_TwoRows(string engine, string sqlText) { var query = new Query("rows").With("rows", new[] { "a", "b", "c" }, - new object[][] { + new object[][] + { new object[] { 1, 2, 3 }, new object[] { 4, 5, 6 }, }); - var c = Compilers.Compile(query); + var c = CompileFor(engine, query); - Assert.Equal("WITH [rows] AS (SELECT [a], [b], [c] FROM (VALUES (1, 2, 3), (4, 5, 6)) AS tbl ([a], [b], [c]))\nSELECT * FROM [rows]", c[EngineCodes.SqlServer].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\")\nSELECT * FROM \"rows\"", c[EngineCodes.PostgreSql].ToString()); - Assert.Equal("WITH `rows` AS (SELECT 1 AS `a`, 2 AS `b`, 3 AS `c` UNION ALL SELECT 4 AS `a`, 5 AS `b`, 6 AS `c`)\nSELECT * FROM `rows`", c[EngineCodes.MySql].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\")\nSELECT * FROM \"rows\"", c[EngineCodes.Sqlite].ToString()); - Assert.Equal("WITH \"ROWS\" AS (SELECT 1 AS \"A\", 2 AS \"B\", 3 AS \"C\" FROM RDB$DATABASE UNION ALL SELECT 4 AS \"A\", 5 AS \"B\", 6 AS \"C\" FROM RDB$DATABASE)\nSELECT * FROM \"ROWS\"", c[EngineCodes.Firebird].ToString()); - Assert.Equal("WITH \"rows\" AS (SELECT 1 AS \"a\", 2 AS \"b\", 3 AS \"c\" FROM DUAL UNION ALL SELECT 4 AS \"a\", 5 AS \"b\", 6 AS \"c\" FROM DUAL)\nSELECT * FROM \"rows\"", c[EngineCodes.Oracle].ToString()); + Assert.Equal(sqlText, c.ToString()); } [Fact] @@ -523,20 +540,22 @@ public void AdHoc_ProperBindingsPlacement() .With("othercte", q => q.From("othertable").Where("othertable.status", "A")) .Where("rows.foo", "bar") .With("rows", - new[] { "a", "b", "c" }, - new object[][] { - new object[] { 1, 2, 3 }, - new object[] { 4, 5, 6 }, - }) + new[] { "a", "b", "c" }, + new object[][] + { + new object[] { 1, 2, 3 }, + new object[] { 4, 5, 6 }, + }) .Where("rows.baz", "buzz"); - var c = Compilers.Compile(query); + var c = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal(string.Join("\n", new[] { + Assert.Equal(string.Join("\n", new[] + { "WITH [othercte] AS (SELECT * FROM [othertable] WHERE [othertable].[status] = 'A'),", "[rows] AS (SELECT [a], [b], [c] FROM (VALUES (1, 2, 3), (4, 5, 6)) AS tbl ([a], [b], [c]))", "SELECT * FROM [rows] WHERE [rows].[foo] = 'bar' AND [rows].[baz] = 'buzz'", - }), c[EngineCodes.SqlServer].ToString()); + }), c.ToString()); } [Fact] @@ -547,13 +566,9 @@ public void UnsafeLiteral_Insert() Count = new UnsafeLiteral("Count + 1") }); - var engines = new[] { - EngineCodes.SqlServer, - }; + var c = CompileFor(EngineCodes.SqlServer, query); - var c = Compilers.Compile(engines, query); - - Assert.Equal("INSERT INTO [Table] ([Count]) VALUES (Count + 1)", c[EngineCodes.SqlServer].ToString()); + Assert.Equal("INSERT INTO [Table] ([Count]) VALUES (Count + 1)", c.ToString()); } [Fact] @@ -564,13 +579,9 @@ public void UnsafeLiteral_Update() Count = new UnsafeLiteral("Count + 1") }); - var engines = new[] { - EngineCodes.SqlServer, - }; - - var c = Compilers.Compile(engines, query); + var c = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal("UPDATE [Table] SET [Count] = Count + 1", c[EngineCodes.SqlServer].ToString()); + Assert.Equal("UPDATE [Table] SET [Count] = Count + 1", c.ToString()); } [Theory] @@ -579,9 +590,9 @@ public void Passing_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse(string { var query = new Query("Table").Where("Col", true); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -590,9 +601,9 @@ public void Passing_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse(s { var query = new Query("Table").Where("Col", false); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -603,9 +614,9 @@ public void Passing_Negative_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFals { var query = new Query("Table").Where("Col", "!=", true); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -616,9 +627,9 @@ public void Passing_Negative_Boolean_False_To_Where_Should_Call_WhereTrue_Or_Whe { var query = new Query("Table").Where("Col", "!=", false); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } } } diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs b/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs deleted file mode 100644 index 3b00e8c3..00000000 --- a/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using SqlKata.Compilers; - -namespace SqlKata.Tests.Infrastructure -{ - public class TestCompilersContainer - { - private static class Messages - { - public const string ERR_INVALID_ENGINECODE = "Engine code '{0}' is not valid"; - public const string ERR_INVALID_ENGINECODES = "Invalid engine codes supplied '{0}'"; - } - - protected readonly IDictionary Compilers = new Dictionary - { - [EngineCodes.Firebird] = new FirebirdCompiler(), - [EngineCodes.MySql] = new MySqlCompiler(), - [EngineCodes.Oracle] = new OracleCompiler(), - [EngineCodes.PostgreSql] = new PostgresCompiler(), - [EngineCodes.Sqlite] = new SqliteCompiler(), - [EngineCodes.SqlServer] = new SqlServerCompiler() - { - UseLegacyPagination = true - } - }; - - public IEnumerable KnownEngineCodes - { - get { return Compilers.Select(s => s.Key); } - } - - /// - /// Returns a instance for the given engine code - /// - /// - /// - public Compiler Get(string engineCode) - { - if (!Compilers.TryGetValue(engineCode, out var compiler)) - { - throw new InvalidOperationException(string.Format(Messages.ERR_INVALID_ENGINECODE, engineCode)); - } - - return compiler; - } - - /// - /// Convenience method - /// - /// Does not validate generic type against engine code before cast - /// - /// - /// - public TCompiler Get(string engineCode) where TCompiler : Compiler - { - return (TCompiler)Get(engineCode); - } - - /// - /// Compiles the against the given engine code - /// - /// - /// - /// - public SqlResult CompileFor(string engineCode, Query query) - { - var compiler = Get(engineCode); - return compiler.Compile(query); - } - - /// - /// Compiles the against the given engine codes - /// - /// - /// - /// - public TestSqlResultContainer Compile(IEnumerable engineCodes, Query query) - { - var codes = engineCodes.ToList(); - - var results = Compilers - .Where(w => codes.Contains(w.Key)) - .ToDictionary(k => k.Key, v => v.Value.Compile(query.Clone())); - - if (results.Count != codes.Count) - { - var missingCodes = codes.Where(w => Compilers.All(a => a.Key != w)); - var templateArg = string.Join(", ", missingCodes); - throw new InvalidOperationException(string.Format(Messages.ERR_INVALID_ENGINECODES, templateArg)); - } - - return new TestSqlResultContainer(results); - } - - /// - /// Compiles the against all s - /// - /// - /// - public TestSqlResultContainer Compile(Query query) - { - var resultKeyValues = Compilers - .ToDictionary(k => k.Key, v => v.Value.Compile(query.Clone())); - return new TestSqlResultContainer(resultKeyValues); - } - } -} diff --git a/QueryBuilder.Tests/Infrastructure/TestSqlResultContainer.cs b/QueryBuilder.Tests/Infrastructure/TestSqlResultContainer.cs deleted file mode 100644 index 16a5eeff..00000000 --- a/QueryBuilder.Tests/Infrastructure/TestSqlResultContainer.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using System.Collections.ObjectModel; - -namespace SqlKata.Tests.Infrastructure -{ - public class TestSqlResultContainer : ReadOnlyDictionary - { - public TestSqlResultContainer(IDictionary dictionary) : base(dictionary) - { - - } - } -} diff --git a/QueryBuilder.Tests/Infrastructure/TestSupport.cs b/QueryBuilder.Tests/Infrastructure/TestSupport.cs index 57c39e7c..1ae0f420 100644 --- a/QueryBuilder.Tests/Infrastructure/TestSupport.cs +++ b/QueryBuilder.Tests/Infrastructure/TestSupport.cs @@ -8,28 +8,11 @@ namespace SqlKata.Tests.Infrastructure { public abstract class TestSupport { - protected readonly TestCompilersContainer Compilers = new TestCompilersContainer(); - - /// - /// For legacy test support - /// - /// - /// - protected IReadOnlyDictionary Compile(Query query) - { - return Compilers.Compile(query).ToDictionary(s => s.Key, v => v.Value.ToString()); - } - protected SqlResult CompileForGeneric(Query query, Func configuration = null) { return CompileFor(EngineCodes.Generic, query, configuration); } - protected SqlResult CompileForGeneric(Query query, Action configuration) - { - return CompileFor(EngineCodes.Generic, query, configuration); - } - protected SqlResult CompileFor(string engine, Query query, Func configuration = null) { var compiler = CreateCompiler(engine); @@ -50,18 +33,21 @@ protected SqlResult CompileFor(string engine, Query query, Action conf }); } - private static Compiler CreateCompiler(string engine) + protected Compiler CreateCompiler(string engine, bool? useLegacyPagination = null) { return engine switch { EngineCodes.Firebird => new FirebirdCompiler(), EngineCodes.MySql => new MySqlCompiler(), - EngineCodes.Oracle => new OracleCompiler(), + EngineCodes.Oracle => new OracleCompiler + { + UseLegacyPagination = useLegacyPagination ?? false + }, EngineCodes.PostgreSql => new PostgresCompiler(), EngineCodes.Sqlite => new SqliteCompiler(), EngineCodes.SqlServer => new SqlServerCompiler { - UseLegacyPagination = true + UseLegacyPagination = useLegacyPagination ?? true }, EngineCodes.Generic => new TestCompiler(), _ => throw new ArgumentException($"Unsupported engine type: {engine}", nameof(engine)), diff --git a/QueryBuilder.Tests/InfrastructureTests.cs b/QueryBuilder.Tests/InfrastructureTests.cs deleted file mode 100644 index 5bb7f2df..00000000 --- a/QueryBuilder.Tests/InfrastructureTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Linq; -using SqlKata.Compilers; -using SqlKata.Tests.Infrastructure; -using Xunit; - -namespace SqlKata.Tests -{ - public class InfrastructureTests : TestSupport - { - [Fact] - public void CanGetCompiler() - { - var compiler = Compilers.Get(EngineCodes.SqlServer); - - Assert.NotNull(compiler); - Assert.IsType(compiler); - } - - [Fact] - public void CanCompile() - { - var results = Compilers.Compile(new Query("Table")); - - Assert.NotNull(results); - Assert.Equal(Compilers.KnownEngineCodes.Count(), results.Count); - } - - [Fact] - public void CanCompileSelectively() - { - var desiredEngines = new[] { EngineCodes.SqlServer, EngineCodes.MySql }; - var results = Compilers.Compile(desiredEngines, new Query("Table")); - - Assert.Equal(desiredEngines.Length, results.Count); - Assert.Contains(results, a => a.Key == EngineCodes.SqlServer); - Assert.Contains(results, a => a.Key == EngineCodes.MySql); - } - - - [Fact] - public void ShouldThrowIfInvalidEngineCode() - { - Assert.Throws(() => Compilers.CompileFor("XYZ", new Query())); - } - - [Fact] - public void ShouldThrowIfAnyEngineCodesAreInvalid() - { - var codes = new[] { EngineCodes.SqlServer, "123", EngineCodes.MySql, "abc" }; - Assert.Throws(() => Compilers.Compile(codes, new Query())); - } - } -} diff --git a/QueryBuilder.Tests/InsertTests.cs b/QueryBuilder.Tests/InsertTests.cs index 5c8fa5d0..ee27337a 100644 --- a/QueryBuilder.Tests/InsertTests.cs +++ b/QueryBuilder.Tests/InsertTests.cs @@ -42,9 +42,9 @@ public void InsertObject(string engine, string sqlText) Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -59,9 +59,9 @@ public void InsertFromSubQueryWithCte(string engine, string sqlText) new[] { "name", "model", "year" }, new Query("old_cars").Where("price", ">", 100).ForPage(2, 10)); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -79,9 +79,9 @@ public void InsertMultiRecords(string engine, string sqlText) new object[] { "Reventon roadster", "Lamborghini", 2009 } }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -94,9 +94,9 @@ public void InsertWithNullValues(string engine, string sqlText) new[] { "Id", "Author", "ISBN", "Date" }, new object[] { 1, "Author 1", "123456", null }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -109,9 +109,9 @@ public void InsertWithEmptyString(string engine, string sqlText) new[] { "Id", "Author", "ISBN", "Description" }, new object[] { 1, "Author 1", "123456", "" }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -127,13 +127,13 @@ public void InsertWithByteArray() fauxImagebytes }); - var c = CompileFor(EngineCodes.SqlServer, query); + var result = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal(2, c.NamedBindings.Count); - Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (?, ?)", c.RawSql); - Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (@p0, @p1)", c.Sql); - Assert.Equal(1, c.NamedBindings["@p0"]); - Assert.Equal(fauxImagebytes, c.NamedBindings["@p1"]); + Assert.Equal(2, result.NamedBindings.Count); + Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (?, ?)", result.RawSql); + Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (@p0, @p1)", result.Sql); + Assert.Equal(1, result.NamedBindings["@p0"]); + Assert.Equal(fauxImagebytes, result.NamedBindings["@p1"]); } [Theory] @@ -144,9 +144,9 @@ public void InsertWithIgnoreAndColumnProperties(string engine, string sqlText) var account = new Account(name: $"popular", color: $"blue", currency: "US"); var query = new Query("Account").AsInsert(account); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -162,9 +162,9 @@ public void InsertFromRaw(string engine, string sqlText) Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -181,7 +181,7 @@ public void InsertFromQueryShouldFail() Assert.Throws(() => { - Compile(query); + CompileFor(EngineCodes.Generic, query); }); } @@ -200,9 +200,9 @@ public void InsertKeyValuePairs(string engine, string sqlText) var query = new Query("Table") .AsInsert(dictionaryUser); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -218,9 +218,9 @@ public void InsertDictionary(string engine, string sqlText) var query = new Query("Table") .AsInsert(dictionaryUser); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -238,9 +238,9 @@ public void InsertReadOnlyDictionary(string engine, string sqlText) var query = new Query("Table") .AsInsert(dictionaryUser); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -255,9 +255,9 @@ public void InsertExpandoObject(string engine, string sqlText) var query = new Query("Table") .AsInsert(expandoUser); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } } } diff --git a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs index 9d5f0874..9fa3484f 100644 --- a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs +++ b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs @@ -6,11 +6,11 @@ namespace SqlKata.Tests.MySql { public class MySqlLimitTests : TestSupport { - private readonly MySqlCompiler compiler; + private readonly Compiler compiler; public MySqlLimitTests() { - compiler = Compilers.Get(EngineCodes.MySql); + compiler = CreateCompiler(EngineCodes.MySql); } [Fact] diff --git a/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs b/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs index 57a5605e..4afa28c9 100644 --- a/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs @@ -9,11 +9,11 @@ public class OracleDateConditionTests : TestSupport private const string TableName = "Table"; private const string SqlPlaceholder = "GENERATED_SQL"; - private readonly OracleCompiler compiler; + private readonly Compiler compiler; public OracleDateConditionTests() { - compiler = Compilers.Get(EngineCodes.Oracle); + compiler = CreateCompiler(EngineCodes.Oracle); } [Fact] diff --git a/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs b/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs index f25cf2ba..fd6fd890 100644 --- a/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs @@ -7,11 +7,11 @@ namespace SqlKata.Tests.Oracle public class OracleInsertManyTests : TestSupport { private const string TableName = "Table"; - private readonly OracleCompiler compiler; + private readonly Compiler compiler; public OracleInsertManyTests() { - compiler = Compilers.Get(EngineCodes.Oracle); + compiler = CreateCompiler(EngineCodes.Oracle); } [Fact] diff --git a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs index 299c71ef..1af5b182 100644 --- a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs @@ -8,12 +8,11 @@ public class OracleLegacyLimitTests : TestSupport { private const string TableName = "Table"; private const string SqlPlaceholder = "GENERATED_SQL"; - private readonly OracleCompiler compiler; + private readonly Compiler compiler; public OracleLegacyLimitTests() { - compiler = Compilers.Get(EngineCodes.Oracle); - compiler.UseLegacyPagination = true; + compiler = CreateCompiler(EngineCodes.Oracle, useLegacyPagination: true); } [Fact] diff --git a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs index 0a8ca969..34186530 100644 --- a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs @@ -9,11 +9,11 @@ public class OracleLimitTests : TestSupport private const string TableName = "Table"; private const string SqlPlaceholder = "GENERATED_SQL"; - private readonly OracleCompiler compiler; + private readonly Compiler compiler; public OracleLimitTests() { - compiler = Compilers.Get(EngineCodes.Oracle); + compiler = CreateCompiler(EngineCodes.Oracle); } [Fact] diff --git a/QueryBuilder.Tests/ParameterTypeTests.cs b/QueryBuilder.Tests/ParameterTypeTests.cs index 819ce7cd..fe197004 100644 --- a/QueryBuilder.Tests/ParameterTypeTests.cs +++ b/QueryBuilder.Tests/ParameterTypeTests.cs @@ -43,9 +43,9 @@ public void CorrectParameterTypeOutput(string rendered, object input) { var query = new Query("Table").Where("Col", input); - var c = Compile(query); + var c = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal($"SELECT * FROM [Table] WHERE [Col] = {rendered}", c[EngineCodes.SqlServer]); + Assert.Equal($"SELECT * FROM [Table] WHERE [Col] = {rendered}", c.ToString()); } } } diff --git a/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs b/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs index 41859e6e..095a128b 100644 --- a/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs +++ b/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs @@ -6,11 +6,11 @@ namespace SqlKata.Tests.PostgreSql { public class PostgreSqlLimitTests : TestSupport { - private readonly PostgresCompiler compiler; + private readonly Compiler compiler; public PostgreSqlLimitTests() { - compiler = Compilers.Get(EngineCodes.PostgreSql); + compiler = CreateCompiler(EngineCodes.PostgreSql); } [Fact] diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs index 96ff17e0..35bf3b1a 100644 --- a/QueryBuilder.Tests/SelectTests.cs +++ b/QueryBuilder.Tests/SelectTests.cs @@ -19,9 +19,9 @@ public void BasicSelect(string engine, string sqlText) { var query = new Query().From("users").Select("id", "name"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -34,9 +34,9 @@ public void BasicSelectEnumerable(string engine, string sqlText) { var query = new Query().From("users").Select(new List() { "id", "name" }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -56,9 +56,9 @@ public void BasicSelectWhereBindingIsEmptyOrNull(string engine, string sqlText) .Where("author", "") .OrWhere("author", null); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -71,9 +71,9 @@ public void BasicSelectWithAlias(string engine, string sqlText) { var query = new Query().From("users as u").Select("id", "name"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -83,9 +83,9 @@ public void ExpandedSelect(string engine, string sqlText) { var query = new Query().From("users").Select("users.{id,name, age}"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -99,19 +99,19 @@ public void ExpandedSelectMultiline(string engine, string sqlText) age }"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] public void ExpandedSelectWithSchema() { var query = new Query().From("users").Select("dbo.users.{id,name, age}"); - var c = Compile(query); + var result = CompileFor(EngineCodes.SqlServer, query); Assert.Equal("SELECT [dbo].[users].[id], [dbo].[users].[name], [dbo].[users].[age] FROM [users]", - c[EngineCodes.SqlServer]); + result.ToString()); } [Fact] @@ -122,10 +122,10 @@ public void ExpandedSelectMultilineWithSchema() name as Name, age }"); - var c = Compile(query); + var result = CompileFor(EngineCodes.SqlServer, query); Assert.Equal("SELECT [dbo].[users].[id], [dbo].[users].[name] AS [Name], [dbo].[users].[age] FROM [users]", - c[EngineCodes.SqlServer]); + result.ToString()); } [Theory] @@ -137,9 +137,9 @@ public void NestedEmptyWhereAtFirstCondition(string engine, string sqlText) .Where(_ => new Query()) .Where("id", 1); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -151,9 +151,9 @@ public void WhereTrue(string engine, string sqlText) { var query = new Query("Table").WhereTrue("IsActive"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -165,9 +165,9 @@ public void WhereFalse(string engine, string sqlText) { var query = new Query("Table").WhereFalse("IsActive"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -178,9 +178,9 @@ public void OrWhereFalse(string engine, string sqlText) { var query = new Query("Table").Where("MyCol", "abc").OrWhereFalse("IsActive"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -191,9 +191,9 @@ public void OrWhereTrue(string engine, string sqlText) { var query = new Query("Table").Where("MyCol", "abc").OrWhereTrue("IsActive"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -203,9 +203,9 @@ public void OrWhereNull(string engine, string sqlText) { var query = new Query("Table").Where("MyCol", "abc").OrWhereNull("IsActive"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -219,9 +219,9 @@ public void WhereSub(string engine, string sqlText) var query = new Query("Table").WhereSub(subQuery, 1); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -235,9 +235,9 @@ public void OrWhereSub(string engine, string sqlText) var query = new Query("Table").WhereNull("MyCol").OrWhereSub(subQuery, "<", 1); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -245,9 +245,9 @@ public void PassingArrayAsParameter() { var query = new Query("Table").WhereRaw("[Id] in (?)", new object[] { new object[] { 1, 2, 3 } }); - var c = Compile(query); + var result = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal("SELECT * FROM [Table] WHERE [Id] in (1,2,3)", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT * FROM [Table] WHERE [Id] in (1,2,3)", result.ToString()); } [Fact] @@ -255,10 +255,10 @@ public void UsingJsonArray() { var query = new Query("Table").WhereRaw("[Json]->'address'->>'country' in (?)", new[] { 1, 2, 3, 4 }); - var c = Compile(query); + var result = CompileFor(EngineCodes.PostgreSql, query); Assert.Equal("SELECT * FROM \"Table\" WHERE \"Json\"->'address'->>'country' in (1,2,3,4)", - c[EngineCodes.PostgreSql]); + result.ToString()); } [Theory] @@ -270,9 +270,9 @@ public void Union(string engine, string sqlText) var laptops = new Query("Laptops"); var mobiles = new Query("Phones").Union(laptops); - var c = CompileFor(engine, mobiles); + var result = CompileFor(engine, mobiles); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -287,9 +287,9 @@ public void UnionWithBindings(string engine, string sqlText) var laptops = new Query("Laptops").Where("Type", "A"); var mobiles = new Query("Phones").Union(laptops); - var c = CompileFor(engine, mobiles); + var result = CompileFor(engine, mobiles); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -303,9 +303,9 @@ public void RawUnionWithBindings(string engine, string sqlText) { var mobiles = new Query("Phones").UnionRaw("UNION SELECT * FROM [Laptops] WHERE [Type] = ?", "A"); - var c = CompileFor(engine, mobiles); + var result = CompileFor(engine, mobiles); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -320,9 +320,9 @@ public void MultipleUnion(string engine, string sqlText) var mobiles = new Query("Phones").Union(laptops).Union(tablets); - var c = CompileFor(engine, mobiles); + var result = CompileFor(engine, mobiles); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -337,9 +337,9 @@ public void MultipleUnionWithBindings(string engine, string sqlText) var mobiles = new Query("Phones").Where("Price", "<", 3000).Union(laptops).Union(tablets); - var c = CompileFor(engine, mobiles); + var result = CompileFor(engine, mobiles); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -354,9 +354,9 @@ public void MultipleUnionWithBindingsAndPagination(string engine, string sqlText var mobiles = new Query("Phones").Where("Price", "<", 3000).Union(laptops).UnionAll(tablets); - var c = CompileFor(engine, mobiles); + var result = CompileFor(engine, mobiles); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -371,9 +371,9 @@ public void UnionWithCallbacks(string engine, string sqlText) .Union(q => q.From("Laptops")) .UnionAll(q => q.From("Tablets")); - var c = CompileFor(engine, mobiles); + var result = CompileFor(engine, mobiles); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -395,9 +395,9 @@ public void UnionWithDifferentEngine(string engine, string sqlText) .ForFirebird(scope => scope.Union(q => q.From("Laptops").Where("Price", "<", 800))) .UnionAll(q => q.From("Tablets").Where("Price", "<", 100)); - var c = CompileFor(engine, mobiles); + var result = CompileFor(engine, mobiles); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -405,9 +405,9 @@ public void CombineRaw() { var query = new Query("Mobiles").CombineRaw("UNION ALL SELECT * FROM Devices"); - var c = Compile(query); + var result = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal("SELECT * FROM [Mobiles] UNION ALL SELECT * FROM Devices", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT * FROM [Mobiles] UNION ALL SELECT * FROM Devices", result.ToString()); } [Theory] @@ -418,9 +418,9 @@ public void CombineRawWithPlaceholders(string engine, string sqlText) { var query = new Query("Mobiles").CombineRaw("UNION ALL SELECT * FROM {Devices}"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -429,9 +429,9 @@ public void NestedEmptyWhere() // Empty nested where should be ignored var query = new Query("A").Where(_ => new Query().Where(_ => new Query().Where(_ => new Query()))); - var c = Compile(query); + var result = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal("SELECT * FROM [A]", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT * FROM [A]", result.ToString()); } [Fact] @@ -439,9 +439,9 @@ public void NestedQuery() { var query = new Query("A").Where(_ => new Query("B")); - var c = Compile(query); + var result = CompileFor(EngineCodes.SqlServer, query); - Assert.Equal("SELECT * FROM [A]", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT * FROM [A]", result.ToString()); } [Fact] @@ -452,10 +452,10 @@ public void NestedQueryAfterNestedJoin() .Join("countries", j => j.On("countries.id", "users.country_id")) .Where(_ => new Query()); - var c = Compile(query); + var result = CompileFor(EngineCodes.SqlServer, query); Assert.Equal("SELECT * FROM [users] \nINNER JOIN [countries] ON ([countries].[id] = [users].[country_id])", - c[EngineCodes.SqlServer]); + result.ToString()); } [Fact] @@ -470,11 +470,11 @@ public void MultipleCte() .With("B", q2) .With("C", q3); - var c = Compile(query); + var result = CompileFor(EngineCodes.SqlServer, query); Assert.Equal( "WITH [A] AS (SELECT * FROM [A]),\n[B] AS (SELECT * FROM [B]),\n[C] AS (SELECT * FROM [C])\nSELECT * FROM [A]", - c[EngineCodes.SqlServer]); + result.ToString()); } [Theory] @@ -514,9 +514,9 @@ public void CteAndBindings(string engine, string sqlText) .Where("Id", ">", 55) .WhereBetween("Value", 18, 24); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } // test for issue #50 @@ -547,9 +547,9 @@ public void CascadedCteAndBindings(string engine, string sqlText) mainQuery.From("cte2"); mainQuery.Where("Column3", 5); - var c = CompileFor(engine, mainQuery); + var result = CompileFor(engine, mainQuery); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } // test for issue #50 @@ -587,9 +587,9 @@ public void CascadedAndMultiReferencedCteAndBindings(string engine, string sqlTe mainQuery.From("cte2"); mainQuery.Where("Column3", 5); - var c = CompileFor(engine, mainQuery); + var result = CompileFor(engine, mainQuery); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } // test for issue #50 @@ -626,9 +626,9 @@ public void MultipleCtesAndBindings(string engine, string sqlText) mainQuery.From("cte3"); mainQuery.Where("Column3_4", 5); - var c = CompileFor(engine, mainQuery); + var result = CompileFor(engine, mainQuery); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -640,9 +640,9 @@ public void Limit(string engine, string sqlText) { var query = new Query().From("users").Select("id", "name").Limit(10); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -655,9 +655,9 @@ public void Offset(string engine, string sqlText) { var query = new Query().From("users").Offset(10); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -670,9 +670,9 @@ public void LimitOffset(string engine, string sqlText) { var query = new Query().From("users").Offset(10).Limit(5); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -684,36 +684,52 @@ public void BasicJoin(string engine, string sqlText) { var query = new Query().From("users").Join("countries", "countries.id", "users.country_id"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } - [Theory] - [InlineData("inner join", "INNER JOIN")] - [InlineData("left join", "LEFT JOIN")] - [InlineData("right join", "RIGHT JOIN")] - [InlineData("cross join", "CROSS JOIN")] - public void JoinTypes(string given, string output) + public static TheoryData JoinTypesData() { - var q = new Query().From("users") - .Join("countries", "countries.id", "users.country_id", "=", given); + var data = new TheoryData(); + AddEngines("inner join", "INNER JOIN", data); + AddEngines("left join", "LEFT JOIN", data); + AddEngines("right join", "RIGHT JOIN", data); + AddEngines("cross join", "CROSS JOIN", data); - var c = Compile(q); + return data; - Assert.Equal($"SELECT * FROM [users] \n{output} [countries] ON [countries].[id] = [users].[country_id]", - c[EngineCodes.SqlServer]); + void AddEngines(string given, string output, TheoryData data) + { + data.Add( + given, + EngineCodes.SqlServer, + $"SELECT * FROM [users] \n{output} [countries] ON [countries].[id] = [users].[country_id]"); + data.Add( + given, + EngineCodes.MySql, + $"SELECT * FROM `users` \n{output} `countries` ON `countries`.`id` = `users`.`country_id`"); + data.Add( + given, + EngineCodes.PostgreSql, + $"SELECT * FROM \"users\" \n{output} \"countries\" ON \"countries\".\"id\" = \"users\".\"country_id\""); + data.Add( + given, + EngineCodes.Firebird, + $"SELECT * FROM \"USERS\" \n{output} \"COUNTRIES\" ON \"COUNTRIES\".\"ID\" = \"USERS\".\"COUNTRY_ID\""); + } + } - Assert.Equal($"SELECT * FROM `users` \n{output} `countries` ON `countries`.`id` = `users`.`country_id`", - c[EngineCodes.MySql]); + [Theory] + [MemberData(nameof(JoinTypesData))] + public void JoinTypes(string given, string engine, string sqlText) + { + var q = new Query().From("users") + .Join("countries", "countries.id", "users.country_id", "=", given); - Assert.Equal( - $"SELECT * FROM \"users\" \n{output} \"countries\" ON \"countries\".\"id\" = \"users\".\"country_id\"", - c[EngineCodes.PostgreSql]); + var result = CompileFor(engine, q); - Assert.Equal( - $"SELECT * FROM \"USERS\" \n{output} \"COUNTRIES\" ON \"COUNTRIES\".\"ID\" = \"USERS\".\"COUNTRY_ID\"", - c[EngineCodes.Firebird]); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -721,9 +737,9 @@ public void OrWhereRawEscaped() { var query = new Query("Table").WhereRaw("[MyCol] = ANY(?::int\\[\\])", "{1,2,3}"); - var c = Compile(query); + var result = CompileFor(EngineCodes.PostgreSql, query); - Assert.Equal("SELECT * FROM \"Table\" WHERE \"MyCol\" = ANY('{1,2,3}'::int[])", c[EngineCodes.PostgreSql]); + Assert.Equal("SELECT * FROM \"Table\" WHERE \"MyCol\" = ANY('{1,2,3}'::int[])", result.ToString()); } [Theory] @@ -733,9 +749,9 @@ public void Having(string engine, string sqlText) var query = new Query("Table1") .Having("Column1", ">", 1); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -746,9 +762,9 @@ public void MultipleHaving(string engine, string sqlText) .Having("Column1", ">", 1) .Having("Column2", "=", 1); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -759,9 +775,9 @@ public void MultipleOrHaving(string engine, string sqlText) .Having("Column1", ">", 1) .OrHaving("Column2", "=", 1); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -772,9 +788,9 @@ public void ShouldUseILikeOnPostgresWhenNonCaseSensitive(string engine, string s var query = new Query("Table1") .WhereLike("Column1", "%Upper Word%", caseSensitive: false); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -785,9 +801,9 @@ public void EscapedWhereLike(string engine, string sqlText) var query = new Query("Table1") .WhereLike("Column1", @"TestString\%", false, @"\"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -798,9 +814,9 @@ public void EscapedWhereStarts(string engine, string sqlText) var query = new Query("Table1") .WhereStarts("Column1", @"TestString\%", false, @"\"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -811,9 +827,9 @@ public void EscapedWhereEnds(string engine, string sqlText) var query = new Query("Table1") .WhereEnds("Column1", @"TestString\%", false, @"\"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -824,9 +840,9 @@ public void EscapedWhereContains(string engine, string sqlText) var query = new Query("Table1") .WhereContains("Column1", @"TestString\%", false, @"\"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -837,9 +853,9 @@ public void EscapedHavingLike(string engine, string sqlText) var query = new Query("Table1") .HavingLike("Column1", @"TestString\%", false, @"\"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -850,9 +866,9 @@ public void EscapedHavingStarts(string engine, string sqlText) var query = new Query("Table1") .HavingStarts("Column1", @"TestString\%", false, @"\"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -863,9 +879,9 @@ public void EscapedHavingEnds(string engine, string sqlText) var query = new Query("Table1") .HavingEnds("Column1", @"TestString\%", false, @"\"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -876,9 +892,9 @@ public void EscapedHavingContains(string engine, string sqlText) var query = new Query("Table1") .HavingContains("Column1", @"TestString\%", false, @"\"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Fact] @@ -897,89 +913,90 @@ public void BasicSelectRaw_WithNoTable() { var q = new Query().SelectRaw("somefunction() as c1"); - var c = Compilers.CompileFor(EngineCodes.SqlServer, q); - Assert.Equal("SELECT somefunction() as c1", c.ToString()); + var result = CompileFor(EngineCodes.SqlServer, q); + + Assert.Equal("SELECT somefunction() as c1", result.ToString()); } [Theory] [InlineData(EngineCodes.SqlServer, "SELECT [c1]")] public void BasicSelect_WithNoTable(string engine, string sqlText) { - var q = new Query().Select("c1"); + var query = new Query().Select("c1"); - var c = CompileFor(engine, q); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] [InlineData(EngineCodes.SqlServer, "SELECT [c1] WHERE [p] = 1")] public void BasicSelect_WithNoTableAndWhereClause(string engine, string sqlText) { - var q = new Query().Select("c1").Where("p", 1); + var query = new Query().Select("c1").Where("p", 1); - var c = CompileFor(engine, q); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] [InlineData(EngineCodes.SqlServer, "SELECT [c1] WHERE 1 = 1")] public void BasicSelect_WithNoTableWhereRawClause(string engine, string sqlText) { - var q = new Query().Select("c1").WhereRaw("1 = 1"); + var query = new Query().Select("c1").WhereRaw("1 = 1"); - var c = CompileFor(engine, q); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM([ViewCount]) FROM [Posts]")] public void BasicSelectAggregate(string engine, string sqlText) { - var q = new Query("Posts").Select("Title") + var query = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount"); - var c = CompileFor(engine, q); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM([ViewCount]) FROM [Posts]")] public void SelectAggregateShouldIgnoreEmptyFilter(string engine, string sqlText) { - var q = new Query("Posts").Select("Title") + var query = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount", q => q); - var c = CompileFor(engine, q); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM([ViewCount]) FROM [Posts]")] public void SelectAggregateShouldIgnoreEmptyQueryFilter(string engine, string sqlText) { - var q = new Query("Posts").Select("Title") + var query = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount", new Query()); - var c = CompileFor(engine, q); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] [InlineData(EngineCodes.SqlServer, "SELECT [Title], SUM([ViewCount]) AS [TotalViews] FROM [Posts]")] public void BasicSelectAggregateWithAlias(string engine, string sqlText) { - var q = new Query("Posts").Select("Title") + var query = new Query("Posts").Select("Title") .SelectAggregate("sum", "ViewCount as TotalViews"); - var c = CompileFor(engine, q); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -993,9 +1010,9 @@ public void SelectWithFilter(string engine, string sqlText) .SelectAggregate("sum", "ViewCount as Published_Jan", q => q.Where("Published_Month", "Jan")) .SelectAggregate("sum", "ViewCount as Published_Feb", q => q.Where("Published_Month", "Feb")); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -1007,9 +1024,9 @@ public void SelectWithExists(string engine, string sqlText) new Query("Comments").WhereColumns("Comments.PostId", "=", "Posts.Id") ); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -1021,12 +1038,12 @@ public void SelectWithExists_OmitSelectIsFalse(string engine, string sqlText) new Query("Comments").Select("Id").WhereColumns("Comments.PostId", "=", "Posts.Id") ); - var c = CompileFor(engine, q, compiler => + var result = CompileFor(engine, q, compiler => { compiler.OmitSelectInsideExists = false; }); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } } } diff --git a/QueryBuilder.Tests/SqlServer/NestedSelectTests.cs b/QueryBuilder.Tests/SqlServer/NestedSelectTests.cs index 4c591ba2..79a04b30 100644 --- a/QueryBuilder.Tests/SqlServer/NestedSelectTests.cs +++ b/QueryBuilder.Tests/SqlServer/NestedSelectTests.cs @@ -6,11 +6,11 @@ namespace SqlKata.Tests.SqlServer { public class NestedSelectTests : TestSupport { - private readonly SqlServerCompiler compiler; + private readonly Compiler compiler; public NestedSelectTests() { - compiler = Compilers.Get(EngineCodes.SqlServer); + compiler = CreateCompiler(EngineCodes.SqlServer); } [Fact] diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs index 20e013bd..3b1650b2 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs @@ -6,12 +6,11 @@ namespace SqlKata.Tests.SqlServer { public class SqlServerLegacyLimitTests : TestSupport { - private readonly SqlServerCompiler compiler; + private readonly Compiler compiler; public SqlServerLegacyLimitTests() { - compiler = Compilers.Get(EngineCodes.SqlServer); - compiler.UseLegacyPagination = true; + compiler = CreateCompiler(EngineCodes.SqlServer, useLegacyPagination: true); } [Fact] diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs index 44e67b89..f0c5e80b 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs @@ -6,12 +6,11 @@ namespace SqlKata.Tests.SqlServer { public class SqlServerLimitTests : TestSupport { - private readonly SqlServerCompiler compiler; + private readonly Compiler compiler; public SqlServerLimitTests() { - compiler = Compilers.Get(EngineCodes.SqlServer); - compiler.UseLegacyPagination = false; + compiler = CreateCompiler(EngineCodes.SqlServer, useLegacyPagination: false); } [Fact] diff --git a/QueryBuilder.Tests/SqlServer/SqlServerTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerTests.cs index 5ab15634..fdbe3708 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerTests.cs @@ -6,11 +6,11 @@ namespace SqlKata.Tests.SqlServer { public class SqlServerTests : TestSupport { - private readonly SqlServerCompiler compiler; + private readonly Compiler compiler; public SqlServerTests() { - compiler = Compilers.Get(EngineCodes.SqlServer); + compiler = CreateCompiler(EngineCodes.SqlServer); } @@ -18,7 +18,9 @@ public SqlServerTests() public void SqlServerTop() { var query = new Query("table").Limit(1); + var result = compiler.Compile(query); + Assert.Equal("SELECT TOP (@p0) * FROM [table]", result.Sql); } @@ -27,7 +29,9 @@ public void SqlServerTop() public void SqlServerSelectWithParameterPlaceHolder() { var query = new Query("table").Select("Column\\?"); + var result = compiler.Compile(query); + Assert.Equal("SELECT [Column\\?] FROM [table]", result.Sql); } @@ -35,31 +39,36 @@ public void SqlServerSelectWithParameterPlaceHolder() public void SqlServerTopWithDistinct() { var query = new Query("table").Limit(1).Distinct(); + var result = compiler.Compile(query); + Assert.Equal("SELECT DISTINCT TOP (@p0) * FROM [table]", result.Sql); } - [Theory()] + [Theory] [InlineData(-100)] [InlineData(0)] public void OffsetSqlServer_Should_Be_Ignored_If_Zero_Or_Negative(int offset) { - var q = new Query().From("users").Offset(offset); - var c = Compilers.CompileFor(EngineCodes.SqlServer, q); + var query = new Query().From("users").Offset(offset); - Assert.Equal("SELECT * FROM [users]", c.ToString()); + var result = compiler.Compile(query); + + Assert.Equal("SELECT * FROM [users]", result.ToString()); } [Fact] public void SqlServerSelectWithParameterPlaceHolderEscaped() { var query = new Query("table").Select("Column\\?"); + var result = compiler.Compile(query); + Assert.Equal("SELECT [Column?] FROM [table]", result.ToString()); } - [Theory()] + [Theory] [InlineData(1)] [InlineData(2)] [InlineData(3)] @@ -68,8 +77,10 @@ public void SqlServerSelectWithParameterPlaceHolderEscaped() [InlineData(1000000)] public void OffsetSqlServer_Should_Be_Incremented_By_One(int offset) { - var q = new Query().From("users").Offset(offset); - var c = Compilers.CompileFor(EngineCodes.SqlServer, q); + var query = new Query().From("users").Offset(offset); + + var c = compiler.Compile(query); + Assert.Equal( "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()); diff --git a/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs b/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs index 421bca27..850e6e1d 100644 --- a/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs +++ b/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs @@ -6,11 +6,11 @@ namespace SqlKata.Tests.Sqlite { public class SqliteLimitTests : TestSupport { - private readonly SqliteCompiler compiler; + private readonly Compiler compiler; public SqliteLimitTests() { - compiler = Compilers.Get(EngineCodes.Sqlite); + compiler = CreateCompiler(EngineCodes.Sqlite); } [Fact] diff --git a/QueryBuilder.Tests/UpdateTests.cs b/QueryBuilder.Tests/UpdateTests.cs index 82162bec..22789bdc 100644 --- a/QueryBuilder.Tests/UpdateTests.cs +++ b/QueryBuilder.Tests/UpdateTests.cs @@ -65,9 +65,9 @@ public void UpdateObject(string engine, string sqlText) Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -80,9 +80,9 @@ public void UpdateWithNullValues(string engine, string sqlText) new object[] { "Author 1", null, null } ); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -95,9 +95,9 @@ public void UpdateWithEmptyString(string engine, string sqlText) new object[] { "Author 1", "" } ); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -113,9 +113,9 @@ public void UpdateWithCte(string engine, string sqlText) {"Price", "150"} }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -126,9 +126,9 @@ public void UpdateWithIgnoreAndColumnProperties(string engine, string sqlText) var book = new Book(name: $"SqlKataBook", author: "Kata", color: $"red", price: 100m); var query = new Query("Book").AsUpdate(book); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -139,9 +139,9 @@ public void UpdateWithKeyAttribute(string engine, string sqlText) var order = new OrderProductComposite("ORD01", "PROD02", 20); var query = new Query("OrderProductComposite").AsUpdate(order); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -153,9 +153,9 @@ public void UpdateFromRaw(string engine, string sqlText) Name = "The User", }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -188,11 +188,11 @@ public void update_should_compile_literal_without_parameters_holders(string engi Address = new UnsafeLiteral("@address") }); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.RawSql); - Assert.Single(c.NamedBindings); - Assert.Equal("The User", c.NamedBindings.First().Value); + Assert.Equal(sqlText, result.RawSql); + Assert.Single(result.NamedBindings); + Assert.Equal("The User", result.NamedBindings.First().Value); } [Theory] @@ -209,9 +209,9 @@ public void UpdateUsingKeyValuePairs(string engine, string sqlText) var query = new Query("Table") .AsUpdate(dictionaryUser); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -225,9 +225,9 @@ public void UpdateUsingExpandoObject(string engine, string sqlText) var query = new Query("Table") .AsUpdate(expandoUser); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -236,9 +236,9 @@ public void IncrementUpdate(string engine, string sqlText) { var query = new Query("Table").AsIncrement("Total"); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -247,9 +247,9 @@ public void IncrementUpdateWithValue(string engine, string sqlText) { var query = new Query("Table").AsIncrement("Total", 2); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -258,9 +258,9 @@ public void IncrementUpdateWithWheres(string engine, string sqlText) { var query = new Query("Table").Where("Name", "A").AsIncrement("Total", 2); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -269,9 +269,9 @@ public void DecrementUpdate(string engine, string sqlText) { var query = new Query("Table").Where("Name", "A").AsDecrement("Total", 2); - var c = CompileFor(engine, query); + var result = CompileFor(engine, query); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } } } diff --git a/QueryBuilder.Tests/WhereTests.cs b/QueryBuilder.Tests/WhereTests.cs index 051ee993..89d201d3 100644 --- a/QueryBuilder.Tests/WhereTests.cs +++ b/QueryBuilder.Tests/WhereTests.cs @@ -15,9 +15,9 @@ public void GroupedWhereFilters(string engine, string sqlText) .Where(q => q.Or().Where("Column1", 10).Or().Where("Column2", 20)) .Where("Column3", 30); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -29,9 +29,9 @@ public void GroupedHavingFilters(string engine, string sqlText) .Having(q => q.Or().HavingRaw("SUM([Column1]) = ?", 10).Or().HavingRaw("SUM([Column2]) = ?", 20)) .HavingRaw("SUM([Column3]) = ?", 30); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } [Theory] @@ -46,9 +46,9 @@ public void UnsafeLiteralConditions(string engine, string sqlText) var q = new Query("Table1") .Where("Field1", new UnsafeLiteral("Field2")); - var c = CompileFor(engine, q); + var result = CompileFor(engine, q); - Assert.Equal(sqlText, c.ToString()); + Assert.Equal(sqlText, result.ToString()); } } } From 7d692004c521ea4a87ea2a01dbbe6068ba8db596 Mon Sep 17 00:00:00 2001 From: faddiv Date: Tue, 24 Dec 2024 20:50:03 +0100 Subject: [PATCH 23/27] Add Select benchmark. --- .../Infrastructure/TestCompiler.cs | 9 +++ .../Infrastructure/TestSupport.cs | 49 ++++++++++++++ QueryBuilder.Benchmarks/Program.cs | 8 +++ .../QueryBuilder.Benchmarks.csproj | 19 ++++++ QueryBuilder.Benchmarks/SelectsBenchmark.cs | 67 +++++++++++++++++++ .../TestCompilers/TestCompiler.cs | 2 +- sqlkata.sln | 14 ++++ 7 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 QueryBuilder.Benchmarks/Infrastructure/TestCompiler.cs create mode 100644 QueryBuilder.Benchmarks/Infrastructure/TestSupport.cs create mode 100644 QueryBuilder.Benchmarks/Program.cs create mode 100644 QueryBuilder.Benchmarks/QueryBuilder.Benchmarks.csproj create mode 100644 QueryBuilder.Benchmarks/SelectsBenchmark.cs diff --git a/QueryBuilder.Benchmarks/Infrastructure/TestCompiler.cs b/QueryBuilder.Benchmarks/Infrastructure/TestCompiler.cs new file mode 100644 index 00000000..171524ac --- /dev/null +++ b/QueryBuilder.Benchmarks/Infrastructure/TestCompiler.cs @@ -0,0 +1,9 @@ +using SqlKata.Compilers; + +namespace QueryBuilder.Benchmarks.Infrastructure; + +public class TestCompiler + : Compiler +{ + public override string EngineCode { get; } = "generic"; +} diff --git a/QueryBuilder.Benchmarks/Infrastructure/TestSupport.cs b/QueryBuilder.Benchmarks/Infrastructure/TestSupport.cs new file mode 100644 index 00000000..2e953a51 --- /dev/null +++ b/QueryBuilder.Benchmarks/Infrastructure/TestSupport.cs @@ -0,0 +1,49 @@ +using SqlKata; +using SqlKata.Compilers; + +namespace QueryBuilder.Benchmarks.Infrastructure; + +public class TestSupport +{ + + public static SqlResult CompileFor(string engine, Query query, Func configuration = null) + { + var compiler = CreateCompiler(engine); + if (configuration != null) + { + compiler = configuration(compiler); + } + + return compiler.Compile(query); + } + + public static SqlResult CompileFor(string engine, Query query, Action configuration) + { + return CompileFor(engine, query, compiler => + { + configuration(compiler); + return compiler; + }); + } + + public static Compiler CreateCompiler(string engine) + { + return engine switch + { + EngineCodes.Firebird => new FirebirdCompiler(), + EngineCodes.MySql => new MySqlCompiler(), + EngineCodes.Oracle => new OracleCompiler + { + UseLegacyPagination = false + }, + EngineCodes.PostgreSql => new PostgresCompiler(), + EngineCodes.Sqlite => new SqliteCompiler(), + EngineCodes.SqlServer => new SqlServerCompiler + { + UseLegacyPagination = false + }, + EngineCodes.Generic => new TestCompiler(), + _ => throw new ArgumentException($"Unsupported engine type: {engine}", nameof(engine)), + }; + } +} diff --git a/QueryBuilder.Benchmarks/Program.cs b/QueryBuilder.Benchmarks/Program.cs new file mode 100644 index 00000000..1a3c5a76 --- /dev/null +++ b/QueryBuilder.Benchmarks/Program.cs @@ -0,0 +1,8 @@ +// See https://aka.ms/new-console-template for more information + +using BenchmarkDotNet.Running; +using QueryBuilder.Benchmarks; + +SelectsBenchmark.Test(); + +BenchmarkRunner.Run(); diff --git a/QueryBuilder.Benchmarks/QueryBuilder.Benchmarks.csproj b/QueryBuilder.Benchmarks/QueryBuilder.Benchmarks.csproj new file mode 100644 index 00000000..2960e8f2 --- /dev/null +++ b/QueryBuilder.Benchmarks/QueryBuilder.Benchmarks.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + enable + false + + + + + + + + + + + diff --git a/QueryBuilder.Benchmarks/SelectsBenchmark.cs b/QueryBuilder.Benchmarks/SelectsBenchmark.cs new file mode 100644 index 00000000..a21e1d27 --- /dev/null +++ b/QueryBuilder.Benchmarks/SelectsBenchmark.cs @@ -0,0 +1,67 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.RegularExpressions; +using BenchmarkDotNet.Attributes; +using QueryBuilder.Benchmarks.Infrastructure; +using SqlKata; +using SqlKata.Compilers; + +namespace QueryBuilder.Benchmarks; + +[MemoryDiagnoser] +public class SelectsBenchmark +{ + private Query query; + + public Compiler compiler; + + [Params( + EngineCodes.Firebird, + EngineCodes.MySql, + EngineCodes.Oracle, + EngineCodes.PostgreSql, + EngineCodes.Sqlite, + EngineCodes.SqlServer)] + public string EngineCode { get; set; } + + [GlobalSetup] + public void Setup() + { + query = new Query("Products") + .Select("ProductID", "ProductName", "SupplierID", "CategoryID", "UnitPrice", "UnitsInStock", "UnitsOnOrder", + "ReorderLevel", "Discontinued") + .WhereContains("ProductName", "Mascarpone") + .Where("UnitPrice", ">=", 10) + .Where("UnitPrice", "<=", 100) + .Take(10) + .Skip(20) + .OrderBy("UnitPrice", "ProductName"); + compiler = TestSupport.CreateCompiler(EngineCode); + } + + [Benchmark] + public SqlResult Select() + { + return compiler.Compile(query); + } + + public static void Test() + { + var benchmark = new SelectsBenchmark(); + benchmark.EngineCode = EngineCodes.SqlServer; + benchmark.Setup(); + var result = benchmark.Select().ToString(); + if (result != + Regex.Replace(""" + SELECT [ProductID], [ProductName], [SupplierID], [CategoryID], [UnitPrice], [UnitsInStock], + [UnitsOnOrder], [ReorderLevel], [Discontinued] + FROM [Products] + WHERE LOWER([ProductName]) like '%mascarpone%' + AND [UnitPrice] >= 10 + AND [UnitPrice] <= 100 + ORDER BY [UnitPrice], [ProductName] OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY + """, @"\s+", " ")) + { + throw new ValidationException($"Invalid result: {result}"); + } + } +} diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs index 0c3afd7a..cf7a6b4d 100644 --- a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs @@ -9,7 +9,7 @@ namespace SqlKata.Tests.Infrastructure.TestCompilers /// class TestCompiler : Compiler { - public override string EngineCode { get; } = "test"; + public override string EngineCode { get; } = "generic"; public virtual MethodInfo Call_FindCompilerMethodInfo(Type clauseType, string methodName) { diff --git a/sqlkata.sln b/sqlkata.sln index 957e67a0..4b9382a1 100644 --- a/sqlkata.sln +++ b/sqlkata.sln @@ -16,6 +16,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .editorconfig = .editorconfig EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QueryBuilder.Benchmarks", "QueryBuilder.Benchmarks\QueryBuilder.Benchmarks.csproj", "{4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -74,6 +76,18 @@ Global {5DEA7DBC-5B8A-44A9-A070-55E95881A4CF}.Release|x64.Build.0 = Release|Any CPU {5DEA7DBC-5B8A-44A9-A070-55E95881A4CF}.Release|x86.ActiveCfg = Release|Any CPU {5DEA7DBC-5B8A-44A9-A070-55E95881A4CF}.Release|x86.Build.0 = Release|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Debug|x64.ActiveCfg = Debug|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Debug|x64.Build.0 = Debug|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Debug|x86.ActiveCfg = Debug|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Debug|x86.Build.0 = Debug|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Release|Any CPU.Build.0 = Release|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Release|x64.ActiveCfg = Release|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Release|x64.Build.0 = Release|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Release|x86.ActiveCfg = Release|Any CPU + {4C4BB0A9-0FD3-455D-B4C4-2BB43C5C7388}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From fdbe84da2800a36ad82affe48a2cd0b26e8beff0 Mon Sep 17 00:00:00 2001 From: faddiv Date: Wed, 25 Dec 2024 11:05:02 +0100 Subject: [PATCH 24/27] Add different benchmarks and tests --- QueryBuilder.Benchmarks/Program.cs | 2 +- QueryBuilder.Benchmarks/SelectsBenchmark.cs | 71 ++++++++------ .../SelectsBenchmarkTests.cs | 95 +++++++++++++++++++ 3 files changed, 139 insertions(+), 29 deletions(-) create mode 100644 QueryBuilder.Benchmarks/SelectsBenchmarkTests.cs diff --git a/QueryBuilder.Benchmarks/Program.cs b/QueryBuilder.Benchmarks/Program.cs index 1a3c5a76..68481a35 100644 --- a/QueryBuilder.Benchmarks/Program.cs +++ b/QueryBuilder.Benchmarks/Program.cs @@ -3,6 +3,6 @@ using BenchmarkDotNet.Running; using QueryBuilder.Benchmarks; -SelectsBenchmark.Test(); +SelectsBenchmarkTests.TestAll(); BenchmarkRunner.Run(); diff --git a/QueryBuilder.Benchmarks/SelectsBenchmark.cs b/QueryBuilder.Benchmarks/SelectsBenchmark.cs index a21e1d27..e81e7bef 100644 --- a/QueryBuilder.Benchmarks/SelectsBenchmark.cs +++ b/QueryBuilder.Benchmarks/SelectsBenchmark.cs @@ -10,58 +10,73 @@ namespace QueryBuilder.Benchmarks; [MemoryDiagnoser] public class SelectsBenchmark { - private Query query; + private Query selectSimple; + private Query selectGroupBy; + private Query selectWith; public Compiler compiler; [Params( - EngineCodes.Firebird, - EngineCodes.MySql, - EngineCodes.Oracle, - EngineCodes.PostgreSql, - EngineCodes.Sqlite, EngineCodes.SqlServer)] public string EngineCode { get; set; } [GlobalSetup] public void Setup() { - query = new Query("Products") + selectSimple = new Query("Products") .Select("ProductID", "ProductName", "SupplierID", "CategoryID", "UnitPrice", "UnitsInStock", "UnitsOnOrder", "ReorderLevel", "Discontinued") - .WhereContains("ProductName", "Mascarpone") + .WhereIn("CategoryID", [1, 2, 3]) + .Where("SupplierID", 5) .Where("UnitPrice", ">=", 10) .Where("UnitPrice", "<=", 100) .Take(10) .Skip(20) .OrderBy("UnitPrice", "ProductName"); + + + selectGroupBy = new Query("Products") + .Select("SupplierID", "CategoryID") + .SelectAvg("UnitPrice") + .SelectMin("UnitPrice") + .SelectMax("UnitPrice") + .Where("CategoryID", 123) + .GroupBy("SupplierID", "CategoryID") + .HavingRaw("MIN(UnitPrice) >= ?", 10) + .Take(10) + .Skip(20) + .OrderBy("SupplierID", "CategoryID"); + + var activePosts = new Query("Comments") + .Select("PostId") + .SelectRaw("count(1) as Count") + .GroupBy("PostId") + .HavingRaw("count(1) > 100"); + + selectWith = new Query("Posts") + .With("ActivePosts", activePosts) + .Join("ActivePosts", "ActivePosts.PostId", "Posts.Id") + .Select("Posts.*", "ActivePosts.Count"); + compiler = TestSupport.CreateCompiler(EngineCode); } [Benchmark] - public SqlResult Select() + public SqlResult SelectSimple() { - return compiler.Compile(query); + return compiler.Compile(selectSimple); } - public static void Test() + [Benchmark] + public SqlResult SelectGroupBy() + { + return compiler.Compile(selectGroupBy); + } + + [Benchmark] + public SqlResult SelectWith() { - var benchmark = new SelectsBenchmark(); - benchmark.EngineCode = EngineCodes.SqlServer; - benchmark.Setup(); - var result = benchmark.Select().ToString(); - if (result != - Regex.Replace(""" - SELECT [ProductID], [ProductName], [SupplierID], [CategoryID], [UnitPrice], [UnitsInStock], - [UnitsOnOrder], [ReorderLevel], [Discontinued] - FROM [Products] - WHERE LOWER([ProductName]) like '%mascarpone%' - AND [UnitPrice] >= 10 - AND [UnitPrice] <= 100 - ORDER BY [UnitPrice], [ProductName] OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY - """, @"\s+", " ")) - { - throw new ValidationException($"Invalid result: {result}"); - } + return compiler.Compile(selectWith); } + } diff --git a/QueryBuilder.Benchmarks/SelectsBenchmarkTests.cs b/QueryBuilder.Benchmarks/SelectsBenchmarkTests.cs new file mode 100644 index 00000000..36aafac0 --- /dev/null +++ b/QueryBuilder.Benchmarks/SelectsBenchmarkTests.cs @@ -0,0 +1,95 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.RegularExpressions; +using SqlKata; +using SqlKata.Compilers; + +namespace QueryBuilder.Benchmarks; + +public static partial class SelectsBenchmarkTests +{ + public static void TestAll() + { + TestSelectSimple(); + TestSelectGroupBy(); + TestSelectWith(); + } + + public static void TestSelectSimple() + { + var benchmark = CreateBenchmark(); + + var result = benchmark.SelectSimple(); + + // language=SQL + ValidateResult( + """ + SELECT [ProductID], [ProductName], [SupplierID], [CategoryID], [UnitPrice], + [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued] + FROM [Products] + WHERE [CategoryID] IN (1, 2, 3) + AND [SupplierID] = 5 + AND [UnitPrice] >= 10 + AND [UnitPrice] <= 100 + ORDER BY [UnitPrice], [ProductName] + OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY + """, result); + } + + public static void TestSelectGroupBy() + { + var benchmark = CreateBenchmark(); + + var result = benchmark.SelectGroupBy(); + + // language=SQL + ValidateResult( + """ + SELECT [SupplierID], [CategoryID], + AVG([UnitPrice]), MIN([UnitPrice]), MAX([UnitPrice]) + FROM [Products] + WHERE [CategoryID] = 123 + GROUP BY [SupplierID], [CategoryID] + HAVING MIN(UnitPrice) >= 10 + ORDER BY [SupplierID], [CategoryID] + OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY + """, result); + } + + public static void TestSelectWith() + { + var benchmark = CreateBenchmark(); + + var result = benchmark.SelectWith(); + + // language=SQL + ValidateResult( + """ + WITH [ActivePosts] AS (SELECT [PostId], count(1) as Count FROM [Comments] GROUP BY [PostId] HAVING count(1) > 100) + SELECT [Posts].*, [ActivePosts].[Count] + FROM [Posts] + INNER JOIN [ActivePosts] ON [ActivePosts].[PostId] = [Posts].[Id] + """, result); + } + + private static SelectsBenchmark CreateBenchmark() + { + var benchmark = new SelectsBenchmark + { + EngineCode = EngineCodes.SqlServer + }; + benchmark.Setup(); + return benchmark; + } + + private static void ValidateResult(string expected, SqlResult result) + { + var actual = result.ToString(); + if (WhiteSpaces().Replace(actual, " ") != WhiteSpaces().Replace(expected, " ")) + { + throw new ValidationException($"Invalid result: {actual}"); + } + } + + [GeneratedRegex(@"\s+")] + private static partial Regex WhiteSpaces(); +} From 441a619224b0af90c8e2a12c2a31c1f37fa6a0c6 Mon Sep 17 00:00:00 2001 From: faddiv Date: Wed, 25 Dec 2024 11:31:35 +0100 Subject: [PATCH 25/27] Global usings --- QueryBuilder.Tests/AggregateTests.cs | 2 -- QueryBuilder.Tests/BindingsTests.cs | 5 +---- QueryBuilder.Tests/DefineTest.cs | 4 +--- QueryBuilder.Tests/DeleteTests.cs | 2 -- QueryBuilder.Tests/ExecutionTests.cs | 2 -- QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs | 2 -- QueryBuilder.Tests/GeneralTests.cs | 4 ---- QueryBuilder.Tests/GlobalUsings.cs | 2 ++ QueryBuilder.Tests/HelperTests.cs | 2 -- QueryBuilder.Tests/Infrastructure/QueryFactoryExtension.cs | 1 - .../Infrastructure/TestCompilers/TestCompiler.cs | 2 -- .../Infrastructure/TestCompilers/TestFirebirdCompiler.cs | 4 +--- .../Infrastructure/TestCompilers/TestMySqlCompiler.cs | 4 +--- .../Infrastructure/TestCompilers/TestPostgresCompiler.cs | 4 +--- .../Infrastructure/TestCompilers/TestSqlServerCompiler.cs | 4 +--- QueryBuilder.Tests/Infrastructure/TestSupport.cs | 4 ---- QueryBuilder.Tests/InsertTests.cs | 5 ----- QueryBuilder.Tests/MySql/MySqlExecutionTest.cs | 5 ----- QueryBuilder.Tests/MySql/MySqlLimitTests.cs | 2 -- QueryBuilder.Tests/OperatorWhitelistTests.cs | 3 --- QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs | 2 -- QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs | 2 -- QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs | 2 -- QueryBuilder.Tests/Oracle/OracleLimitTests.cs | 2 -- QueryBuilder.Tests/ParameterTypeTests.cs | 4 ---- QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs | 2 -- QueryBuilder.Tests/QueryBuilder.Tests.csproj | 5 +++-- QueryBuilder.Tests/SelectTests.cs | 4 ---- QueryBuilder.Tests/SqlServer/NestedSelectTests.cs | 2 -- QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs | 2 -- QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs | 2 -- QueryBuilder.Tests/SqlServer/SqlServerTests.cs | 2 -- QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs | 4 ---- QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs | 2 -- QueryBuilder.Tests/UpdateTests.cs | 5 ----- QueryBuilder.Tests/WhereTests.cs | 2 -- 36 files changed, 11 insertions(+), 96 deletions(-) create mode 100644 QueryBuilder.Tests/GlobalUsings.cs diff --git a/QueryBuilder.Tests/AggregateTests.cs b/QueryBuilder.Tests/AggregateTests.cs index 7c0efbc8..d299b96f 100644 --- a/QueryBuilder.Tests/AggregateTests.cs +++ b/QueryBuilder.Tests/AggregateTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/BindingsTests.cs b/QueryBuilder.Tests/BindingsTests.cs index dba6f38a..7a684920 100644 --- a/QueryBuilder.Tests/BindingsTests.cs +++ b/QueryBuilder.Tests/BindingsTests.cs @@ -1,8 +1,5 @@ -using System.Linq; -using System.Text.RegularExpressions; -using SqlKata.Compilers; +using System.Text.RegularExpressions; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests; diff --git a/QueryBuilder.Tests/DefineTest.cs b/QueryBuilder.Tests/DefineTest.cs index ee516220..2dcead75 100644 --- a/QueryBuilder.Tests/DefineTest.cs +++ b/QueryBuilder.Tests/DefineTest.cs @@ -1,7 +1,5 @@ -using static SqlKata.Expressions; -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; +using static SqlKata.Expressions; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/DeleteTests.cs b/QueryBuilder.Tests/DeleteTests.cs index 798da42a..9df932e8 100644 --- a/QueryBuilder.Tests/DeleteTests.cs +++ b/QueryBuilder.Tests/DeleteTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/ExecutionTests.cs b/QueryBuilder.Tests/ExecutionTests.cs index a726a1c9..23a84bd5 100644 --- a/QueryBuilder.Tests/ExecutionTests.cs +++ b/QueryBuilder.Tests/ExecutionTests.cs @@ -1,6 +1,4 @@ -using System; using SqlKata.Execution; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs index ca906073..760434ed 100644 --- a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs +++ b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.Firebird { diff --git a/QueryBuilder.Tests/GeneralTests.cs b/QueryBuilder.Tests/GeneralTests.cs index d7750703..8f0c7c56 100644 --- a/QueryBuilder.Tests/GeneralTests.cs +++ b/QueryBuilder.Tests/GeneralTests.cs @@ -1,10 +1,6 @@ -using SqlKata.Compilers; using SqlKata.Extensions; using SqlKata.Tests.Infrastructure; -using System; -using System.Linq; using SqlKata.Tests.Infrastructure.TestCompilers; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/GlobalUsings.cs b/QueryBuilder.Tests/GlobalUsings.cs new file mode 100644 index 00000000..63d30c4a --- /dev/null +++ b/QueryBuilder.Tests/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using SqlKata.Compilers; +global using Xunit; diff --git a/QueryBuilder.Tests/HelperTests.cs b/QueryBuilder.Tests/HelperTests.cs index ab80e2c5..f7ce375c 100644 --- a/QueryBuilder.Tests/HelperTests.cs +++ b/QueryBuilder.Tests/HelperTests.cs @@ -1,6 +1,4 @@ using System.Collections; -using System.Linq; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/Infrastructure/QueryFactoryExtension.cs b/QueryBuilder.Tests/Infrastructure/QueryFactoryExtension.cs index 0b993217..35b206ab 100644 --- a/QueryBuilder.Tests/Infrastructure/QueryFactoryExtension.cs +++ b/QueryBuilder.Tests/Infrastructure/QueryFactoryExtension.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using SqlKata.Execution; namespace SqlKata.Tests.Infrastructure; diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs index cf7a6b4d..83033a08 100644 --- a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestCompiler.cs @@ -1,6 +1,4 @@ -using System; using System.Reflection; -using SqlKata.Compilers; namespace SqlKata.Tests.Infrastructure.TestCompilers { diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestFirebirdCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestFirebirdCompiler.cs index b246a1a4..4be3e0ae 100644 --- a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestFirebirdCompiler.cs +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestFirebirdCompiler.cs @@ -1,6 +1,4 @@ -using System; -using System.Reflection; -using SqlKata.Compilers; +using System.Reflection; namespace SqlKata.Tests.Infrastructure.TestCompilers; diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestMySqlCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestMySqlCompiler.cs index 08898dca..6b51eabc 100644 --- a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestMySqlCompiler.cs +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestMySqlCompiler.cs @@ -1,6 +1,4 @@ -using System; -using System.Reflection; -using SqlKata.Compilers; +using System.Reflection; namespace SqlKata.Tests.Infrastructure.TestCompilers; diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestPostgresCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestPostgresCompiler.cs index 38644095..555c2ba7 100644 --- a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestPostgresCompiler.cs +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestPostgresCompiler.cs @@ -1,6 +1,4 @@ -using System; -using System.Reflection; -using SqlKata.Compilers; +using System.Reflection; namespace SqlKata.Tests.Infrastructure.TestCompilers; diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestSqlServerCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestSqlServerCompiler.cs index 706fee6e..554c4642 100644 --- a/QueryBuilder.Tests/Infrastructure/TestCompilers/TestSqlServerCompiler.cs +++ b/QueryBuilder.Tests/Infrastructure/TestCompilers/TestSqlServerCompiler.cs @@ -1,6 +1,4 @@ -using System; -using System.Reflection; -using SqlKata.Compilers; +using System.Reflection; namespace SqlKata.Tests.Infrastructure.TestCompilers; diff --git a/QueryBuilder.Tests/Infrastructure/TestSupport.cs b/QueryBuilder.Tests/Infrastructure/TestSupport.cs index 1ae0f420..d351da73 100644 --- a/QueryBuilder.Tests/Infrastructure/TestSupport.cs +++ b/QueryBuilder.Tests/Infrastructure/TestSupport.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure.TestCompilers; namespace SqlKata.Tests.Infrastructure diff --git a/QueryBuilder.Tests/InsertTests.cs b/QueryBuilder.Tests/InsertTests.cs index ee27337a..ae0428b7 100644 --- a/QueryBuilder.Tests/InsertTests.cs +++ b/QueryBuilder.Tests/InsertTests.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; using System.Collections.ObjectModel; using System.Dynamic; -using System.Linq; -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs b/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs index 93a84360..e614e4f7 100644 --- a/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs +++ b/QueryBuilder.Tests/MySql/MySqlExecutionTest.cs @@ -1,12 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; using Microsoft.Extensions.Configuration; using MySql.Data.MySqlClient; -using SqlKata.Compilers; using SqlKata.Execution; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.MySql { diff --git a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs index 9fa3484f..6925355c 100644 --- a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs +++ b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.MySql { diff --git a/QueryBuilder.Tests/OperatorWhitelistTests.cs b/QueryBuilder.Tests/OperatorWhitelistTests.cs index 79116f42..7c8e6867 100644 --- a/QueryBuilder.Tests/OperatorWhitelistTests.cs +++ b/QueryBuilder.Tests/OperatorWhitelistTests.cs @@ -1,8 +1,5 @@ -using System; -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; using SqlKata.Tests.Infrastructure.TestCompilers; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs b/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs index 4afa28c9..c91d72fa 100644 --- a/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.Oracle { diff --git a/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs b/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs index fd6fd890..2c366503 100644 --- a/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.Oracle { diff --git a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs index 1af5b182..d19af76e 100644 --- a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.Oracle { diff --git a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs index 34186530..21e38e3b 100644 --- a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.Oracle { diff --git a/QueryBuilder.Tests/ParameterTypeTests.cs b/QueryBuilder.Tests/ParameterTypeTests.cs index fe197004..39263e1e 100644 --- a/QueryBuilder.Tests/ParameterTypeTests.cs +++ b/QueryBuilder.Tests/ParameterTypeTests.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using SqlKata.Compilers; -using Xunit; using System.Collections; using SqlKata.Tests.Infrastructure; diff --git a/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs b/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs index 095a128b..34e8076e 100644 --- a/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs +++ b/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.PostgreSql { diff --git a/QueryBuilder.Tests/QueryBuilder.Tests.csproj b/QueryBuilder.Tests/QueryBuilder.Tests.csproj index 90203dfd..3616518a 100755 --- a/QueryBuilder.Tests/QueryBuilder.Tests.csproj +++ b/QueryBuilder.Tests/QueryBuilder.Tests.csproj @@ -2,6 +2,7 @@ Library false + true SqlKata.Tests net8.0 c675ce13-c233-4a60-9fcc-dadf8f5238ca @@ -11,7 +12,7 @@ - + @@ -19,4 +20,4 @@ - \ No newline at end of file + diff --git a/QueryBuilder.Tests/SelectTests.cs b/QueryBuilder.Tests/SelectTests.cs index 35bf3b1a..5c896233 100644 --- a/QueryBuilder.Tests/SelectTests.cs +++ b/QueryBuilder.Tests/SelectTests.cs @@ -1,9 +1,5 @@ -using SqlKata.Compilers; using SqlKata.Extensions; using SqlKata.Tests.Infrastructure; -using System; -using System.Collections.Generic; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/SqlServer/NestedSelectTests.cs b/QueryBuilder.Tests/SqlServer/NestedSelectTests.cs index 79a04b30..0bad0a20 100644 --- a/QueryBuilder.Tests/SqlServer/NestedSelectTests.cs +++ b/QueryBuilder.Tests/SqlServer/NestedSelectTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.SqlServer { diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs index 3b1650b2..62a1acae 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.SqlServer { diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs index f0c5e80b..6eee774a 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.SqlServer { diff --git a/QueryBuilder.Tests/SqlServer/SqlServerTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerTests.cs index fdbe3708..db1736de 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.SqlServer { diff --git a/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs b/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs index d70812c8..3fdd6b37 100644 --- a/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs +++ b/QueryBuilder.Tests/Sqlite/SQLiteExecutionTest.cs @@ -1,10 +1,6 @@ -using System.Collections.Generic; -using System.Linq; using Microsoft.Data.Sqlite; -using SqlKata.Compilers; using SqlKata.Execution; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.Sqlite { diff --git a/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs b/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs index 850e6e1d..cf0fb1f2 100644 --- a/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs +++ b/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests.Sqlite { diff --git a/QueryBuilder.Tests/UpdateTests.cs b/QueryBuilder.Tests/UpdateTests.cs index 22789bdc..5e189682 100644 --- a/QueryBuilder.Tests/UpdateTests.cs +++ b/QueryBuilder.Tests/UpdateTests.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; using System.Dynamic; -using System.Linq; -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests { diff --git a/QueryBuilder.Tests/WhereTests.cs b/QueryBuilder.Tests/WhereTests.cs index 89d201d3..613be6d7 100644 --- a/QueryBuilder.Tests/WhereTests.cs +++ b/QueryBuilder.Tests/WhereTests.cs @@ -1,6 +1,4 @@ -using SqlKata.Compilers; using SqlKata.Tests.Infrastructure; -using Xunit; namespace SqlKata.Tests { From 817c514ab521ac0f45c151c4345df9ba28ba8087 Mon Sep 17 00:00:00 2001 From: faddiv Date: Wed, 25 Dec 2024 12:14:01 +0100 Subject: [PATCH 26/27] Remove direct Limit test from Firebird --- .../Firebird/FirebirdLimitTests.cs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs index 760434ed..e0593efa 100644 --- a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs +++ b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs @@ -15,39 +15,43 @@ public FirebirdLimitTests() public void NoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + var result = compiler.Compile(query); + + Assert.Equal("SELECT * FROM \"TABLE\"", result.ToString()); } [Fact] public void LimitOnly() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + var result = compiler.Compile(query); + + Assert.Equal("SELECT FIRST 10 * FROM \"TABLE\"", result.ToString()); } [Fact] public void OffsetOnly() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + var result = compiler.Compile(query); + + Assert.Equal("SELECT SKIP 20 * FROM \"TABLE\"", result.ToString()); } [Fact] public void LimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Equal("ROWS ? TO ?", compiler.CompileLimit(ctx)); - Assert.Equal(21L, ctx.Bindings[0]); - Assert.Equal(25L, ctx.Bindings[1]); - Assert.Equal(2, ctx.Bindings.Count); + var result = compiler.Compile(query); + + Assert.Equal("SELECT * FROM \"TABLE\" ROWS ? TO ?", result.RawSql); + Assert.Equal(2, result.Bindings.Count); + Assert.Equal(21L, result.Bindings[0]); + Assert.Equal(25L, result.Bindings[1]); } } } From 39c971957921db943ad2d96a73602e2375350058 Mon Sep 17 00:00:00 2001 From: faddiv Date: Wed, 25 Dec 2024 13:38:42 +0100 Subject: [PATCH 27/27] Remove direct Limit test from Oracle and SqlServer --- QueryBuilder.Tests/Oracle/OracleLimitTests.cs | 12 ++++------ .../SqlServer/SqlServerLimitTests.cs | 24 ++++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs index 21e38e3b..8354f39f 100644 --- a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs @@ -65,15 +65,13 @@ public void LimitAndOffset() var query = new Query(TableName).Limit(5).Offset(20); // Act - var ctx = compiler.Compile(query); + var result = compiler.Compile(query); // Assert: - Assert.Equal("SELECT * FROM \"Table\" ORDER BY (SELECT 0 FROM DUAL) OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", ctx.RawSql); - Assert.Equal(2, ctx.Bindings.Count); - Assert.Equal(20L, ctx.Bindings[0]); - Assert.Equal(5, ctx.Bindings[1]); - - compiler.CompileLimit(ctx); + Assert.Equal("SELECT * FROM \"Table\" ORDER BY (SELECT 0 FROM DUAL) OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", result.RawSql); + Assert.Equal(2, result.Bindings.Count); + Assert.Equal(20L, result.Bindings[0]); + Assert.Equal(5, result.Bindings[1]); } } } diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs index 6eee774a..ac80b10d 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs @@ -15,33 +15,35 @@ public SqlServerLimitTests() public void NoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.Null(compiler.CompileLimit(ctx)); + var result = compiler.Compile(query); + + Assert.Equal("SELECT * FROM [Table]", result.ToString()); } [Fact] public void LimitOnly() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.EndsWith("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", compiler.CompileLimit(ctx)); - Assert.Equal(2, ctx.Bindings.Count); - Assert.Equal(0L, ctx.Bindings[0]); - Assert.Equal(10, ctx.Bindings[1]); + var result = compiler.Compile(query); + + Assert.Equal("SELECT * FROM [Table] ORDER BY (SELECT 0) OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", result.RawSql); + Assert.Equal(2, result.Bindings.Count); + Assert.Equal(0L, result.Bindings[0]); + Assert.Equal(10, result.Bindings[1]); } [Fact] public void OffsetOnly() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult("?", "\\") {Query = query}; - Assert.EndsWith("OFFSET ? ROWS", compiler.CompileLimit(ctx)); + var result = compiler.Compile(query); - Assert.Single(ctx.Bindings); - Assert.Equal(20L, ctx.Bindings[0]); + Assert.Equal("SELECT * FROM [Table] ORDER BY (SELECT 0) OFFSET ? ROWS", result.RawSql); + Assert.Single(result.Bindings); + Assert.Equal(20L, result.Bindings[0]); } [Fact]