diff --git a/.editorconfig b/.editorconfig
index b33fe946..1333402c 100755
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,28 +1,84 @@
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-# Note: the trim_trailing_whitespace option is br0ken in visualstudio, it
-# simply does not follow the EditorConfig specification. Therefor you are
-# strongly encouraged to not rely on this setting alone, but please install
-# the following extension too: https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TrailingWhitespaceVisualizer
-#
-# References:
-# https://developercommunity.visualstudio.com/t/EditorConfig:-trim_trailing_whitespace-d/1240174?space=8&q=trim_trailing_whitespace
-# https://developercommunity.visualstudio.com/t/editorconfig-trim_trailing_whitespace-on/134457?space=8&q=trim_trailing_whitespace
-# https://developercommunity.visualstudio.com/t/trim_trailing_whitespace-in-editorconfi/1351034?space=8&q=trim_trailing_whitespace
-# https://developercommunity.visualstudio.com/t/BUG:-editorconfig-trim_trailing_whitespa/953937?space=8&q=trim_trailing_whitespace
-trim_trailing_whitespace = true
-insert_final_newline = true
-indent_style = tab
-indent_size = 2
-
-
-[*.cs] # To match existing style
-indent_style = space
-indent_size = 4
-
-
-[*.yml]
-indent_style = space
+# top-most EditorConfig file
+root = true
+
+###########################################################
+# Core EditorConfig Settings - Apply to ALL files
+###########################################################
+
+[*]
+# Indentation and spacing
+indent_style = space
+indent_size = 4
+tab_width = 4
+
+# Newline preferences
+end_of_line = crlf
+insert_final_newline = true
+trim_trailing_whitespace = true
+charset = utf-8
+
+###########################################################
+# .NET / C# Code Style Rules
+###########################################################
+
+[*.cs]
+
+#### C# Language Style Rules (csharp_style_) ####
+
+# Use "var" when the type is obvious or when a tuple/anonymous type
+csharp_style_var_for_built_in_types = false:suggestion
+csharp_style_var_when_type_is_obvious = true:suggestion
+csharp_style_var_elsewhere = false:suggestion
+
+# Use file-scoped namespaces (if targeting .NET 6+)
+csharp_style_namespace_declarations = file_scoped:warning
+
+# Use pattern matching for 'is' and 'switch'
+csharp_style_pattern_matching_over_is_with_not_null = true:suggestion
+csharp_style_pattern_matching_over_as = true:suggestion
+csharp_style_prefer_switch_expression = true:suggestion
+
+# Use explicit type for arrays
+csharp_style_explicit_array_type = true:suggestion
+
+# Use simplified accessors (e.g., private set)
+csharp_style_expression_bodied_accessors = false:suggestion
+csharp_style_expression_bodied_properties = false:suggestion
+csharp_style_expression_bodied_methods = false:suggestion
+
+# Prefer to use `_` or `this.` for member access
+csharp_prefer_static_local_function = true:suggestion
+csharp_style_qualification_for_field = false:suggestion
+csharp_style_qualification_for_property = false:suggestion
+csharp_style_qualification_for_method = false:suggestion
+csharp_style_qualification_for_event = false:suggestion
+
+# Prefer throwing an exception over returning null (if applicable)
+csharp_style_throw_expression = true:suggestion
+
+#### .NET Language Style Rules (dotnet_style_) ####
+
+# Use 'using' declarations instead of using statements
+dotnet_style_prefer_dispose_pattern = true:suggestion
+
+# Prefer collection expressions for arrays and lists (if targeting C# 12+)
+dotnet_style_prefer_collection_expression = true:suggestion
+
+# Prefer to use C# built-in type names (e.g., 'int' instead of 'Int32')
+dotnet_style_predefined_type_names = true:suggestion
+
+#### Formatting Rules (csharp_space_, csharp_indent_) ####
+
+# Control spacing around binary operators (e.g., `a = b` vs `a=b`)
+csharp_space_around_binary_operators = true:suggestion
+
+# Control space within parentheses (e.g., `( a )` vs `(a)`)
+csharp_space_within_parentheses = false:suggestion
+
+# Control new line for braces (e.g., `if () {` vs `if () \n {`)
+csharp_new_line_before_open_brace = all:suggestion
+csharp_new_line_before_members_in_classes = true:suggestion
+csharp_new_line_before_members_in_structs = true:suggestion
+
+# Ensure using directives are sorted alphabetically
+csharp_using_directive_placement = inside_namespace:suggestion
diff --git a/QueryBuilder.Tests/AggregateTests.cs b/QueryBuilder.Tests/AggregateTests.cs
index 68a69842..eab8a9d2 100644
--- a/QueryBuilder.Tests/AggregateTests.cs
+++ b/QueryBuilder.Tests/AggregateTests.cs
@@ -1,92 +1,82 @@
-using SqlKata.Compilers;
-using SqlKata.Tests.Infrastructure;
-using Xunit;
-
-namespace SqlKata.Tests
-{
- public class AggregateTests : TestSupport
- {
- [Fact]
- public void Count()
- {
- var query = new Query("A").AsCount();
-
- var c = Compile(query);
-
- 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]);
- }
-
- [Fact]
- public void CountMultipleColumns()
- {
- var query = new Query("A").AsCount(new[] { "ColumnA", "ColumnB" });
-
- var c = Compile(query);
-
- 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]);
- }
-
- [Fact]
- public void DistinctCount()
- {
- var query = new Query("A").Distinct().AsCount();
-
- var c = Compile(query);
-
- Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT * FROM [A]) AS [countQuery]", c[EngineCodes.SqlServer]);
- }
-
- [Fact]
- public void DistinctCountMultipleColumns()
- {
- var query = new Query("A").Distinct().AsCount(new[] { "ColumnA", "ColumnB" });
-
- var c = Compile(query);
-
- Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT [ColumnA], [ColumnB] FROM [A]) AS [countQuery]", c[EngineCodes.SqlServer]);
- }
-
- [Fact]
- public void Average()
- {
- var query = new Query("A").AsAverage("TTL");
-
- var c = Compile(query);
-
- Assert.Equal("SELECT AVG([TTL]) AS [avg] FROM [A]", c[EngineCodes.SqlServer]);
- }
-
- [Fact]
- public void Sum()
- {
- var query = new Query("A").AsSum("PacketsDropped");
-
- var c = Compile(query);
-
- Assert.Equal("SELECT SUM([PacketsDropped]) AS [sum] FROM [A]", c[EngineCodes.SqlServer]);
- }
-
- [Fact]
- public void Max()
- {
- var query = new Query("A").AsMax("LatencyMs");
-
- var c = Compile(query);
-
- Assert.Equal("SELECT MAX([LatencyMs]) AS [max] FROM [A]", c[EngineCodes.SqlServer]);
- }
-
- [Fact]
- public void Min()
- {
- var query = new Query("A").AsMin("LatencyMs");
-
- var c = Compile(query);
-
- Assert.Equal("SELECT MIN([LatencyMs]) AS [min] FROM [A]", c[EngineCodes.SqlServer]);
- }
- }
-}
+namespace SqlKata.Tests;
+
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+public class AggregateTests : TestSupport {
+ [Fact]
+ public void Count() {
+ var query = new Query("A").AsCount();
+
+ var c = Compile(query);
+
+ 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]);
+ }
+
+ [Fact]
+ public void CountMultipleColumns() {
+ var query = new Query("A").AsCount(new[] { "ColumnA", "ColumnB" });
+
+ var c = Compile(query);
+
+ 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]);
+ }
+
+ [Fact]
+ public void DistinctCount() {
+ var query = new Query("A").Distinct().AsCount();
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT * FROM [A]) AS [countQuery]", c[EngineCodes.SqlServer]);
+ }
+
+ [Fact]
+ public void DistinctCountMultipleColumns() {
+ var query = new Query("A").Distinct().AsCount(new[] { "ColumnA", "ColumnB" });
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT COUNT(*) AS [count] FROM (SELECT DISTINCT [ColumnA], [ColumnB] FROM [A]) AS [countQuery]", c[EngineCodes.SqlServer]);
+ }
+
+ [Fact]
+ public void Average() {
+ var query = new Query("A").AsAverage("TTL");
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT AVG([TTL]) AS [avg] FROM [A]", c[EngineCodes.SqlServer]);
+ }
+
+ [Fact]
+ public void Sum() {
+ var query = new Query("A").AsSum("PacketsDropped");
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT SUM([PacketsDropped]) AS [sum] FROM [A]", c[EngineCodes.SqlServer]);
+ }
+
+ [Fact]
+ public void Max() {
+ var query = new Query("A").AsMax("LatencyMs");
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT MAX([LatencyMs]) AS [max] FROM [A]", c[EngineCodes.SqlServer]);
+ }
+
+ [Fact]
+ public void Min() {
+ var query = new Query("A").AsMin("LatencyMs");
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT MIN([LatencyMs]) AS [min] FROM [A]", c[EngineCodes.SqlServer]);
+ }
+}
diff --git a/QueryBuilder.Tests/DefineTest.cs b/QueryBuilder.Tests/DefineTest.cs
index 0b5ff292..56b22b0f 100644
--- a/QueryBuilder.Tests/DefineTest.cs
+++ b/QueryBuilder.Tests/DefineTest.cs
@@ -1,427 +1,407 @@
-using static SqlKata.Expressions;
-using SqlKata.Compilers;
-using SqlKata.Tests.Infrastructure;
-using Xunit;
-
-namespace SqlKata.Tests
-{
- ///
- /// If you want to test this queries against a database use NorthWind database
- ///
- public class DefineTest : TestSupport
- {
-
- [Fact]
- public void Test_Define_Where()
- {
- var query = new Query("Products")
- .Define("@name", "Anto")
- .Where("ProductName", Variable("@name"));
-
- var c = Compile(query);
-
- Assert.Equal("SELECT * FROM [Products] WHERE [ProductName] = 'Anto'", c[EngineCodes.SqlServer]);
-
- }
-
- [Fact]
- public void Test_Define_SubQuery()
- {
-
- var subquery = new Query("Products")
- .AsAverage("unitprice")
- .Define("@UnitsInSt", 10)
- .Where("UnitsInStock", ">", Variable("@UnitsInSt"));
-
- var query = new Query("Products")
- .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]);
-
- }
-
-
- [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]);
-
- }
-
-
-
- [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]);
- }
-
-
- [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]);
-
- }
-
-
- [Fact]
- public void Test_Define_WhereLike()
- {
- var query1 = new Query("Products")
- .Select("ProductId", "ProductName", "SupplierID")
- .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]);
- }
-
-
- [Fact]
- public void Test_Define_WhereInSubquery()
- {
-
- var subquery = new Query("Orders")
- .Define("@shipId", 3)
- .Select("ShipVia").Where("ShipVia", Variable("@shipId"));
-
-
- var query1 = new Query("Shippers")
- .Select("ShipperID", "CompanyName")
- .WhereIn("ShipperID", subquery);
-
-
- var c1 = Compile(query1);
-
- Assert.Equal("SELECT [ShipperID], [CompanyName] FROM [Shippers] WHERE [ShipperID] IN (SELECT [ShipVia] FROM [Orders] WHERE [ShipVia] = 3)", c1[EngineCodes.SqlServer]);
- }
-
- [Fact]
- public void Test_Define_Having()
- {
- var c = Compile(new Query("Table")
- .Define("@foo", 1)
- .Having("Id", "=", Variable("@foo")));
-
- Assert.Equal("SELECT * FROM [Table] HAVING [Id] = 1", c[EngineCodes.SqlServer]);
- }
-
- /*
- [Fact]
- public void Test_Define_HavingRaw()
- {
- 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 = Compile(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]);
-
- }
- */
-
- [Fact]
- public void Test_Define_HavingStarts()
- {
-
- var query = new Query("Customers")
- .Define("@label", "U")
- .SelectRaw("COUNT(CustomerID)")
- .Select("Country")
- .GroupBy("Country")
- .HavingStarts("Country", Variable("@label"));
-
- var c = Compile(query);
-
- Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like 'u%'", c[EngineCodes.SqlServer]);
-
- }
-
-
-
- [Fact]
- public void Test_Define_Having_Ends()
- {
- var query = new Query("Customers")
- .Define("@label", "d")
- .SelectRaw("COUNT(CustomerID)")
- .Select("Country")
- .GroupBy("Country")
- .HavingEnds("Country", Variable("@label"));
-
- var c = Compile(query);
-
- Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d'", c[EngineCodes.SqlServer]);
- }
-
-
- [Fact]
- public void Test_Define_Having_Contains()
- {
-
-
- var query = new Query("Customers")
- .Define("@label", "d")
- .SelectRaw("COUNT(CustomerID)")
- .Select("Country")
- .GroupBy("Country")
- .HavingContains("Country", Variable("@label"));
-
- var c = Compile(query);
-
- Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d%'", c[EngineCodes.SqlServer]);
-
- }
-
-
- [Fact]
- public void Test_Define_NestedCondition()
- {
- var query = new Query("Orders")
- .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]);
-
- }
-
-
- [Fact]
- public void Test_Define_WhereDate()
- {
- var dateObj = new System.DateTime(year: 1996, month: 8, day: 1);
-
- var query = new Query("Orders")
- .Define("@d", dateObj)
- .WhereDate("RequiredDate", Variable("@d"));
-
-
- var query2 = 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]);
-
-
-
- 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]);
-
- }
-
-
- [Fact]
- public void Test_Define_WhereExists()
- {
- 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]);
- }
-
-
-
- [Fact]
- public void Test_Define_With()
- {
-
- var query = new Query("Products")
- .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);
-
-
- 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]);
- }
-
-
-
- /*
- [Fact]
- public void Test_Define_WithRaw()
- {
-
- //WithRaw
- var query = new Query("prodCTE")
- .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");
-
- 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]);
-
- }
- */
-
- //
- [Fact]
- public void Test_Define_Union()
- {
- var q1 = new Query("Suppliers")
- .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"));
-
- 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]);
- }
-
-
- [Fact]
- public void Test_Define_Except()
- {
- var q1 = new Query("Suppliers")
- .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"));
-
- 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]);
- }
-
- [Fact]
- public void Test_Define_Intersect()
- {
- var q1 = new Query("Suppliers")
- .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"));
-
- 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]);
- }
-
- /*
- [Fact]
- public void Test_Define_CombineRaw()
- {
-
- 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");
-
- 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]);
- }
- */
-
- }
-}
+namespace SqlKata.Tests;
+
+using static SqlKata.Expressions;
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+///
+/// If you want to test this queries against a database use NorthWind database
+///
+public class DefineTest : TestSupport {
+
+ [Fact]
+ public void Test_Define_Where() {
+ var query = new Query("Products")
+ .Define("@name", "Anto")
+ .Where("ProductName", Variable("@name"));
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT * FROM [Products] WHERE [ProductName] = 'Anto'", c[EngineCodes.SqlServer]);
+
+ }
+
+ [Fact]
+ public void Test_Define_SubQuery() {
+
+ var subquery = new Query("Products")
+ .AsAverage("unitprice")
+ .Define("@UnitsInSt", 10)
+ .Where("UnitsInStock", ">", Variable("@UnitsInSt"));
+
+ var query = new Query("Products")
+ .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]);
+
+ }
+
+
+ [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]);
+
+ }
+
+
+
+ [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]);
+ }
+
+
+ [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]);
+
+ }
+
+
+ [Fact]
+ public void Test_Define_WhereLike() {
+ var query1 = new Query("Products")
+ .Select("ProductId", "ProductName", "SupplierID")
+ .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]);
+ }
+
+
+ [Fact]
+ public void Test_Define_WhereInSubquery() {
+
+ var subquery = new Query("Orders")
+ .Define("@shipId", 3)
+ .Select("ShipVia").Where("ShipVia", Variable("@shipId"));
+
+
+ var query1 = new Query("Shippers")
+ .Select("ShipperID", "CompanyName")
+ .WhereIn("ShipperID", subquery);
+
+
+ var c1 = Compile(query1);
+
+ Assert.Equal("SELECT [ShipperID], [CompanyName] FROM [Shippers] WHERE [ShipperID] IN (SELECT [ShipVia] FROM [Orders] WHERE [ShipVia] = 3)", c1[EngineCodes.SqlServer]);
+ }
+
+ [Fact]
+ public void Test_Define_Having() {
+ var c = Compile(new Query("Table")
+ .Define("@foo", 1)
+ .Having("Id", "=", Variable("@foo")));
+
+ Assert.Equal("SELECT * FROM [Table] HAVING [Id] = 1", c[EngineCodes.SqlServer]);
+ }
+
+ /*
+ [Fact]
+ public void Test_Define_HavingRaw()
+ {
+ 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 = Compile(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]);
+
+ }
+ */
+
+ [Fact]
+ public void Test_Define_HavingStarts() {
+
+ var query = new Query("Customers")
+ .Define("@label", "U")
+ .SelectRaw("COUNT(CustomerID)")
+ .Select("Country")
+ .GroupBy("Country")
+ .HavingStarts("Country", Variable("@label"));
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like 'u%'", c[EngineCodes.SqlServer]);
+
+ }
+
+
+
+ [Fact]
+ public void Test_Define_Having_Ends() {
+ var query = new Query("Customers")
+ .Define("@label", "d")
+ .SelectRaw("COUNT(CustomerID)")
+ .Select("Country")
+ .GroupBy("Country")
+ .HavingEnds("Country", Variable("@label"));
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d'", c[EngineCodes.SqlServer]);
+ }
+
+
+ [Fact]
+ public void Test_Define_Having_Contains() {
+
+
+ var query = new Query("Customers")
+ .Define("@label", "d")
+ .SelectRaw("COUNT(CustomerID)")
+ .Select("Country")
+ .GroupBy("Country")
+ .HavingContains("Country", Variable("@label"));
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT COUNT(CustomerID), [Country] FROM [Customers] GROUP BY [Country] HAVING LOWER([Country]) like '%d%'", c[EngineCodes.SqlServer]);
+
+ }
+
+
+ [Fact]
+ public void Test_Define_NestedCondition() {
+ var query = new Query("Orders")
+ .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]);
+
+ }
+
+
+ [Fact]
+ public void Test_Define_WhereDate() {
+ var dateObj = new System.DateTime(year: 1996, month: 8, day: 1);
+
+ var query = new Query("Orders")
+ .Define("@d", dateObj)
+ .WhereDate("RequiredDate", Variable("@d"));
+
+
+ var query2 = 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]);
+
+
+
+ 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]);
+
+ }
+
+
+ [Fact]
+ public void Test_Define_WhereExists() {
+ 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]);
+ }
+
+
+
+ [Fact]
+ public void Test_Define_With() {
+
+ var query = new Query("Products")
+ .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);
+
+
+ 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]);
+ }
+
+
+
+ /*
+ [Fact]
+ public void Test_Define_WithRaw()
+ {
+
+ //WithRaw
+ var query = new Query("prodCTE")
+ .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");
+
+ 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]);
+
+ }
+ */
+
+ //
+ [Fact]
+ public void Test_Define_Union() {
+ var q1 = new Query("Suppliers")
+ .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"));
+
+ 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]);
+ }
+
+
+ [Fact]
+ public void Test_Define_Except() {
+ var q1 = new Query("Suppliers")
+ .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"));
+
+ 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]);
+ }
+
+ [Fact]
+ public void Test_Define_Intersect() {
+ var q1 = new Query("Suppliers")
+ .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"));
+
+ 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]);
+ }
+
+ /*
+ [Fact]
+ public void Test_Define_CombineRaw()
+ {
+
+ 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");
+
+ 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]);
+ }
+ */
+
+}
diff --git a/QueryBuilder.Tests/DeleteTests.cs b/QueryBuilder.Tests/DeleteTests.cs
index 14fd4043..faa35a10 100644
--- a/QueryBuilder.Tests/DeleteTests.cs
+++ b/QueryBuilder.Tests/DeleteTests.cs
@@ -1,49 +1,44 @@
-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()
- {
- var q = new Query("Posts").AsDelete();
-
- var c = Compile(q);
-
- Assert.Equal("DELETE FROM [Posts]", c[EngineCodes.SqlServer]);
- }
-
- [Fact]
- public void DeleteWithJoin()
- {
- var q = new Query("Posts")
- .Join("Authors", "Authors.Id", "Posts.AuthorId")
- .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", c[EngineCodes.SqlServer]);
- Assert.Equal("DELETE `Posts` FROM `Posts` \nINNER JOIN `Authors` ON `Authors`.`Id` = `Posts`.`AuthorId` WHERE `Authors`.`Id` = 5", c[EngineCodes.MySql]);
- }
-
- [Fact]
- public void DeleteWithJoinAndAlias()
- {
- var q = new Query("Posts as P")
- .Join("Authors", "Authors.Id", "P.AuthorId")
- .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", c[EngineCodes.SqlServer]);
- }
- }
-}
+namespace SqlKata.Tests;
+
+using SqlKata.Compilers;
+using SqlKata.Extensions;
+using SqlKata.Tests.Infrastructure;
+using System;
+using System.Linq;
+using Xunit;
+
+public class DeleteTests : TestSupport {
+ [Fact]
+ public void BasicDelete() {
+ var q = new Query("Posts").AsDelete();
+
+ var c = Compile(q);
+
+ Assert.Equal("DELETE FROM [Posts]", c[EngineCodes.SqlServer]);
+ }
+
+ [Fact]
+ public void DeleteWithJoin() {
+ var q = new Query("Posts")
+ .Join("Authors", "Authors.Id", "Posts.AuthorId")
+ .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", c[EngineCodes.SqlServer]);
+ Assert.Equal("DELETE `Posts` FROM `Posts` \nINNER JOIN `Authors` ON `Authors`.`Id` = `Posts`.`AuthorId` WHERE `Authors`.`Id` = 5", c[EngineCodes.MySql]);
+ }
+
+ [Fact]
+ public void DeleteWithJoinAndAlias() {
+ var q = new Query("Posts as P")
+ .Join("Authors", "Authors.Id", "P.AuthorId")
+ .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", c[EngineCodes.SqlServer]);
+ }
+}
diff --git a/QueryBuilder.Tests/ExecutionTests.cs b/QueryBuilder.Tests/ExecutionTests.cs
index 5d41e7fd..f02555f5 100644
--- a/QueryBuilder.Tests/ExecutionTests.cs
+++ b/QueryBuilder.Tests/ExecutionTests.cs
@@ -1,36 +1,30 @@
-using System;
-using SqlKata.Execution;
-using Xunit;
-
-namespace SqlKata.Tests
-{
- public class ExecutionTests
- {
- [Fact]
- public void ShouldThrowException()
- {
- Assert.Throws(() =>
- {
- new Query("Books").Get();
- });
- }
-
- [Fact]
- public void TimeoutShouldBeCarriedToNewCreatedFactory()
- {
- var db = new QueryFactory();
- db.QueryTimeout = 4000;
- var newFactory = QueryExtensions.CreateQueryFactory(db.Query());
- Assert.Equal(db.QueryTimeout, newFactory.QueryTimeout);
- }
-
- [Fact(Skip = "timeout over cloned xQuery is not supported yet")]
- public void TimeoutShouldBeCarriedToNewCreatedFactoryAfterClone()
- {
- var db = new QueryFactory();
- db.QueryTimeout = 4000;
- var newFactory = QueryExtensions.CreateQueryFactory(db.Query().Clone());
- Assert.Equal(db.QueryTimeout, newFactory.QueryTimeout);
- }
- }
-}
+namespace SqlKata.Tests;
+
+using System;
+using SqlKata.Execution;
+using Xunit;
+
+public class ExecutionTests {
+ [Fact]
+ public void ShouldThrowException() {
+ Assert.Throws(() => {
+ new Query("Books").Get();
+ });
+ }
+
+ [Fact]
+ public void TimeoutShouldBeCarriedToNewCreatedFactory() {
+ var db = new QueryFactory();
+ db.QueryTimeout = 4000;
+ var newFactory = QueryExtensions.CreateQueryFactory(db.Query());
+ Assert.Equal(db.QueryTimeout, newFactory.QueryTimeout);
+ }
+
+ [Fact(Skip = "timeout over cloned xQuery is not supported yet")]
+ public void TimeoutShouldBeCarriedToNewCreatedFactoryAfterClone() {
+ var db = new QueryFactory();
+ db.QueryTimeout = 4000;
+ var newFactory = QueryExtensions.CreateQueryFactory(db.Query().Clone());
+ Assert.Equal(db.QueryTimeout, newFactory.QueryTimeout);
+ }
+}
diff --git a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs
index b449bae8..677919d4 100644
--- a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs
+++ b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs
@@ -1,55 +1,48 @@
-using SqlKata.Compilers;
-using SqlKata.Tests.Infrastructure;
-using Xunit;
-
-namespace SqlKata.Tests.Firebird
-{
- public class FirebirdLimitTests : TestSupport
- {
- private readonly FirebirdCompiler compiler;
-
- public FirebirdLimitTests()
- {
- compiler = Compilers.Get(EngineCodes.Firebird);
- }
-
- [Fact]
- public void NoLimitNorOffset()
- {
- var query = new Query("Table");
- var ctx = new SqlResult("?", "\\") {Query = query};
-
- Assert.Null(compiler.CompileLimit(ctx));
- }
-
- [Fact]
- public void LimitOnly()
- {
- var query = new Query("Table").Limit(10);
- var ctx = new SqlResult("?", "\\") {Query = query};
-
- Assert.Null(compiler.CompileLimit(ctx));
- }
-
- [Fact]
- public void OffsetOnly()
- {
- var query = new Query("Table").Offset(20);
- var ctx = new SqlResult("?", "\\") {Query = query};
-
- Assert.Null(compiler.CompileLimit(ctx));
- }
-
- [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);
- }
- }
-}
+namespace SqlKata.Tests.Firebird;
+
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+public class FirebirdLimitTests : TestSupport {
+ private readonly FirebirdCompiler compiler;
+
+ public FirebirdLimitTests() {
+ compiler = Compilers.Get(EngineCodes.Firebird);
+ }
+
+ [Fact]
+ public void NoLimitNorOffset() {
+ var query = new Query("Table");
+ var ctx = new SqlResult("?", "\\") { Query = query };
+
+ Assert.Null(compiler.CompileLimit(ctx));
+ }
+
+ [Fact]
+ public void LimitOnly() {
+ var query = new Query("Table").Limit(10);
+ var ctx = new SqlResult("?", "\\") { Query = query };
+
+ Assert.Null(compiler.CompileLimit(ctx));
+ }
+
+ [Fact]
+ public void OffsetOnly() {
+ var query = new Query("Table").Offset(20);
+ var ctx = new SqlResult("?", "\\") { Query = query };
+
+ Assert.Null(compiler.CompileLimit(ctx));
+ }
+
+ [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);
+ }
+}
diff --git a/QueryBuilder.Tests/GeneralTests.cs b/QueryBuilder.Tests/GeneralTests.cs
index 63fb3d3f..4e0dd202 100644
--- a/QueryBuilder.Tests/GeneralTests.cs
+++ b/QueryBuilder.Tests/GeneralTests.cs
@@ -1,605 +1,564 @@
-using SqlKata.Compilers;
-using SqlKata.Extensions;
-using SqlKata.Tests.Infrastructure;
-using System;
-using System.Linq;
-using Xunit;
-
-namespace SqlKata.Tests
-{
- public class GeneralTests : TestSupport
- {
- [Fact]
- public void ColumnsEscaping()
- {
- var q = new Query().From("users")
- .Select("mycol[isthis]");
-
- var c = Compile(q);
-
- Assert.Equal("SELECT [mycol[isthis]]] FROM [users]", c[EngineCodes.SqlServer]);
- }
-
-
- [Fact]
- public void InnerScopeEngineWithinCTE()
- {
- var series = new Query("table")
- .ForPostgreSql(q => q.WhereRaw("postgres = true"))
- .ForSqlServer(q => q.WhereRaw("sqlsrv = 1"))
- .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]);
-
- 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]);
- }
-
- [Fact]
- public void InnerScopeEngineWithinSubQuery()
- {
- var series = new Query("table")
- .ForPostgreSql(q => q.WhereRaw("postgres = true"))
- .ForSqlServer(q => q.WhereRaw("sqlsrv = 1"))
- .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]);
-
- 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]);
- }
-
- [Fact]
- public void ItShouldCacheMethodInfoByType()
- {
- var compiler = new TestSqlServerCompiler();
-
- var call1 = compiler.Call_FindCompilerMethodInfo(
- typeof(BasicCondition), "CompileBasicCondition"
- );
-
- var call2 = compiler.Call_FindCompilerMethodInfo(
- typeof(BasicCondition), "CompileBasicCondition"
- );
-
- Assert.Same(call1, call2);
- }
-
- [Fact]
- public void Return_Different_MethodInfo_WhenSame_Method_With_Different_GenericTypes()
- {
- var compiler = new TestSqlServerCompiler();
-
- var call1 = compiler.Call_FindCompilerMethodInfo(
- typeof(NestedCondition), "CompileNestedCondition"
- );
-
- var call2 = compiler.Call_FindCompilerMethodInfo(
- typeof(NestedCondition), "CompileNestedCondition"
- );
-
- Assert.NotSame(call1, call2);
- }
-
- [Fact]
- public void Custom_compiler_with_empty_identifier_overrides_should_remove_identifiers()
- {
- var compiler = new TestEmptyIdentifiersCompiler();
-
- var wrappedValue = compiler.WrapValue("Table");
-
- Assert.Equal("Table", wrappedValue);
- }
-
- [Fact]
- public void Should_Equal_AfterMultipleCompile()
- {
- var query = new Query()
- .Select("Id", "Name")
- .From("Table")
- .OrderBy("Name")
- .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 second = Compile(query);
-
- 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]);
- }
-
- [Fact]
- public void Raw_WrapIdentifiers()
- {
- var query = new Query("Users").SelectRaw("[Id], [Name], {Age}");
-
- var c = Compile(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]);
- }
-
- [Fact]
- public void Raw_WrapIdentifiers_Escaped()
- {
- var query = new Query("Users").SelectRaw("'\\{1,2,3\\}'::int\\[\\]");
-
- var c = Compile(query);
-
- Assert.Equal("SELECT '{1,2,3}'::int[] FROM \"Users\"", c[EngineCodes.PostgreSql]);
- }
-
- [Fact]
- public void WrapWithSpace()
- {
- var compiler = new SqlServerCompiler();
-
-
- Assert.Equal("[My Table] AS [Table]", compiler.Wrap("My Table as Table"));
- }
-
- [Fact]
- public void WrapWithDotes()
- {
- var compiler = new SqlServerCompiler();
-
-
- Assert.Equal("[My Schema].[My Table] AS [Table]", compiler.Wrap("My Schema.My Table as Table"));
- }
-
- [Fact]
- 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()
- {
- 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);
- }
-
- [Fact]
- public void CompilerSpecificFromRaw()
- {
- 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);
- }
-
- [Fact]
- public void CompilerSpecificFromMixed()
- {
- 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);
- }
-
- [Fact]
- 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);
-
- 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);
- }
-
- [Theory]
- [InlineData(null, null)]
- [InlineData(null, "mssql")]
- [InlineData("original", null)]
- [InlineData("original", "mssql")]
- 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 });
- var froms = query.Clauses.OfType();
-
- Assert.Single(froms);
- Assert.Equal("updated", froms.Single().Table);
- }
-
- [Theory]
- [InlineData(null, "generic")]
- [InlineData(EngineCodes.SqlServer, "mssql")]
- [InlineData(EngineCodes.MySql, "generic")]
- public void GetOneComponent_Prefers_Engine(string engine, string column)
- {
- var query = new Query()
- .Where("generic", "foo")
- .ForSqlServer(q => q.Where("mssql", "foo"));
-
- var where = query.GetOneComponent("where", engine) as BasicCondition;
-
- Assert.NotNull(where);
- Assert.Equal(column, where.Column);
- }
-
- [Fact]
- public void AddOrReplace_Throws_MoreThanOne()
- {
- var query = new Query()
- .Where("a", "b")
- .Where("c", "d");
-
- Action act = () => query.AddOrReplaceComponent("where", new BasicCondition());
- Assert.Throws(act);
- }
-
- [Fact]
- public void OneLimitPerEngine()
- {
- var query = new Query("mytable")
- .ForSqlServer(q => q.Limit(5))
- .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()
- {
- 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);
-
- 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());
- }
-
- [Fact]
- public void OneOffsetPerEngine()
- {
- var query = new Query("mytable")
- .ForSqlServer(q => q.Offset(5))
- .ForSqlServer(q => q.Offset(10));
-
- var limits = query.GetComponents("offset", EngineCodes.SqlServer);
- Assert.Single(limits);
- Assert.Equal(10, limits.Single().Offset);
- }
-
- [Fact]
- public void CompilerSpecificOffset()
- {
- 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);
-
- 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());
- }
-
- [Fact]
- public void Limit_Takes_Generic_If_Needed()
- {
- var query = new Query("mytable")
- .Limit(5)
- .Offset(10)
- .ForPostgreSql(q => q.Offset(20));
-
- var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql };
- var c = Compilers.Compile(engines, 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());
- }
-
- [Fact]
- public void Offset_Takes_Generic_If_Needed()
- {
- var query = new Query("mytable")
- .Limit(5)
- .Offset(10)
- .ForPostgreSql(q => q.Limit(20));
-
- var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql };
- var c = Compilers.Compile(engines, 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());
- }
-
- [Fact]
- public void Can_Change_Generic_Limit_After_SpecificOffset()
- {
- var query = new Query("mytable")
- .Limit(5)
- .Offset(10)
- .ForPostgreSql(q => q.Offset(20))
- .Limit(7);
-
- var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql };
- var c = Compilers.Compile(engines, 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());
- }
-
- [Fact]
- public void Can_Change_Generic_Offset_After_SpecificLimit()
- {
- var query = new Query("mytable")
- .Limit(5)
- .Offset(10)
- .ForPostgreSql(q => q.Limit(20))
- .Offset(7);
-
- var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql };
- var c = Compilers.Compile(engines, 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());
- }
-
- [Fact]
- public void Where_Nested()
- {
- var query = new Query("table")
- .Where(q => q.Where("a", 1).OrWhere("a", 2));
-
- var engines = new[] {
- EngineCodes.SqlServer,
- };
-
- var c = Compilers.Compile(engines, query);
-
- Assert.Equal("SELECT * FROM [table] WHERE ([a] = 1 OR [a] = 2)", c[EngineCodes.SqlServer].ToString());
- }
-
- [Fact]
- public void AdHoc_Throws_WhenNoColumnsProvided() =>
- Assert.Throws(() =>
- new Query("rows").With("rows",
- new string[0],
- new object[][] {
- new object[] {},
- new object[] {},
- }));
-
- [Fact]
- public void AdHoc_Throws_WhenNoValueRowsProvided() =>
- Assert.Throws(() =>
- new Query("rows").With("rows",
- new[] { "a", "b", "c" },
- new object[][] {
- }));
-
- [Fact]
- public void AdHoc_Throws_WhenColumnsOutnumberFieldValues() =>
- Assert.Throws(() =>
- new Query("rows").With("rows",
- new[] { "a", "b", "c", "d" },
- new object[][] {
- new object[] { 1, 2, 3 },
- new object[] { 4, 5, 6 },
- }));
-
- [Fact]
- public void AdHoc_Throws_WhenFieldValuesOutNumberColumns() =>
- Assert.Throws(() =>
- new Query("rows").With("rows",
- new[] { "a", "b" },
- new object[][] {
- new object[] { 1, 2, 3 },
- new object[] { 4, 5, 6 },
- }));
-
- [Fact]
- public void AdHoc_SingletonRow()
- {
- var query = new Query("rows").With("rows",
- new[] { "a" },
- new object[][] {
- new object[] { 1 },
- });
-
- var c = Compilers.Compile(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());
- }
-
- [Fact]
- public void AdHoc_TwoRows()
- {
- var query = new Query("rows").With("rows",
- new[] { "a", "b", "c" },
- new object[][] {
- new object[] { 1, 2, 3 },
- new object[] { 4, 5, 6 },
- });
-
- var c = Compilers.Compile(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());
- }
-
- [Fact]
- public void AdHoc_ProperBindingsPlacement()
- {
- var query = new Query("rows")
- .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 },
- })
- .Where("rows.baz", "buzz");
-
- var c = Compilers.Compile(query);
-
- 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());
- }
-
- [Fact]
- public void UnsafeLiteral_Insert()
- {
- var query = new Query("Table").AsInsert(new
- {
- Count = new UnsafeLiteral("Count + 1")
- });
-
- var engines = new[] {
- EngineCodes.SqlServer,
- };
-
- var c = Compilers.Compile(engines, query);
-
- Assert.Equal("INSERT INTO [Table] ([Count]) VALUES (Count + 1)", c[EngineCodes.SqlServer].ToString());
- }
-
- [Fact]
- public void UnsafeLiteral_Update()
- {
- var query = new Query("Table").AsUpdate(new
- {
- Count = new UnsafeLiteral("Count + 1")
- });
-
- var engines = new[] {
- EngineCodes.SqlServer,
- };
-
- var c = Compilers.Compile(engines, query);
-
- Assert.Equal("UPDATE [Table] SET [Count] = Count + 1", c[EngineCodes.SqlServer].ToString());
- }
-
- [Fact]
- public void Passing_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse()
- {
- var query = new Query("Table").Where("Col", true);
-
- var engines = new[] {
- EngineCodes.SqlServer,
- };
-
- var c = Compilers.Compile(engines, query);
-
- Assert.Equal("SELECT * FROM [Table] WHERE [Col] = cast(1 as bit)", c[EngineCodes.SqlServer].ToString());
- }
-
- [Fact]
- public void Passing_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse()
- {
- var query = new Query("Table").Where("Col", false);
-
- var engines = new[] {
- EngineCodes.SqlServer,
- };
-
- var c = Compilers.Compile(engines, query);
-
- Assert.Equal("SELECT * FROM [Table] WHERE [Col] = cast(0 as bit)", c[EngineCodes.SqlServer].ToString());
- }
-
- [Fact]
- public void Passing_Negative_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse()
- {
- var query = new Query("Table").Where("Col", "!=", true);
-
- var engines = new[] {
- EngineCodes.SqlServer,
- };
-
- var c = Compilers.Compile(engines, query);
-
- Assert.Equal("SELECT * FROM [Table] WHERE [Col] != cast(1 as bit)", c[EngineCodes.SqlServer].ToString());
- }
-
- [Fact]
- public void Passing_Negative_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse()
- {
- var query = new Query("Table").Where("Col", "!=", false);
-
- var engines = new[] {
- EngineCodes.SqlServer,
- };
-
- var c = Compilers.Compile(engines, query);
-
- Assert.Equal("SELECT * FROM [Table] WHERE [Col] != cast(0 as bit)", c[EngineCodes.SqlServer].ToString());
- }
- }
-}
+namespace SqlKata.Tests;
+
+using SqlKata.Compilers;
+using SqlKata.Extensions;
+using SqlKata.Tests.Infrastructure;
+using System;
+using System.Linq;
+using Xunit;
+
+public class GeneralTests : TestSupport {
+ [Fact]
+ public void ColumnsEscaping() {
+ var q = new Query().From("users")
+ .Select("mycol[isthis]");
+
+ var c = Compile(q);
+
+ Assert.Equal("SELECT [mycol[isthis]]] FROM [users]", c[EngineCodes.SqlServer]);
+ }
+
+
+ [Fact]
+ public void InnerScopeEngineWithinCTE() {
+ var series = new Query("table")
+ .ForPostgreSql(q => q.WhereRaw("postgres = true"))
+ .ForSqlServer(q => q.WhereRaw("sqlsrv = 1"))
+ .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]);
+
+ 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]);
+ }
+
+ [Fact]
+ public void InnerScopeEngineWithinSubQuery() {
+ var series = new Query("table")
+ .ForPostgreSql(q => q.WhereRaw("postgres = true"))
+ .ForSqlServer(q => q.WhereRaw("sqlsrv = 1"))
+ .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]);
+
+ 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]);
+ }
+
+ [Fact]
+ public void ItShouldCacheMethodInfoByType() {
+ var compiler = new TestSqlServerCompiler();
+
+ var call1 = compiler.Call_FindCompilerMethodInfo(
+ typeof(BasicCondition), "CompileBasicCondition"
+ );
+
+ var call2 = compiler.Call_FindCompilerMethodInfo(
+ typeof(BasicCondition), "CompileBasicCondition"
+ );
+
+ Assert.Same(call1, call2);
+ }
+
+ [Fact]
+ public void Return_Different_MethodInfo_WhenSame_Method_With_Different_GenericTypes() {
+ var compiler = new TestSqlServerCompiler();
+
+ var call1 = compiler.Call_FindCompilerMethodInfo(
+ typeof(NestedCondition), "CompileNestedCondition"
+ );
+
+ var call2 = compiler.Call_FindCompilerMethodInfo(
+ typeof(NestedCondition), "CompileNestedCondition"
+ );
+
+ Assert.NotSame(call1, call2);
+ }
+
+ [Fact]
+ public void Custom_compiler_with_empty_identifier_overrides_should_remove_identifiers() {
+ var compiler = new TestEmptyIdentifiersCompiler();
+
+ var wrappedValue = compiler.WrapValue("Table");
+
+ Assert.Equal("Table", wrappedValue);
+ }
+
+ [Fact]
+ public void Should_Equal_AfterMultipleCompile() {
+ var query = new Query()
+ .Select("Id", "Name")
+ .From("Table")
+ .OrderBy("Name")
+ .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 second = Compile(query);
+
+ 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]);
+ }
+
+ [Fact]
+ public void Raw_WrapIdentifiers() {
+ var query = new Query("Users").SelectRaw("[Id], [Name], {Age}");
+
+ var c = Compile(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]);
+ }
+
+ [Fact]
+ public void Raw_WrapIdentifiers_Escaped() {
+ var query = new Query("Users").SelectRaw("'\\{1,2,3\\}'::int\\[\\]");
+
+ var c = Compile(query);
+
+ Assert.Equal("SELECT '{1,2,3}'::int[] FROM \"Users\"", c[EngineCodes.PostgreSql]);
+ }
+
+ [Fact]
+ public void WrapWithSpace() {
+ var compiler = new SqlServerCompiler();
+
+
+ Assert.Equal("[My Table] AS [Table]", compiler.Wrap("My Table as Table"));
+ }
+
+ [Fact]
+ public void WrapWithDotes() {
+ var compiler = new SqlServerCompiler();
+
+
+ Assert.Equal("[My Schema].[My Table] AS [Table]", compiler.Wrap("My Schema.My Table as Table"));
+ }
+
+ [Fact]
+ 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() {
+ 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);
+ }
+
+ [Fact]
+ public void CompilerSpecificFromRaw() {
+ 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);
+ }
+
+ [Fact]
+ public void CompilerSpecificFromMixed() {
+ 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);
+ }
+
+ [Fact]
+ 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);
+
+ 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);
+ }
+
+ [Theory]
+ [InlineData(null, null)]
+ [InlineData(null, "mssql")]
+ [InlineData("original", null)]
+ [InlineData("original", "mssql")]
+ 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 });
+ var froms = query.Clauses.OfType();
+
+ Assert.Single(froms);
+ Assert.Equal("updated", froms.Single().Table);
+ }
+
+ [Theory]
+ [InlineData(null, "generic")]
+ [InlineData(EngineCodes.SqlServer, "mssql")]
+ [InlineData(EngineCodes.MySql, "generic")]
+ public void GetOneComponent_Prefers_Engine(string engine, string column) {
+ var query = new Query()
+ .Where("generic", "foo")
+ .ForSqlServer(q => q.Where("mssql", "foo"));
+
+ var where = query.GetOneComponent("where", engine) as BasicCondition;
+
+ Assert.NotNull(where);
+ Assert.Equal(column, where.Column);
+ }
+
+ [Fact]
+ public void AddOrReplace_Throws_MoreThanOne() {
+ var query = new Query()
+ .Where("a", "b")
+ .Where("c", "d");
+
+ Action act = () => query.AddOrReplaceComponent("where", new BasicCondition());
+ Assert.Throws(act);
+ }
+
+ [Fact]
+ public void OneLimitPerEngine() {
+ var query = new Query("mytable")
+ .ForSqlServer(q => q.Limit(5))
+ .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() {
+ 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);
+
+ 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());
+ }
+
+ [Fact]
+ public void OneOffsetPerEngine() {
+ var query = new Query("mytable")
+ .ForSqlServer(q => q.Offset(5))
+ .ForSqlServer(q => q.Offset(10));
+
+ var limits = query.GetComponents("offset", EngineCodes.SqlServer);
+ Assert.Single(limits);
+ Assert.Equal(10, limits.Single().Offset);
+ }
+
+ [Fact]
+ public void CompilerSpecificOffset() {
+ 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);
+
+ 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());
+ }
+
+ [Fact]
+ public void Limit_Takes_Generic_If_Needed() {
+ var query = new Query("mytable")
+ .Limit(5)
+ .Offset(10)
+ .ForPostgreSql(q => q.Offset(20));
+
+ var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql };
+ var c = Compilers.Compile(engines, 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());
+ }
+
+ [Fact]
+ public void Offset_Takes_Generic_If_Needed() {
+ var query = new Query("mytable")
+ .Limit(5)
+ .Offset(10)
+ .ForPostgreSql(q => q.Limit(20));
+
+ var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql };
+ var c = Compilers.Compile(engines, 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());
+ }
+
+ [Fact]
+ public void Can_Change_Generic_Limit_After_SpecificOffset() {
+ var query = new Query("mytable")
+ .Limit(5)
+ .Offset(10)
+ .ForPostgreSql(q => q.Offset(20))
+ .Limit(7);
+
+ var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql };
+ var c = Compilers.Compile(engines, 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());
+ }
+
+ [Fact]
+ public void Can_Change_Generic_Offset_After_SpecificLimit() {
+ var query = new Query("mytable")
+ .Limit(5)
+ .Offset(10)
+ .ForPostgreSql(q => q.Limit(20))
+ .Offset(7);
+
+ var engines = new[] { EngineCodes.MySql, EngineCodes.PostgreSql };
+ var c = Compilers.Compile(engines, 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());
+ }
+
+ [Fact]
+ public void Where_Nested() {
+ var query = new Query("table")
+ .Where(q => q.Where("a", 1).OrWhere("a", 2));
+
+ var engines = new[] {
+ EngineCodes.SqlServer,
+ };
+
+ var c = Compilers.Compile(engines, query);
+
+ Assert.Equal("SELECT * FROM [table] WHERE ([a] = 1 OR [a] = 2)", c[EngineCodes.SqlServer].ToString());
+ }
+
+ [Fact]
+ public void AdHoc_Throws_WhenNoColumnsProvided() =>
+ Assert.Throws(() =>
+ new Query("rows").With("rows",
+ new string[0],
+ new object[][] {
+ new object[] {},
+ new object[] {},
+ }));
+
+ [Fact]
+ public void AdHoc_Throws_WhenNoValueRowsProvided() =>
+ Assert.Throws(() =>
+ new Query("rows").With("rows",
+ new[] { "a", "b", "c" },
+ new object[][] {
+ }));
+
+ [Fact]
+ public void AdHoc_Throws_WhenColumnsOutnumberFieldValues() =>
+ Assert.Throws(() =>
+ new Query("rows").With("rows",
+ new[] { "a", "b", "c", "d" },
+ new object[][] {
+ new object[] { 1, 2, 3 },
+ new object[] { 4, 5, 6 },
+ }));
+
+ [Fact]
+ public void AdHoc_Throws_WhenFieldValuesOutNumberColumns() =>
+ Assert.Throws(() =>
+ new Query("rows").With("rows",
+ new[] { "a", "b" },
+ new object[][] {
+ new object[] { 1, 2, 3 },
+ new object[] { 4, 5, 6 },
+ }));
+
+ [Fact]
+ public void AdHoc_SingletonRow() {
+ var query = new Query("rows").With("rows",
+ new[] { "a" },
+ new object[][] {
+ new object[] { 1 },
+ });
+
+ var c = Compilers.Compile(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());
+ }
+
+ [Fact]
+ public void AdHoc_TwoRows() {
+ var query = new Query("rows").With("rows",
+ new[] { "a", "b", "c" },
+ new object[][] {
+ new object[] { 1, 2, 3 },
+ new object[] { 4, 5, 6 },
+ });
+
+ var c = Compilers.Compile(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());
+ }
+
+ [Fact]
+ public void AdHoc_ProperBindingsPlacement() {
+ var query = new Query("rows")
+ .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 },
+ })
+ .Where("rows.baz", "buzz");
+
+ var c = Compilers.Compile(query);
+
+ 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());
+ }
+
+ [Fact]
+ public void UnsafeLiteral_Insert() {
+ var query = new Query("Table").AsInsert(new {
+ Count = new UnsafeLiteral("Count + 1")
+ });
+
+ var engines = new[] {
+ EngineCodes.SqlServer,
+ };
+
+ var c = Compilers.Compile(engines, query);
+
+ Assert.Equal("INSERT INTO [Table] ([Count]) VALUES (Count + 1)", c[EngineCodes.SqlServer].ToString());
+ }
+
+ [Fact]
+ public void UnsafeLiteral_Update() {
+ var query = new Query("Table").AsUpdate(new {
+ Count = new UnsafeLiteral("Count + 1")
+ });
+
+ var engines = new[] {
+ EngineCodes.SqlServer,
+ };
+
+ var c = Compilers.Compile(engines, query);
+
+ Assert.Equal("UPDATE [Table] SET [Count] = Count + 1", c[EngineCodes.SqlServer].ToString());
+ }
+
+ [Fact]
+ public void Passing_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse() {
+ var query = new Query("Table").Where("Col", true);
+
+ var engines = new[] {
+ EngineCodes.SqlServer,
+ };
+
+ var c = Compilers.Compile(engines, query);
+
+ Assert.Equal("SELECT * FROM [Table] WHERE [Col] = cast(1 as bit)", c[EngineCodes.SqlServer].ToString());
+ }
+
+ [Fact]
+ public void Passing_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse() {
+ var query = new Query("Table").Where("Col", false);
+
+ var engines = new[] {
+ EngineCodes.SqlServer,
+ };
+
+ var c = Compilers.Compile(engines, query);
+
+ Assert.Equal("SELECT * FROM [Table] WHERE [Col] = cast(0 as bit)", c[EngineCodes.SqlServer].ToString());
+ }
+
+ [Fact]
+ public void Passing_Negative_Boolean_To_Where_Should_Call_WhereTrue_Or_WhereFalse() {
+ var query = new Query("Table").Where("Col", "!=", true);
+
+ var engines = new[] {
+ EngineCodes.SqlServer,
+ };
+
+ var c = Compilers.Compile(engines, query);
+
+ Assert.Equal("SELECT * FROM [Table] WHERE [Col] != cast(1 as bit)", c[EngineCodes.SqlServer].ToString());
+ }
+
+ [Fact]
+ public void Passing_Negative_Boolean_False_To_Where_Should_Call_WhereTrue_Or_WhereFalse() {
+ var query = new Query("Table").Where("Col", "!=", false);
+
+ var engines = new[] {
+ EngineCodes.SqlServer,
+ };
+
+ var c = Compilers.Compile(engines, query);
+
+ Assert.Equal("SELECT * FROM [Table] WHERE [Col] != cast(0 as bit)", c[EngineCodes.SqlServer].ToString());
+ }
+}
diff --git a/QueryBuilder.Tests/HelperTests.cs b/QueryBuilder.Tests/HelperTests.cs
index ab80e2c5..d2d7acde 100644
--- a/QueryBuilder.Tests/HelperTests.cs
+++ b/QueryBuilder.Tests/HelperTests.cs
@@ -1,239 +1,221 @@
-using System.Collections;
-using System.Linq;
-using Xunit;
-
-namespace SqlKata.Tests
-{
- public class HelperTests
- {
- [Theory]
- [InlineData("")]
- [InlineData(null)]
- [InlineData(" ")]
- [InlineData(" ")]
- [InlineData(" ")]
- public void ItShouldKeepItAsIs(string input)
- {
- var output = Helper.ReplaceAll(input, "any", "\\", x => x + "");
-
- Assert.Equal(input, output);
- }
-
- [Theory]
- [InlineData("hello", "hello")]
- [InlineData("?hello", "@hello")]
- [InlineData("??hello", "@@hello")]
- [InlineData("?? hello", "@@ hello")]
- [InlineData("? ? hello", "@ @ hello")]
- [InlineData(" ? ? hello", " @ @ hello")]
- public void ReplaceOnTheBegining(string input, string expected)
- {
- var output = Helper.ReplaceAll(input, "?", "\\", x => "@");
- Assert.Equal(expected, output);
- }
-
- [Theory]
- [InlineData("hello?", "hello@")]
- [InlineData("hello? ", "hello@ ")]
- [InlineData("hello??? ", "hello@@@ ")]
- [InlineData("hello ? ?? ? ", "hello @ @@ @ ")]
- public void ReplaceOnTheEnd(string input, string expected)
- {
- var output = Helper.ReplaceAll(input, "?", "\\", x => "@");
- Assert.Equal(expected, output);
- }
-
- [Theory]
- [InlineData("hel\\?o ??? ", "hel\\?o 012 ")]
- [InlineData("hel\\?o ?? \\?", "hel\\?o 01 \\?")]
- [InlineData("hello?", "hello0")]
- [InlineData("hello? ", "hello0 ")]
- [InlineData("hello??? ", "hello012 ")]
- [InlineData("hel?lo ? ?? ? ", "hel0lo 1 23 4 ")]
- [InlineData("????", "0123")]
- public void ReplaceWithPositions(string input, string expected)
- {
- var output = Helper.ReplaceAll(input, "?", "\\", x => x + "");
- Assert.Equal(expected, output);
- }
-
- [Fact]
- public void AllIndexesOf_ReturnIndexes_IfValueIsContainedInAString()
- {
- // Given
- var input = "hello";
-
- // When
- var result = Helper.AllIndexesOf(input, "l");
-
- // Then
- Assert.Equal(new[] { 2, 3 }, result);
- }
-
- [Theory]
- [InlineData("")]
- [InlineData(null)]
- public void AllIndexesOf_ReturnEmptyCollection_IfValueIsEmptyOrNull(string value)
- {
- // Given
- var input = "hello";
-
- // When
- var result = Helper.AllIndexesOf(input, value);
-
- // Then
- Assert.Empty(result);
- }
-
- [Fact]
- public void AllIndexesOf_ReturnEmptyCollection_IfValueIsNotContainedInAString()
- {
- // Given
- var input = "hello";
-
- // When
- var result = Helper.AllIndexesOf(input, "F");
-
- // Then
- Assert.Empty(result);
- }
-
- [Fact]
- public void Flatten_ReturnFlatttenDeepCollectionRecursively_IfArrayIsNested()
- {
- // Given
- var objects = new object[]
- {
- 1,
- 0.1,
- 'A',
- new object[]
- {
- 'A',
- "B",
- new object[]
- {
- "C",
- 'D'
- }
- }
- };
-
- // When
- var flatten = Helper.FlattenDeep(objects);
-
- // Then
- Assert.Equal(new object[] { 1, 0.1, 'A', 'A', "B", "C", 'D' }, flatten);
- }
-
- [Fact]
- public void Flatten_FlatOneLevel()
- {
- // Given
- var objects = new object[]
- {
- 1,
- new object[]
- {
- 2,
- 3,
- new [] {4,5,6}
- }
- };
-
- // When
- var flatten = Helper.Flatten(objects);
-
- // Then
- Assert.Equal(new[] { 4, 5, 6 }, flatten.ElementAt(3));
- }
- [Fact]
- public void Flatten_ShouldRemoveEmptyCollections()
- {
- // Given
- var objects = new object[]
- {
- 1,
- new object[] {},
- new object[]
- {
- 2,
- 3,
- }
- };
-
- // When
- var flatten = Helper.Flatten(objects);
-
- // Then
- Assert.Equal(new object[] { 1, 2, 3 }, flatten);
- }
-
- [Fact]
- public void IsArray_ReturnFalse_IfValueIsNull()
- {
- // Given
- IEnumerable test = null;
-
- // When
- var isArray = Helper.IsArray(test);
-
- // Then
- Assert.False(isArray);
- }
-
- [Fact]
- public void IsArray_ReturnFalse_IfTypeOfValueIsString()
- {
- // Given
- var value = "string";
-
- // When
- var isArray = Helper.IsArray(value);
-
- // Then
- Assert.False(isArray);
- }
-
- [Fact]
- public void IsArray_ReturnTrue_IfValueIsExactlyIEnumerable()
- {
- // Given
- var value = new object[] { 1, 'B', "C" };
-
- // When
- var isArray = Helper.IsArray(value);
-
- // Then
- Assert.True(isArray);
- }
-
- [Theory]
- [InlineData("Users.Id", "Users.Id")]
- [InlineData("Users.{Id", "Users.{Id")]
- [InlineData("Users.{Id}", "Users.Id")]
- [InlineData("Users.{Id,Name}", "Users.Id, Users.Name")]
- [InlineData("Users.{Id,Name, Last_Name }", "Users.Id, Users.Name, Users.Last_Name")]
- public void ExpandExpression(string input, string expected)
- {
- Assert.Equal(expected, string.Join(", ", Helper.ExpandExpression(input)));
- }
-
- [Fact]
- public void ExpandParameters()
- {
- var expanded = Helper.ExpandParameters("where id = ? or id in (?) or id in (?)", "?", "\\", new object[] { 1, new[] { 1, 2 }, new object[] { } });
-
- Assert.Equal("where id = ? or id in (?,?) or id in ()", expanded);
- }
-
- [Theory]
- [InlineData(@"\{ text {", @"\", "{", "[", "{ text [")]
- [InlineData(@"{ text {", @"\", "{", "[", "[ text [")]
- public void WrapIdentifiers(string input, string escapeCharacter, string identifier, string newIdentifier, string expected)
- {
- var result = input.ReplaceIdentifierUnlessEscaped(escapeCharacter, identifier, newIdentifier);
- Assert.Equal(expected, result);
- }
- }
-}
+namespace SqlKata.Tests;
+
+using System.Collections;
+using System.Linq;
+using Xunit;
+
+public class HelperTests {
+ [Theory]
+ [InlineData("")]
+ [InlineData(null)]
+ [InlineData(" ")]
+ [InlineData(" ")]
+ [InlineData(" ")]
+ public void ItShouldKeepItAsIs(string input) {
+ var output = Helper.ReplaceAll(input, "any", "\\", x => x + "");
+
+ Assert.Equal(input, output);
+ }
+
+ [Theory]
+ [InlineData("hello", "hello")]
+ [InlineData("?hello", "@hello")]
+ [InlineData("??hello", "@@hello")]
+ [InlineData("?? hello", "@@ hello")]
+ [InlineData("? ? hello", "@ @ hello")]
+ [InlineData(" ? ? hello", " @ @ hello")]
+ public void ReplaceOnTheBegining(string input, string expected) {
+ var output = Helper.ReplaceAll(input, "?", "\\", x => "@");
+ Assert.Equal(expected, output);
+ }
+
+ [Theory]
+ [InlineData("hello?", "hello@")]
+ [InlineData("hello? ", "hello@ ")]
+ [InlineData("hello??? ", "hello@@@ ")]
+ [InlineData("hello ? ?? ? ", "hello @ @@ @ ")]
+ public void ReplaceOnTheEnd(string input, string expected) {
+ var output = Helper.ReplaceAll(input, "?", "\\", x => "@");
+ Assert.Equal(expected, output);
+ }
+
+ [Theory]
+ [InlineData("hel\\?o ??? ", "hel\\?o 012 ")]
+ [InlineData("hel\\?o ?? \\?", "hel\\?o 01 \\?")]
+ [InlineData("hello?", "hello0")]
+ [InlineData("hello? ", "hello0 ")]
+ [InlineData("hello??? ", "hello012 ")]
+ [InlineData("hel?lo ? ?? ? ", "hel0lo 1 23 4 ")]
+ [InlineData("????", "0123")]
+ public void ReplaceWithPositions(string input, string expected) {
+ var output = Helper.ReplaceAll(input, "?", "\\", x => x + "");
+ Assert.Equal(expected, output);
+ }
+
+ [Fact]
+ public void AllIndexesOf_ReturnIndexes_IfValueIsContainedInAString() {
+ // Given
+ var input = "hello";
+
+ // When
+ var result = Helper.AllIndexesOf(input, "l");
+
+ // Then
+ Assert.Equal(new[] { 2, 3 }, result);
+ }
+
+ [Theory]
+ [InlineData("")]
+ [InlineData(null)]
+ public void AllIndexesOf_ReturnEmptyCollection_IfValueIsEmptyOrNull(string value) {
+ // Given
+ var input = "hello";
+
+ // When
+ var result = Helper.AllIndexesOf(input, value);
+
+ // Then
+ Assert.Empty(result);
+ }
+
+ [Fact]
+ public void AllIndexesOf_ReturnEmptyCollection_IfValueIsNotContainedInAString() {
+ // Given
+ var input = "hello";
+
+ // When
+ var result = Helper.AllIndexesOf(input, "F");
+
+ // Then
+ Assert.Empty(result);
+ }
+
+ [Fact]
+ public void Flatten_ReturnFlatttenDeepCollectionRecursively_IfArrayIsNested() {
+ // Given
+ var objects = new object[]
+ {
+ 1,
+ 0.1,
+ 'A',
+ new object[]
+ {
+ 'A',
+ "B",
+ new object[]
+ {
+ "C",
+ 'D'
+ }
+ }
+ };
+
+ // When
+ var flatten = Helper.FlattenDeep(objects);
+
+ // Then
+ Assert.Equal(new object[] { 1, 0.1, 'A', 'A', "B", "C", 'D' }, flatten);
+ }
+
+ [Fact]
+ public void Flatten_FlatOneLevel() {
+ // Given
+ var objects = new object[]
+ {
+ 1,
+ new object[]
+ {
+ 2,
+ 3,
+ new [] {4,5,6}
+ }
+ };
+
+ // When
+ var flatten = Helper.Flatten(objects);
+
+ // Then
+ Assert.Equal(new[] { 4, 5, 6 }, flatten.ElementAt(3));
+ }
+ [Fact]
+ public void Flatten_ShouldRemoveEmptyCollections() {
+ // Given
+ var objects = new object[]
+ {
+ 1,
+ new object[] {},
+ new object[]
+ {
+ 2,
+ 3,
+ }
+ };
+
+ // When
+ var flatten = Helper.Flatten(objects);
+
+ // Then
+ Assert.Equal(new object[] { 1, 2, 3 }, flatten);
+ }
+
+ [Fact]
+ public void IsArray_ReturnFalse_IfValueIsNull() {
+ // Given
+ IEnumerable test = null;
+
+ // When
+ var isArray = Helper.IsArray(test);
+
+ // Then
+ Assert.False(isArray);
+ }
+
+ [Fact]
+ public void IsArray_ReturnFalse_IfTypeOfValueIsString() {
+ // Given
+ var value = "string";
+
+ // When
+ var isArray = Helper.IsArray(value);
+
+ // Then
+ Assert.False(isArray);
+ }
+
+ [Fact]
+ public void IsArray_ReturnTrue_IfValueIsExactlyIEnumerable() {
+ // Given
+ var value = new object[] { 1, 'B', "C" };
+
+ // When
+ var isArray = Helper.IsArray(value);
+
+ // Then
+ Assert.True(isArray);
+ }
+
+ [Theory]
+ [InlineData("Users.Id", "Users.Id")]
+ [InlineData("Users.{Id", "Users.{Id")]
+ [InlineData("Users.{Id}", "Users.Id")]
+ [InlineData("Users.{Id,Name}", "Users.Id, Users.Name")]
+ [InlineData("Users.{Id,Name, Last_Name }", "Users.Id, Users.Name, Users.Last_Name")]
+ public void ExpandExpression(string input, string expected) {
+ Assert.Equal(expected, string.Join(", ", Helper.ExpandExpression(input)));
+ }
+
+ [Fact]
+ public void ExpandParameters() {
+ var expanded = Helper.ExpandParameters("where id = ? or id in (?) or id in (?)", "?", "\\", new object[] { 1, new[] { 1, 2 }, new object[] { } });
+
+ Assert.Equal("where id = ? or id in (?,?) or id in ()", expanded);
+ }
+
+ [Theory]
+ [InlineData(@"\{ text {", @"\", "{", "[", "{ text [")]
+ [InlineData(@"{ text {", @"\", "{", "[", "[ text [")]
+ public void WrapIdentifiers(string input, string escapeCharacter, string identifier, string newIdentifier, string expected) {
+ var result = input.ReplaceIdentifierUnlessEscaped(escapeCharacter, identifier, newIdentifier);
+ Assert.Equal(expected, result);
+ }
+}
diff --git a/QueryBuilder.Tests/Infrastructure/TestCompiler.cs b/QueryBuilder.Tests/Infrastructure/TestCompiler.cs
index aded9fd1..8a3f1509 100644
--- a/QueryBuilder.Tests/Infrastructure/TestCompiler.cs
+++ b/QueryBuilder.Tests/Infrastructure/TestCompiler.cs
@@ -1,58 +1,46 @@
-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; } = "";
- }
-}
-
+namespace SqlKata.Tests.Infrastructure;
+
+using System;
+using System.Reflection;
+using SqlKata.Compilers;
+
+///
+/// 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/TestCompilersContainer.cs b/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs
index 2312a192..0750f5c4 100644
--- a/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs
+++ b/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs
@@ -1,109 +1,96 @@
-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.ContainsKey(engineCode))
- {
- throw new InvalidOperationException(string.Format(Messages.ERR_INVALID_ENGINECODE, engineCode));
- }
-
- return Compilers[engineCode];
- }
-
- ///
- /// 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);
- }
- }
-}
+namespace SqlKata.Tests.Infrastructure;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using SqlKata.Compilers;
+
+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.ContainsKey(engineCode)) {
+ throw new InvalidOperationException(string.Format(Messages.ERR_INVALID_ENGINECODE, engineCode));
+ }
+
+ return Compilers[engineCode];
+ }
+
+ ///
+ /// 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
index 16a5eeff..989a3f7e 100644
--- a/QueryBuilder.Tests/Infrastructure/TestSqlResultContainer.cs
+++ b/QueryBuilder.Tests/Infrastructure/TestSqlResultContainer.cs
@@ -1,13 +1,10 @@
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-
-namespace SqlKata.Tests.Infrastructure
-{
- public class TestSqlResultContainer : ReadOnlyDictionary
- {
- public TestSqlResultContainer(IDictionary dictionary) : base(dictionary)
- {
-
- }
- }
-}
+namespace SqlKata.Tests.Infrastructure;
+
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+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 78d912cc..51820911 100644
--- a/QueryBuilder.Tests/Infrastructure/TestSupport.cs
+++ b/QueryBuilder.Tests/Infrastructure/TestSupport.cs
@@ -1,20 +1,17 @@
-using System.Collections.Generic;
-using System.Linq;
-
-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());
- }
- }
-}
+namespace SqlKata.Tests.Infrastructure;
+
+using System.Collections.Generic;
+using System.Linq;
+
+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());
+ }
+}
diff --git a/QueryBuilder.Tests/InfrastructureTests.cs b/QueryBuilder.Tests/InfrastructureTests.cs
index 5bb7f2df..9223f51a 100644
--- a/QueryBuilder.Tests/InfrastructureTests.cs
+++ b/QueryBuilder.Tests/InfrastructureTests.cs
@@ -1,54 +1,47 @@
-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()));
- }
- }
-}
+namespace SqlKata.Tests;
+
+using System;
+using System.Linq;
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+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 926e18b2..0156a423 100644
--- a/QueryBuilder.Tests/InsertTests.cs
+++ b/QueryBuilder.Tests/InsertTests.cs
@@ -1,308 +1,287 @@
-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
-{
- public class InsertTests : TestSupport
- {
- private class Account
- {
- public Account(string name, string currency = null, string created_at = null, string color = null)
- {
- this.name = name ?? throw new ArgumentNullException(nameof(name));
- this.Currency = currency;
- this.color = color;
- }
-
- public string name { get; set; }
-
- [Column("currency_id")]
- public string Currency { get; set; }
-
- [Ignore]
- public string color { get; set; }
- }
-
- [Fact]
- public void InsertObject()
- {
- var query = new Query("Table")
- .AsInsert(
- new
- {
- Name = "The User",
- 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]);
-
- Assert.Equal(
- "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
- c[EngineCodes.Firebird]);
- }
-
- [Fact]
- public void InsertFromSubQueryWithCte()
- {
- var query = new Query("expensive_cars")
- .With("old_cards", new Query("all_cars").Where("year", "<", 2000))
- .AsInsert(
- 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]);
-
- 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]);
- }
-
- [Fact]
- public void InsertMultiRecords()
- {
- var query = new Query("expensive_cars")
- .AsInsert(
- new[] { "name", "brand", "year" },
- new[]
- {
- new object[] { "Chiron", "Bugatti", null },
- new object[] { "Huayra", "Pagani", 2012 },
- 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]);
-
- 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]);
- }
-
- [Fact]
- public void InsertWithNullValues()
- {
- 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]);
-
-
- Assert.Equal(
- "INSERT INTO \"BOOKS\" (\"ID\", \"AUTHOR\", \"ISBN\", \"DATE\") VALUES (1, 'Author 1', '123456', NULL)",
- c[EngineCodes.Firebird]);
- }
-
- [Fact]
- public void InsertWithEmptyString()
- {
- 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]);
-
-
- Assert.Equal(
- "INSERT INTO \"BOOKS\" (\"ID\", \"AUTHOR\", \"ISBN\", \"DESCRIPTION\") VALUES (1, 'Author 1', '123456', '')",
- c[EngineCodes.Firebird]);
- }
-
- [Fact]
- public void InsertWithByteArray()
- {
- var fauxImagebytes = new byte[] { 0x1, 0x3, 0x3, 0x7 };
- var query = new Query("Books")
- .AsInsert(
- new[] { "Id", "CoverImageBytes" },
- new object[]
- {
- 1,
- fauxImagebytes
- });
-
- var c = Compilers.Compile(query);
- Assert.All(c.Values, a => Assert.Equal(2, a.NamedBindings.Count));
-
- var exemplar = c[EngineCodes.SqlServer];
-
- Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (?, ?)", exemplar.RawSql);
- Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (@p0, @p1)", exemplar.Sql);
- }
-
- [Fact]
- public void InsertWithIgnoreAndColumnProperties()
- {
- 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]);
-
- Assert.Equal(
- "INSERT INTO \"ACCOUNT\" (\"NAME\", \"CURRENCY_ID\") VALUES ('popular', 'US')",
- c[EngineCodes.Firebird]);
- }
-
- [Fact]
- public void InsertFromRaw()
- {
- var query = new Query()
- .FromRaw("Table.With.Dots")
- .AsInsert(
- new
- {
- Name = "The User",
- Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc),
- });
-
- var c = Compile(query);
-
- Assert.Equal(
- "INSERT INTO Table.With.Dots ([Name], [Age]) VALUES ('The User', '2018-01-01')",
- c[EngineCodes.SqlServer]);
- }
-
- [Fact]
- public void InsertFromQueryShouldFail()
- {
- var query = new Query()
- .From(new Query("InnerTable"))
- .AsInsert(
- new
- {
- Name = "The User",
- Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc),
- });
-
- Assert.Throws(() =>
- {
- Compile(query);
- });
- }
-
- [Fact]
- public void InsertKeyValuePairs()
- {
- var dictionaryUser = new Dictionary
- {
- { "Name", "The User" },
- { "Age", new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc) },
- }
- .ToArray();
-
- 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]);
-
- Assert.Equal(
- "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
- c[EngineCodes.Firebird]);
- }
-
- [Fact]
- public void InsertDictionary()
- {
- var dictionaryUser = new Dictionary {
- { "Name", "The User" },
- { "Age", new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc) },
- };
-
- 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]);
-
- Assert.Equal(
- "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
- c[EngineCodes.Firebird]);
- }
-
- [Fact]
- public void InsertReadOnlyDictionary()
- {
- 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")
- .AsInsert(dictionaryUser);
-
- var c = Compile(query);
-
- Assert.Equal(
- "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')",
- c[EngineCodes.SqlServer]);
-
- Assert.Equal(
- "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
- c[EngineCodes.Firebird]);
- }
-
- [Fact]
- public void InsertExpandoObject()
- {
- dynamic expandoUser = new ExpandoObject();
- expandoUser.Name = "The User";
- expandoUser.Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-
- 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]);
-
- Assert.Equal(
- "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
- c[EngineCodes.Firebird]);
- }
- }
-}
+namespace SqlKata.Tests;
+
+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;
+
+public class InsertTests : TestSupport {
+ private class Account {
+ public Account(string name, string currency = null, string created_at = null, string color = null) {
+ this.name = name ?? throw new ArgumentNullException(nameof(name));
+ this.Currency = currency;
+ this.color = color;
+ }
+
+ public string name { get; set; }
+
+ [Column("currency_id")]
+ public string Currency { get; set; }
+
+ [Ignore]
+ public string color { get; set; }
+ }
+
+ [Fact]
+ public void InsertObject() {
+ var query = new Query("Table")
+ .AsInsert(
+ new {
+ Name = "The User",
+ 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]);
+
+ Assert.Equal(
+ "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
+ c[EngineCodes.Firebird]);
+ }
+
+ [Fact]
+ public void InsertFromSubQueryWithCte() {
+ var query = new Query("expensive_cars")
+ .With("old_cards", new Query("all_cars").Where("year", "<", 2000))
+ .AsInsert(
+ 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]);
+
+ 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]);
+ }
+
+ [Fact]
+ public void InsertMultiRecords() {
+ var query = new Query("expensive_cars")
+ .AsInsert(
+ new[] { "name", "brand", "year" },
+ new[]
+ {
+ new object[] { "Chiron", "Bugatti", null },
+ new object[] { "Huayra", "Pagani", 2012 },
+ 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]);
+
+ 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]);
+ }
+
+ [Fact]
+ public void InsertWithNullValues() {
+ 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]);
+
+
+ Assert.Equal(
+ "INSERT INTO \"BOOKS\" (\"ID\", \"AUTHOR\", \"ISBN\", \"DATE\") VALUES (1, 'Author 1', '123456', NULL)",
+ c[EngineCodes.Firebird]);
+ }
+
+ [Fact]
+ public void InsertWithEmptyString() {
+ 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]);
+
+
+ Assert.Equal(
+ "INSERT INTO \"BOOKS\" (\"ID\", \"AUTHOR\", \"ISBN\", \"DESCRIPTION\") VALUES (1, 'Author 1', '123456', '')",
+ c[EngineCodes.Firebird]);
+ }
+
+ [Fact]
+ public void InsertWithByteArray() {
+ var fauxImagebytes = new byte[] { 0x1, 0x3, 0x3, 0x7 };
+ var query = new Query("Books")
+ .AsInsert(
+ new[] { "Id", "CoverImageBytes" },
+ new object[]
+ {
+ 1,
+ fauxImagebytes
+ });
+
+ var c = Compilers.Compile(query);
+ Assert.All(c.Values, a => Assert.Equal(2, a.NamedBindings.Count));
+
+ var exemplar = c[EngineCodes.SqlServer];
+
+ Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (?, ?)", exemplar.RawSql);
+ Assert.Equal("INSERT INTO [Books] ([Id], [CoverImageBytes]) VALUES (@p0, @p1)", exemplar.Sql);
+ }
+
+ [Fact]
+ public void InsertWithIgnoreAndColumnProperties() {
+ 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]);
+
+ Assert.Equal(
+ "INSERT INTO \"ACCOUNT\" (\"NAME\", \"CURRENCY_ID\") VALUES ('popular', 'US')",
+ c[EngineCodes.Firebird]);
+ }
+
+ [Fact]
+ public void InsertFromRaw() {
+ var query = new Query()
+ .FromRaw("Table.With.Dots")
+ .AsInsert(
+ new {
+ Name = "The User",
+ Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc),
+ });
+
+ var c = Compile(query);
+
+ Assert.Equal(
+ "INSERT INTO Table.With.Dots ([Name], [Age]) VALUES ('The User', '2018-01-01')",
+ c[EngineCodes.SqlServer]);
+ }
+
+ [Fact]
+ public void InsertFromQueryShouldFail() {
+ var query = new Query()
+ .From(new Query("InnerTable"))
+ .AsInsert(
+ new {
+ Name = "The User",
+ Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc),
+ });
+
+ Assert.Throws(() => {
+ Compile(query);
+ });
+ }
+
+ [Fact]
+ public void InsertKeyValuePairs() {
+ var dictionaryUser = new Dictionary
+ {
+ { "Name", "The User" },
+ { "Age", new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc) },
+ }
+ .ToArray();
+
+ 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]);
+
+ Assert.Equal(
+ "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
+ c[EngineCodes.Firebird]);
+ }
+
+ [Fact]
+ public void InsertDictionary() {
+ var dictionaryUser = new Dictionary {
+ { "Name", "The User" },
+ { "Age", new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc) },
+ };
+
+ 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]);
+
+ Assert.Equal(
+ "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
+ c[EngineCodes.Firebird]);
+ }
+
+ [Fact]
+ public void InsertReadOnlyDictionary() {
+ 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")
+ .AsInsert(dictionaryUser);
+
+ var c = Compile(query);
+
+ Assert.Equal(
+ "INSERT INTO [Table] ([Name], [Age]) VALUES ('The User', '2018-01-01')",
+ c[EngineCodes.SqlServer]);
+
+ Assert.Equal(
+ "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
+ c[EngineCodes.Firebird]);
+ }
+
+ [Fact]
+ public void InsertExpandoObject() {
+ dynamic expandoUser = new ExpandoObject();
+ expandoUser.Name = "The User";
+ expandoUser.Age = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+ 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]);
+
+ Assert.Equal(
+ "INSERT INTO \"TABLE\" (\"NAME\", \"AGE\") VALUES ('The User', '2018-01-01')",
+ c[EngineCodes.Firebird]);
+ }
+}
diff --git a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs
index 3e22c19a..3abfadc2 100644
--- a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs
+++ b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs
@@ -1,58 +1,51 @@
-using SqlKata.Compilers;
-using SqlKata.Tests.Infrastructure;
-using Xunit;
-
-namespace SqlKata.Tests.MySql
-{
- public class MySqlLimitTests : TestSupport
- {
- private readonly MySqlCompiler compiler;
-
- public MySqlLimitTests()
- {
- compiler = Compilers.Get(EngineCodes.MySql);
- }
-
- [Fact]
- public void WithNoLimitNorOffset()
- {
- var query = new Query("Table");
- var ctx = new SqlResult("?", "\\") {Query = query};
-
- Assert.Null(compiler.CompileLimit(ctx));
- }
-
- [Fact]
- public void WithNoOffset()
- {
- var query = new Query("Table").Limit(10);
- var ctx = new SqlResult("?", "\\") {Query = query};
-
- Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx));
- Assert.Equal(10, ctx.Bindings[0]);
- }
-
- [Fact]
- public void WithNoLimit()
- {
- var query = new Query("Table").Offset(20);
- var ctx = new SqlResult("?", "\\") {Query = query};
-
- Assert.Equal("LIMIT 18446744073709551615 OFFSET ?", compiler.CompileLimit(ctx));
- Assert.Equal(20L, ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- 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));
- Assert.Equal(5, ctx.Bindings[0]);
- Assert.Equal(20L, ctx.Bindings[1]);
- Assert.Equal(2, ctx.Bindings.Count);
- }
- }
-}
+namespace SqlKata.Tests.MySql;
+
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+public class MySqlLimitTests : TestSupport {
+ private readonly MySqlCompiler compiler;
+
+ public MySqlLimitTests() {
+ compiler = Compilers.Get(EngineCodes.MySql);
+ }
+
+ [Fact]
+ public void WithNoLimitNorOffset() {
+ var query = new Query("Table");
+ var ctx = new SqlResult("?", "\\") { Query = query };
+
+ Assert.Null(compiler.CompileLimit(ctx));
+ }
+
+ [Fact]
+ public void WithNoOffset() {
+ var query = new Query("Table").Limit(10);
+ var ctx = new SqlResult("?", "\\") { Query = query };
+
+ Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx));
+ Assert.Equal(10, ctx.Bindings[0]);
+ }
+
+ [Fact]
+ public void WithNoLimit() {
+ var query = new Query("Table").Offset(20);
+ var ctx = new SqlResult("?", "\\") { Query = query };
+
+ Assert.Equal("LIMIT 18446744073709551615 OFFSET ?", compiler.CompileLimit(ctx));
+ Assert.Equal(20L, ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ 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));
+ Assert.Equal(5, ctx.Bindings[0]);
+ Assert.Equal(20L, ctx.Bindings[1]);
+ Assert.Equal(2, ctx.Bindings.Count);
+ }
+}
diff --git a/QueryBuilder.Tests/MySqlExecutionTest.cs b/QueryBuilder.Tests/MySqlExecutionTest.cs
index 259dcccf..8aecf8a7 100644
--- a/QueryBuilder.Tests/MySqlExecutionTest.cs
+++ b/QueryBuilder.Tests/MySqlExecutionTest.cs
@@ -1,270 +1,250 @@
-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;
-
-namespace SqlKata.Tests
-{
- public class MySqlExecutionTest
- {
- [Fact]
- public void EmptySelect()
- {
-
- var db = DB().Create("Cars", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Brand TEXT NOT NULL",
- "Year INT NOT NULL",
- "Color TEXT NULL",
- });
-
- var rows = db.Query("Cars").Get();
-
- Assert.Empty(rows);
-
- db.Drop("Cars");
- }
-
- [Fact]
- public void SelectWithLimit()
- {
- var db = DB().Create("Cars", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Brand TEXT NOT NULL",
- "Year INT NOT NULL",
- "Color TEXT NULL",
- });
-
- db.Statement("INSERT INTO `Cars`(Brand, Year) VALUES ('Honda', 2020)");
-
- var rows = db.Query("Cars").Get().ToList();
-
- Assert.Single(rows);
-
- db.Drop("Cars");
- }
-
- [Fact]
- public void Count()
- {
- var db = DB().Create("Cars", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Brand TEXT NOT NULL",
- "Year INT NOT NULL",
- "Color TEXT NULL",
- });
-
- db.Statement("INSERT INTO `Cars`(Brand, Year) VALUES ('Honda', 2020)");
- var count = db.Query("Cars").Count();
- Assert.Equal(1, count);
-
- db.Statement("INSERT INTO `Cars`(Brand, Year) VALUES ('Toyota', 2021)");
- count = db.Query("Cars").Count();
- Assert.Equal(2, count);
-
- int affected = db.Query("Cars").Delete();
- Assert.Equal(2, affected);
-
- count = db.Query("Cars").Count();
- Assert.Equal(0, count);
-
- db.Drop("Cars");
- }
-
- [Fact]
- public void CloneThenCount()
- {
- var db = DB().Create("Cars", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Brand TEXT NOT NULL",
- "Year INT NOT NULL",
- "Color TEXT NULL",
- });
-
- for (int i = 0; i < 10; i++)
- {
- db.Query("Cars").Insert(new
- {
- Brand = "Brand " + i,
- Year = "2020",
- });
- }
-
- var query = db.Query("Cars").Where("Id", "<", 5);
- var count = query.Count();
- var cloneCount = query.Clone().Count();
-
- Assert.Equal(4, count);
- Assert.Equal(4, cloneCount);
-
- db.Drop("Cars");
- }
-
- [Fact]
- public void QueryWithVariable()
- {
- var db = DB().Create("Cars", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Brand TEXT NOT NULL",
- "Year INT NOT NULL",
- "Color TEXT NULL",
- });
-
- for (int i = 0; i < 10; i++)
- {
- db.Query("Cars").Insert(new
- {
- Brand = "Brand " + i,
- Year = "2020",
- });
- }
-
-
- var count = db.Query("Cars")
- .Define("Threshold", 5)
- .Where("Id", "<", SqlKata.Expressions.Variable("Threshold"))
- .Count();
-
- Assert.Equal(4, count);
-
- db.Drop("Cars");
- }
-
- [Fact]
- public void InlineTable()
- {
- var db = DB().Create("Transaction", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Amount int NOT NULL",
- "Date DATE NOT NULL",
- });
-
- db.Query("Transaction").Insert(new
- {
- Date = "2022-01-01",
- Amount = 10
- });
-
-
- var rows = db.Query("Transaction")
- .With("Rates", new[] { "Date", "Rate" }, new object[][] {
- new object[] {"2022-01-01", 0.5},
- })
- .Join("Rates", "Rates.Date", "Transaction.Date")
- .SelectRaw("Transaction.Amount * Rates.Rate as AmountConverted")
- .Get();
-
- Assert.Single(rows);
- Assert.Equal(5, rows.First().AmountConverted);
-
- db.Drop("Transaction");
- }
-
- [Fact]
- public void ExistsShouldReturnFalseForEmptyTable()
- {
- var db = DB().Create("Transaction", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Amount int NOT NULL",
- "Date DATE NOT NULL",
- });
-
- var exists = db.Query("Transaction").Exists();
- Assert.False(exists);
-
- db.Drop("Transaction");
- }
-
- [Fact]
- public void ExistsShouldReturnTrueForNonEmptyTable()
- {
- var db = DB().Create("Transaction", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Amount int NOT NULL",
- "Date DATE NOT NULL",
- });
-
- db.Query("Transaction").Insert(new
- {
- Date = "2022-01-01",
- Amount = 10
- });
-
- var exists = db.Query("Transaction").Exists();
- Assert.True(exists);
-
- db.Drop("Transaction");
- }
-
- [Fact]
- public void BasicSelectFilter()
- {
- var db = DB().Create("Transaction", new[] {
- "Id INT PRIMARY KEY AUTO_INCREMENT",
- "Date DATE NOT NULL",
- "Amount int NOT NULL",
- });
-
- var data = new Dictionary {
- // 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},
- {"2022-05-01", 50},
- };
-
- foreach (var row in data)
- {
- db.Query("Transaction").Insert(new
- {
- Date = row.Key,
- Amount = row.Value
- });
- }
-
- var query = db.Query("Transaction")
- .SelectSum("Amount as Total_2020", q => q.WhereDatePart("year", "date", 2020))
- .SelectSum("Amount as Total_2021", q => q.WhereDatePart("year", "date", 2021))
- .SelectSum("Amount as Total_2022", q => q.WhereDatePart("year", "date", 2022))
- ;
-
- var results = query.Get().ToList();
- Assert.Single(results);
- Assert.Equal(30, results[0].Total_2020);
- Assert.Equal(40, results[0].Total_2021);
- Assert.Equal(100, results[0].Total_2022);
-
- db.Drop("Transaction");
- }
-
- QueryFactory DB()
- {
- var host = Environment.GetEnvironmentVariable("SQLKATA_MYSQL_HOST");
- var user = Environment.GetEnvironmentVariable("SQLKATA_MYSQL_USER");
- var dbName = Environment.GetEnvironmentVariable("SQLKATA_MYSQL_DB");
- var dbPass = Environment.GetEnvironmentVariable("SQLKATA_MYSQL_PASSWORD");
- var cs = $"Server={host};User={user};Database={dbName};Password={dbPass}";
-
- var connection = new MySqlConnection(cs);
-
- var db = new QueryFactory(connection, new MySqlCompiler());
-
- return db;
- }
-
-
-
- }
-}
+namespace SqlKata.Tests;
+
+using SqlKata.Compilers;
+using Xunit;
+using SqlKata.Execution;
+using global::MySql.Data.MySqlClient;
+using System;
+using System.Linq;
+using static SqlKata.Expressions;
+using System.Collections.Generic;
+
+public class MySqlExecutionTest {
+ [Fact]
+ public void EmptySelect() {
+
+ var db = DB().Create("Cars", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Brand TEXT NOT NULL",
+ "Year INT NOT NULL",
+ "Color TEXT NULL",
+ });
+
+ var rows = db.Query("Cars").Get();
+
+ Assert.Empty(rows);
+
+ db.Drop("Cars");
+ }
+
+ [Fact]
+ public void SelectWithLimit() {
+ var db = DB().Create("Cars", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Brand TEXT NOT NULL",
+ "Year INT NOT NULL",
+ "Color TEXT NULL",
+ });
+
+ db.Statement("INSERT INTO `Cars`(Brand, Year) VALUES ('Honda', 2020)");
+
+ var rows = db.Query("Cars").Get().ToList();
+
+ Assert.Single(rows);
+
+ db.Drop("Cars");
+ }
+
+ [Fact]
+ public void Count() {
+ var db = DB().Create("Cars", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Brand TEXT NOT NULL",
+ "Year INT NOT NULL",
+ "Color TEXT NULL",
+ });
+
+ db.Statement("INSERT INTO `Cars`(Brand, Year) VALUES ('Honda', 2020)");
+ var count = db.Query("Cars").Count();
+ Assert.Equal(1, count);
+
+ db.Statement("INSERT INTO `Cars`(Brand, Year) VALUES ('Toyota', 2021)");
+ count = db.Query("Cars").Count();
+ Assert.Equal(2, count);
+
+ int affected = db.Query("Cars").Delete();
+ Assert.Equal(2, affected);
+
+ count = db.Query("Cars").Count();
+ Assert.Equal(0, count);
+
+ db.Drop("Cars");
+ }
+
+ [Fact]
+ public void CloneThenCount() {
+ var db = DB().Create("Cars", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Brand TEXT NOT NULL",
+ "Year INT NOT NULL",
+ "Color TEXT NULL",
+ });
+
+ for (int i = 0; i < 10; i++) {
+ db.Query("Cars").Insert(new {
+ Brand = "Brand " + i,
+ Year = "2020",
+ });
+ }
+
+ var query = db.Query("Cars").Where("Id", "<", 5);
+ var count = query.Count();
+ var cloneCount = query.Clone().Count();
+
+ Assert.Equal(4, count);
+ Assert.Equal(4, cloneCount);
+
+ db.Drop("Cars");
+ }
+
+ [Fact]
+ public void QueryWithVariable() {
+ var db = DB().Create("Cars", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Brand TEXT NOT NULL",
+ "Year INT NOT NULL",
+ "Color TEXT NULL",
+ });
+
+ for (int i = 0; i < 10; i++) {
+ db.Query("Cars").Insert(new {
+ Brand = "Brand " + i,
+ Year = "2020",
+ });
+ }
+
+
+ var count = db.Query("Cars")
+ .Define("Threshold", 5)
+ .Where("Id", "<", SqlKata.Expressions.Variable("Threshold"))
+ .Count();
+
+ Assert.Equal(4, count);
+
+ db.Drop("Cars");
+ }
+
+ [Fact]
+ public void InlineTable() {
+ var db = DB().Create("Transaction", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Amount int NOT NULL",
+ "Date DATE NOT NULL",
+ });
+
+ db.Query("Transaction").Insert(new {
+ Date = "2022-01-01",
+ Amount = 10
+ });
+
+
+ var rows = db.Query("Transaction")
+ .With("Rates", new[] { "Date", "Rate" }, new object[][] {
+ new object[] {"2022-01-01", 0.5},
+ })
+ .Join("Rates", "Rates.Date", "Transaction.Date")
+ .SelectRaw("Transaction.Amount * Rates.Rate as AmountConverted")
+ .Get();
+
+ Assert.Single(rows);
+ Assert.Equal(5, rows.First().AmountConverted);
+
+ db.Drop("Transaction");
+ }
+
+ [Fact]
+ public void ExistsShouldReturnFalseForEmptyTable() {
+ var db = DB().Create("Transaction", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Amount int NOT NULL",
+ "Date DATE NOT NULL",
+ });
+
+ var exists = db.Query("Transaction").Exists();
+ Assert.False(exists);
+
+ db.Drop("Transaction");
+ }
+
+ [Fact]
+ public void ExistsShouldReturnTrueForNonEmptyTable() {
+ var db = DB().Create("Transaction", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Amount int NOT NULL",
+ "Date DATE NOT NULL",
+ });
+
+ db.Query("Transaction").Insert(new {
+ Date = "2022-01-01",
+ Amount = 10
+ });
+
+ var exists = db.Query("Transaction").Exists();
+ Assert.True(exists);
+
+ db.Drop("Transaction");
+ }
+
+ [Fact]
+ public void BasicSelectFilter() {
+ var db = DB().Create("Transaction", new[] {
+ "Id INT PRIMARY KEY AUTO_INCREMENT",
+ "Date DATE NOT NULL",
+ "Amount int NOT NULL",
+ });
+
+ var data = new Dictionary {
+ // 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},
+ {"2022-05-01", 50},
+ };
+
+ foreach (var row in data) {
+ db.Query("Transaction").Insert(new {
+ Date = row.Key,
+ Amount = row.Value
+ });
+ }
+
+ var query = db.Query("Transaction")
+ .SelectSum("Amount as Total_2020", q => q.WhereDatePart("year", "date", 2020))
+ .SelectSum("Amount as Total_2021", q => q.WhereDatePart("year", "date", 2021))
+ .SelectSum("Amount as Total_2022", q => q.WhereDatePart("year", "date", 2022))
+ ;
+
+ var results = query.Get().ToList();
+ Assert.Single(results);
+ Assert.Equal(30, results[0].Total_2020);
+ Assert.Equal(40, results[0].Total_2021);
+ Assert.Equal(100, results[0].Total_2022);
+
+ db.Drop("Transaction");
+ }
+
+ QueryFactory DB() {
+ var host = Environment.GetEnvironmentVariable("SQLKATA_MYSQL_HOST");
+ var user = Environment.GetEnvironmentVariable("SQLKATA_MYSQL_USER");
+ var dbName = Environment.GetEnvironmentVariable("SQLKATA_MYSQL_DB");
+ var dbPass = Environment.GetEnvironmentVariable("SQLKATA_MYSQL_PASSWORD");
+ var cs = $"Server={host};User={user};Database={dbName};Password={dbPass}";
+
+ var connection = new MySqlConnection(cs);
+
+ var db = new QueryFactory(connection, new MySqlCompiler());
+
+ return db;
+ }
+
+
+
+}
diff --git a/QueryBuilder.Tests/OperatorWhitelistTests.cs b/QueryBuilder.Tests/OperatorWhitelistTests.cs
index 55c3aafc..6dc653dc 100644
--- a/QueryBuilder.Tests/OperatorWhitelistTests.cs
+++ b/QueryBuilder.Tests/OperatorWhitelistTests.cs
@@ -1,139 +1,127 @@
-using System;
-using SqlKata.Compilers;
-using Xunit;
-
-namespace SqlKata.Tests
-{
- public class OperatorWhitelistTests
- {
-
- public OperatorWhitelistTests()
- {
-
- }
-
- [Theory]
- [InlineData("!!")]
- [InlineData("~!")]
- [InlineData("*=")]
- public void DenyInvalidOperatorsInWhere(string op)
- {
- var compiler = new SqlServerCompiler();
-
- 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"));
- });
- }
-
- [Theory]
- [InlineData("!!")]
- [InlineData("~!")]
- [InlineData("*=")]
- public void DenyInvalidOperatorsInHaving(string op)
- {
- var compiler = new SqlServerCompiler();
-
- 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"));
- });
- }
-
-
- [Theory]
- [InlineData("=")]
- [InlineData("!=")]
- [InlineData("ilike")]
- 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);
-
- new Query("Table").WhereColumns("Col1", op, "Col2");
- new Query("Table").OrWhereColumns("Col1", op, "Col2");
- }
-
- [Theory]
- [InlineData("=")]
- [InlineData("!=")]
- [InlineData("ilike")]
- 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);
-
- new Query("Table").HavingColumns("Col1", op, "Col2");
- new Query("Table").OrHavingColumns("Col1", op, "Col2");
- }
-
- [Theory]
- [InlineData("^")]
- [InlineData("<<")]
- [InlineData(">>")]
- [InlineData("~")]
- [InlineData("~*")]
- [InlineData("!~")]
- [InlineData("!~*")]
- public void ShouldNotThrowAfterWhiteListing(string op)
- {
- var compiler = new SqlServerCompiler().Whitelist(op);
-
- var query = new Query("Table");
-
- 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));
-
- 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);
- }
-
- [Fact]
- public void ShouldNotConsiderWhereRawCondition()
- {
- var compiler = new SqlServerCompiler();
-
- var query = new Query("Table")
- .WhereRaw("Col !! value");
-
- }
-
- }
-}
+namespace SqlKata.Tests;
+
+using System;
+using SqlKata.Compilers;
+using Xunit;
+
+public class OperatorWhitelistTests {
+
+ public OperatorWhitelistTests() {
+
+ }
+
+ [Theory]
+ [InlineData("!!")]
+ [InlineData("~!")]
+ [InlineData("*=")]
+ public void DenyInvalidOperatorsInWhere(string op) {
+ var compiler = new SqlServerCompiler();
+
+ 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"));
+ });
+ }
+
+ [Theory]
+ [InlineData("!!")]
+ [InlineData("~!")]
+ [InlineData("*=")]
+ public void DenyInvalidOperatorsInHaving(string op) {
+ var compiler = new SqlServerCompiler();
+
+ 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"));
+ });
+ }
+
+
+ [Theory]
+ [InlineData("=")]
+ [InlineData("!=")]
+ [InlineData("ilike")]
+ 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);
+
+ new Query("Table").WhereColumns("Col1", op, "Col2");
+ new Query("Table").OrWhereColumns("Col1", op, "Col2");
+ }
+
+ [Theory]
+ [InlineData("=")]
+ [InlineData("!=")]
+ [InlineData("ilike")]
+ 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);
+
+ new Query("Table").HavingColumns("Col1", op, "Col2");
+ new Query("Table").OrHavingColumns("Col1", op, "Col2");
+ }
+
+ [Theory]
+ [InlineData("^")]
+ [InlineData("<<")]
+ [InlineData(">>")]
+ [InlineData("~")]
+ [InlineData("~*")]
+ [InlineData("!~")]
+ [InlineData("!~*")]
+ public void ShouldNotThrowAfterWhiteListing(string op) {
+ var compiler = new SqlServerCompiler().Whitelist(op);
+
+ var query = new Query("Table");
+
+ 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));
+
+ 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);
+ }
+
+ [Fact]
+ public void ShouldNotConsiderWhereRawCondition() {
+ var compiler = new SqlServerCompiler();
+
+ var query = new Query("Table")
+ .WhereRaw("Col !! value");
+
+ }
+
+}
diff --git a/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs b/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs
index 57a5605e..b667ad19 100644
--- a/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs
+++ b/QueryBuilder.Tests/Oracle/OracleDateConditionTests.cs
@@ -1,223 +1,208 @@
-using SqlKata.Compilers;
-using SqlKata.Tests.Infrastructure;
-using Xunit;
-
-namespace SqlKata.Tests.Oracle
-{
- public class OracleDateConditionTests : TestSupport
- {
- private const string TableName = "Table";
- private const string SqlPlaceholder = "GENERATED_SQL";
-
- private readonly OracleCompiler compiler;
-
- public OracleDateConditionTests()
- {
- compiler = Compilers.Get(EngineCodes.Oracle);
- }
-
- [Fact]
- public void SimpleWhereDateTest()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDate("STAMP", "=", "2018-04-01");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'YY-MM-DD') = TO_CHAR(TO_DATE(?, 'YY-MM-DD'), 'YY-MM-DD')", ctx.RawSql);
- Assert.Equal("2018-04-01", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartDateTest()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("date", "STAMP", "=", "2018-04-01");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'YY-MM-DD') = TO_CHAR(TO_DATE(?, 'YY-MM-DD'), 'YY-MM-DD')", ctx.RawSql);
- Assert.Equal("2018-04-01", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereTimeWithSecondsTest()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereTime("STAMP", "=", "19:01:10");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'HH24:MI:SS') = TO_CHAR(TO_DATE(?, 'HH24:MI:SS'), 'HH24:MI:SS')", ctx.RawSql);
- Assert.Equal("19:01:10", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartTimeWithSecondsTest()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("time", "STAMP", "=", "19:01:10");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'HH24:MI:SS') = TO_CHAR(TO_DATE(?, 'HH24:MI:SS'), 'HH24:MI:SS')", ctx.RawSql);
- Assert.Equal("19:01:10", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereTimeWithoutSecondsTest()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereTime("STAMP", "=", "19:01");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'HH24:MI:SS') = TO_CHAR(TO_DATE(?, 'HH24:MI'), 'HH24:MI:SS')", ctx.RawSql);
- Assert.Equal("19:01", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartTimeWithoutSecondsTest()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("time", "STAMP", "=", "19:01");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'HH24:MI:SS') = TO_CHAR(TO_DATE(?, 'HH24:MI'), 'HH24:MI:SS')", ctx.RawSql);
- Assert.Equal("19:01", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartYear()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("year", "STAMP", "=", "2018");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(YEAR FROM \"STAMP\") = ?", ctx.RawSql);
- Assert.Equal("2018", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartMonth()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("month", "STAMP", "=", "9");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(MONTH FROM \"STAMP\") = ?", ctx.RawSql);
- Assert.Equal("9", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartDay()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("day", "STAMP", "=", "15");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(DAY FROM \"STAMP\") = ?", ctx.RawSql);
- Assert.Equal("15", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartHour()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("hour", "STAMP", "=", "15");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(HOUR FROM \"STAMP\") = ?", ctx.RawSql);
- Assert.Equal("15", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartMinute()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("minute", "STAMP", "=", "25");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(MINUTE FROM \"STAMP\") = ?", ctx.RawSql);
- Assert.Equal("25", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void SimpleWhereDatePartSecond()
- {
- // Arrange:
- var query = new Query(TableName)
- .Select()
- .WhereDatePart("second", "STAMP", "=", "59");
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(SECOND FROM \"STAMP\") = ?", ctx.RawSql);
- Assert.Equal("59", ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
- }
-}
+namespace SqlKata.Tests.Oracle;
+
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+public class OracleDateConditionTests : TestSupport {
+ private const string TableName = "Table";
+ private const string SqlPlaceholder = "GENERATED_SQL";
+
+ private readonly OracleCompiler compiler;
+
+ public OracleDateConditionTests() {
+ compiler = Compilers.Get(EngineCodes.Oracle);
+ }
+
+ [Fact]
+ public void SimpleWhereDateTest() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDate("STAMP", "=", "2018-04-01");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'YY-MM-DD') = TO_CHAR(TO_DATE(?, 'YY-MM-DD'), 'YY-MM-DD')", ctx.RawSql);
+ Assert.Equal("2018-04-01", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartDateTest() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("date", "STAMP", "=", "2018-04-01");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'YY-MM-DD') = TO_CHAR(TO_DATE(?, 'YY-MM-DD'), 'YY-MM-DD')", ctx.RawSql);
+ Assert.Equal("2018-04-01", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereTimeWithSecondsTest() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereTime("STAMP", "=", "19:01:10");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'HH24:MI:SS') = TO_CHAR(TO_DATE(?, 'HH24:MI:SS'), 'HH24:MI:SS')", ctx.RawSql);
+ Assert.Equal("19:01:10", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartTimeWithSecondsTest() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("time", "STAMP", "=", "19:01:10");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'HH24:MI:SS') = TO_CHAR(TO_DATE(?, 'HH24:MI:SS'), 'HH24:MI:SS')", ctx.RawSql);
+ Assert.Equal("19:01:10", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereTimeWithoutSecondsTest() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereTime("STAMP", "=", "19:01");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'HH24:MI:SS') = TO_CHAR(TO_DATE(?, 'HH24:MI'), 'HH24:MI:SS')", ctx.RawSql);
+ Assert.Equal("19:01", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartTimeWithoutSecondsTest() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("time", "STAMP", "=", "19:01");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE TO_CHAR(\"STAMP\", 'HH24:MI:SS') = TO_CHAR(TO_DATE(?, 'HH24:MI'), 'HH24:MI:SS')", ctx.RawSql);
+ Assert.Equal("19:01", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartYear() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("year", "STAMP", "=", "2018");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(YEAR FROM \"STAMP\") = ?", ctx.RawSql);
+ Assert.Equal("2018", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartMonth() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("month", "STAMP", "=", "9");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(MONTH FROM \"STAMP\") = ?", ctx.RawSql);
+ Assert.Equal("9", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartDay() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("day", "STAMP", "=", "15");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(DAY FROM \"STAMP\") = ?", ctx.RawSql);
+ Assert.Equal("15", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartHour() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("hour", "STAMP", "=", "15");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(HOUR FROM \"STAMP\") = ?", ctx.RawSql);
+ Assert.Equal("15", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartMinute() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("minute", "STAMP", "=", "25");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(MINUTE FROM \"STAMP\") = ?", ctx.RawSql);
+ Assert.Equal("25", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void SimpleWhereDatePartSecond() {
+ // Arrange:
+ var query = new Query(TableName)
+ .Select()
+ .WhereDatePart("second", "STAMP", "=", "59");
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($"SELECT * FROM \"{TableName}\" WHERE EXTRACT(SECOND FROM \"STAMP\") = ?", ctx.RawSql);
+ Assert.Equal("59", ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+}
diff --git a/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs b/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs
index f25cf2ba..b284994d 100644
--- a/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs
+++ b/QueryBuilder.Tests/Oracle/OracleInsertManyTests.cs
@@ -1,61 +1,56 @@
-using SqlKata.Compilers;
-using SqlKata.Tests.Infrastructure;
-using Xunit;
-
-namespace SqlKata.Tests.Oracle
-{
- public class OracleInsertManyTests : TestSupport
- {
- private const string TableName = "Table";
- private readonly OracleCompiler compiler;
-
- public OracleInsertManyTests()
- {
- compiler = Compilers.Get(EngineCodes.Oracle);
- }
-
- [Fact]
- public void InsertManyForOracle_ShouldRepeatColumnsAndAddSelectFromDual()
- {
- // Arrange:
- var cols = new[] { "Name", "Price" };
-
- var data = new[] {
- new object[] { "A", 1000 },
- new object[] { "B", 2000 },
- new object[] { "C", 3000 },
- };
-
- var query = new Query(TableName)
- .AsInsert(cols, data);
-
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($@"INSERT ALL INTO ""{TableName}"" (""Name"", ""Price"") VALUES (?, ?) INTO ""{TableName}"" (""Name"", ""Price"") VALUES (?, ?) INTO ""{TableName}"" (""Name"", ""Price"") VALUES (?, ?) SELECT 1 FROM DUAL", ctx.RawSql);
- }
-
- [Fact]
- public void InsertForOracle_SingleInsertShouldNotAddALLKeywordAndNotHaveSelectFromDual()
- {
- // Arrange:
- var cols = new[] { "Name", "Price" };
-
- var data = new[] {
- new object[] { "A", 1000 }
- };
-
- var query = new Query(TableName)
- .AsInsert(cols, data);
-
-
- // Act:
- var ctx = compiler.Compile(query);
-
- // Assert:
- Assert.Equal($@"INSERT INTO ""{TableName}"" (""Name"", ""Price"") VALUES (?, ?)", ctx.RawSql);
- }
- }
-}
+namespace SqlKata.Tests.Oracle;
+
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+public class OracleInsertManyTests : TestSupport {
+ private const string TableName = "Table";
+ private readonly OracleCompiler compiler;
+
+ public OracleInsertManyTests() {
+ compiler = Compilers.Get(EngineCodes.Oracle);
+ }
+
+ [Fact]
+ public void InsertManyForOracle_ShouldRepeatColumnsAndAddSelectFromDual() {
+ // Arrange:
+ var cols = new[] { "Name", "Price" };
+
+ var data = new[] {
+ new object[] { "A", 1000 },
+ new object[] { "B", 2000 },
+ new object[] { "C", 3000 },
+ };
+
+ var query = new Query(TableName)
+ .AsInsert(cols, data);
+
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($@"INSERT ALL INTO ""{TableName}"" (""Name"", ""Price"") VALUES (?, ?) INTO ""{TableName}"" (""Name"", ""Price"") VALUES (?, ?) INTO ""{TableName}"" (""Name"", ""Price"") VALUES (?, ?) SELECT 1 FROM DUAL", ctx.RawSql);
+ }
+
+ [Fact]
+ public void InsertForOracle_SingleInsertShouldNotAddALLKeywordAndNotHaveSelectFromDual() {
+ // Arrange:
+ var cols = new[] { "Name", "Price" };
+
+ var data = new[] {
+ new object[] { "A", 1000 }
+ };
+
+ var query = new Query(TableName)
+ .AsInsert(cols, data);
+
+
+ // Act:
+ var ctx = compiler.Compile(query);
+
+ // Assert:
+ Assert.Equal($@"INSERT INTO ""{TableName}"" (""Name"", ""Price"") VALUES (?, ?)", ctx.RawSql);
+ }
+}
diff --git a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs
index 47a233dd..027ce174 100644
--- a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs
+++ b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs
@@ -1,82 +1,75 @@
-using SqlKata.Compilers;
-using SqlKata.Tests.Infrastructure;
-using Xunit;
-
-namespace SqlKata.Tests.Oracle
-{
- public class OracleLegacyLimitTests : TestSupport
- {
- private const string TableName = "Table";
- private const string SqlPlaceholder = "GENERATED_SQL";
- private readonly OracleCompiler compiler;
-
- public OracleLegacyLimitTests()
- {
- compiler = Compilers.Get(EngineCodes.Oracle);
- compiler.UseLegacyPagination = true;
- }
-
- [Fact]
- public void WithNoLimitNorOffset()
- {
- // Arrange:
- var query = new Query(TableName);
- var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder };
-
- // Act:
- compiler.ApplyLegacyLimit(ctx);
-
- // Assert:
- Assert.Equal(SqlPlaceholder, ctx.RawSql);
- }
-
- [Fact]
- public void WithNoOffset()
- {
- // Arrange:
- var query = new Query(TableName).Limit(10);
- var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder };
-
- // Act:
- compiler.ApplyLegacyLimit(ctx);
-
- // Assert:
- Assert.Matches($"SELECT \\* FROM \\({SqlPlaceholder}\\) WHERE ROWNUM <= ?", ctx.RawSql);
- Assert.Equal(10, ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- public void WithNoLimit()
- {
- // Arrange:
- var query = new Query(TableName).Offset(20);
- var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder };
-
- // Act:
- compiler.ApplyLegacyLimit(ctx);
-
- // Assert:
- Assert.Equal("SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM (GENERATED_SQL) \"results_wrapper\") WHERE \"row_num\" > ?", ctx.RawSql);
- Assert.Equal(20L, ctx.Bindings[0]);
- Assert.Single(ctx.Bindings);
- }
-
- [Fact]
- 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);
-
- // 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(25L, ctx.Bindings[0]);
- Assert.Equal(20L, ctx.Bindings[1]);
- Assert.Equal(2, ctx.Bindings.Count);
- }
- }
-}
+namespace SqlKata.Tests.Oracle;
+
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+public class OracleLegacyLimitTests : TestSupport {
+ private const string TableName = "Table";
+ private const string SqlPlaceholder = "GENERATED_SQL";
+ private readonly OracleCompiler compiler;
+
+ public OracleLegacyLimitTests() {
+ compiler = Compilers.Get(EngineCodes.Oracle);
+ compiler.UseLegacyPagination = true;
+ }
+
+ [Fact]
+ public void WithNoLimitNorOffset() {
+ // Arrange:
+ var query = new Query(TableName);
+ var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder };
+
+ // Act:
+ compiler.ApplyLegacyLimit(ctx);
+
+ // Assert:
+ Assert.Equal(SqlPlaceholder, ctx.RawSql);
+ }
+
+ [Fact]
+ public void WithNoOffset() {
+ // Arrange:
+ var query = new Query(TableName).Limit(10);
+ var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder };
+
+ // Act:
+ compiler.ApplyLegacyLimit(ctx);
+
+ // Assert:
+ Assert.Matches($"SELECT \\* FROM \\({SqlPlaceholder}\\) WHERE ROWNUM <= ?", ctx.RawSql);
+ Assert.Equal(10, ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ public void WithNoLimit() {
+ // Arrange:
+ var query = new Query(TableName).Offset(20);
+ var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder };
+
+ // Act:
+ compiler.ApplyLegacyLimit(ctx);
+
+ // Assert:
+ Assert.Equal("SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM (GENERATED_SQL) \"results_wrapper\") WHERE \"row_num\" > ?", ctx.RawSql);
+ Assert.Equal(20L, ctx.Bindings[0]);
+ Assert.Single(ctx.Bindings);
+ }
+
+ [Fact]
+ 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);
+
+ // 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(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..c98b90cc 100644
--- a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs
+++ b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs
@@ -1,75 +1,68 @@
-using SqlKata.Compilers;
-using SqlKata.Tests.Infrastructure;
-using Xunit;
-
-namespace SqlKata.Tests.Oracle
-{
- public class OracleLimitTests : TestSupport
- {
- private const string TableName = "Table";
- private const string SqlPlaceholder = "GENERATED_SQL";
-
- private readonly OracleCompiler compiler;
-
- public OracleLimitTests()
- {
- compiler = Compilers.Get(EngineCodes.Oracle);
- }
-
- [Fact]
- public void NoLimitNorOffset()
- {
- // Arrange:
- var query = new Query(TableName);
- var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder };
-
- // Act & Assert:
- Assert.Null(compiler.CompileLimit(ctx));
- }
-
- [Fact]
- 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));
- Assert.Equal(2, ctx.Bindings.Count);
- Assert.Equal(0L, ctx.Bindings[0]);
- Assert.Equal(10, ctx.Bindings[1]);
- }
-
- [Fact]
- 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));
-
- Assert.Single(ctx.Bindings);
- Assert.Equal(20L, ctx.Bindings[0]);
- }
-
- [Fact]
- 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));
-
- Assert.Equal(2, ctx.Bindings.Count);
- Assert.Equal(20L, ctx.Bindings[0]);
- Assert.Equal(5, ctx.Bindings[1]);
-
- compiler.CompileLimit(ctx);
- }
- }
-}
+namespace SqlKata.Tests.Oracle;
+
+using SqlKata.Compilers;
+using SqlKata.Tests.Infrastructure;
+using Xunit;
+
+public class OracleLimitTests : TestSupport {
+ private const string TableName = "Table";
+ private const string SqlPlaceholder = "GENERATED_SQL";
+
+ private readonly OracleCompiler compiler;
+
+ public OracleLimitTests() {
+ compiler = Compilers.Get(EngineCodes.Oracle);
+ }
+
+ [Fact]
+ public void NoLimitNorOffset() {
+ // Arrange:
+ var query = new Query(TableName);
+ var ctx = new SqlResult("?", "\\") { Query = query, RawSql = SqlPlaceholder };
+
+ // Act & Assert:
+ Assert.Null(compiler.CompileLimit(ctx));
+ }
+
+ [Fact]
+ 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));
+ Assert.Equal(2, ctx.Bindings.Count);
+ Assert.Equal(0L, ctx.Bindings[0]);
+ Assert.Equal(10, ctx.Bindings[1]);
+ }
+
+ [Fact]
+ 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));
+
+ Assert.Single(ctx.Bindings);
+ Assert.Equal(20L, ctx.Bindings[0]);
+ }
+
+ [Fact]
+ 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));
+
+ Assert.Equal(2, ctx.Bindings.Count);
+ Assert.Equal(20L, ctx.Bindings[0]);
+ Assert.Equal(5, ctx.Bindings[1]);
+
+ compiler.CompileLimit(ctx);
+ }
+}
diff --git a/QueryBuilder.Tests/ParameterTypeTests.cs b/QueryBuilder.Tests/ParameterTypeTests.cs
index 095a6e53..8c26cc31 100644
--- a/QueryBuilder.Tests/ParameterTypeTests.cs
+++ b/QueryBuilder.Tests/ParameterTypeTests.cs
@@ -1,52 +1,47 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using SqlKata.Compilers;
-using Xunit;
-using System.Collections;
-using SqlKata.Tests.Infrastructure;
-
-namespace SqlKata.Tests
-{
- public class ParameterTypeTests : TestSupport
- {
- public enum EnumExample
- {
- First,
- Second,
- Third,
- }
-
- public class ParameterTypeGenerator : IEnumerable