public static IExpression Parse(string whereClause, QueryItem table, IServerContext context = null) { context = context ?? ElementFactory.Utc.LocalizationContext; var tokens = new SqlTokenizer(whereClause).Where(t => t.Type != SqlType.Comment).ToArray(); var expressions = GetExpressions(tokens, table).ToArray(); var output = new List <IExpression>(); var ops = new List <IExpression>(); var last = default(IExpression); foreach (var expression in expressions) { var expr = expression; if (expr is ILiteral || expr is PropertyReference) { output.Push(expr); } else { if (expr is NotOperator && last is IsOperator) { expr = new NotIsOperator(); } else if (expr is AndOperator) { for (var i = ops.Count - 1; i >= 0; i--) { if (ops[i] is AndOperator) { break; } else if (ops[i] is BetweenOperator) { expr = new AndBetweenOperator(); break; } } } var precedence = GetPrecedence(expr); if (expr is EndParen) { while (ops.Count > 0 && !IsOpenParen(ops.Peek())) { output.Push(HandleOperator(ops.Pop(), output, context)); } var parenExpr = ops.Pop(); if (!IsOpenParen(last)) { var args = new List <IExpression>(); FlattenArgs(args, output.Pop()); if (ops.Count > 0 && ops.Peek() is InOperator && parenExpr is ListExpression listExpr) { foreach (var arg in args.Cast <IOperand>()) { listExpr.Values.Add(arg); } } else if (parenExpr is SqlFunction funcExpr) { foreach (var arg in args) { funcExpr.Add(arg); } parenExpr = funcExpr.Normalize(); } else if (args.Count == 1) { parenExpr = args[0]; } else { throw new NotSupportedException(); } } output.Push(parenExpr); } else if (expr is ListExpression && last is PropertyReference prop) { output.Pop(); ops.Push(new SqlFunction(prop.Name)); } else if (ops.Count < 1 || precedence > GetPrecedence(ops.Peek())) { ops.Push(expr); } else { while (ops.Count > 0 && precedence <= GetPrecedence(ops.Peek()) && !IsOpenParen(ops.Peek())) { output.Push(HandleOperator(ops.Pop(), output, context)); } ops.Push(expr); } } last = expr; } while (ops.Count > 0) { output.Push(HandleOperator(ops.Pop(), output, context)); } if (output.Count == 1) { return(output.Pop()); } throw new NotSupportedException(); }
protected virtual void WriteTableName(QueryItem item) { TryFillName(item); WriteIdentifier(item.Type); }
protected virtual IExpression GetWhereClause(QueryItem query, bool skipIdWhereClause = false) { return(query.Where); }
public PropertyReference(string name, QueryItem table) { Name = name; Table = table; }
public void Visit(QueryItem query) { var refId = Guid.NewGuid().ToArasId(); _writer.WriteStartElement("Item"); _writer.WriteAttributeString("type", "qry_QueryDefinition"); _writer.WriteAttributeString("action", "qry_ExecuteQueryDefinition"); _writer.WriteStartElement("Relationships"); _writer.WriteStartElement("Item"); _writer.WriteAttributeString("type", "qry_QueryItem"); _writer.WriteElementString("alias", query.Alias); _writer.WriteStartElement("item_type"); _writer.WriteAttributeString("keyed_name", query.Type); _writer.WriteEndElement(); _writer.WriteElementString("ref_id", refId); if (!query.Select.All(s => s.Expression is PropertyReference)) { throw new NotSupportedException(); } if (!query.OrderBy.All(s => s.Expression is PropertyReference)) { throw new NotSupportedException(); } _writer.WriteStartElement("Relationships"); foreach (var select in query.Select) { _writer.WriteStartElement("Item"); _writer.WriteAttributeString("type", "qry_QueryItemSelectProperty"); _writer.WriteElementString("property_name", ((PropertyReference)select.Expression).Name); _writer.WriteEndElement(); // Item } var idx = 10; foreach (var orderBy in query.OrderBy) { _writer.WriteStartElement("Item"); _writer.WriteAttributeString("type", "qry_QueryItemSortProperty"); _writer.WriteElementString("property_name", ((PropertyReference)orderBy.Expression).Name); _writer.WriteElementString("sort_order_direction", orderBy.Ascending ? "asc" : "desc"); _writer.WriteElementString("sort_order", _context.Format(idx)); _writer.WriteEndElement(); // Item idx += 10; } _writer.WriteEndElement(); // Relationships var where = query.Where; if (query.Version is CurrentVersion) { where = new AndOperator() { Left = where, Right = new EqualsOperator() { Left = new PropertyReference("is_current", query), Right = new BooleanLiteral(true) }.Normalize() }.Normalize(); } if (where != null) { using (var strWriter = new StringWriter()) using (_conditionWriter = XmlWriter.Create(strWriter, new XmlWriterSettings() { OmitXmlDeclaration = true })) { _conditionWriter.WriteStartElement("condition"); query.Where.Visit(this); _conditionWriter.WriteEndElement(); _conditionWriter.Flush(); strWriter.Flush(); _writer.WriteStartElement("filter_xml"); _writer.WriteCData(strWriter.ToString()); _writer.WriteEndElement(); } _conditionWriter = null; } if (query.Offset.HasValue || query.Fetch.HasValue) { using (var strWriter = new StringWriter()) using (_conditionWriter = XmlWriter.Create(strWriter, new XmlWriterSettings() { OmitXmlDeclaration = true })) { _conditionWriter.WriteStartElement("configuration"); _conditionWriter.WriteStartElement("option"); if (query.Offset.HasValue) { _conditionWriter.WriteElementString("offset", _context.Format(query.Offset)); } if (query.Fetch.HasValue) { _conditionWriter.WriteElementString("fetch", _context.Format(query.Fetch)); } _conditionWriter.WriteEndElement(); _conditionWriter.WriteEndElement(); _conditionWriter.Flush(); strWriter.Flush(); _writer.WriteStartElement("offset_fetch_xml"); _writer.WriteCData(strWriter.ToString()); _writer.WriteEndElement(); } _conditionWriter = null; } _writer.WriteEndElement(); // Item foreach (var param in _parameters) { _writer.WriteStartElement("Item"); _writer.WriteAttributeString("type", "qry_QueryParameter"); _writer.WriteElementString("name", param.Name); _writer.WriteEndElement(); // Item } _writer.WriteStartElement("Item"); _writer.WriteAttributeString("type", "qry_QueryReference"); _writer.WriteElementString("child_ref_id", refId); _writer.WriteEndElement(); // Item _writer.WriteEndElement(); // Relationships _writer.WriteEndElement(); // Item }
public void Visit(QueryItem query) { var newQuery = new QueryItem(query.Context) { Alias = query.Alias, Fetch = query.Fetch, Offset = query.Offset, Type = query.Type, }; _clones[query] = newQuery; if (query.Version is CurrentVersion) { newQuery.Version = new CurrentVersion(); } else if (query.Version is LatestMatch latest) { newQuery.Version = new LatestMatch() { AsOf = latest.AsOf } } ; else if (query.Version is VersionCriteria crit) { newQuery.Version = new VersionCriteria() { Condition = CloneAndReturn(crit.Condition) } } ; else if (query.Version is LastVersionOfId last) { newQuery.Version = new LastVersionOfId() { Id = last.Id } } ; foreach (var attr in query.Attributes) { newQuery.Attributes.Add(attr); } if (query.TypeProvider != null) { newQuery.TypeProvider = Clone(query.TypeProvider) as PropertyReference; } foreach (var join in query.Joins .Select(Clone) .Where(j => j != null && !(j.Condition is IgnoreNode))) { newQuery.Joins.Add(join); } foreach (var orderBy in query.OrderBy .Select(Clone) .Where(o => o != null && !(o.Expression is IgnoreNode))) { newQuery.OrderBy.Add(orderBy); } foreach (var select in query.Select .Select(Clone) .Where(s => s != null && !(s.Expression is IgnoreNode))) { newQuery.Select.Add(select); } if (query.Where != null) { newQuery.Where = CloneAndReturn(query.Where); } _query = newQuery; }
internal IExpression Parse(QueryItem table, IPropertyDefinition prop, string value, Condition condition = Condition.Undefined) { var propRef = new PropertyReference(prop.NameProp().Value ?? prop.KeyedName().Value ?? prop.IdProp().KeyedName().Value, table); var meta = prop.Metadata(); if (meta.DataType().Value == "item") { propRef = new PropertyReference("keyed_name", propRef.GetOrAddTable(table.Context)); } var expressions = new List <IExpression>(); var values = default(IEnumerable <string>); switch (condition) { case Condition.Undefined: case Condition.Equal: case Condition.NotEqual: case Condition.Like: case Condition.NotLike: values = SplitOr(value); break; default: values = new[] { value }; break; } foreach (var val in values) { if ((val == "*" || (val == "%" && String.IsPercentWildcard)) && condition == Condition.Undefined) { expressions.Add(new LikeOperator() { Left = propRef, Right = AmlLikeParser.Instance.Parse("%") }.Normalize()); } else if (condition == Condition.IsNotNull) { return(new IsOperator() { Left = propRef, Right = IsOperand.NotNull }.Normalize()); } else if (condition == Condition.IsNull) { return(new IsOperator() { Left = propRef, Right = IsOperand.Null }.Normalize()); } else { switch (meta.DataType().AsString("").ToLowerInvariant()) { case "boolean": expressions.Add(Boolean.Parse(propRef, val, condition)); break; case "date": expressions.Add(Date.Parse(propRef, val, condition)); break; case "decimal": case "float": case "integer": expressions.Add(Number.Parse(propRef, val, condition)); break; default: expressions.Add(String.Parse(propRef, val, condition)); break; } } } var addNotOperator = expressions.Count > 0 && expressions.All(e => e is NotOperator); if (addNotOperator) { expressions = expressions.Cast <NotOperator>().Select(n => n.Arg).ToList(); } var result = default(IExpression); if (expressions.Count > 0 && expressions.All(e => e is EqualsOperator eq && eq.Right is IOperand)) { var list = new ListExpression(); foreach (var op in expressions.Cast <EqualsOperator>().Select(e => (IOperand)e.Right)) { list.Values.Add(op); } result = new InOperator() { Left = propRef, Right = list }.Normalize(); }
/// <summary> /// Initializes a new instance of the <see cref="AllProperties"/> class. /// </summary> /// <param name="table">The table.</param> public AllProperties(QueryItem table) { Table = table; }
protected override void VisitTopRecords(QueryItem query) { // Do nothing }
public AmlToModelWriter(IServerContext context) { Query = new QueryItem(context); _context = context; }