diff --git a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs index 9ef93ff3..47c1d0d3 100644 --- a/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs +++ b/QueryBuilder.Tests/Firebird/FirebirdLimitTests.cs @@ -17,7 +17,7 @@ public FirebirdLimitTests() public void NoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -26,7 +26,7 @@ public void NoLimitNorOffset() public void LimitOnly() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -35,7 +35,7 @@ public void LimitOnly() public void OffsetOnly() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -44,7 +44,7 @@ public void OffsetOnly() public void LimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("ROWS ? TO ?", compiler.CompileLimit(ctx)); Assert.Equal(21L, ctx.Bindings[0]); diff --git a/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs b/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs index 2312a192..fcd22c41 100644 --- a/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs +++ b/QueryBuilder.Tests/Infrastructure/TestCompilersContainer.cs @@ -1,8 +1,7 @@ +using SqlKata.Compilers; using System; using System.Collections.Generic; using System.Linq; -using SqlKata.Compilers; - namespace SqlKata.Tests.Infrastructure { public class TestCompilersContainer diff --git a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs index 074c5ad8..74b90f97 100644 --- a/QueryBuilder.Tests/MySql/MySqlLimitTests.cs +++ b/QueryBuilder.Tests/MySql/MySqlLimitTests.cs @@ -17,7 +17,7 @@ public MySqlLimitTests() public void WithNoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -26,7 +26,7 @@ public void WithNoLimitNorOffset() public void WithNoOffset() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx)); Assert.Equal(10, ctx.Bindings[0]); @@ -36,7 +36,7 @@ public void WithNoOffset() public void WithNoLimit() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("LIMIT 18446744073709551615 OFFSET ?", compiler.CompileLimit(ctx)); Assert.Equal(20L, ctx.Bindings[0]); @@ -47,7 +47,7 @@ public void WithNoLimit() public void WithLimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("LIMIT ? OFFSET ?", compiler.CompileLimit(ctx)); Assert.Equal(5, ctx.Bindings[0]); diff --git a/QueryBuilder.Tests/MySqlExecutionTest.cs b/QueryBuilder.Tests/MySqlExecutionTest.cs index 07df93c8..e055c7e5 100644 --- a/QueryBuilder.Tests/MySqlExecutionTest.cs +++ b/QueryBuilder.Tests/MySqlExecutionTest.cs @@ -1,11 +1,9 @@ +using MySql.Data.MySqlClient; using SqlKata.Compilers; -using Xunit; using SqlKata.Execution; -using MySql.Data.MySqlClient; -using System; -using System.Linq; -using static SqlKata.Expressions; using System.Collections.Generic; +using System.Linq; +using Xunit; namespace SqlKata.Tests { @@ -174,7 +172,7 @@ public void ExistsShouldReturnFalseForEmptyTable() }); var exists = db.Query("Transaction").Exists(); - Assert.Equal(false, exists); + Assert.False(exists); db.Drop("Transaction"); } @@ -195,7 +193,7 @@ public void ExistsShouldReturnTrueForNonEmptyTable() }); var exists = db.Query("Transaction").Exists(); - Assert.Equal(true, exists); + Assert.True(exists); db.Drop("Transaction"); } @@ -266,4 +264,4 @@ QueryFactory DB() } -} \ No newline at end of file +} diff --git a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs index 2b18769f..5f3c0281 100644 --- a/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLegacyLimitTests.cs @@ -21,7 +21,7 @@ public void WithNoLimitNorOffset() { // Arrange: var query = new Query(TableName); - var ctx = new SqlResult { Query = query, RawSql = SqlPlaceholder }; + var ctx = new SqlResult(compiler) { Query = query, RawSql = SqlPlaceholder }; // Act: compiler.ApplyLegacyLimit(ctx); @@ -35,7 +35,7 @@ public void WithNoOffset() { // Arrange: var query = new Query(TableName).Limit(10); - var ctx = new SqlResult { Query = query, RawSql = SqlPlaceholder }; + var ctx = new SqlResult(compiler) { Query = query, RawSql = SqlPlaceholder }; // Act: compiler.ApplyLegacyLimit(ctx); @@ -51,7 +51,7 @@ public void WithNoLimit() { // Arrange: var query = new Query(TableName).Offset(20); - var ctx = new SqlResult { Query = query, RawSql = SqlPlaceholder }; + var ctx = new SqlResult(compiler) { Query = query, RawSql = SqlPlaceholder }; // Act: compiler.ApplyLegacyLimit(ctx); @@ -67,7 +67,7 @@ public void WithLimitAndOffset() { // Arrange: var query = new Query(TableName).Limit(5).Offset(20); - var ctx = new SqlResult { Query = query, RawSql = SqlPlaceholder }; + var ctx = new SqlResult(compiler) { Query = query, RawSql = SqlPlaceholder }; // Act: compiler.ApplyLegacyLimit(ctx); diff --git a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs index 404fd5b1..18f99883 100644 --- a/QueryBuilder.Tests/Oracle/OracleLimitTests.cs +++ b/QueryBuilder.Tests/Oracle/OracleLimitTests.cs @@ -21,7 +21,7 @@ public void NoLimitNorOffset() { // Arrange: var query = new Query(TableName); - var ctx = new SqlResult { Query = query, RawSql = SqlPlaceholder }; + var ctx = new SqlResult(compiler) { Query = query, RawSql = SqlPlaceholder }; // Act & Assert: Assert.Null(compiler.CompileLimit(ctx)); @@ -32,7 +32,7 @@ public void LimitOnly() { // Arrange: var query = new Query(TableName).Limit(10); - var ctx = new SqlResult { Query = query, RawSql = SqlPlaceholder }; + var ctx = new SqlResult(compiler) { Query = query, RawSql = SqlPlaceholder }; // Act & Assert: Assert.EndsWith("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", compiler.CompileLimit(ctx)); @@ -46,7 +46,7 @@ public void OffsetOnly() { // Arrange: var query = new Query(TableName).Offset(20); - var ctx = new SqlResult { Query = query, RawSql = SqlPlaceholder }; + var ctx = new SqlResult(compiler) { Query = query, RawSql = SqlPlaceholder }; // Act & Assert: Assert.EndsWith("OFFSET ? ROWS", compiler.CompileLimit(ctx)); @@ -60,7 +60,7 @@ public void LimitAndOffset() { // Arrange: var query = new Query(TableName).Limit(5).Offset(20); - var ctx = new SqlResult { Query = query, RawSql = SqlPlaceholder }; + var ctx = new SqlResult(compiler) { Query = query, RawSql = SqlPlaceholder }; // Act & Assert: Assert.EndsWith("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", compiler.CompileLimit(ctx)); diff --git a/QueryBuilder.Tests/ParameterTypeTests.cs b/QueryBuilder.Tests/ParameterTypeTests.cs index 095a6e53..cef7f2ef 100644 --- a/QueryBuilder.Tests/ParameterTypeTests.cs +++ b/QueryBuilder.Tests/ParameterTypeTests.cs @@ -1,10 +1,10 @@ +using SqlKata.Compilers; +using SqlKata.Tests.Infrastructure; using System; +using System.Collections; using System.Collections.Generic; using System.Globalization; -using SqlKata.Compilers; using Xunit; -using System.Collections; -using SqlKata.Tests.Infrastructure; namespace SqlKata.Tests { @@ -22,9 +22,9 @@ public class ParameterTypeGenerator : IEnumerable private readonly List _data = new List { new object[] {"1", 1}, - new object[] {Convert.ToSingle("10.5", CultureInfo.InvariantCulture).ToString(), 10.5}, + new object[] {Convert.ToSingle("10.5", CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture), 10.5}, new object[] {"-2", -2}, - new object[] {Convert.ToSingle("-2.8", CultureInfo.InvariantCulture).ToString(), -2.8}, + new object[] {Convert.ToSingle("-2.8", CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture), -2.8}, new object[] {"cast(1 as bit)", true}, new object[] {"cast(0 as bit)", false}, new object[] {"'2018-10-28 19:22:00'", new DateTime(2018, 10, 28, 19, 22, 0)}, diff --git a/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs b/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs index 3c8d054a..95b2f360 100644 --- a/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs +++ b/QueryBuilder.Tests/PostgreSql/PostgreSqlLimitTests.cs @@ -17,7 +17,7 @@ public PostgreSqlLimitTests() public void WithNoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -26,7 +26,7 @@ public void WithNoLimitNorOffset() public void WithNoOffset() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx)); Assert.Equal(10, ctx.Bindings[0]); @@ -36,7 +36,7 @@ public void WithNoOffset() public void WithNoLimit() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("OFFSET ?", compiler.CompileLimit(ctx)); Assert.Equal(20L, ctx.Bindings[0]); @@ -47,7 +47,7 @@ public void WithNoLimit() public void WithLimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("LIMIT ? OFFSET ?", compiler.CompileLimit(ctx)); Assert.Equal(5, ctx.Bindings[0]); diff --git a/QueryBuilder.Tests/PostgreSql/PostgresJsonTests.cs b/QueryBuilder.Tests/PostgreSql/PostgresJsonTests.cs new file mode 100644 index 00000000..e458fa24 --- /dev/null +++ b/QueryBuilder.Tests/PostgreSql/PostgresJsonTests.cs @@ -0,0 +1,70 @@ +using SqlKata.Compilers; +using SqlKata.Tests.Infrastructure; +using System; +using Xunit; + +namespace SqlKata.Tests.PostgreSql +{ + public class PostgresJsonTests : TestSupport + { + public class JsonAwarePostgresCompiler : PostgresCompiler + { + public override string ParameterPlaceholder { get; protected set; } = "$$"; + } + + private readonly JsonAwarePostgresCompiler compiler = new(); + private PostgresCompiler regularCompiler; + + public PostgresJsonTests() + { + regularCompiler = Compilers.Get(EngineCodes.PostgreSql); + } + + [Fact] + public void LimitWithCustomPlaceHolder() + { + var query = new Query("Table").Limit(10); + var ctx = new SqlResult(compiler) { Query = query }; + + Assert.Equal($"LIMIT $$", compiler.CompileLimit(ctx)); + Assert.Equal(10, ctx.Bindings[0]); + } + + [Fact] + public void RegularCompilerThrowsExceptionWhereRawJsonContainsQuestionMarkData() + { + Assert.Throws(() => + { + Query query = CreateQuestionMarkJsonQuery(out var rawCondition); + + SqlResult result = regularCompiler.Compile(query); + Assert.Equal($"SELECT * FROM \"Table\" WHERE {rawCondition}", result.ToString()); + }); + } + + private Query CreateQuestionMarkJsonQuery(out string rawCondition) + { + rawCondition = "my_json_column @> '{\"json_param\" : \"question mark ? \"}'"; + var escapedJsonCondition = rawCondition.Replace("{", "\\{").Replace("}", "\\}"); + return new Query("Table").WhereRaw(escapedJsonCondition); + } + + [Fact] + public void WhereRawJsonWithQuestionMarkData() + { + Query query = CreateQuestionMarkJsonQuery(out var rawCondition); + SqlResult result = compiler.Compile(query); + Assert.Equal($"SELECT * FROM \"Table\" WHERE {rawCondition}", result.ToString()); + } + + [Fact] + public void UsingJsonArray() + { + var query = new Query("Table").WhereRaw("[Json]->'address'->>'country' in ($$)", new[] { 1, 2, 3, 4 }); + + SqlResult result = compiler.Compile(query); + + Assert.Equal("SELECT * FROM \"Table\" WHERE \"Json\"->'address'->>'country' in (1,2,3,4)", result.ToString()); + } + } +} diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs index 85493d2f..c881e4d9 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLegacyLimitTests.cs @@ -18,7 +18,7 @@ public SqlServerLegacyLimitTests() public void NoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -27,7 +27,7 @@ public void NoLimitNorOffset() public void LimitOnly() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -36,7 +36,7 @@ public void LimitOnly() public void OffsetOnly() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -45,7 +45,7 @@ public void OffsetOnly() public void LimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } diff --git a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs index 1e54413c..16ce2de9 100644 --- a/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs +++ b/QueryBuilder.Tests/SqlServer/SqlServerLimitTests.cs @@ -18,7 +18,7 @@ public SqlServerLimitTests() public void NoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -27,7 +27,7 @@ public void NoLimitNorOffset() public void LimitOnly() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.EndsWith("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", compiler.CompileLimit(ctx)); Assert.Equal(2, ctx.Bindings.Count); @@ -39,7 +39,7 @@ public void LimitOnly() public void OffsetOnly() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.EndsWith("OFFSET ? ROWS", compiler.CompileLimit(ctx)); @@ -51,7 +51,7 @@ public void OffsetOnly() public void LimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.EndsWith("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", compiler.CompileLimit(ctx)); diff --git a/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs b/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs index 047605df..e4c24751 100644 --- a/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs +++ b/QueryBuilder.Tests/Sqlite/SqliteLimitTests.cs @@ -17,7 +17,7 @@ public SqliteLimitTests() public void WithNoLimitNorOffset() { var query = new Query("Table"); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Null(compiler.CompileLimit(ctx)); } @@ -26,7 +26,7 @@ public void WithNoLimitNorOffset() public void WithNoOffset() { var query = new Query("Table").Limit(10); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx)); Assert.Equal(10, ctx.Bindings[0]); @@ -36,7 +36,7 @@ public void WithNoOffset() public void WithNoLimit() { var query = new Query("Table").Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("LIMIT -1 OFFSET ?", compiler.CompileLimit(ctx)); Assert.Equal(20L, ctx.Bindings[0]); @@ -47,7 +47,7 @@ public void WithNoLimit() public void WithLimitAndOffset() { var query = new Query("Table").Limit(5).Offset(20); - var ctx = new SqlResult { Query = query }; + var ctx = new SqlResult(compiler) { Query = query }; Assert.Equal("LIMIT ? OFFSET ?", compiler.CompileLimit(ctx)); Assert.Equal(5, ctx.Bindings[0]); diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs index aa15c789..d489a216 100644 --- a/QueryBuilder/Compilers/Compiler.cs +++ b/QueryBuilder/Compilers/Compiler.cs @@ -8,7 +8,7 @@ namespace SqlKata.Compilers public partial class Compiler { private readonly ConditionsCompilerProvider _compileConditionMethodsProvider; - protected virtual string parameterPlaceholder { get; set; } = "?"; + public virtual string ParameterPlaceholder { get; protected set; } = "?"; protected virtual string parameterPrefix { get; set; } = "@p"; protected virtual string OpeningIdentifier { get; set; } = "\""; protected virtual string ClosingIdentifier { get; set; } = "\""; @@ -72,7 +72,7 @@ protected Dictionary generateNamedBindings(object[] bindings) protected SqlResult PrepareResult(SqlResult ctx) { ctx.NamedBindings = generateNamedBindings(ctx.Bindings.ToArray()); - ctx.Sql = Helper.ReplaceAll(ctx.RawSql, parameterPlaceholder, i => parameterPrefix + i); + ctx.Sql = Helper.ReplaceAll(ctx.RawSql, ParameterPlaceholder, i => parameterPrefix + i); return ctx; } @@ -144,7 +144,7 @@ protected virtual SqlResult CompileRaw(Query query) ctx = CompileCteQuery(ctx, query); } - ctx.RawSql = Helper.ExpandParameters(ctx.RawSql, parameterPlaceholder, ctx.Bindings.ToArray()); + ctx.RawSql = Helper.ExpandParameters(ctx.RawSql, ParameterPlaceholder, ctx.Bindings.ToArray()); return ctx; } @@ -187,7 +187,7 @@ public virtual SqlResult Compile(IEnumerable queries) combinedBindings.AddRange(cb); } - var ctx = new SqlResult + var ctx = new SqlResult(this) { RawSql = compiled.Select(r => r.RawSql).Aggregate((a, b) => a + ";\n" + b), Bindings = combinedBindings, @@ -200,7 +200,7 @@ public virtual SqlResult Compile(IEnumerable queries) protected virtual SqlResult CompileSelectQuery(Query query) { - var ctx = new SqlResult + var ctx = new SqlResult(this) { Query = query.Clone(), }; @@ -229,9 +229,9 @@ protected virtual SqlResult CompileSelectQuery(Query query) protected virtual SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) { - var ctx = new SqlResult(); + var ctx = new SqlResult(this); - var row = "SELECT " + string.Join(", ", adHoc.Columns.Select(col => $"{parameterPlaceholder} AS {Wrap(col)}")); + var row = "SELECT " + string.Join(", ", adHoc.Columns.Select(col => $"{ParameterPlaceholder} AS {Wrap(col)}")); var fromTable = SingleRowDummyTableName; @@ -250,7 +250,7 @@ protected virtual SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) protected virtual SqlResult CompileDeleteQuery(Query query) { - var ctx = new SqlResult + var ctx = new SqlResult(this) { Query = query }; @@ -312,7 +312,7 @@ protected virtual SqlResult CompileDeleteQuery(Query query) protected virtual SqlResult CompileUpdateQuery(Query query) { - var ctx = new SqlResult + var ctx = new SqlResult(this) { Query = query }; @@ -390,7 +390,7 @@ protected virtual SqlResult CompileUpdateQuery(Query query) protected virtual SqlResult CompileInsertQuery(Query query) { - var ctx = new SqlResult + var ctx = new SqlResult(this) { Query = query }; @@ -573,7 +573,7 @@ protected virtual string CompileFilterConditions(SqlResult ctx, AggregatedColumn public virtual SqlResult CompileCte(AbstractFrom cte) { - var ctx = new SqlResult(); + var ctx = new SqlResult(this); if (null == cte) { @@ -852,19 +852,19 @@ public virtual string CompileLimit(SqlResult ctx) if (offset == 0) { ctx.Bindings.Add(limit); - return $"LIMIT {parameterPlaceholder}"; + return $"LIMIT {ParameterPlaceholder}"; } if (limit == 0) { ctx.Bindings.Add(offset); - return $"OFFSET {parameterPlaceholder}"; + return $"OFFSET {ParameterPlaceholder}"; } ctx.Bindings.Add(limit); ctx.Bindings.Add(offset); - return $"LIMIT {parameterPlaceholder} OFFSET {parameterPlaceholder}"; + return $"LIMIT {ParameterPlaceholder} OFFSET {ParameterPlaceholder}"; } /// @@ -1019,11 +1019,11 @@ public virtual string Parameter(SqlResult ctx, object parameter) { var value = ctx.Query.FindVariable(variable.Name); ctx.Bindings.Add(value); - return parameterPlaceholder; + return ParameterPlaceholder; } ctx.Bindings.Add(parameter); - return parameterPlaceholder; + return ParameterPlaceholder; } /// diff --git a/QueryBuilder/Compilers/FirebirdCompiler.cs b/QueryBuilder/Compilers/FirebirdCompiler.cs index 61ab9547..5eeea558 100644 --- a/QueryBuilder/Compilers/FirebirdCompiler.cs +++ b/QueryBuilder/Compilers/FirebirdCompiler.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using System.Linq; using System.Text.RegularExpressions; namespace SqlKata.Compilers @@ -39,7 +37,7 @@ public override string CompileLimit(SqlResult ctx) ctx.Bindings.Add(offset + 1); ctx.Bindings.Add(limit + offset); - return $"ROWS {parameterPlaceholder} TO {parameterPlaceholder}"; + return $"ROWS {ParameterPlaceholder} TO {ParameterPlaceholder}"; } return null; @@ -59,7 +57,7 @@ protected override string CompileColumns(SqlResult ctx) ctx.Query.ClearComponent("limit"); - return $"SELECT FIRST {parameterPlaceholder}" + compiled.Substring(6); + return $"SELECT FIRST {ParameterPlaceholder}" + compiled.Substring(6); } else if (limit == 0 && offset > 0) { @@ -67,7 +65,7 @@ protected override string CompileColumns(SqlResult ctx) ctx.Query.ClearComponent("offset"); - return $"SELECT SKIP {parameterPlaceholder}" + compiled.Substring(6); + return $"SELECT SKIP {ParameterPlaceholder}" + compiled.Substring(6); } return compiled; diff --git a/QueryBuilder/Compilers/MySqlCompiler.cs b/QueryBuilder/Compilers/MySqlCompiler.cs index 4729125b..1647bad5 100644 --- a/QueryBuilder/Compilers/MySqlCompiler.cs +++ b/QueryBuilder/Compilers/MySqlCompiler.cs @@ -24,7 +24,7 @@ public override string CompileLimit(SqlResult ctx) if (offset == 0) { ctx.Bindings.Add(limit); - return $"LIMIT {parameterPlaceholder}"; + return $"LIMIT {ParameterPlaceholder}"; } if (limit == 0) @@ -34,7 +34,7 @@ public override string CompileLimit(SqlResult ctx) // to avoid this error. ctx.Bindings.Add(offset); - return $"LIMIT 18446744073709551615 OFFSET {parameterPlaceholder}"; + return $"LIMIT 18446744073709551615 OFFSET {ParameterPlaceholder}"; } // We have both values @@ -42,7 +42,7 @@ public override string CompileLimit(SqlResult ctx) ctx.Bindings.Add(limit); ctx.Bindings.Add(offset); - return $"LIMIT {parameterPlaceholder} OFFSET {parameterPlaceholder}"; + return $"LIMIT {ParameterPlaceholder} OFFSET {ParameterPlaceholder}"; } } diff --git a/QueryBuilder/Compilers/OracleCompiler.cs b/QueryBuilder/Compilers/OracleCompiler.cs index 610ec20d..0c5a9e8f 100644 --- a/QueryBuilder/Compilers/OracleCompiler.cs +++ b/QueryBuilder/Compilers/OracleCompiler.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Text.RegularExpressions; namespace SqlKata.Compilers { @@ -60,13 +58,13 @@ public override string CompileLimit(SqlResult ctx) if (limit == 0) { ctx.Bindings.Add(offset); - return $"{safeOrder}OFFSET {parameterPlaceholder} ROWS"; + return $"{safeOrder}OFFSET {ParameterPlaceholder} ROWS"; } ctx.Bindings.Add(offset); ctx.Bindings.Add(limit); - return $"{safeOrder}OFFSET {parameterPlaceholder} ROWS FETCH NEXT {parameterPlaceholder} ROWS ONLY"; + return $"{safeOrder}OFFSET {ParameterPlaceholder} ROWS FETCH NEXT {ParameterPlaceholder} ROWS ONLY"; } internal void ApplyLegacyLimit(SqlResult ctx) @@ -82,17 +80,17 @@ internal void ApplyLegacyLimit(SqlResult ctx) string newSql; if (limit == 0) { - newSql = $"SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM ({ctx.RawSql}) \"results_wrapper\") WHERE \"row_num\" > {parameterPlaceholder}"; + newSql = $"SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM ({ctx.RawSql}) \"results_wrapper\") WHERE \"row_num\" > {ParameterPlaceholder}"; ctx.Bindings.Add(offset); } else if (offset == 0) { - newSql = $"SELECT * FROM ({ctx.RawSql}) WHERE ROWNUM <= {parameterPlaceholder}"; + newSql = $"SELECT * FROM ({ctx.RawSql}) WHERE ROWNUM <= {ParameterPlaceholder}"; ctx.Bindings.Add(limit); } else { - newSql = $"SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM ({ctx.RawSql}) \"results_wrapper\" WHERE ROWNUM <= {parameterPlaceholder}) WHERE \"row_num\" > {parameterPlaceholder}"; + newSql = $"SELECT * FROM (SELECT \"results_wrapper\".*, ROWNUM \"row_num\" FROM ({ctx.RawSql}) \"results_wrapper\" WHERE ROWNUM <= {ParameterPlaceholder}) WHERE \"row_num\" > {ParameterPlaceholder}"; ctx.Bindings.Add(limit + offset); ctx.Bindings.Add(offset); } diff --git a/QueryBuilder/Compilers/SqlServerCompiler.cs b/QueryBuilder/Compilers/SqlServerCompiler.cs index 0202f0f1..e17c3182 100644 --- a/QueryBuilder/Compilers/SqlServerCompiler.cs +++ b/QueryBuilder/Compilers/SqlServerCompiler.cs @@ -23,7 +23,7 @@ protected override SqlResult CompileSelectQuery(Query query) query = query.Clone(); - var ctx = new SqlResult + var ctx = new SqlResult(this) { Query = query, }; @@ -48,12 +48,12 @@ protected override SqlResult CompileSelectQuery(Query query) if (limit == 0) { - result.RawSql = $"SELECT * FROM ({result.RawSql}) AS [results_wrapper] WHERE [row_num] >= {parameterPlaceholder}"; + result.RawSql = $"SELECT * FROM ({result.RawSql}) AS [results_wrapper] WHERE [row_num] >= {ParameterPlaceholder}"; result.Bindings.Add(offset + 1); } else { - result.RawSql = $"SELECT * FROM ({result.RawSql}) AS [results_wrapper] WHERE [row_num] BETWEEN {parameterPlaceholder} AND {parameterPlaceholder}"; + result.RawSql = $"SELECT * FROM ({result.RawSql}) AS [results_wrapper] WHERE [row_num] BETWEEN {ParameterPlaceholder} AND {ParameterPlaceholder}"; result.Bindings.Add(offset + 1); result.Bindings.Add(limit + offset); } @@ -86,10 +86,10 @@ protected override string CompileColumns(SqlResult ctx) // handle distinct if (compiled.IndexOf("SELECT DISTINCT") == 0) { - return $"SELECT DISTINCT TOP ({parameterPlaceholder}){compiled.Substring(15)}"; + return $"SELECT DISTINCT TOP ({ParameterPlaceholder}){compiled.Substring(15)}"; } - return $"SELECT TOP ({parameterPlaceholder}){compiled.Substring(6)}"; + return $"SELECT TOP ({ParameterPlaceholder}){compiled.Substring(6)}"; } return compiled; @@ -121,13 +121,13 @@ public override string CompileLimit(SqlResult ctx) if (limit == 0) { ctx.Bindings.Add(offset); - return $"{safeOrder}OFFSET {parameterPlaceholder} ROWS"; + return $"{safeOrder}OFFSET {ParameterPlaceholder} ROWS"; } ctx.Bindings.Add(offset); ctx.Bindings.Add(limit); - return $"{safeOrder}OFFSET {parameterPlaceholder} ROWS FETCH NEXT {parameterPlaceholder} ROWS ONLY"; + return $"{safeOrder}OFFSET {ParameterPlaceholder} ROWS FETCH NEXT {ParameterPlaceholder} ROWS ONLY"; } public override string CompileRandom(string seed) @@ -173,11 +173,11 @@ protected override string CompileBasicDateCondition(SqlResult ctx, BasicDateCond protected override SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) { - var ctx = new SqlResult(); + var ctx = new SqlResult(this); var colNames = string.Join(", ", adHoc.Columns.Select(Wrap)); - var valueRow = string.Join(", ", Enumerable.Repeat(parameterPlaceholder, adHoc.Columns.Count)); + var valueRow = string.Join(", ", Enumerable.Repeat(ParameterPlaceholder, adHoc.Columns.Count)); var valueRows = string.Join(", ", Enumerable.Repeat($"({valueRow})", adHoc.Values.Count / adHoc.Columns.Count)); var sql = $"SELECT {colNames} FROM (VALUES {valueRows}) AS tbl ({colNames})"; diff --git a/QueryBuilder/Compilers/SqliteCompiler.cs b/QueryBuilder/Compilers/SqliteCompiler.cs index 1401dd35..08780c31 100644 --- a/QueryBuilder/Compilers/SqliteCompiler.cs +++ b/QueryBuilder/Compilers/SqliteCompiler.cs @@ -28,7 +28,7 @@ public override string CompileLimit(SqlResult ctx) if (limit == 0 && offset > 0) { ctx.Bindings.Add(offset); - return $"LIMIT -1 OFFSET {parameterPlaceholder}"; + return $"LIMIT -1 OFFSET {ParameterPlaceholder}"; } return base.CompileLimit(ctx); diff --git a/QueryBuilder/SqlResult.cs b/QueryBuilder/SqlResult.cs index 58a7b722..d66f73d2 100644 --- a/QueryBuilder/SqlResult.cs +++ b/QueryBuilder/SqlResult.cs @@ -1,3 +1,4 @@ +using SqlKata.Compilers; using System; using System.Collections; using System.Collections.Generic; @@ -8,6 +9,13 @@ namespace SqlKata { public class SqlResult { + private readonly Compiler compiler; + + public SqlResult(Compiler compiler) + { + this.compiler = compiler; + } + public Query Query { get; set; } public string RawSql { get; set; } = ""; public List Bindings { get; set; } = new List(); @@ -16,21 +24,21 @@ public class SqlResult private static readonly Type[] NumberTypes = { - typeof(int), - typeof(long), - typeof(decimal), - typeof(double), - typeof(float), - typeof(short), - typeof(ushort), - typeof(ulong), - }; + typeof(int), + typeof(long), + typeof(decimal), + typeof(double), + typeof(float), + typeof(short), + typeof(ushort), + typeof(ulong), + }; public override string ToString() { var deepParameters = Helper.Flatten(Bindings).ToList(); - return Helper.ReplaceAll(RawSql, "?", i => + return Helper.ReplaceAll(RawSql, compiler.ParameterPlaceholder, i => { if (i >= deepParameters.Count) { @@ -81,7 +89,7 @@ private string ChangeToSqlValue(object value) } // fallback to string - return "'" + value.ToString().Replace("'","''") + "'"; + return "'" + value.ToString().Replace("'", "''") + "'"; } } }