From ee0d467e51474fa32dff97128d7b908b9c7dc2ee Mon Sep 17 00:00:00 2001 From: RFBomb Date: Thu, 11 Aug 2022 11:56:52 -0400 Subject: [PATCH 1/4] Update SqlResult.cs Allow Overrides when creating the string parameters --- QueryBuilder/SqlResult.cs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/QueryBuilder/SqlResult.cs b/QueryBuilder/SqlResult.cs index 58a7b722..679fc7d4 100644 --- a/QueryBuilder/SqlResult.cs +++ b/QueryBuilder/SqlResult.cs @@ -8,6 +8,8 @@ namespace SqlKata { public class SqlResult { + public SqlResult() { } + public Query Query { get; set; } public string RawSql { get; set; } = ""; public List Bindings { get; set; } = new List(); @@ -26,6 +28,7 @@ public class SqlResult typeof(ulong), }; + /// public override string ToString() { var deepParameters = Helper.Flatten(Bindings).ToList(); @@ -43,7 +46,12 @@ public override string ToString() }); } - private string ChangeToSqlValue(object value) + /// + /// Convert each value to its string representation + /// + /// value to convert + /// string representation of the + protected virtual string ChangeToSqlValue(object value) { if (value == null) { @@ -81,7 +89,23 @@ private string ChangeToSqlValue(object value) } // fallback to string - return "'" + value.ToString().Replace("'","''") + "'"; + return WrapStringValue(value.ToString()); } + + /// + /// Wrap a string value with identifiers + /// + /// string parameter + /// + /// + /// Default Functionality wraps in single quotes + ///
value --> 'value' + ///
'value' --> ''value''' + ///
+ protected virtual string WrapStringValue(string value) + { + return "'" + value.ToString().Replace("'", "''") + "'"; + } + } } From 4d507646b73f4dd6f0ea14fc14db4fe918fdd7e1 Mon Sep 17 00:00:00 2001 From: RFBomb Date: Thu, 11 Aug 2022 12:00:11 -0400 Subject: [PATCH 2/4] Update Compiler.cs Create method for instantiating the SqlResult object to allow for using derived classes instead --- QueryBuilder/Compilers/Compiler.cs | 75 +++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/QueryBuilder/Compilers/Compiler.cs b/QueryBuilder/Compilers/Compiler.cs index f670bdb8..07cbda7c 100644 --- a/QueryBuilder/Compilers/Compiler.cs +++ b/QueryBuilder/Compilers/Compiler.cs @@ -8,13 +8,21 @@ namespace SqlKata.Compilers public partial class Compiler { private readonly ConditionsCompilerProvider _compileConditionMethodsProvider; + /// protected virtual string parameterPlaceholder { get; set; } = "?"; + /// protected virtual string parameterPrefix { get; set; } = "@p"; + /// Character used to identify the start of a keyword ( such as a column or table name ) protected virtual string OpeningIdentifier { get; set; } = "\""; + /// Character used to identify the end of a keyword ( such as a column or table name ) protected virtual string ClosingIdentifier { get; set; } = "\""; + /// Keyword used to indicate a column alias protected virtual string ColumnAsKeyword { get; set; } = "AS "; + /// Keyword used to indicate a table alias protected virtual string TableAsKeyword { get; set; } = "AS "; + /// protected virtual string LastId { get; set; } = ""; + /// Character used to escape special characters to allow interpreting them as their literal value protected virtual string EscapeCharacter { get; set; } = "\\"; protected Compiler() @@ -41,6 +49,10 @@ protected Compiler() "similar to", "not similar to" }; + /// + /// A list of white-listed operators specific to this compiler + /// + /// protected HashSet userOperators = new HashSet { @@ -170,11 +182,9 @@ public virtual SqlResult Compile(IEnumerable queries) combinedBindings.AddRange(cb); } - var ctx = new SqlResult - { - RawSql = compiled.Select(r => r.RawSql).Aggregate((a, b) => a + ";\n" + b), - Bindings = combinedBindings, - }; + var ctx = GetNewSqlResult(); + ctx.RawSql = compiled.Select(r => r.RawSql).Aggregate((a, b) => a + ";\n" + b); + ctx.Bindings = combinedBindings; ctx = PrepareResult(ctx); @@ -183,10 +193,7 @@ public virtual SqlResult Compile(IEnumerable queries) protected virtual SqlResult CompileSelectQuery(Query query) { - var ctx = new SqlResult - { - Query = query.Clone(), - }; + var ctx = GetNewSqlResult(query.Clone()); var results = new[] { this.CompileColumns(ctx), @@ -212,7 +219,7 @@ protected virtual SqlResult CompileSelectQuery(Query query) protected virtual SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) { - var ctx = new SqlResult(); + var ctx = GetNewSqlResult(); var row = "SELECT " + string.Join(", ", adHoc.Columns.Select(col => $"? AS {Wrap(col)}")); @@ -233,10 +240,7 @@ protected virtual SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) protected virtual SqlResult CompileDeleteQuery(Query query) { - var ctx = new SqlResult - { - Query = query - }; + var ctx = GetNewSqlResult(query); if (!ctx.Query.HasComponent("from", EngineCode)) { @@ -277,10 +281,7 @@ protected virtual SqlResult CompileDeleteQuery(Query query) protected virtual SqlResult CompileUpdateQuery(Query query) { - var ctx = new SqlResult - { - Query = query - }; + var ctx = GetNewSqlResult(query); if (!ctx.Query.HasComponent("from", EngineCode)) { @@ -355,10 +356,7 @@ protected virtual SqlResult CompileUpdateQuery(Query query) protected virtual SqlResult CompileInsertQuery(Query query) { - var ctx = new SqlResult - { - Query = query - }; + var ctx = GetNewSqlResult(query); if (!ctx.Query.HasComponent("from", EngineCode)) { @@ -501,7 +499,7 @@ public virtual string CompileColumn(SqlResult ctx, AbstractColumn column) public virtual SqlResult CompileCte(AbstractFrom cte) { - var ctx = new SqlResult(); + var ctx = GetNewSqlResult(); if (null == cte) { @@ -940,6 +938,27 @@ public virtual string Parameter(SqlResult ctx, object parameter) return "?"; } + /// + /// Create a new object + /// + /// + public virtual SqlResult GetNewSqlResult() + { + return new SqlResult(); + } + + /// + /// Create a new object via , then assign the to it + /// + /// The query to assign to the object + /// + public SqlResult GetNewSqlResult(Query query) + { + SqlResult ctx = GetNewSqlResult(); + ctx.Query = query; + return ctx; + } + /// /// Create query parameter place-holders for an array. /// @@ -961,6 +980,16 @@ public virtual List WrapArray(List values) return values.Select(x => Wrap(x)).ToList(); } + /// + /// Replaces opening/closing braces and brackets if the character is not preceeded by the + ///
{ [ --> Replaced by + ///
} ] --> Replaced by + ///
+ /// string to wrap with and + /// + /// {text} --> + "text" + + ///
[text] --> + "text" + + ///
public virtual string WrapIdentifiers(string input) { return input From f1a7669d9791f202c3f4bb2440b8adcae633574e Mon Sep 17 00:00:00 2001 From: RFBomb Date: Thu, 11 Aug 2022 12:01:12 -0400 Subject: [PATCH 3/4] Update SqlServerCompiler.cs --- QueryBuilder/Compilers/SqlServerCompiler.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/QueryBuilder/Compilers/SqlServerCompiler.cs b/QueryBuilder/Compilers/SqlServerCompiler.cs index f9aee65e..274e4abd 100644 --- a/QueryBuilder/Compilers/SqlServerCompiler.cs +++ b/QueryBuilder/Compilers/SqlServerCompiler.cs @@ -23,10 +23,7 @@ protected override SqlResult CompileSelectQuery(Query query) query = query.Clone(); - var ctx = new SqlResult - { - Query = query, - }; + var ctx = GetNewSqlResult(query); var limit = query.GetLimit(EngineCode); var offset = query.GetOffset(EngineCode); @@ -173,7 +170,7 @@ protected override string CompileBasicDateCondition(SqlResult ctx, BasicDateCond protected override SqlResult CompileAdHocQuery(AdHocTableFromClause adHoc) { - var ctx = new SqlResult(); + var ctx = GetNewSqlResult(); var colNames = string.Join(", ", adHoc.Columns.Select(Wrap)); From b36ee661f0b1b4030849d164cb87a9ee2de5b5d6 Mon Sep 17 00:00:00 2001 From: RFBomb Date: Thu, 11 Aug 2022 12:02:45 -0400 Subject: [PATCH 4/4] Add xml documentation to Helper.cs --- QueryBuilder/Helper.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/QueryBuilder/Helper.cs b/QueryBuilder/Helper.cs index 218a95e3..9417c2ca 100644 --- a/QueryBuilder/Helper.cs +++ b/QueryBuilder/Helper.cs @@ -161,6 +161,23 @@ public static IEnumerable Repeat(this string str, int count) return Enumerable.Repeat(str, count); } + /// + /// Replace instances of the within the string with the , unless the was escaped via the + /// + /// input string to modify + /// escape character to search for within the string + /// string to search for and replace with + /// string that will replace instances of that have not been escaped + /// + ///Example ( Not Escaped ) : + ///
Input = [ Test ] , = '\', = '[', = '{' + ///
Result: { Test ] + /// + ///Example ( Escaped ) : + ///
Input = \[ Test ] , = '\', = '[', = '{' + ///
Result: [ Test ] + ///
+ ///
public static string ReplaceIdentifierUnlessEscaped(this string input, string escapeCharacter, string identifier, string newIdentifier) { //Replace standard, non-escaped identifiers first