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 (); }
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()); }
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); }