starts updating sqlexpressions to include sql params

This commit is contained in:
Shannon
2014-09-23 18:38:42 +10:00
parent 5dbedcf67b
commit d3365bc751
5 changed files with 283 additions and 168 deletions

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence
var expresionist = new PocoToSqlExpressionHelper<T>();
string whereExpression = expresionist.Visit(predicate);
return sql.Where(whereExpression);
return sql.Where(whereExpression, expresionist.GetSqlParameters());
}
public static Sql OrderBy<TColumn>(this Sql sql, Expression<Func<TColumn, object>> columnMember)

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -9,6 +10,13 @@ namespace Umbraco.Core.Persistence.Querying
/// </summary>
internal class BaseExpressionHelper
{
protected List<object> SqlParameters = new List<object>();
public object[] GetSqlParameters()
{
return SqlParameters.ToArray();
}
protected string HandleStringComparison(string col, string val, string verb, TextColumnType columnType)
{
switch (verb)
@@ -44,54 +52,54 @@ namespace Umbraco.Core.Persistence.Querying
}
}
public virtual string GetQuotedValue(object value, Type fieldType, Func<object, string> escapeCallback = null, Func<Type, bool> shouldQuoteCallback = null)
{
if (value == null) return "NULL";
//public virtual string GetQuotedValue(object value, Type fieldType, Func<object, string> escapeCallback = null, Func<Type, bool> shouldQuoteCallback = null)
//{
// if (value == null) return "NULL";
if (escapeCallback == null)
{
escapeCallback = EscapeParam;
}
if (shouldQuoteCallback == null)
{
shouldQuoteCallback = ShouldQuoteValue;
}
// if (escapeCallback == null)
// {
// escapeCallback = EscapeParam;
// }
// if (shouldQuoteCallback == null)
// {
// shouldQuoteCallback = ShouldQuoteValue;
// }
if (!fieldType.UnderlyingSystemType.IsValueType && fieldType != typeof(string))
{
//if (TypeSerializer.CanCreateFromString(fieldType))
//{
// return "'" + escapeCallback(TypeSerializer.SerializeToString(value)) + "'";
//}
// if (!fieldType.UnderlyingSystemType.IsValueType && fieldType != typeof(string))
// {
// //if (TypeSerializer.CanCreateFromString(fieldType))
// //{
// // return "'" + escapeCallback(TypeSerializer.SerializeToString(value)) + "'";
// //}
throw new NotSupportedException(
string.Format("Property of type: {0} is not supported", fieldType.FullName));
}
// throw new NotSupportedException(
// string.Format("Property of type: {0} is not supported", fieldType.FullName));
// }
if (fieldType == typeof(int))
return ((int)value).ToString(CultureInfo.InvariantCulture);
// if (fieldType == typeof(int))
// return ((int)value).ToString(CultureInfo.InvariantCulture);
if (fieldType == typeof(float))
return ((float)value).ToString(CultureInfo.InvariantCulture);
// if (fieldType == typeof(float))
// return ((float)value).ToString(CultureInfo.InvariantCulture);
if (fieldType == typeof(double))
return ((double)value).ToString(CultureInfo.InvariantCulture);
// if (fieldType == typeof(double))
// return ((double)value).ToString(CultureInfo.InvariantCulture);
if (fieldType == typeof(decimal))
return ((decimal)value).ToString(CultureInfo.InvariantCulture);
// if (fieldType == typeof(decimal))
// return ((decimal)value).ToString(CultureInfo.InvariantCulture);
if (fieldType == typeof(DateTime))
{
return "'" + escapeCallback(((DateTime)value).ToIsoString()) + "'";
}
// if (fieldType == typeof(DateTime))
// {
// return "'" + escapeCallback(((DateTime)value).ToIsoString()) + "'";
// }
if (fieldType == typeof(bool))
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
// if (fieldType == typeof(bool))
// return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
return shouldQuoteCallback(fieldType)
? "'" + escapeCallback(value) + "'"
: value.ToString();
}
// return shouldQuoteCallback(fieldType)
// ? "'" + escapeCallback(value) + "'"
// : value.ToString();
//}
public virtual string EscapeParam(object paramValue)
{

View File

@@ -13,7 +13,7 @@ namespace Umbraco.Core.Persistence.Querying
internal class ModelToSqlExpressionHelper<T> : BaseExpressionHelper
{
private string sep = " ";
private BaseMapper _mapper;
private readonly BaseMapper _mapper;
public ModelToSqlExpressionHelper()
{
@@ -88,7 +88,11 @@ namespace Umbraco.Core.Persistence.Querying
if (m.Expression != null)
{
string r = VisitMemberAccess(m);
return string.Format("{0}={1}", r, GetQuotedTrueValue());
SqlParameters.Add(1);
return string.Format("{0}=@{1}", r, SqlParameters.Count - 1);
//return string.Format("{0}={1}", r, GetQuotedTrueValue());
}
}
@@ -105,7 +109,11 @@ namespace Umbraco.Core.Persistence.Querying
if (m != null && m.Expression != null)
{
string r = VisitMemberAccess(m);
left = string.Format("{0}={1}", r, GetQuotedTrueValue());
SqlParameters.Add(1);
left = string.Format("{0}=@{1}", r, SqlParameters.Count - 1);
//left = string.Format("{0}={1}", r, GetQuotedTrueValue());
}
else
{
@@ -115,7 +123,11 @@ namespace Umbraco.Core.Persistence.Querying
if (m != null && m.Expression != null)
{
string r = VisitMemberAccess(m);
right = string.Format("{0}={1}", r, GetQuotedTrueValue());
SqlParameters.Add(1);
right = string.Format("{0}=@{1}", r, SqlParameters.Count - 1);
//right = string.Format("{0}={1}", r, GetQuotedTrueValue());
}
else
{
@@ -132,11 +144,11 @@ namespace Umbraco.Core.Persistence.Querying
else if (operand == "<>" && right == "null") operand = "is not";
else if (operand == "=" || operand == "<>")
{
if (IsTrueExpression(right)) right = GetQuotedTrueValue();
else if (IsFalseExpression(right)) right = GetQuotedFalseValue();
//if (IsTrueExpression(right)) right = GetQuotedTrueValue();
//else if (IsFalseExpression(right)) right = GetQuotedFalseValue();
if (IsTrueExpression(left)) left = GetQuotedTrueValue();
else if (IsFalseExpression(left)) left = GetQuotedFalseValue();
//if (IsTrueExpression(left)) left = GetQuotedTrueValue();
//else if (IsFalseExpression(left)) left = GetQuotedFalseValue();
}
@@ -168,7 +180,11 @@ namespace Umbraco.Core.Persistence.Querying
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
object o = getter();
return GetQuotedValue(o, o != null ? o.GetType() : null);
SqlParameters.Add(o);
return string.Format("(@{0})", SqlParameters.Count - 1);
//return GetQuotedValue(o, o != null ? o.GetType() : null);
}
@@ -181,7 +197,11 @@ namespace Umbraco.Core.Persistence.Querying
{
var getter = lambda.Compile();
object o = getter();
return GetQuotedValue(o, o.GetType());
SqlParameters.Add(o);
return string.Format("(@{0})", SqlParameters.Count - 1);
//return GetQuotedValue(o, o.GetType());
}
catch (System.InvalidOperationException)
{ // FieldName ?
@@ -205,26 +225,31 @@ namespace Umbraco.Core.Persistence.Querying
{
if (c.Value == null)
return "null";
if (c.Value is bool)
{
object o = GetQuotedValue(c.Value, c.Value.GetType());
return string.Format("({0}={1})", GetQuotedTrueValue(), o);
}
return GetQuotedValue(c.Value, c.Value.GetType());
SqlParameters.Add(c.Value);
return string.Format("(@{0})", SqlParameters.Count - 1);
//if (c.Value is bool)
//{
// object o = GetQuotedValue(c.Value, c.Value.GetType());
// return string.Format("({0}={1})", GetQuotedTrueValue(), o);
//}
//return GetQuotedValue(c.Value, c.Value.GetType());
}
protected virtual string VisitUnary(UnaryExpression u)
{
switch (u.NodeType)
{
case ExpressionType.Not:
string o = Visit(u.Operand);
if (IsFieldName(o)) o = o + "=" + GetQuotedValue(true, typeof(bool));
return "NOT (" + o + ")";
default:
return Visit(u.Operand);
}
//switch (u.NodeType)
//{
// case ExpressionType.Not:
// string o = Visit(u.Operand);
// if (IsFieldName(o)) o = o + "=" + GetQuotedValue(true, typeof(bool));
// return "NOT (" + o + ")";
// default:
// return Visit(u.Operand);
//}
return Visit(u.Operand);
}
protected virtual string VisitMethodCall(MethodCallExpression m)
@@ -316,18 +341,30 @@ namespace Umbraco.Core.Persistence.Querying
{
if (e.GetType().ToString() != "System.Collections.Generic.List`1[System.Object]")
{
SqlParameters.Add(e);
sIn.AppendFormat("{0}{1}",
sIn.Length > 0 ? "," : "",
GetQuotedValue(e, e.GetType()));
string.Format("@{0}", SqlParameters.Count - 1));
//sIn.AppendFormat("{0}{1}",
// sIn.Length > 0 ? "," : "",
// GetQuotedValue(e, e.GetType()));
}
else
{
var listArgs = e as IList<Object>;
foreach (Object el in listArgs)
{
SqlParameters.Add(el);
sIn.AppendFormat("{0}{1}",
sIn.Length > 0 ? "," : "",
GetQuotedValue(el, el.GetType()));
string.Format("@{0}", SqlParameters.Count - 1));
//sIn.AppendFormat("{0}{1}",
// sIn.Length > 0 ? "," : "",
// GetQuotedValue(el, el.GetType()));
}
}
}
@@ -342,12 +379,15 @@ namespace Umbraco.Core.Persistence.Querying
case "ToString":
return r.ToString();
default:
var s2 = new StringBuilder();
foreach (Object e in args)
{
s2.AppendFormat(",{0}", GetQuotedValue(e, e.GetType()));
}
return string.Format("{0}({1}{2})", m.Method.Name, r, s2.ToString());
return r.ToString();
//var s2 = new StringBuilder();
//foreach (Object e in args)
//{
// s2.AppendFormat(",{0}", GetQuotedValue(e, e.GetType()));
//}
//return string.Format("{0}({1}{2})", m.Method.Name, r, s2.ToString());
}
}
@@ -443,44 +483,44 @@ namespace Umbraco.Core.Persistence.Querying
return string.Format("\"{0}\"", name);
}
private string GetQuotedTrueValue()
{
return GetQuotedValue(true, typeof(bool));
}
//private string GetQuotedTrueValue()
//{
// return GetQuotedValue(true, typeof(bool));
//}
private string GetQuotedFalseValue()
{
return GetQuotedValue(false, typeof(bool));
}
//private string GetQuotedFalseValue()
//{
// return GetQuotedValue(false, typeof(bool));
//}
public virtual string GetQuotedValue(object value, Type fieldType)
{
return GetQuotedValue(value, fieldType, EscapeParam, ShouldQuoteValue);
}
//public virtual string GetQuotedValue(object value, Type fieldType)
//{
// return GetQuotedValue(value, fieldType, EscapeParam, ShouldQuoteValue);
//}
private string GetTrueExpression()
{
object o = GetQuotedTrueValue();
return string.Format("({0}={1})", o, o);
}
//private string GetTrueExpression()
//{
// object o = GetQuotedTrueValue();
// return string.Format("({0}={1})", o, o);
//}
private string GetFalseExpression()
{
//private string GetFalseExpression()
//{
return string.Format("({0}={1})",
GetQuotedTrueValue(),
GetQuotedFalseValue());
}
// return string.Format("({0}={1})",
// GetQuotedTrueValue(),
// GetQuotedFalseValue());
//}
private bool IsTrueExpression(string exp)
{
return (exp == GetTrueExpression());
}
//private bool IsTrueExpression(string exp)
//{
// return (exp == GetTrueExpression());
//}
private bool IsFalseExpression(string exp)
{
return (exp == GetFalseExpression());
}
//private bool IsFalseExpression(string exp)
//{
// return (exp == GetFalseExpression());
//}
protected bool IsFieldName(string quotedExp)
{

View File

@@ -86,7 +86,11 @@ namespace Umbraco.Core.Persistence.Querying
if (m.Expression != null)
{
string r = VisitMemberAccess(m);
return string.Format("{0}={1}", r, GetQuotedTrueValue());
SqlParameters.Add(1);
return string.Format("{0}=@{1}", r, 1);
//return string.Format("{0}={1}", r, GetQuotedTrueValue());
}
}
@@ -103,7 +107,11 @@ namespace Umbraco.Core.Persistence.Querying
if (m != null && m.Expression != null)
{
string r = VisitMemberAccess(m);
left = string.Format("{0}={1}", r, GetQuotedTrueValue());
SqlParameters.Add(1);
left = string.Format("{0}=@{1}", r, SqlParameters.Count - 1);
//left = string.Format("{0}={1}", r, GetQuotedTrueValue());
}
else
{
@@ -113,7 +121,11 @@ namespace Umbraco.Core.Persistence.Querying
if (m != null && m.Expression != null)
{
string r = VisitMemberAccess(m);
right = string.Format("{0}={1}", r, GetQuotedTrueValue());
SqlParameters.Add(1);
right = string.Format("{0}=@{1}", r, SqlParameters.Count - 1);
//right = string.Format("{0}={1}", r, GetQuotedTrueValue());
}
else
{
@@ -130,11 +142,11 @@ namespace Umbraco.Core.Persistence.Querying
else if (operand == "<>" && right == "null") operand = "is not";
else if (operand == "=" || operand == "<>")
{
if (IsTrueExpression(right)) right = GetQuotedTrueValue();
else if (IsFalseExpression(right)) right = GetQuotedFalseValue();
//if (IsTrueExpression(right)) right = GetQuotedTrueValue();
//else if (IsFalseExpression(right)) right = GetQuotedFalseValue();
if (IsTrueExpression(left)) left = GetQuotedTrueValue();
else if (IsFalseExpression(left)) left = GetQuotedFalseValue();
//if (IsTrueExpression(left)) left = GetQuotedTrueValue();
//else if (IsFalseExpression(left)) left = GetQuotedFalseValue();
}
@@ -168,7 +180,11 @@ namespace Umbraco.Core.Persistence.Querying
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
object o = getter();
return GetQuotedValue(o, o != null ? o.GetType() : null);
SqlParameters.Add(o);
return string.Format("(@{0})", SqlParameters.Count - 1);
//return GetQuotedValue(o, o != null ? o.GetType() : null);
}
@@ -181,9 +197,13 @@ namespace Umbraco.Core.Persistence.Querying
{
var getter = lambda.Compile();
object o = getter();
return GetQuotedValue(o, o.GetType());
SqlParameters.Add(o);
return string.Format("(@{0})", SqlParameters.Count - 1);
//return GetQuotedValue(o, o.GetType());
}
catch (System.InvalidOperationException)
catch (InvalidOperationException)
{ // FieldName ?
List<Object> exprs = VisitExpressionList(nex.Arguments);
var r = new StringBuilder();
@@ -207,26 +227,37 @@ namespace Umbraco.Core.Persistence.Querying
{
if (c.Value == null)
return "null";
else if (c.Value.GetType() == typeof(bool))
{
object o = GetQuotedValue(c.Value, c.Value.GetType());
return string.Format("({0}={1})", GetQuotedTrueValue(), o);
}
else
return GetQuotedValue(c.Value, c.Value.GetType());
SqlParameters.Add(c.Value);
return string.Format("(@{0})", SqlParameters.Count - 1);
//if (c.Value is bool)
//{
// object o = GetQuotedValue(c.Value, c.Value.GetType());
// SqlParameters.Add(o);
// return string.Format("({0}=@{1})", GetQuotedTrueValue(), SqlParameters.Count);
//}
//return GetQuotedValue(c.Value, c.Value.GetType());
}
protected virtual string VisitUnary(UnaryExpression u)
{
switch (u.NodeType)
{
case ExpressionType.Not:
string o = Visit(u.Operand);
if (IsFieldName(o)) o = o + "=" + GetQuotedValue(true, typeof(bool));
return "NOT (" + o + ")";
default:
return Visit(u.Operand);
}
//switch (u.NodeType)
//{
// case ExpressionType.Not:
// string o = Visit(u.Operand);
// if (IsFieldName(o))
// o = o + "=" + GetQuotedValue(true, typeof(bool));
// return "NOT (" + o + ")";
// default:
// return Visit(u.Operand);
//}
return Visit(u.Operand);
}
@@ -323,18 +354,30 @@ namespace Umbraco.Core.Persistence.Querying
{
if (e.GetType().ToString() != "System.Collections.Generic.List`1[System.Object]")
{
SqlParameters.Add(e);
sIn.AppendFormat("{0}{1}",
sIn.Length > 0 ? "," : "",
GetQuotedValue(e, e.GetType()));
string.Format("@{0}", SqlParameters.Count - 1));
//sIn.AppendFormat("{0}{1}",
// sIn.Length > 0 ? "," : "",
// GetQuotedValue(e, e.GetType()));
}
else
{
var listArgs = e as IList<Object>;
foreach (Object el in listArgs)
{
SqlParameters.Add(el);
sIn.AppendFormat("{0}{1}",
sIn.Length > 0 ? "," : "",
GetQuotedValue(el, el.GetType()));
string.Format("@{0}", SqlParameters.Count - 1));
//sIn.AppendFormat("{0}{1}",
// sIn.Length > 0 ? "," : "",
// GetQuotedValue(el, el.GetType()));
}
}
}
@@ -349,12 +392,15 @@ namespace Umbraco.Core.Persistence.Querying
case "ToString":
return r.ToString();
default:
var s2 = new StringBuilder();
foreach (Object e in args)
{
s2.AppendFormat(",{0}", GetQuotedValue(e, e.GetType()));
}
return string.Format("{0}({1}{2})", m.Method.Name, r, s2.ToString());
return r.ToString();
//var s2 = new StringBuilder();
//foreach (Object e in args)
//{
// s2.AppendFormat(",{0}", GetQuotedValue(e, e.GetType()));
//}
//return string.Format("{0}({1}{2})", m.Method.Name, r, s2.ToString());
}
}
@@ -450,20 +496,20 @@ namespace Umbraco.Core.Persistence.Querying
return string.Format("\"{0}\"", name);
}
private string GetQuotedTrueValue()
{
return GetQuotedValue(true, typeof(bool));
}
//private string GetQuotedTrueValue()
//{
// return GetQuotedValue(true, typeof(bool));
//}
private string GetQuotedFalseValue()
{
return GetQuotedValue(false, typeof(bool));
}
//private string GetQuotedFalseValue()
//{
// return GetQuotedValue(false, typeof(bool));
//}
public virtual string GetQuotedValue(object value, Type fieldType)
{
return GetQuotedValue(value, fieldType, EscapeParam, ShouldQuoteValue);
}
//public virtual string GetQuotedValue(object value, Type fieldType)
//{
// return GetQuotedValue(value, fieldType, EscapeParam, ShouldQuoteValue);
//}
protected virtual string GetFieldName(Database.PocoData pocoData, string name)
{
@@ -473,29 +519,29 @@ namespace Umbraco.Core.Persistence.Querying
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(column.Value.ColumnName));
}
private string GetTrueExpression()
{
object o = GetQuotedTrueValue();
return string.Format("({0}={1})", o, o);
}
//private string GetTrueExpression()
//{
// object o = GetQuotedTrueValue();
// return string.Format("({0}={1})", o, o);
//}
private string GetFalseExpression()
{
//private string GetFalseExpression()
//{
return string.Format("({0}={1})",
GetQuotedTrueValue(),
GetQuotedFalseValue());
}
// return string.Format("({0}={1})",
// GetQuotedTrueValue(),
// GetQuotedFalseValue());
//}
private bool IsTrueExpression(string exp)
{
return (exp == GetTrueExpression());
}
//private bool IsTrueExpression(string exp)
//{
// return (exp == GetTrueExpression());
//}
private bool IsFalseExpression(string exp)
{
return (exp == GetFalseExpression());
}
//private bool IsFalseExpression(string exp)
//{
// return (exp == GetFalseExpression());
//}
protected bool IsFieldName(string quotedExp)
{

View File

@@ -13,6 +13,27 @@ namespace Umbraco.Tests.Persistence.Querying
public class PetaPocoSqlTests : BaseUsingSqlCeSyntax
{
[Test]
public void Generates_Sql_Parameter_Where_Clause_Single_Constant()
{
var sql = new Sql("SELECT *").From<NodeDto>().Where<NodeDto>(x => x.NodeId == 2);
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ([umbracoNode].[id] = (@0))", sql.SQL.Replace("\n", " "));
Assert.AreEqual(1, sql.Arguments.Length);
Assert.AreEqual(2, sql.Arguments[0]);
}
[Test]
public void Generates_Sql_Parameter_Where_Clause_And_Constant()
{
var sql = new Sql("SELECT *").From<NodeDto>().Where<NodeDto>(x => x.NodeId != 2 && x.NodeId != 3);
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ([umbracoNode].[id] <> (@0) AND [umbracoNode].[id] <> (@1))", sql.SQL.Replace("\n", " "));
Assert.AreEqual(2, sql.Arguments.Length);
Assert.AreEqual(2, sql.Arguments[0]);
Assert.AreEqual(3, sql.Arguments[0]);
}
[Test]
public void Can_Select_From_With_Type()
{