Skip to content
64 changes: 10 additions & 54 deletions QueryBuilder.Tests/DefineTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,77 +47,42 @@ public void Test_Define_SubQuery()
[Fact]
public void Test_Define_WhereEnds()
{

var query1 = new Query("Products")
.Select("ProductId")
.Define("@product", "Coffee")
.WhereEnds("ProductName", Variable("@product"));


var query2 = 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]);

Assert.Equal("SELECT [ProductId], [ProductName] FROM [Products] WHERE [ProductName] like '%Coffee'", c2[EngineCodes.SqlServer]);

Assert.Equal("SELECT [ProductId] FROM [Products] WHERE [ProductName] like '%Coffee'", c1[EngineCodes.SqlServer]);
}



[Fact]
public void Test_Define_WhereStarts()
{


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("SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE [QuantityPerUnit] like '12%'", c1[EngineCodes.SqlServer]);
}


[Fact]
public void Test_Define_WhereContains()
{

var query1 = new Query("Products")
.Define("@perUnit", "500")
.Select("ProductId", "QuantityPerUnit")
.WhereContains("QuantityPerUnit", Variable("@perUnit"));


var query2 = new Query("Products")
.Define("@perUnit", "500")
.Select("ProductId", "QuantityPerUnit")
.WhereContains("QuantityPerUnit", Variable("@perUnit"), true);

var c1 = Compile(query1);
var c2 = Compile(query2);

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]);

Assert.Equal("SELECT [ProductId], [QuantityPerUnit] FROM [Products] WHERE [QuantityPerUnit] like '%500%'", c1[EngineCodes.SqlServer]);
}


[Fact]
public void Test_Define_WhereLike()
{
Expand All @@ -126,18 +91,9 @@ public void Test_Define_WhereLike()
.Define("@id", "20")
.WhereLike("SupplierID", Variable("@id"));


var query2 = new Query("Products")
.Select("ProductId", "ProductName", "SupplierID")
.Define("@id", "20")
.WhereLike("SupplierID", Variable("@id"), true);

var c1 = Compile(query1);
var c2 = Compile(query2);

Assert.Equal("SELECT [ProductId], [ProductName], [SupplierID] FROM [Products] WHERE LOWER([SupplierID]) like '20'", c1[EngineCodes.SqlServer]);

Assert.Equal("SELECT [ProductId], [ProductName], [SupplierID] FROM [Products] WHERE [SupplierID] like '20'", c2[EngineCodes.SqlServer]);
Assert.Equal("SELECT [ProductId], [ProductName], [SupplierID] FROM [Products] WHERE [SupplierID] like '20'", c1[EngineCodes.SqlServer]);
}


Expand Down Expand Up @@ -202,7 +158,7 @@ public void Test_Define_HavingStarts()

var c = Compile(query);

Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like 'u%'", c[EngineCodes.SqlServer]);
Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING [Country] like 'U%'", c[EngineCodes.SqlServer]);

}

Expand All @@ -220,7 +176,7 @@ public void Test_Define_Having_Ends()

var c = Compile(query);

Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d'", c[EngineCodes.SqlServer]);
Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING [Country] like '%d'", c[EngineCodes.SqlServer]);
}


Expand All @@ -238,7 +194,7 @@ public void Test_Define_Having_Contains()

var c = Compile(query);

Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d%'", c[EngineCodes.SqlServer]);
Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING [Country] like '%d%'", c[EngineCodes.SqlServer]);

}

Expand Down Expand Up @@ -367,7 +323,7 @@ public void Test_Define_Union()
.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]);
Assert.Equal("SELECT [City] FROM [Customers] WHERE NOT ([City] like 'Z') UNION SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'", c[EngineCodes.SqlServer]);
}


Expand All @@ -386,7 +342,7 @@ public void Test_Define_Except()
.WhereNotLike("City", Variable("@city"));

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("SELECT [City] FROM [Customers] WHERE NOT ([City] like 'Z') EXCEPT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'", c[EngineCodes.SqlServer]);
}

[Fact]
Expand All @@ -404,7 +360,7 @@ public void Test_Define_Intersect()
.WhereNotLike("City", Variable("@city"));

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("SELECT [City] FROM [Customers] WHERE NOT ([City] like 'Z') INTERSECT SELECT [City] FROM [Suppliers] WHERE [City] = 'Beirut'", c[EngineCodes.SqlServer]);
}

