static void BuildSkip(ExpressionBuilder builder, IBuildContext sequence, ISqlExpression prevSkipValue, ISqlExpression expr) { var sql = sequence.SqlQuery; builder.SqlProvider.SqlQuery = sql; sql.Select.Skip(expr); builder.SqlProvider.SqlQuery = sql; if (sql.Select.TakeValue != null) { if (builder.DataContextInfo.SqlProviderFlags.GetIsSkipSupportedFlag(sql) || !builder.DataContextInfo.SqlProviderFlags.IsTakeSupported) sql.Select.Take(builder.Convert( sequence, new SqlBinaryExpression(typeof(int), sql.Select.TakeValue, "-", sql.Select.SkipValue, Precedence.Additive))); if (prevSkipValue != null) sql.Select.Skip(builder.Convert( sequence, new SqlBinaryExpression(typeof(int), prevSkipValue, "+", sql.Select.SkipValue, Precedence.Additive))); } if (!builder.DataContextInfo.SqlProviderFlags.GetAcceptsTakeAsParameterFlag(sql)) { var p = sql.Select.SkipValue as SqlParameter; if (p != null) p.IsQueryParameter = false; } }
protected override void BuildFunction(StringBuilder sb, SqlFunction func) { func = ConvertFunctionParameters(func); switch (func.Name) { case "CASE" : func = ConvertCase(func.SystemType, func.Parameters, 0); break; case "Coalesce" : if (func.Parameters.Length > 2) { var parms = new ISqlExpression[func.Parameters.Length - 1]; Array.Copy(func.Parameters, 1, parms, 0, parms.Length); BuildFunction(sb, new SqlFunction(func.SystemType, func.Name, func.Parameters[0], new SqlFunction(func.SystemType, func.Name, parms))); return; } var sc = new SqlQuery.SearchCondition(); sc.Conditions.Add(new SqlQuery.Condition(false, new SqlQuery.Predicate.IsNull(func.Parameters[0], false))); func = new SqlFunction(func.SystemType, "IIF", sc, func.Parameters[1], func.Parameters[0]); break; } base.BuildFunction(sb, func); }
static void ParseSkip(ExpressionParser parser, IParseContext sequence, ISqlExpression prevSkipValue, ISqlExpression expr) { var sql = sequence.SqlQuery; parser.SqlProvider.SqlQuery = sql; sql.Select.Skip(expr); parser.SqlProvider.SqlQuery = sql; if (sql.Select.TakeValue != null) { if (parser.SqlProvider.IsSkipSupported || !parser.SqlProvider.IsTakeSupported) sql.Select.Take(parser.Convert( sequence, new SqlBinaryExpression(typeof(int), sql.Select.TakeValue, "-", sql.Select.SkipValue, Precedence.Additive))); if (prevSkipValue != null) sql.Select.Skip(parser.Convert( sequence, new SqlBinaryExpression(typeof(int), prevSkipValue, "+", sql.Select.SkipValue, Precedence.Additive))); } if (!parser.SqlProvider.TakeAcceptsParameter) { var p = sql.Select.SkipValue as SqlParameter; if (p != null) p.IsQueryParameter = false; } }
protected ISqlExpression[] ConvertArgs(MemberInfo member, ISqlExpression[] args) { if (member is MethodInfo) { var method = (MethodInfo)member; if (method.DeclaringType.IsGenericType) args = args.Concat(method.DeclaringType.GetGenericArguments().Select(t => (ISqlExpression)SqlDataType.GetDataType(t))).ToArray(); if (method.IsGenericMethod) args = args.Concat(method.GetGenericArguments().Select(t => (ISqlExpression)SqlDataType.GetDataType(t))).ToArray(); } if (ArgIndices != null) { var idxs = new ISqlExpression[ArgIndices.Length]; for (var i = 0; i < ArgIndices.Length; i++) idxs[i] = args[ArgIndices[i]]; return idxs; } return args; }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); switch (expr.ElementType) { case QueryElementType.SqlBinaryExpression: { var be = (SqlBinaryExpression)expr; switch (be.Operation) { case "%": { var type1 = TypeHelper.GetUnderlyingType(be.Expr1.SystemType); if (type1 == typeof(double) || type1 == typeof(float)) { return new SqlBinaryExpression( be.Expr2.SystemType, new SqlFunction(typeof(int), "Convert", SqlDataType.Int32, be.Expr1), be.Operation, be.Expr2); } break; } } break; } case QueryElementType.SqlFunction: { var func = (SqlFunction)expr; switch (func.Name) { case "Convert" : { if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(ulong) && TypeHelper.IsFloatType(func.Parameters[1].SystemType)) return new SqlFunction( func.SystemType, func.Name, func.Precedence, func.Parameters[0], new SqlFunction(func.SystemType, "Floor", func.Parameters[1])); break; } } break; } } return expr; }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlFunction) return ConvertConvertFunction((SqlFunction)expr); return expr; }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlBinaryExpression) { var be = (SqlBinaryExpression)expr; switch (be.Operation) { case "^": return new SqlBinaryExpression(be.SystemType, be.Expr1, "#", be.Expr2); case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; } } else if (expr is SqlFunction) { var func = (SqlFunction) expr; switch (func.Name) { case "Convert" : if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(bool)) { var ex = AlternativeConvertToBoolean(func, 1); if (ex != null) return ex; } return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0]); case "CharIndex" : return func.Parameters.Length == 2? new SqlExpression(func.SystemType, "Position({0} in {1})", Precedence.Primary, func.Parameters[0], func.Parameters[1]): Add<int>( new SqlExpression(func.SystemType, "Position({0} in {1})", Precedence.Primary, func.Parameters[0], ConvertExpression(new SqlFunction(typeof(string), "Substring", func.Parameters[1], func.Parameters[2], Sub<int>(ConvertExpression(new SqlFunction(typeof(int), "Length", func.Parameters[1])), func.Parameters[2])))), Sub(func.Parameters[2], 1)); } } else if (expr is SqlExpression) { var e = (SqlExpression)expr; if (e.Expr.StartsWith("Extract(DOW")) return Inc(new SqlExpression(expr.SystemType, e.Expr.Replace("Extract(DOW", "Extract(Dow"), e.Parameters)); if (e.Expr.StartsWith("Extract(Millisecond")) return new SqlExpression(expr.SystemType, "Cast(To_Char({0}, 'MS') as int)", e.Parameters); } return expr; }
protected override IDacParameter[] GenerateRsSizeLimitingParametersForPaging(IQuery query, ISqlExpression sqlExpression) { var skipRows = (query.Paging.PageIndex * query.Paging.PageSize); var takeRows = (skipRows + query.Paging.PageSize); return new IDacParameter[] { new DacParameter("skipRows", skipRows), new DacParameter("takeRows", takeRows) }; }
protected virtual string GenerateOrderByString(IQuery query, ISqlExpression sqlExpression) { var sortings = sqlExpression.SortingMembers.Select( sorting => (sorting.MemberPath != IndexStorageSchema.Fields.StructureId.Name) ? string.Format("mem{0} {1}", sorting.Index, sorting.Direction) : string.Format("s.[{0}] {1}", IndexStorageSchema.Fields.StructureId.Name, sorting.Direction)).ToArray(); return sortings.Length == 0 ? string.Empty : string.Join(", ", sortings); }
protected virtual string GenerateOrderByMembersString(IQuery queryCommand, ISqlExpression sqlExpression) { var sortings = sqlExpression.SortingMembers.Select( sorting => (sorting.MemberPath != IndexStorageSchema.Fields.StructureId.Name) ? string.Format("min(mem{0}.[{1}]) mem{0}", sorting.Index, sorting.IndexStorageColumnName) : string.Empty).Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); return sortings.Length == 0 ? string.Empty : string.Join(", ", sortings); }
private static void ConvertEmptyStringToNullIfNeeded(ISqlExpression expr) { var sqlParameter = expr as SqlParameter; var sqlValue = expr as SqlValue; if (sqlParameter != null && sqlParameter.Value is string && sqlParameter.Value.ToString() == "") sqlParameter.Value = null; if (sqlValue != null && sqlValue.Value is string && sqlValue.Value.ToString() == "") sqlValue.Value = null; }
protected override string GeneratePagingString(IQuery query, ISqlExpression sqlExpression) { if (!query.HasPaging) return string.Empty; var s = string.Join(", ", sqlExpression.SortingMembers.Select( sorting => sorting.MemberPath != IndexStorageSchema.Fields.StructureId.Name ? string.Format("min(mem{0}.[{1}]) {2}", sorting.Index, sorting.IndexStorageColumnName, sorting.Direction) : string.Format("s.[{0}] {1}", IndexStorageSchema.Fields.StructureId.Name, sorting.Direction))); return string.Format("row_number() over (order by {0}) RowNum", s); }
protected override IDacParameter[] GeneratePagingParameters(IQuery query, ISqlExpression sqlExpression) { if (!query.HasPaging) return new IDacParameter[0]; var takeFromRowNum = (query.Paging.PageIndex * query.Paging.PageSize) + 1; var takeToRowNum = (takeFromRowNum + query.Paging.PageSize) - 1; return new IDacParameter[] { new DacParameter("pagingFrom", takeFromRowNum), new DacParameter("pagingTo", takeToRowNum) }; }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlFunction) { var func = expr as SqlFunction; if (func.Name == "Convert") { var ftype = func.SystemType.ToUnderlying(); if (ftype == typeof(bool)) { var ex = AlternativeConvertToBoolean(func, 1); if (ex != null) return ex; } return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0]); } } else if (expr is SqlBinaryExpression) { var be = expr as SqlBinaryExpression; switch (be.Operation) { case "%": return new SqlFunction(be.SystemType, "MOD", be.Expr1, be.Expr2); case "&": return new SqlFunction(be.SystemType, "BITAND", be.Expr1, be.Expr2); case "|": return Sub( Add(be.Expr1, be.Expr2, be.SystemType), new SqlFunction(be.SystemType, "BITAND", be.Expr1, be.Expr2), be.SystemType); case "^": // (a + b) - BITAND(a, b) * 2 return Sub( Add(be.Expr1, be.Expr2, be.SystemType), Mul(new SqlFunction(be.SystemType, "BITAND", be.Expr1, be.Expr2), 2), be.SystemType); case "+": return be.SystemType == typeof(string) ? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence) : expr; } } return expr; }
protected override SqlQueryFormatter CreateSqlQueryFormatter(IQuery query, ISqlExpression sqlExpression) { return new SqlQueryFormatter { Start = GenerateStartString(query, sqlExpression), End = GenerateEndString(query, sqlExpression), Take = GenerateTakeString(query), OrderByMembers = GenerateOrderByMembersString(query, sqlExpression), MainStructureTable = query.StructureSchema.GetStructureTableName(), WhereAndSortingJoins = GenerateWhereAndSortingJoins(query, sqlExpression), WhereCriteria = GenerateWhereCriteriaString(sqlExpression), OrderBy = GenerateOrderByString(query, sqlExpression), Paging = GeneratePagingString(query, sqlExpression).PrependWith(", "), }; }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlFunction) { var func = (SqlFunction)expr; switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) { case TypeCode.DateTime : if (func.Name == "Convert") { var type1 = TypeHelper.GetUnderlyingType(func.Parameters[1].SystemType); if (IsTimeDataType(func.Parameters[0])) { if (type1 == typeof(DateTime) || type1 == typeof(DateTimeOffset)) return new SqlExpression( func.SystemType, "Cast(Convert(Char, {0}, 114) as DateTime)", Precedence.Primary, func.Parameters[1]); if (func.Parameters[1].SystemType == typeof(string)) return func.Parameters[1]; return new SqlExpression( func.SystemType, "Convert(Char, {0}, 114)", Precedence.Primary, func.Parameters[1]); } if (type1 == typeof(DateTime) || type1 == typeof(DateTimeOffset)) { if (IsDateDataType(func.Parameters[0], "Datetime")) return new SqlExpression( func.SystemType, "Cast(Floor(Cast({0} as Float)) as DateTime)", Precedence.Primary, func.Parameters[1]); } if (func.Parameters.Length == 2 && func.Parameters[0] is SqlDataType && func.Parameters[0] == SqlDataType.DateTime) return new SqlFunction(func.SystemType, func.Name, func.Precedence, func.Parameters[0], func.Parameters[1], new SqlValue(120)); } break; } } return expr; }
static void BuildTake(ExpressionBuilder builder, IBuildContext sequence, ISqlExpression expr) { var sql = sequence.SqlQuery; builder.SqlProvider.SqlQuery = sql; sql.Select.Take(expr); if (sql.Select.SkipValue != null && builder.SqlProvider.IsTakeSupported && !builder.SqlProvider.IsSkipSupported) { if (sql.Select.SkipValue is SqlParameter && sql.Select.TakeValue is SqlValue) { var skip = (SqlParameter)sql.Select.SkipValue; var parm = (SqlParameter)sql.Select.SkipValue.Clone(new Dictionary<ICloneableElement,ICloneableElement>(), _ => true); parm.SetTakeConverter((int)((SqlValue)sql.Select.TakeValue).Value); sql.Select.Take(parm); var ep = (from pm in builder.CurrentSqlParameters where pm.SqlParameter == skip select pm).First(); ep = new ParameterAccessor { Expression = ep.Expression, Accessor = ep.Accessor, SqlParameter = parm }; builder.CurrentSqlParameters.Add(ep); } else sql.Select.Take(builder.Convert( sequence, new SqlBinaryExpression(typeof(int), sql.Select.SkipValue, "+", sql.Select.TakeValue, Precedence.Additive))); } if (!builder.SqlProvider.TakeAcceptsParameter) { var p = sql.Select.TakeValue as SqlParameter; if (p != null) p.IsQueryParameter = false; } }
protected override void BuildColumnExpression(ISqlExpression expr, string alias, ref bool addAlias) { var wrap = false; if (expr.SystemType == typeof(bool)) { if (expr is SelectQuery.SearchCondition) wrap = true; else { var ex = expr as SqlExpression; wrap = ex != null && ex.Expr == "{0}" && ex.Parameters.Length == 1 && ex.Parameters[0] is SelectQuery.SearchCondition; } } if (wrap) StringBuilder.Append("CASE WHEN "); base.BuildColumnExpression(expr, alias, ref addAlias); if (wrap) StringBuilder.Append(" THEN 1 ELSE 0 END"); }
protected override IDacParameter[] GenerateRsSizeLimitingParametersForSkipAndTake(IQuery query, ISqlExpression sqlExpression) { var skipRows = 0; var ps = new List<IDacParameter>(2); if (query.SkipNumOfStructures.HasValue) { skipRows = query.SkipNumOfStructures.Value; ps.Add(new DacParameter("skipRows", skipRows)); } if (query.TakeNumOfStructures.HasValue) { var takeRows = skipRows + query.TakeNumOfStructures.Value; ps.Add(new DacParameter("takeRows", takeRows)); } return ps.ToArray(); }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlFunction) { var func = (SqlFunction) expr; switch (func.Name) { case "CharIndex" : if (func.Parameters.Length == 3) return Add<int>( ConvertExpression(new SqlFunction(func.SystemType, "CharIndex", func.Parameters[0], ConvertExpression(new SqlFunction(typeof(string), "Substring", func.Parameters[1], func.Parameters[2], new SqlFunction(typeof(int), "Len", func.Parameters[1]))))), Sub(func.Parameters[2], 1)); break; case "Stuff" : if (func.Parameters[3] is SqlValue) { var value = (SqlValue)func.Parameters[3]; if (value.Value is string && string.IsNullOrEmpty((string)value.Value)) return new SqlFunction( func.SystemType, func.Name, func.Precedence, func.Parameters[0], func.Parameters[1], func.Parameters[1], new SqlValue(null)); } break; } } return expr; }
static SqlFunction ConvertCase(Type systemType, ISqlExpression[] parameters, int start) { var len = parameters.Length - start; var name = start == 0 ? "IIF" : "CASE"; var cond = parameters[start]; if (start == 0 && SqlExpression.NeedsEqual(cond)) { cond = new SelectQuery.SearchCondition( new SelectQuery.Condition( false, new SelectQuery.Predicate.ExprExpr(cond, SelectQuery.Predicate.Operator.Equal, new SqlValue(1)))); } if (len == 3) return new SqlFunction(systemType, name, cond, parameters[start + 1], parameters[start + 2]); return new SqlFunction(systemType, name, cond, parameters[start + 1], ConvertCase(systemType, parameters, start + 2)); }
public override void SetTable(MappingSchema mappingSchema, SqlTable table, MemberInfo member, IEnumerable<Expression> expArgs, IEnumerable<ISqlExpression> sqlArgs) { var method = member as MethodInfo; if (method == null) throw new ArgumentNullException("member"); var paramsList = method.GetParameters().ToList(); var valuesList = expArgs.Cast<ConstantExpression>().ToList(); if (paramsList.Count != valuesList.Count) throw new TargetParameterCountException("Invalid number of parameters"); var sqlValues = new List<ISqlExpression>(); for(var i = 0; i < paramsList.Count; i++) { var val = valuesList[i].Value; if (val == null) continue; var p = paramsList[i]; sqlValues.Add(new SqlValue("$$" + p.Name + "$$")); sqlValues.Add(new SqlValue(ValueToString(val))); } var arg = new ISqlExpression[1]; arg[0] = new SqlExpression( String.Join(", ", Enumerable.Range(0, sqlValues.Count) .Select(x => "{" + x + "}")), sqlValues.ToArray()); table.SqlTableType = SqlTableType.Expression; table.Name = "{0}('PLACEHOLDER' = {2}) {1}"; table.TableArguments = arg.ToArray(); }
public static IUntypedSqlExpression GetUntypedSqlExpression(this ISqlExpression sqlExpression) { var hasUntyped = sqlExpression as IHasUntypedSqlExpression; return(hasUntyped == null ? null : hasUntyped.GetUntyped()); }
public SqlBinaryExpression(Type systemType, ISqlExpression expr1, string operation, ISqlExpression expr2) : this(systemType, expr1, operation, expr2, Sql.Precedence.Unknown) { }
/// <summary> /// Returns a Dictionary from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlExpression. E.g: /// <para>db.Dictionary<int, string>(db.From<Person>().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50))</para> /// </summary> public static Dictionary <K, V> Dictionary <K, V>(this IDbConnection dbConn, ISqlExpression query) { return(dbConn.Exec(dbCmd => dbCmd.Dictionary <K, V>(query.ToSelectStatement()))); }
public static ISqlExpression Div <T>(this Sql.ISqExtensionBuilder builder, ISqlExpression expr1, ISqlExpression expr2) { return(builder.Div(expr1, expr2, typeof(T))); }
/// <summary> /// Returns the distinct first column values in a HashSet using an SqlExpression. E.g: /// <para>db.ColumnDistinct<int>(db.From<Persion>().Select(x => x.Age).Where(q => q.Age < 50))</para> /// </summary> public static HashSet <T> ColumnDistinct <T>(this IDbConnection dbConn, ISqlExpression query) { return(dbConn.Exec(dbCmd => dbCmd.ColumnDistinct <T>(query.ToSelectStatement()))); }
/// <summary> /// Returns a list KeyValuePairs from the first 2 columns: Column 1 (Keys), Column 2 (Values) using an SqlExpression. E.g: /// <para>db.KeyValuePairs<int, string>(db.From<Person>().Select(x => new { x.Id, x.LastName }).Where(x => x.Age < 50))</para> /// </summary> public static List <KeyValuePair <K, V> > KeyValuePairs <K, V>(this IDbConnection dbConn, ISqlExpression query) { return(dbConn.Exec(dbCmd => dbCmd.KeyValuePairs <K, V>(query))); }
bool IEquatable <ISqlExpression> .Equals(ISqlExpression other) { return(this == other); }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlBinaryExpression) { SqlBinaryExpression be = (SqlBinaryExpression)expr; switch (be.Operation) { case "%": return new SqlFunction(be.SystemType, "Mod", be.Expr1, be.Expr2); case "&": return new SqlFunction(be.SystemType, "Bin_And", be.Expr1, be.Expr2); case "|": return new SqlFunction(be.SystemType, "Bin_Or", be.Expr1, be.Expr2); case "^": return new SqlFunction(be.SystemType, "Bin_Xor", be.Expr1, be.Expr2); case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; } } else if (expr is SqlFunction) { SqlFunction func = (SqlFunction)expr; switch (func.Name) { case "Convert" : if (func.SystemType.ToUnderlying() == typeof(bool)) { ISqlExpression ex = AlternativeConvertToBoolean(func, 1); if (ex != null) return ex; } return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0]); case "DateAdd" : switch ((Sql.DateParts)((SqlValue)func.Parameters[0]).Value) { case Sql.DateParts.Quarter : return new SqlFunction(func.SystemType, func.Name, new SqlValue(Sql.DateParts.Month), Mul(func.Parameters[1], 3), func.Parameters[2]); case Sql.DateParts.DayOfYear: case Sql.DateParts.WeekDay: return new SqlFunction(func.SystemType, func.Name, new SqlValue(Sql.DateParts.Day), func.Parameters[1], func.Parameters[2]); case Sql.DateParts.Week : return new SqlFunction(func.SystemType, func.Name, new SqlValue(Sql.DateParts.Day), Mul(func.Parameters[1], 7), func.Parameters[2]); } break; } } else if (expr is SqlExpression) { SqlExpression e = (SqlExpression)expr; if (e.Expr.StartsWith("Extract(Quarter")) return Inc(Div(Dec(new SqlExpression(e.SystemType, "Extract(Month from {0})", e.Parameters)), 3)); if (e.Expr.StartsWith("Extract(YearDay")) return Inc(new SqlExpression(e.SystemType, e.Expr.Replace("Extract(YearDay", "Extract(yearDay"), e.Parameters)); if (e.Expr.StartsWith("Extract(WeekDay")) return Inc(new SqlExpression(e.SystemType, e.Expr.Replace("Extract(WeekDay", "Extract(weekDay"), e.Parameters)); } return expr; }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlBinaryExpression) { var be = (SqlBinaryExpression)expr; switch (be.Operation[0]) { case '%': return new SqlBinaryExpression(be.SystemType, be.Expr1, "MOD", be.Expr2, Precedence.Additive - 1); case '&': case '|': case '^': throw new SqlException("Operator '{0}' is not supported by the {1}.", be.Operation, GetType().Name); } } else if (expr is SqlFunction) { var func = (SqlFunction) expr; switch (func.Name) { case "Coalesce": if (func.Parameters.Length > 2) { var parms = new ISqlExpression[func.Parameters.Length - 1]; Array.Copy(func.Parameters, 1, parms, 0, parms.Length); return new SqlFunction(func.SystemType, func.Name, func.Parameters[0], new SqlFunction(func.SystemType, func.Name, parms)); } var sc = new SqlQuery.SearchCondition(); sc.Conditions.Add(new SqlQuery.Condition(false, new SqlQuery.Predicate.IsNull(func.Parameters[0], false))); return new SqlFunction(func.SystemType, "Iif", sc, func.Parameters[1], func.Parameters[0]); case "CASE" : return ConvertCase(func.SystemType, func.Parameters, 0); case "CharIndex" : return func.Parameters.Length == 2? new SqlFunction(func.SystemType, "InStr", new SqlValue(1), func.Parameters[1], func.Parameters[0], new SqlValue(1)): new SqlFunction(func.SystemType, "InStr", func.Parameters[2], func.Parameters[1], func.Parameters[0], new SqlValue(1)); case "Convert" : { switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) { case TypeCode.String : return new SqlFunction(func.SystemType, "CStr", func.Parameters[1]); case TypeCode.DateTime : if (IsDateDataType(func.Parameters[0], "Date")) return new SqlFunction(func.SystemType, "DateValue", func.Parameters[1]); if (IsTimeDataType(func.Parameters[0])) return new SqlFunction(func.SystemType, "TimeValue", func.Parameters[1]); return new SqlFunction(func.SystemType, "CDate", func.Parameters[1]); default: if (func.SystemType == typeof(DateTime)) goto case TypeCode.DateTime; break; } return func.Parameters[1]; } /* case "Convert" : { string name = null; switch (((SqlDataType)func.Parameters[0]).DbType) { case SqlDbType.BigInt : name = "CLng"; break; case SqlDbType.TinyInt : name = "CByte"; break; case SqlDbType.Int : case SqlDbType.SmallInt : name = "CInt"; break; case SqlDbType.Bit : name = "CBool"; break; case SqlDbType.Char : case SqlDbType.Text : case SqlDbType.VarChar : case SqlDbType.NChar : case SqlDbType.NText : case SqlDbType.NVarChar : name = "CStr"; break; case SqlDbType.DateTime : case SqlDbType.Date : case SqlDbType.Time : case SqlDbType.DateTime2 : case SqlDbType.SmallDateTime : case SqlDbType.DateTimeOffset : name = "CDate"; break; case SqlDbType.Decimal : name = "CDec"; break; case SqlDbType.Float : name = "CDbl"; break; case SqlDbType.Money : case SqlDbType.SmallMoney : name = "CCur"; break; case SqlDbType.Real : name = "CSng"; break; case SqlDbType.Image : case SqlDbType.Binary : case SqlDbType.UniqueIdentifier : case SqlDbType.Timestamp : case SqlDbType.VarBinary : case SqlDbType.Variant : case SqlDbType.Xml : case SqlDbType.Udt : case SqlDbType.Structured : name = "CVar"; break; } return new SqlFunction(name, func.Parameters[1]); } */ } } return expr; }
bool IEquatable <ISqlExpression> .Equals(ISqlExpression other) { return(Equals(other, SqlExpression.DefaultComparer)); }
public OrderByClause Descending(ISqlExpression expression) { Expressions.Add(new OrderByExpression(expression, SortType.Descending)); return(this); }
public static ISqlExpression Div(this Sql.ISqExtensionBuilder builder, ISqlExpression expr1, int value) { return(builder.Div <int>(expr1, new SqlValue(value))); }
/// <summary> /// Returns an Dictionary<K, List<V>> grouping made from the first two columns using an Sql Expression. E.g: /// <para>db.Lookup<int, string>(db.From<Person>().Select(x => new { x.Age, x.LastName }).Where(q => q.Age < 50))</para> /// </summary> public static Dictionary <K, List <V> > Lookup <K, V>(this IDbConnection dbConn, ISqlExpression sqlExpression) { return(dbConn.Exec(dbCmd => dbCmd.Lookup <K, V>(sqlExpression.ToSelectStatement()))); }
/// <summary> /// Returns results from an arbitrary SqlExpression. E.g: /// <para>db.SqlList<Person>(db.From<Person>().Select("*").Where(q => q.Age < 50))</para> /// </summary> public static List <T> SqlList <T>(this IDbConnection dbConn, ISqlExpression sqlExpression) { return(dbConn.Exec(dbCmd => dbCmd.SqlList <T>(sqlExpression.ToSelectStatement(QueryType.Select), sqlExpression.Params))); }
public SqlBinaryExpression(Type systemType, ISqlExpression expr1, string operation, ISqlExpression expr2, int precedence) { if (expr1 == null) { throw new ArgumentNullException("expr1"); } if (operation == null) { throw new ArgumentNullException("operation"); } if (expr2 == null) { throw new ArgumentNullException("expr2"); } Expr1 = expr1; Operation = operation; Expr2 = expr2; SystemType = systemType; Precedence = precedence; }
/// <summary> /// Returns a single Scalar value using an SqlExpression. E.g: /// <para>db.SqlScalar<int>(db.From<Person>().Select(Sql.Count("*")).Where(q => q.Age < 50))</para> /// </summary> public static T SqlScalar <T>(this IDbConnection dbConn, ISqlExpression sqlExpression) { return(dbConn.Exec(dbCmd => dbCmd.SqlScalar <T>(sqlExpression.ToSelectStatement()))); }
public bool Equals(ISqlExpression other, Func <ISqlExpression, ISqlExpression, bool> comparer) { return(this == other); }
public static ISqlExpression Div(this Sql.ISqExtensionBuilder builder, ISqlExpression expr1, ISqlExpression expr2, Type type) { return(new SqlBinaryExpression(type, expr1, "/", expr2, Precedence.Multiplicative)); }
protected override void BuildFunction(SqlFunction func) { switch (func.Name) { case "Coalesce" : if (func.Parameters.Length > 2) { var parms = new ISqlExpression[func.Parameters.Length - 1]; Array.Copy(func.Parameters, 1, parms, 0, parms.Length); BuildFunction(new SqlFunction(func.SystemType, func.Name, func.Parameters[0], new SqlFunction(func.SystemType, func.Name, parms))); return; } var sc = new SelectQuery.SearchCondition(); sc.Conditions.Add(new SelectQuery.Condition(false, new SelectQuery.Predicate.IsNull(func.Parameters[0], false))); func = new SqlFunction(func.SystemType, "Iif", sc, func.Parameters[1], func.Parameters[0]); break; case "CASE" : func = ConvertCase(func.SystemType, func.Parameters, 0); break; case "CharIndex" : func = func.Parameters.Length == 2? new SqlFunction(func.SystemType, "InStr", new SqlValue(1), func.Parameters[1], func.Parameters[0], new SqlValue(1)): new SqlFunction(func.SystemType, "InStr", func.Parameters[2], func.Parameters[1], func.Parameters[0], new SqlValue(1)); break; case "Convert" : switch (func.SystemType.ToUnderlying().GetTypeCodeEx()) { case TypeCode.String : func = new SqlFunction(func.SystemType, "CStr", func.Parameters[1]); break; case TypeCode.DateTime : if (IsDateDataType(func.Parameters[0], "Date")) func = new SqlFunction(func.SystemType, "DateValue", func.Parameters[1]); else if (IsTimeDataType(func.Parameters[0])) func = new SqlFunction(func.SystemType, "TimeValue", func.Parameters[1]); else func = new SqlFunction(func.SystemType, "CDate", func.Parameters[1]); break; default: if (func.SystemType == typeof(DateTime)) goto case TypeCode.DateTime; BuildExpression(func.Parameters[1]); return; } break; } base.BuildFunction(func); }
/// <summary> /// Returns the first column in a List using an SqlExpression. E.g: /// <para>db.SqlColumn<string>(db.From<Person>().Select(x => x.LastName).Where(q => q.Age < 50))</para> /// </summary> public static List <T> SqlColumn <T>(this IDbConnection dbConn, ISqlExpression sqlExpression) { return(dbConn.Exec(dbCmd => dbCmd.SqlColumn <T>(sqlExpression.ToSelectStatement()))); }
/// <summary> /// Returns the distinct first column values in a HashSet using an SqlExpression. E.g: /// <para>db.Column<int>(db.From<Person>().Select(x => x.LastName).Where(q => q.Age == 27))</para> /// </summary> public static List <T> Column <T>(this IDbConnection dbConn, ISqlExpression query) { return(dbConn.Exec(dbCmd => dbCmd.Column <T>(query.ToSelectStatement(QueryType.Select), query.Params))); }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlBinaryExpression) { var be = (SqlBinaryExpression)expr; switch (be.Operation) { case "+": if (be.SystemType == typeof(string)) { if (be.Expr1 is SqlFunction) { var func = (SqlFunction)be.Expr1; if (func.Name == "Concat") { var list = new List <ISqlExpression>(func.Parameters) { be.Expr2 }; return(new SqlFunction(be.SystemType, "Concat", list.ToArray())); } } return(new SqlFunction(be.SystemType, "Concat", be.Expr1, be.Expr2)); } break; } } else if (expr is SqlFunction) { var func = (SqlFunction)expr; switch (func.Name) { case "Convert": var ftype = TypeHelper.GetUnderlyingType(func.SystemType); if (ftype == typeof(bool)) { var ex = AlternativeConvertToBoolean(func, 1); if (ex != null) { return(ex); } } if ((ftype == typeof(double) || ftype == typeof(float)) && TypeHelper.GetUnderlyingType(func.Parameters[1].SystemType) == typeof(decimal)) { return(func.Parameters[1]); } return(new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, FloorBeforeConvert(func), func.Parameters[0])); } } else if (expr is SqlExpression) { var e = (SqlExpression)expr; if (e.Expr.StartsWith("Extract(DayOfYear")) { return(new SqlFunction(e.SystemType, "DayOfYear", e.Parameters)); } if (e.Expr.StartsWith("Extract(WeekDay")) { return(Inc( new SqlFunction(e.SystemType, "WeekDay", new SqlFunction( null, "Date_Add", e.Parameters[0], new SqlExpression(null, "interval 1 day"))))); } } return(expr); }
SqlValuesTable BuildValuesTableFromArray(NewArrayExpression arrayExpression) { if (Builder.MappingSchema.IsScalarType(_elementType)) { var rows = arrayExpression.Expressions.Select(e => new[] { Builder.ConvertToSql(Parent, e) }).ToList(); var field = new SqlField(Table, "item"); return(new SqlValuesTable(new[] { field }, null, rows)); } var knownMembers = new HashSet <MemberInfo>(); foreach (var row in arrayExpression.Expressions) { var members = new Dictionary <MemberInfo, Expression>(); Builder.ProcessProjection(members, row); knownMembers.AddRange(members.Keys); } var ed = Builder.MappingSchema.GetEntityDescriptor(_elementType); var builtRows = new List <ISqlExpression[]>(arrayExpression.Expressions.Count); var columnsInfo = knownMembers.Select(m => (Member: m, Column: ed.Columns.Find(c => c.MemberInfo == m))) .ToList(); foreach (var row in arrayExpression.Expressions) { var members = new Dictionary <MemberInfo, Expression>(); Builder.ProcessProjection(members, row); var rowValues = new ISqlExpression[columnsInfo.Count]; var idx = 0; foreach (var(member, column) in columnsInfo) { ISqlExpression sql; if (members.TryGetValue(member, out var accessExpr)) { sql = Builder.ConvertToSql(Parent, accessExpr, columnDescriptor: column); } else { var nullValue = Expression.Constant(Builder.MappingSchema.GetDefaultValue(_elementType), _elementType); sql = Builder.ConvertToSql(Parent, nullValue, columnDescriptor: column); } rowValues[idx] = sql; ++idx; } builtRows.Add(rowValues); } var fields = new SqlField[columnsInfo.Count]; for (var index = 0; index < columnsInfo.Count; index++) { var(member, column) = columnsInfo[index]; var field = column != null ? new SqlField(column) : new SqlField(member.GetMemberType(), "item" + (index + 1), true); fields[index] = field; } return(new SqlValuesTable(fields, columnsInfo.Select(ci => ci.Member).ToArray(), builtRows)); }
public static ISqlExpression Dec(this Sql.ISqExtensionBuilder builder, ISqlExpression expr) { return(builder.Sub(expr, 1)); }
public SqlExtensionParam AddParameter(string name, ISqlExpression sqlExpression) { return(AddParameter(new SqlExtensionParam(name ?? string.Empty, sqlExpression))); }
/// <summary> /// Returns the distinct first column values in a HashSet using an SqlExpression. E.g: /// <para>db.ColumnLazy<int>(db.From<Persion>().Select(x => x.LastName).Where(q => q.Age == 27))</para> /// </summary> public static IEnumerable <T> ColumnLazy <T>(this IDbConnection dbConn, ISqlExpression query) { return(dbConn.ExecLazy(dbCmd => dbCmd.ColumnLazy <T>(query.ToSelectStatement()))); }
protected override string GenerateOrderByString(IQuery query, ISqlExpression sqlExpression) { return query.HasPaging ? string.Empty : base.GenerateOrderByString(query, sqlExpression); }
public SqlExtensionParam(string?name, ISqlExpression expression) { Name = name; Expression = expression; }
protected override string GenerateEndString(IQuery query, ISqlExpression sqlExpression) { return query.HasPaging ? "where rs.RowNum between @pagingFrom and @pagingTo" : string.Empty; }
public SqlExtensionParam AddParameter(string name, ISqlExpression expr) { return(Extension.AddParameter(name, expr)); }
public static ISqlExpression Add(this Sql.ISqExtensionBuilder builder, ISqlExpression left, ISqlExpression right, Type type) { return(new SqlBinaryExpression(type, left, "+", right, Precedence.Additive)); }
public static ISqlExpression Sub(this Sql.ISqExtensionBuilder builder, ISqlExpression left, ISqlExpression right, Type type) { return(new SqlBinaryExpression(type, left, "-", right, Precedence.Subtraction)); }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlBinaryExpression) { var be = (SqlBinaryExpression)expr; switch (be.Operation) { case "%": { var expr1 = !be.Expr1.SystemType.IsIntegerType() ? new SqlFunction(typeof(int), "Int", be.Expr1) : be.Expr1; return new SqlFunction(be.SystemType, "Mod", expr1, be.Expr2); } case "&": return new SqlFunction(be.SystemType, "BitAnd", be.Expr1, be.Expr2); case "|": return new SqlFunction(be.SystemType, "BitOr", be.Expr1, be.Expr2); case "^": return new SqlFunction(be.SystemType, "BitXor", be.Expr1, be.Expr2); case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; } } else if (expr is SqlFunction) { var func = (SqlFunction) expr; switch (func.Name) { case "Convert" : if (func.SystemType.ToUnderlying() == typeof(bool)) { var ex = AlternativeConvertToBoolean(func, 1); if (ex != null) return ex; } if (func.Parameters[0] is SqlDataType) { var type = (SqlDataType)func.Parameters[0]; if (type.Type == typeof(string) && func.Parameters[1].SystemType != typeof(string)) return new SqlFunction(func.SystemType, "RTrim", new SqlFunction(typeof(string), "Char", func.Parameters[1])); if (type.Length > 0) return new SqlFunction(func.SystemType, type.SqlDbType.ToString(), func.Parameters[1], new SqlValue(type.Length)); if (type.Precision > 0) return new SqlFunction(func.SystemType, type.SqlDbType.ToString(), func.Parameters[1], new SqlValue(type.Precision), new SqlValue(type.Scale)); return new SqlFunction(func.SystemType, type.SqlDbType.ToString(), func.Parameters[1]); } if (func.Parameters[0] is SqlFunction) { var f = (SqlFunction)func.Parameters[0]; return f.Name == "Char" ? new SqlFunction(func.SystemType, f.Name, func.Parameters[1]) : f.Parameters.Length == 1 ? new SqlFunction(func.SystemType, f.Name, func.Parameters[1], f.Parameters[0]) : new SqlFunction(func.SystemType, f.Name, func.Parameters[1], f.Parameters[0], f.Parameters[1]); } { var e = (SqlExpression)func.Parameters[0]; return new SqlFunction(func.SystemType, e.Expr, func.Parameters[1]); } case "Millisecond" : return Div(new SqlFunction(func.SystemType, "Microsecond", func.Parameters), 1000); case "SmallDateTime" : case "DateTime" : case "DateTime2" : return new SqlFunction(func.SystemType, "TimeStamp", func.Parameters); case "TinyInt" : return new SqlFunction(func.SystemType, "SmallInt", func.Parameters); case "Money" : return new SqlFunction(func.SystemType, "Decimal", func.Parameters[0], new SqlValue(19), new SqlValue(4)); case "SmallMoney" : return new SqlFunction(func.SystemType, "Decimal", func.Parameters[0], new SqlValue(10), new SqlValue(4)); case "VarChar" : if (func.Parameters[0].SystemType.ToUnderlying() == typeof(decimal)) return new SqlFunction(func.SystemType, "Char", func.Parameters[0]); break; case "NChar" : case "NVarChar" : return new SqlFunction(func.SystemType, "Char", func.Parameters); case "DateDiff" : { switch ((Sql.DateParts)((SqlValue)func.Parameters[0]).Value) { case Sql.DateParts.Day : return new SqlExpression(typeof(int), "((Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))) / 86400", Precedence.Multiplicative, func.Parameters[2], func.Parameters[1]); case Sql.DateParts.Hour : return new SqlExpression(typeof(int), "((Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))) / 3600", Precedence.Multiplicative, func.Parameters[2], func.Parameters[1]); case Sql.DateParts.Minute : return new SqlExpression(typeof(int), "((Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))) / 60", Precedence.Multiplicative, func.Parameters[2], func.Parameters[1]); case Sql.DateParts.Second : return new SqlExpression(typeof(int), "(Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))", Precedence.Additive, func.Parameters[2], func.Parameters[1]); case Sql.DateParts.Millisecond : return new SqlExpression(typeof(int), "((Days({0}) - Days({1})) * 86400 + (MIDNIGHT_SECONDS({0}) - MIDNIGHT_SECONDS({1}))) * 1000 + (MICROSECOND({0}) - MICROSECOND({1})) / 1000", Precedence.Additive, func.Parameters[2], func.Parameters[1]); } } break; } } return expr; }
public static ISqlExpression Sub <T>(this Sql.ISqExtensionBuilder builder, ISqlExpression left, ISqlExpression right) { return(builder.Sub(left, right, typeof(T))); }
public override ISqlExpression ConvertExpression(ISqlExpression expr) { expr = base.ConvertExpression(expr); if (expr is SqlBinaryExpression) { var be = (SqlBinaryExpression)expr; switch (be.Operation) { case "%": return new SqlFunction(be.SystemType, "Mod", be.Expr1, be.Expr2); case "&": return new SqlFunction(be.SystemType, "BitAnd", be.Expr1, be.Expr2); case "|": return new SqlFunction(be.SystemType, "BitOr", be.Expr1, be.Expr2); case "^": return new SqlFunction(be.SystemType, "BitXor", be.Expr1, be.Expr2); case "+": return be.SystemType == typeof(string)? new SqlBinaryExpression(be.SystemType, be.Expr1, "||", be.Expr2, be.Precedence): expr; } } else if (expr is SqlFunction) { var func = (SqlFunction)expr; switch (func.Name) { case "Coalesce" : return new SqlFunction(func.SystemType, "Nvl", func.Parameters); case "Convert" : { var par0 = func.Parameters[0]; var par1 = func.Parameters[1]; switch (Type.GetTypeCode(TypeHelper.GetUnderlyingType(func.SystemType))) { case TypeCode.String : return new SqlFunction(func.SystemType, "To_Char", func.Parameters[1]); case TypeCode.Boolean : { var ex = AlternativeConvertToBoolean(func, 1); if (ex != null) return ex; break; } case TypeCode.UInt64: if (TypeHelper.IsFloatType(func.Parameters[1].SystemType)) par1 = new SqlFunction(func.SystemType, "Floor", func.Parameters[1]); break; case TypeCode.DateTime : if (IsDateDataType(func.Parameters[0], "Date")) { if (func.Parameters[1].SystemType == typeof(string)) { return new SqlFunction( func.SystemType, "Date", new SqlFunction(func.SystemType, "To_Date", func.Parameters[1], new SqlValue("%Y-%m-%d"))); } return new SqlFunction(func.SystemType, "Date", func.Parameters[1]); } if (IsTimeDataType(func.Parameters[0])) return new SqlExpression(func.SystemType, "Cast(Extend({0}, hour to second) as Char(8))", Precedence.Primary, func.Parameters[1]); return new SqlFunction(func.SystemType, "To_Date", func.Parameters[1]); default: if (TypeHelper.GetUnderlyingType(func.SystemType) == typeof(DateTimeOffset)) goto case TypeCode.DateTime; break; } return new SqlExpression(func.SystemType, "Cast({0} as {1})", Precedence.Primary, par1, par0); } case "Quarter" : return Inc(Div(Dec(new SqlFunction(func.SystemType, "Month", func.Parameters)), 3)); case "WeekDay" : return Inc(new SqlFunction(func.SystemType, "weekDay", func.Parameters)); case "DayOfYear": return Inc(Sub<int>( new SqlFunction(null, "Mdy", new SqlFunction(null, "Month", func.Parameters), new SqlFunction(null, "Day", func.Parameters), new SqlFunction(null, "Year", func.Parameters)), new SqlFunction(null, "Mdy", new SqlValue(1), new SqlValue(1), new SqlFunction(null, "Year", func.Parameters)))); case "Week" : return new SqlExpression( func.SystemType, "((Extend({0}, year to day) - (Mdy(12, 31 - WeekDay(Mdy(1, 1, year({0}))), Year({0}) - 1) + Interval(1) day to day)) / 7 + Interval(1) day to day)::char(10)::int", func.Parameters); case "Hour" : case "Minute" : case "Second" : return new SqlExpression(func.SystemType, string.Format("({{0}}::datetime {0} to {0})::char(3)::int", func.Name), func.Parameters); } } return expr; }
public static ISqlExpression Sub(this Sql.ISqExtensionBuilder builder, ISqlExpression left, int value) { return(builder.Sub <int>(left, new SqlValue(value))); }
SqlFunction ConvertCase(Type systemType, ISqlExpression[] parameters, int start) { var len = parameters.Length - start; if (len < 3) throw new SqlException("CASE statement is not supported by the {0}.", GetType().Name); if (len == 3) return new SqlFunction(systemType, "Iif", parameters[start], parameters[start + 1], parameters[start + 2]); return new SqlFunction(systemType, "Iif", parameters[start], parameters[start + 1], ConvertCase(systemType, parameters, start + 2)); }
public bool Equals([AllowNull] ISqlExpression other) => other is SqlRow row && Values.SequenceEqual(row.Values);