public override QueryNode BuildTree (QueryFieldSet fieldSet) { field_set = fieldSet; root = current_parent = new QueryListNode (Keyword.And); bool last_was_term = false; while (true) { QueryToken token = Scan (); if (token.ID == TokenID.Unknown) { break; } token.Column = token_start_column; token.Line = token_start_line; // If we have two terms in a row, put an AND between them if (last_was_term && token.ID == TokenID.Term) ParseToken (new QueryToken (TokenID.And)); ParseToken (token); last_was_term = token.ID == TokenID.Term; } return root.Trim (); }
private IEnumerable <T> SearchForValuesByBreadth <T> () where T : QueryValue { Queue <QueryNode> queue = new Queue <QueryNode> (); queue.Enqueue(this); do { QueryNode node = queue.Dequeue(); QueryListNode list = node as QueryListNode; if (list != null) { foreach (QueryNode child in list.Children) { queue.Enqueue(child); } } else { QueryTermNode term = node as QueryTermNode; if (term != null) { T value = term.Value as T; if (value != null) { yield return(value); } } } } while (queue.Count > 0); }
public void TakeChildren (QueryListNode from) { foreach (QueryNode child in from.Children) { AddChild (child); } from.Children.Clear (); }
public override QueryNode Trim() { // Trim depth first List<QueryNode> copy = new List<QueryNode> (Children); foreach (QueryNode child in copy) child.Trim (); if (Keyword == Keyword.Not) { if (ChildCount != 1) { if (Parent != null) { Parent.RemoveChild (this); } else { return null; } } } else { if (ChildCount <= 1) { if (Parent != null) { QueryListNode p = Parent; p.RemoveChild (this); p.TakeChildren (this); } else if (ChildCount == 1) { Children[0].Parent = null; return Children[0]; } } } return this; }
private static IEnumerable <T> SearchForValuesByDepth <T> (QueryNode node) where T : QueryValue { QueryListNode list = node as QueryListNode; if (list != null) { foreach (QueryNode child in list.Children) { foreach (T item in SearchForValuesByDepth <T> (child)) { yield return(item); } } } else { QueryTermNode term = node as QueryTermNode; if (term != null) { T value = term.Value as T; if (value != null) { yield return(value); } } } }
public override QueryNode BuildTree(QueryFieldSet fieldSet) { field_set = fieldSet; root = current_parent = new QueryListNode(Keyword.And); bool last_was_term = false; while (true) { var token = Scan(); if (token.ID == TokenID.Unknown) { break; } token.Column = token_start_column; token.Line = token_start_line; // If we have two terms in a row, put an AND between them if (last_was_term && token.ID == TokenID.Term) { ParseToken(new QueryToken(TokenID.And)); } ParseToken(token); last_was_term = token.ID == TokenID.Term; } return(root.Trim()); }
public IEnumerable <QueryTermNode> GetTerms() { Queue <QueryNode> queue = new Queue <QueryNode> (); queue.Enqueue(this); do { QueryNode node = queue.Dequeue(); QueryListNode list = node as QueryListNode; if (list != null) { foreach (QueryNode child in list.Children) { queue.Enqueue(child); } } else { QueryTermNode term = node as QueryTermNode; if (term != null) { yield return(term); } } } while (queue.Count > 0); }
public void TakeChildren(QueryListNode from) { foreach (QueryNode child in from.Children) { AddChild (child); } from.Children.Clear (); }
void DepthPop() { // Avoid trying to pop more than is possible if (current_parent.Parent != null) { current_parent = current_parent.Parent; } }
private QueryNode Parse (XmlElement node, QueryListNode parent) { if (node == null) return null; QueryListNode list = null; //Console.WriteLine ("Parsing node: {0}", node.Name); switch (node.Name.ToLower ()) { case "and": list = new QueryListNode (Keyword.And); break; case "or": list = new QueryListNode (Keyword.Or); break; case "not": list = new QueryListNode (Keyword.Not); break; default: QueryTermNode term = new QueryTermNode (); // Get the field (if any) that this term applies to if (node["field"] != null) term.Field = field_set [node["field"].GetAttribute ("name")]; // Get the value term.Value = QueryValue.CreateFromXml (node, term.Field); // Get the operator from the term's name term.Operator = term.Value.OperatorSet [node.Name]; if (parent != null) { parent.AddChild (term); } return term; } if (list != null) { if (parent != null) parent.AddChild (list); // Recursively parse the children of a QueryListNode foreach (XmlNode child in node.ChildNodes) { Parse (child as XmlElement, list); } } return list; }
void ParseToken(QueryToken token) { switch (token.ID) { case TokenID.OpenParen: DepthPush(); break; case TokenID.CloseParen: DepthPop(); break; case TokenID.Not: NodePush(new QueryListNode(Keyword.Not)); break; case TokenID.Or: case TokenID.And: // Only push a node if the current_parent is not the same as this token if (current_parent.Keyword == Keyword.Not || current_parent.Keyword == (token.ID == TokenID.Or ? Keyword.And : Keyword.Or)) { var list = new QueryListNode(token.ID == TokenID.Or ? Keyword.Or : Keyword.And); var p = current_parent.Parent; if (p != null) { current_parent.Parent.RemoveChild(current_parent); } if (current_parent.Keyword == Keyword.Not || current_parent.ChildCount > 1) { list.AddChild(current_parent); } else { list.TakeChildren(current_parent); } current_parent = p; NodePush(list); } break; case TokenID.Term: NodePush(QueryTermNode.ParseUserQuery(field_set, token.Term)); break; } }
void NodePush(QueryNode node) { if (current_parent == null && node is QueryListNode) { root = current_parent = node as QueryListNode; return; } if (current_parent.Keyword == Keyword.Not && current_parent.ChildCount == 1) { DepthPop(); } current_parent.AddChild(node); // If the node is a list, it's our new parent if (node is QueryListNode list) { current_parent = list; } }
private void ParseToken(QueryToken token) { switch (token.ID) { case TokenID.OpenParen: DepthPush (); break; case TokenID.CloseParen: DepthPop (); break; case TokenID.Not: NodePush (new QueryListNode (Keyword.Not)); break; case TokenID.Or: case TokenID.And: // Only push a node if the current_parent is not the same as this token if (current_parent.Keyword == Keyword.Not || current_parent.Keyword == (token.ID == TokenID.Or ? Keyword.And : Keyword.Or)) { QueryListNode list = new QueryListNode (token.ID == TokenID.Or ? Keyword.Or : Keyword.And); QueryListNode p = current_parent.Parent; if (p != null) { current_parent.Parent.RemoveChild (current_parent); } if (current_parent.Keyword == Keyword.Not || current_parent.ChildCount > 1) { list.AddChild (current_parent); } else { list.TakeChildren (current_parent); } current_parent = p; NodePush (list); } break; case TokenID.Term: NodePush (QueryTermNode.ParseUserQuery (field_set, token.Term)); break; } }
public QueryListNode(Keyword keyword, QueryListNode parent) : base(parent) { this.keyword = keyword; }
private void NodePush(QueryNode node) { if (current_parent == null && node is QueryListNode) { root = current_parent = node as QueryListNode; return; } if (current_parent.Keyword == Keyword.Not && current_parent.ChildCount == 1) DepthPop (); current_parent.AddChild (node); // If the node is a list, it's our new parent QueryListNode list = node as QueryListNode; if (list != null) { current_parent = list; } }
private void DepthPush() { current_parent = new QueryListNode (Keyword.And, current_parent); }
private void DepthPop() { // Avoid trying to pop more than is possible if (current_parent.Parent != null) current_parent = current_parent.Parent; }
internal void CalculateSync () { if (SyncEntireLibrary) { sync_src.ConditionTree = null; } else if (SyncSource != null) { var src = SyncSource; QueryListNode playlists_node = new QueryListNode (Keyword.Or); if (src is PlaylistSource) { playlists_node.AddChild (UserQueryParser.Parse (String.Format ("playlistid:{0}", (src as PlaylistSource).DbId), BansheeQuery.FieldSet)); } else if (src is SmartPlaylistSource) { playlists_node.AddChild (UserQueryParser.Parse (String.Format ("smartplaylistid:{0}", (src as SmartPlaylistSource).DbId), BansheeQuery.FieldSet)); } sync_src.ConditionTree = playlists_node; } sync_src.RefreshAndReload (); to_add.RefreshAndReload (); to_remove.RefreshAndReload (); }
public QueryNode(QueryListNode parent) { Parent = parent; Parent.AddChild(this); }
private QueryNode Parse(XmlElement node, QueryListNode parent) { if (node == null) { return(null); } QueryListNode list = null; //Console.WriteLine ("Parsing node: {0}", node.Name); switch (node.Name.ToLower()) { case "and": list = new QueryListNode(Keyword.And); break; case "or": list = new QueryListNode(Keyword.Or); break; case "not": list = new QueryListNode(Keyword.Not); break; default: QueryTermNode term = new QueryTermNode(); // Get the field (if any) that this term applies to if (node["field"] != null) { term.Field = field_set [node["field"].GetAttribute("name")]; } // Get the value term.Value = QueryValue.CreateFromXml(node, term.Field); // Get the operator from the term's name term.Operator = term.Value.OperatorSet [node.Name]; if (parent != null) { parent.AddChild(term); } return(term); } if (list != null) { if (parent != null) { parent.AddChild(list); } // Recursively parse the children of a QueryListNode foreach (XmlNode child in node.ChildNodes) { Parse(child as XmlElement, list); } } return(list); }
void DepthPush() { current_parent = new QueryListNode(Keyword.And, current_parent); }
private string ParseCondition (string value) { if (String.IsNullOrEmpty (value)) return null; // Check for ANDs or ORs and split into conditions as needed string [] conditions; bool ands = true; if (value.IndexOf(") AND (") != -1) { ands = true; conditions = System.Text.RegularExpressions.Regex.Split (value, "\\) AND \\("); } else if (value.IndexOf(") OR (") != -1) { ands = false; conditions = System.Text.RegularExpressions.Regex.Split (value, "\\) OR \\("); } else { conditions = new string [] {value}; } QueryListNode root = new QueryListNode (ands ? Keyword.And : Keyword.Or); // Remove leading spaces and parens from the first condition conditions[0] = conditions[0].Remove(0, 2); // Remove trailing spaces and last paren from the last condition string tmp = conditions[conditions.Length-1]; tmp = tmp.TrimEnd(new char[] {' '}); tmp = tmp.Substring(0, tmp.Length - 1); conditions[conditions.Length-1] = tmp; int count = 0; foreach (string condition in conditions) { // Add a new row for this condition string col, v1, v2; foreach (QueryOperator op in QueryOperator.Operators) { if (op.MatchesCondition (condition, out col, out v1, out v2)) { QueryTermNode term = new QueryTermNode (); QueryField field = BansheeQuery.FieldSet [col]; bool is_relative_date = false; if (field == null) { if (col.IndexOf ("DateAddedStamp") != -1) { field = BansheeQuery.FieldSet ["added"]; } else if (col.IndexOf ("LastPlayedStamp") != -1) { field = BansheeQuery.FieldSet ["lastplayed"]; } // Fix ugly implementation of playlist/smart playlist conditions if (op == QueryOperator.InPlaylist || op == QueryOperator.NotInPlaylist) { field = BansheeQuery.FieldSet ["playlist"]; } else if (op == QueryOperator.InSmartPlaylist || op == QueryOperator.NotInSmartPlaylist) { field = BansheeQuery.FieldSet ["smartplaylist"]; } if (field == null) { continue; } is_relative_date = true; } term.Field = field; if (op == QueryOperator.Between) { QueryListNode and = new QueryListNode (Keyword.And); QueryTermNode t2 = new QueryTermNode (); t2.Field = term.Field; if (is_relative_date) { ParseRelativeDateCondition (term, v1, field, ">="); ParseRelativeDateCondition (t2, v2, field, "<="); } else { term.Value = QueryValue.CreateFromUserQuery (v1, field); term.Operator = term.Value.OperatorSet ["<="]; t2.Value = QueryValue.CreateFromUserQuery (v2, field); t2.Operator = t2.Value.OperatorSet [">="]; } and.AddChild (term); and.AddChild (t2); root.AddChild (and); } else if (is_relative_date) { ParseRelativeDateCondition (term, v1, field, op.NewOp); root.AddChild (term); } else { term.Value = QueryValue.CreateFromUserQuery (v1, field); term.Operator = term.Value.OperatorSet [op.NewOp]; root.AddChild (term); } break; } } count++; } QueryNode node = root.Trim (); if (node != null) { //Console.WriteLine ("After XML: {0}", node.ToXml (BansheeQuery.FieldSet, true)); //Console.WriteLine ("After SQL: {0}", node.ToSql (BansheeQuery.FieldSet)); } return node == null ? String.Empty : node.ToXml (BansheeQuery.FieldSet); }