public static UnaryRestDbExpression Avg(RestDbExpression expression) { if (!expression.ReturnColumnType.IsNumeric()) { throw new ArgumentException("Expression return type must be numeric"); } return(new UnaryRestDbExpression(RestDbExpressionType.Avg, expression.ReturnColumnType, expression)); }
public static RestDbExpression Div(RestDbExpression left, RestDbExpression right) { if (!left.ReturnColumnType.IsNumeric() || !right.ReturnColumnType.IsNumeric()) { throw new ArgumentException("Argument must be of numeric type"); } return(new BinaryRestDbExpression(RestDbExpressionType.Div, ColumnType.Decimal, left, right)); }
public static BinaryRestDbExpression NotIn(RestDbExpression left, RestDbExpression right) { if (right.ReturnColumnType != ColumnType.Array && left.ReturnColumnType != right.ReturnColumnType) { throw new ArgumentException($"Expression type [{right.ReturnColumnType}] does not match [{left.ReturnColumnType}]", nameof(right)); } return(new BinaryRestDbExpression(RestDbExpressionType.NotIn, ColumnType.Boolean, left, right)); }
public static UnaryRestDbExpression Not(RestDbExpression expression) { if (expression.ReturnColumnType != ColumnType.Boolean) { throw new ArgumentException("NOT parameter expression must be of type boolean"); } return(new UnaryRestDbExpression(RestDbExpressionType.Not, ColumnType.Boolean, expression)); }
public static BinaryRestDbExpression LessThanOrEqual(RestDbExpression left, RestDbExpression right) { if (left.ReturnColumnType != right.ReturnColumnType) { throw new ArgumentException($"Expression type [{right.ReturnColumnType}] does not match [{left.ReturnColumnType}]", nameof(right)); } return(new BinaryRestDbExpression(RestDbExpressionType.LessThanOrEqual, ColumnType.Boolean, left, right)); }
public static RestDbExpression ToRestDbExpression(this ExpressionNode expressionNode, Dictionary <string, ColumnDefinition> columns) { // variadic expressions if (expressionNode.Children.Count >= 2) { switch (expressionNode.Name.ToLower()) { case "add": return(RestDbExpression.Add(expressionNode.Children.Select(n => n.ToRestDbExpression(columns)))); case "mul": return(RestDbExpression.Mul(expressionNode.Children.Select(n => n.ToRestDbExpression(columns)))); case "and": return(RestDbExpression.And(expressionNode.Children.Select(n => n.ToRestDbExpression(columns)))); case "or": return(RestDbExpression.Or(expressionNode.Children.Select(n => n.ToRestDbExpression(columns)))); } } // binary expressions if (expressionNode.Children.Count == 2) { switch (expressionNode.Name.ToLower()) { case "eq": return(RestDbExpression.Equal(expressionNode.Children[0].ToRestDbExpression(columns), expressionNode.Children[1].ToRestDbExpression(columns))); case "ne": return(RestDbExpression.NotEqual(expressionNode.Children[0].ToRestDbExpression(columns), expressionNode.Children[1].ToRestDbExpression(columns))); case "gt": return(RestDbExpression.GreaterThan(expressionNode.Children[0].ToRestDbExpression(columns), expressionNode.Children[1].ToRestDbExpression(columns))); case "gte": return(RestDbExpression.GreaterThanOrEqual(expressionNode.Children[0].ToRestDbExpression(columns), expressionNode.Children[1].ToRestDbExpression(columns))); case "lt": return(RestDbExpression.LessThan(expressionNode.Children[0].ToRestDbExpression(columns), expressionNode.Children[1].ToRestDbExpression(columns))); case "lte": return(RestDbExpression.LessThanOrEqual(expressionNode.Children[0].ToRestDbExpression(columns), expressionNode.Children[1].ToRestDbExpression(columns))); case "in": return(RestDbExpression.In(expressionNode.Children[0].ToRestDbExpression(columns), expressionNode.Children[1].ToRestDbExpression(columns))); case "nin": return(RestDbExpression.NotIn(expressionNode.Children[0].ToRestDbExpression(columns), expressionNode.Children[1].ToRestDbExpression(columns))); } } // unary expressions if (expressionNode.Children.Count == 1) { switch (expressionNode.Name.ToLower()) { case "not": return(RestDbExpression.Not(expressionNode.Children[0].ToRestDbExpression(columns))); default: if (!expressionNode.Children[0].Children.Any() && Enum.TryParse <ColumnType>(expressionNode.Name, true, out var columnType)) { var value = expressionNode.Children[0].Name.ConvertTo(columnType); return(RestDbExpression.Constant(value)); } break; } } // array if (expressionNode.Children.Count > 0 && expressionNode.Name == "") { return(RestDbExpression.Array(expressionNode.Children.Select(n => n.ToRestDbExpression(columns)))); } // columns or values if (expressionNode.Children.Count == 0) { if (expressionNode.Name.StartsWith("@")) { var columnName = expressionNode.Name.Substring(1); var column = columns.GetValueOrDefault(columnName); if (column == null) { throw new ArgumentException($"Column [{columnName}] does not exists", nameof(expressionNode)); } return(RestDbExpression.Column(column.ColumnType, columnName)); } return(RestDbExpression.Constant(expressionNode.Name.ToColumnValue())); } throw new ArgumentException($"Operation {expressionNode.Name}({string.Join(",", expressionNode.Children.Select(c => c.Name))}) not supported", nameof(expressionNode)); }
public static string ToSql(this RestDbExpression expression, Dictionary <string, object> parameters) { switch (expression) { case VariadicRestDbExpression { NodeType: RestDbExpressionType.Add } expr: return("(" + string.Join(" + ", expr.Expressions.Select(e => e.ToSql(parameters))) + ")"); case VariadicRestDbExpression { NodeType: RestDbExpressionType.Mul } expr: return("(" + string.Join(" * ", expr.Expressions.Select(e => e.ToSql(parameters))) + ")"); case VariadicRestDbExpression { NodeType: RestDbExpressionType.And } expr: return("(" + string.Join(" AND ", expr.Expressions.Select(e => e.ToSql(parameters))) + ")"); case VariadicRestDbExpression { NodeType: RestDbExpressionType.Or } expr: return("(" + string.Join(" OR ", expr.Expressions.Select(e => e.ToSql(parameters))) + ")"); case UnaryRestDbExpression { NodeType: RestDbExpressionType.Not } expr: return($"NOT({expr.Expression.ToSql(parameters)})"); case BinaryRestDbExpression { NodeType: RestDbExpressionType.Equal } expr: return($"{expr.Left.ToSql(parameters)}={expr.Right.ToSql(parameters)}"); case BinaryRestDbExpression { NodeType: RestDbExpressionType.NotEqual } expr: return($"{expr.Left.ToSql(parameters)}!={expr.Right.ToSql(parameters)}"); case BinaryRestDbExpression { NodeType: RestDbExpressionType.GreaterThan } expr: return($"{expr.Left.ToSql(parameters)}>{expr.Right.ToSql(parameters)}"); case BinaryRestDbExpression { NodeType: RestDbExpressionType.GreaterThanOrEqual } expr: return($"{expr.Left.ToSql(parameters)}>={expr.Right.ToSql(parameters)}"); case BinaryRestDbExpression { NodeType: RestDbExpressionType.LessThan } expr: return($"{expr.Left.ToSql(parameters)}<{expr.Right.ToSql(parameters)}"); case BinaryRestDbExpression { NodeType: RestDbExpressionType.LessThanOrEqual } expr: return($"{expr.Left.ToSql(parameters)}<={expr.Right.ToSql(parameters)}"); case BinaryRestDbExpression { NodeType: RestDbExpressionType.In } expr: return($"{expr.Left.ToSql(parameters)} IN ({expr.Right.ToSql(parameters)})"); case BinaryRestDbExpression { NodeType: RestDbExpressionType.NotIn } expr: return($"{expr.Left.ToSql(parameters)} NOT IN ({expr.Right.ToSql(parameters)})"); case ArrayRestDbExpression { NodeType: RestDbExpressionType.Array } expr: return(string.Join(",", expr.Expressions.Select(e => e.ToSql(parameters)))); case ColumnRestDbExpression { NodeType: RestDbExpressionType.Column } expr: return(expr.ColumnName); case ConstantRestDbExpression { NodeType: RestDbExpressionType.Constant } expr: { var parameterName = $"p{parameters.Count}"; parameters[parameterName] = expr.Value; return($"@{parameterName}"); } } throw new NotSupportedException($"Unsupported expression {expression.NodeType}"); }
public BinaryRestDbExpression(RestDbExpressionType nodeType, ColumnType returnColumnType, RestDbExpression left, RestDbExpression right) : base(nodeType, returnColumnType) { Left = left; Right = right; }
public UnaryRestDbExpression(RestDbExpressionType restDbExpressionType, ColumnType returnColumnType, RestDbExpression expression) : base(restDbExpressionType, returnColumnType) { Expression = expression; }