Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SqlResult Overrides #594

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 52 additions & 23 deletions QueryBuilder/Compilers/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@ namespace SqlKata.Compilers
public partial class Compiler
{
private readonly ConditionsCompilerProvider _compileConditionMethodsProvider;
/// <summary> </summary>
protected virtual string parameterPlaceholder { get; set; } = "?";
/// <summary> </summary>
protected virtual string parameterPrefix { get; set; } = "@p";
/// <summary> Character used to identify the start of a keyword ( such as a column or table name ) </summary>
protected virtual string OpeningIdentifier { get; set; } = "\"";
/// <summary> Character used to identify the end of a keyword ( such as a column or table name ) </summary>
protected virtual string ClosingIdentifier { get; set; } = "\"";
/// <summary> Keyword used to indicate a column alias </summary>
protected virtual string ColumnAsKeyword { get; set; } = "AS ";
/// <summary> Keyword used to indicate a table alias </summary>
protected virtual string TableAsKeyword { get; set; } = "AS ";
/// <summary> </summary>
protected virtual string LastId { get; set; } = "";
/// <summary> Character used to escape special characters to allow interpreting them as their literal value </summary>
protected virtual string EscapeCharacter { get; set; } = "\\";

protected Compiler()
Expand All @@ -41,6 +49,10 @@ protected Compiler()
"similar to", "not similar to"
};

/// <summary>
/// A list of white-listed operators specific to this compiler
/// </summary>
/// <value></value>
protected HashSet<string> userOperators = new HashSet<string>
{

Expand Down Expand Up @@ -170,11 +182,9 @@ public virtual SqlResult Compile(IEnumerable<Query> 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);

Expand All @@ -183,10 +193,7 @@ public virtual SqlResult Compile(IEnumerable<Query> 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),
Expand All @@ -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)}"));

Expand All @@ -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))
{
Expand Down Expand Up @@ -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))
{
Expand Down Expand Up @@ -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))
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -940,6 +938,27 @@ public virtual string Parameter(SqlResult ctx, object parameter)
return "?";
}

/// <summary>
/// Create a new <see cref="SqlResult"/> object
/// </summary>
/// <returns></returns>
public virtual SqlResult GetNewSqlResult()
{
return new SqlResult();
}

/// <summary>
/// Create a new <see cref="SqlResult"/> object via <see cref="GetNewSqlResult()"/>, then assign the <paramref name="query"/> to it
/// </summary>
/// <param name="query">The query to assign to the object</param>
/// <returns></returns>
public SqlResult GetNewSqlResult(Query query)
{
SqlResult ctx = GetNewSqlResult();
ctx.Query = query;
return ctx;
}

/// <summary>
/// Create query parameter place-holders for an array.
/// </summary>
Expand All @@ -961,6 +980,16 @@ public virtual List<string> WrapArray(List<string> values)
return values.Select(x => Wrap(x)).ToList();
}

/// <summary>
/// Replaces opening/closing braces and brackets if the character is not preceeded by the <see cref="EscapeCharacter"/>
/// <br/> { [ --> Replaced by <see cref="OpeningIdentifier"/>
/// <br/> } ] --> Replaced by <see cref="ClosingIdentifier"/>
/// </summary>
/// <param name="input">string to wrap with <see cref="OpeningIdentifier"/> and <see cref="ClosingIdentifier"/></param>
/// <returns>
/// {text} --> <see cref="OpeningIdentifier"/> + "text" + <see cref="ClosingIdentifier"/>
/// <br/> [text] --> <see cref="OpeningIdentifier"/> + "text" + <see cref="ClosingIdentifier"/>
/// </returns>
public virtual string WrapIdentifiers(string input)
{
return input
Expand Down
7 changes: 2 additions & 5 deletions QueryBuilder/Compilers/SqlServerCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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));

Expand Down
17 changes: 17 additions & 0 deletions QueryBuilder/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,23 @@ public static IEnumerable<string> Repeat(this string str, int count)
return Enumerable.Repeat(str, count);
}

/// <summary>
/// Replace instances of the <paramref name="identifier"/> within the string with the <paramref name="newIdentifier"/>, unless the <paramref name="identifier"/> was escaped via the <paramref name="escapeCharacter"/>
/// </summary>
/// <param name="input">input string to modify</param>
/// <param name="escapeCharacter">escape character to search for within the string</param>
/// <param name="identifier">string to search for and replace with <paramref name="newIdentifier"/></param>
/// <param name="newIdentifier">string that will replace instances of <paramref name="identifier"/> that have not been escaped</param>
/// <returns>
///Example ( Not Escaped ) :
///<br/> Input = [ Test ] , <paramref name="escapeCharacter"/> = '\', <paramref name="identifier"/> = '[', <paramref name="newIdentifier"/> = '{'
///<br/> Result: { Test ]
///<para/>
///Example ( Escaped ) :
///<br/> Input = \[ Test ] , <paramref name="escapeCharacter"/> = '\', <paramref name="identifier"/> = '[', <paramref name="newIdentifier"/> = '{'
///<br/> Result: [ Test ]
///<br/>
/// </returns>
public static string ReplaceIdentifierUnlessEscaped(this string input, string escapeCharacter, string identifier, string newIdentifier)
{
//Replace standard, non-escaped identifiers first
Expand Down
28 changes: 26 additions & 2 deletions QueryBuilder/SqlResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace SqlKata
{
public class SqlResult
{
public SqlResult() { }

public Query Query { get; set; }
public string RawSql { get; set; } = "";
public List<object> Bindings { get; set; } = new List<object>();
Expand All @@ -26,6 +28,7 @@ public class SqlResult
typeof(ulong),
};

/// <inheritdoc/>
public override string ToString()
{
var deepParameters = Helper.Flatten(Bindings).ToList();
Expand All @@ -43,7 +46,12 @@ public override string ToString()
});
}

private string ChangeToSqlValue(object value)
/// <summary>
/// Convert each value to its string representation
/// </summary>
/// <param name="value">value to convert</param>
/// <returns>string representation of the <paramref name="value"/></returns>
protected virtual string ChangeToSqlValue(object value)
{
if (value == null)
{
Expand Down Expand Up @@ -81,7 +89,23 @@ private string ChangeToSqlValue(object value)
}

// fallback to string
return "'" + value.ToString().Replace("'","''") + "'";
return WrapStringValue(value.ToString());
}

/// <summary>
/// Wrap a string value with identifiers
/// </summary>
/// <param name="value">string parameter</param>
/// <returns></returns>
/// <remarks>
/// Default Functionality wraps in single quotes
/// <br/> value --> 'value'
/// <br/> 'value' --> ''value'''
/// </remarks>
protected virtual string WrapStringValue(string value)
{
return "'" + value.ToString().Replace("'", "''") + "'";
}

}
}