private RqlExpression VisitOperatorEq(RqlFunctionCallExpression node) { if (node.Arguments.Count != 2) { ThrowError(node, "Equality takes exactly two arguments"); } RqlIdentifierExpression identifier = node.Arguments[0] as RqlIdentifierExpression; if (identifier == null) { ThrowError(node.Arguments[0], "First argument must be a field identifier"); } RqlConstantExpression constant = node.Arguments[1] as RqlConstantExpression; if (constant == null) { ThrowError(node, "Second argument must be a constant"); } sb.Append("{"); VisitIdentifier(identifier); VisitConstant(constant); sb.Append("}"); return(node); }
private RqlExpression VisitOperatorSize(RqlFunctionCallExpression node) { if (node.Arguments.Count != 2) { ThrowError(node, "{0} takes exactly two arguments", node.Name); } RqlIdentifierExpression identifier = node.Arguments[0] as RqlIdentifierExpression; if (identifier == null) { ThrowError(node.Arguments[0], "First argument must be an identifier"); } RqlConstantExpression constant = node.Arguments[1] as RqlConstantExpression; if (constant == null || constant.Value.GetType() != typeof(int)) { ThrowError(node.Arguments[1], "Second argument must be an integer constant"); } sb.Append("{"); VisitIdentifier(identifier); sb.Append("{$"); sb.Append(node.Name); sb.Append(": "); VisitConstant(constant); sb.Append("}"); sb.Append("}"); return(node); }
private RqlExpression VisitOperatorLikeLikei(RqlFunctionCallExpression node) { if (node.Arguments.Count != 2) { ThrowError(node, "{0} takes exactly two arguments", node.Name); } RqlIdentifierExpression identifier = node.Arguments[0] as RqlIdentifierExpression; if (identifier == null) { ThrowError(node.Arguments[0], "First argument must be an identifier"); } RqlConstantExpression constant = node.Arguments[1] as RqlConstantExpression; if (constant == null || constant.Value.GetType() != typeof(string)) { ThrowError(node, "Second argument must be a string constant"); } bool ignoreCase = (identifier.Name == "likei"); sb.Append("{"); VisitIdentifier(identifier); sb.AppendFormat(@"/\b{0}/{1}", Regex.Escape((string)((RqlConstantExpression)node.Arguments[1]).Value), ignoreCase ? "i" : ""); sb.Append("}"); return(node); }
private RqlExpression VisitOperatorAndOr(RqlFunctionCallExpression node) { sb.Append("{"); sb.Append("$"); sb.Append(node.Name); sb.Append(": ["); for (int i = 0; i < node.Arguments.Count; i++) { RqlExpression argument = node.Arguments[i]; if (argument.ExpressionType != RqlExpressionType.FunctionCall || (argument.ExpressionType == RqlExpressionType.Constant && argument.Token.Data.GetType() != typeof(bool))) { ThrowError(argument, "Argument must be boolean constant or expression"); } Visit(argument); if (i < node.Arguments.Count - 1) { sb.Append(","); } } sb.Append("]"); sb.Append("}"); return(node); }
private RqlExpression VisitOperatorInNinAll(RqlFunctionCallExpression node) { if (node.Arguments.Count != 2) { ThrowError(node, String.Format("{0} needs two arguments", node.Name)); } RqlIdentifierExpression identifier = node.Arguments[0] as RqlIdentifierExpression; if (identifier == null) { ThrowError(node.Arguments[0], "First argument must be a field identifier"); } RqlTupleExpression tuple = node.Arguments[1] as RqlTupleExpression; RqlFunctionCallExpression funcCall = node.Arguments[1] as RqlFunctionCallExpression; // TODO: Need a way to find the return types of operators if (tuple == null && !(funcCall != null && (funcCall.Name == "where" || funcCall.Name == "ids"))) { ThrowError(node.Arguments[1], "Second argument must be a tuple or an expression returning a tuple"); } sb.Append("{"); VisitIdentifier(identifier); sb.Append("{$"); sb.Append(node.Name); sb.Append(": "); Visit(node.Arguments[1]); sb.Append("}"); sb.Append("}"); return(node); }
private RqlExpression VisitOperatorNeGtGteLtLte(RqlFunctionCallExpression node) { if (node.Arguments.Count != 2) { ThrowError(node, String.Format("{0} takes exactly two arguments", node.Name)); } RqlIdentifierExpression identifier = node.Arguments[0] as RqlIdentifierExpression; if (identifier == null) { ThrowError(node.Arguments[0], "First argument must be a field identifier"); } RqlConstantExpression constant = node.Arguments[1] as RqlConstantExpression; if (constant == null) { ThrowError(node, "Second argument must be a constant"); } sb.Append("{"); VisitIdentifier(identifier); sb.Append("{$"); sb.Append(node.Name); sb.Append(": "); VisitConstant(constant); sb.Append("}"); sb.Append("}"); return(node); }
protected override RqlExpression VisitFunctionCall(RqlFunctionCallExpression node) { s += node.Name; s += "("; for (int i = 0, n = node.Arguments.Count; i < n; i++) { this.Visit(node.Arguments[i]); if (i < node.Arguments.Count - 1) { s += ","; } } s += ")"; return(node); }
protected override RqlExpression VisitFunctionCall(RqlFunctionCallExpression node) { switch (node.Name) { case "eq": return(VisitOperatorEq(node)); case "ne": case "gt": case "gte": case "lt": case "lte": return(VisitOperatorNeGtGteLtLte(node)); case "in": case "nin": case "all": return(VisitOperatorInNinAll(node)); case "and": case "or": return(VisitOperatorAndOr(node)); case "like": case "likei": return(VisitOperatorLikeLikei(node)); case "exists": case "nexists": return(VisitOperatorExistsNexists(node)); case "size": return(VisitOperatorSize(node)); default: ThrowError(node, "{0} is not a supported operator", node.Name); break; } return(node); }
private RqlExpression VisitOperatorExistsNexists(RqlFunctionCallExpression node) { if (node.Arguments.Count != 1) { ThrowError(node, "{0} takes exactly one argument", node.Name); } RqlIdentifierExpression identifier = node.Arguments[0] as RqlIdentifierExpression; if (identifier == null) { ThrowError(node.Arguments[0], "Argument must be an identifier"); } bool exists = (node.Name == "exists"); sb.Append("{"); VisitIdentifier(identifier); sb.Append("{$"); sb.Append(node.Name); sb.AppendFormat(": {0} }}", exists ? "true" : "false"); sb.Append("}"); return(node); }