/*
Expand Down
23 changes: 18 additions & 5 deletions QueryBuilder.Tests/DeleteTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ public void DeleteWithJoin()
.Where("Authors.Id", 5)
.AsDelete();

var c = Compile(q);
Assert.Equal("DELETE [Posts] FROM [Posts] \nINNER JOIN [Authors] ON [Authors].[Id] = [Posts].[AuthorId] WHERE [Authors].[Id] = 5", Compilers.CompileFor(EngineCodes.SqlServer, q).ToString());
Assert.Equal("DELETE `Posts` FROM `Posts` \nINNER JOIN `Authors` ON `Authors`.`Id` = `Posts`.`AuthorId` WHERE `Authors`.`Id` = 5", Compilers.CompileFor(EngineCodes.MySql, q).ToString());

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.Throws<NotSupportedException>(() => Compilers.CompileFor(EngineCodes.PostgreSql, q));
Assert.Throws<NotSupportedException>(() => Compilers.CompileFor(EngineCodes.Sqlite, q));
Assert.Throws<NotSupportedException>(() => Compilers.CompileFor(EngineCodes.Oracle, q));
Assert.Throws<NotSupportedException>(() => Compilers.CompileFor(EngineCodes.Firebird, q));
}

[Fact]
Expand All @@ -41,9 +44,19 @@ public void DeleteWithJoinAndAlias()
.Where("Authors.Id", 5)
.AsDelete();

var c = Compile(q);
Assert.Equal("DELETE [P] FROM [Posts] AS [P] \nINNER JOIN [Authors] ON [Authors].[Id] = [P].[AuthorId] WHERE [Authors].[Id] = 5", Compilers.CompileFor(EngineCodes.SqlServer, q).ToString());
Assert.Equal("DELETE `P` FROM `Posts` AS `P` \nINNER JOIN `Authors` ON `Authors`.`Id` = `P`.`AuthorId` WHERE `Authors`.`Id` = 5", Compilers.CompileFor(EngineCodes.MySql, q).ToString());
}

[Fact]
public void DeleteWithJoinAndSchema()
{
var q = new Query("Audit.Posts")
.Join("Authors", "Authors.Id", "Posts.AuthorId")
.AsDelete();

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("DELETE [Posts] FROM [Audit].[Posts] \nINNER JOIN [Authors] ON [Authors].[Id] = [Posts].[AuthorId]", Compilers.CompileFor(EngineCodes.SqlServer, q).ToString());
Assert.Equal("DELETE `Posts` FROM `Audit`.`Posts` \nINNER JOIN `Authors` ON `Authors`.`Id` = `Posts`.`AuthorId`", Compilers.CompileFor(EngineCodes.MySql, q).ToString());
}
}
}
8 changes: 4 additions & 4 deletions QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public FirebirdLimitTests()
public void NoLimitNorOffset()
{
var query = new Query("Table");
var ctx = new SqlResult("?", "\\") {Query = query};
var ctx = new CompileContext(query);

Assert.Null(compiler.CompileLimit(ctx));
}
Expand All @@ -26,7 +26,7 @@ public void NoLimitNorOffset()
public void LimitOnly()
{
var query = new Query("Table").Limit(10);
var ctx = new SqlResult("?", "\\") {Query = query};
var ctx = new CompileContext(query);

Assert.Null(compiler.CompileLimit(ctx));
}
Expand All @@ -35,7 +35,7 @@ public void LimitOnly()
public void OffsetOnly()
{
var query = new Query("Table").Offset(20);
var ctx = new SqlResult("?", "\\") {Query = query};
var ctx = new CompileContext(query);

Assert.Null(compiler.CompileLimit(ctx));
}
Expand All @@ -44,7 +44,7 @@ public void OffsetOnly()
public void LimitAndOffset()
{
var query = new Query("Table").Limit(5).Offset(20);
var ctx = new SqlResult("?", "\\") {Query = query};
var ctx = new CompileContext(query);

Assert.Equal("ROWS ? TO ?", compiler.CompileLimit(ctx));
Assert.Equal(21L, ctx.Bindings[0]);
Expand Down
95 changes: 93 additions & 2 deletions QueryBuilder.Tests/GeneralTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.Linq;
using SqlKata.Compilers;
using SqlKata.Extensions;
using SqlKata.Tests.Infrastructure;
using System;
using System.Linq;
using Xunit;

namespace SqlKata.Tests
Expand Down Expand Up @@ -754,5 +754,96 @@ public void Compile_WhereExists_DoesNotMutateSubquery()

Assert.Equal(2, inner.SelectClauses.Count);
}

[Fact]
public void SqlServer_SelectPrefix_TopWithColumnBindings_PreservesParameterOrder()
{
var query = new Query("users").SelectRaw("? AS [bonus]", 100).Limit(5);
var compiler = new SqlServerCompiler { UseLegacyPagination = true };

var result = compiler.Compile(query);

Assert.Equal("SELECT TOP (@p0) @p1 AS [bonus] FROM [users]", result.Sql);
Assert.Equal(5, result.NamedBindings["@p0"]);
Assert.Equal(100, result.NamedBindings["@p1"]);
}

[Fact]
public void Firebird_SelectPrefix_FirstWithDistinct()
{
var query = new Query("users").Select("name").Distinct().Limit(10);
var compiler = new FirebirdCompiler();

var result = compiler.Compile(query);

Assert.Equal("SELECT FIRST 10 DISTINCT \"NAME\" FROM \"USERS\"", result.ToString());
}

[Fact]
public void OrderByRandom_Compiles_EmitsRandomExpression()
{
var query = new Query("Users").OrderByRandom();

var sqlServer = Compilers.CompileFor(EngineCodes.SqlServer, query).ToString();
Assert.Equal("SELECT * FROM [Users] ORDER BY NEWID()", sqlServer);

var postgres = Compilers.CompileFor(EngineCodes.PostgreSql, query).ToString();
Assert.Equal("SELECT * FROM \"Users\" ORDER BY RANDOM()", postgres);

var sqlite = Compilers.CompileFor(EngineCodes.Sqlite, query).ToString();
Assert.Equal("SELECT * FROM \"Users\" ORDER BY RANDOM()", sqlite);

var mysql = Compilers.CompileFor(EngineCodes.MySql, query).ToString();
Assert.Equal("SELECT * FROM `Users` ORDER BY RAND()", mysql);

var firebird = Compilers.CompileFor(EngineCodes.Firebird, query).ToString();
Assert.Equal("SELECT * FROM \"USERS\" ORDER BY RAND()", firebird);

var oracle = Compilers.CompileFor(EngineCodes.Oracle, query).ToString();
Assert.Equal("SELECT * FROM \"Users\" ORDER BY DBMS_RANDOM.VALUE", oracle);
}

private class SeedCompiler : Compiler
{
public override string EngineCode => "seed_engine";
public override string CompileRandom(int? seed) => $"RANDOM_WITH_SEED({seed})";
}

[Fact]
public void OrderByRandom_RetainsAndForwardsSeed_AndClonesCorrectly()
{
var query = new Query("Users").OrderByRandom(1234);
var cloned = query.Clone();

var clause = Assert.IsType<OrderByRandom>(Assert.Single(cloned.OrderByClauses));
Assert.Equal(1234, clause.Seed);

var compiler = new SeedCompiler();
var result = compiler.Compile(query).ToString();
Assert.Equal("SELECT * FROM \"Users\" ORDER BY RANDOM_WITH_SEED(1234)", result);
}

[Fact]
public void OrderByRandom_RetainsAndForwardsSeed_InMySQL()
{
var query = new Query("Users").OrderByRandom(1234);
var cloned = query.Clone();

var clause = Assert.IsType<OrderByRandom>(Assert.Single(cloned.OrderByClauses));
Assert.Equal(1234, clause.Seed);

var compiler = new MySqlCompiler();
var result = compiler.Compile(query).ToString();
Assert.Equal("SELECT * FROM `Users` ORDER BY RAND(1234)", result);
}

[Fact]
public void OrderByRandom_CombinedWithOtherOrderAndLimit_DoesNotProduceDanglingOrderBy()
{
var query = new Query("Users").OrderBy("Id").OrderByRandom().Limit(10);

var postgres = Compilers.CompileFor(EngineCodes.PostgreSql, query).ToString();
Assert.Equal("SELECT * FROM \"Users\" ORDER BY \"Id\", RANDOM() LIMIT 10", postgres);
}
}
}
8 changes: 4 additions & 4 deletions QueryBuilder.Tests/MySql/MySqlLimitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public MySqlLimitTests()
public void WithNoLimitNorOffset()
{
var query = new Query("Table");
var ctx = new SqlResult("?", "\\") {Query = query};
var ctx = new CompileContext(query);

Assert.Null(compiler.CompileLimit(ctx));
}
Expand All @@ -26,7 +26,7 @@ public void WithNoLimitNorOffset()
public void WithNoOffset()
{
var query = new Query("Table").Limit(10);
var ctx = new SqlResult("?", "\\") {Query = query};
var ctx = new CompileContext(query);

Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx));
Assert.Equal(10, ctx.Bindings[0]);
Expand All @@ -36,7 +36,7 @@ public void WithNoOffset()
public void WithNoLimit()
{
var query = new Query("Table").Offset(20);
var ctx = new SqlResult("?", "\\") {Query = query};
var ctx = new CompileContext(query);

Assert.Equal("LIMIT 18446744073709551615 OFFSET ?", compiler.CompileLimit(ctx));
Assert.Equal(20L, ctx.Bindings[0]);
Expand All @@ -47,7 +47,7 @@ public void WithNoLimit()
public void WithLimitAndOffset()
{
var query = new Query("Table").Limit(5).Offset(20);
var ctx = new SqlResult("?", "\\") {Query = query};
var ctx = new CompileContext(query);

Assert.Equal("LIMIT ? OFFSET ?", compiler.CompileLimit(ctx));
Assert.Equal(5, ctx.Bindings[0]);
Expand Down
Loading
Loading