internal static LogicalSearchExpression Create(
     SearchConfigurationOptions options,
     SearchExpression left,
     SearchExpression right,
     Operator @operator,
     string text)
 {
     return(new LogicalSearchExpression(options, text)
     {
         Left = left,
         Right = right,
         Operator = @operator
     });
 }
示例#2
0
        internal static ContainsSearchExpression Create(
            SearchConfigurationOptions options,
            SearchExpression left,
            SearchExpression right)
        {
            if (left == null)
            {
                throw new ArgumentNullException(nameof(left));
            }

            if (right == null)
            {
                throw new ArgumentNullException(nameof(right));
            }

            return(new ContainsSearchExpression(options, right.Text)
            {
                Left = left,
                Right = right
            });
        }
示例#3
0
        /// <summary>
        /// Attemps to create LogicalSearchExpressions from the given text based on
        /// binary operators found in the text (AND, OR, etc.).
        /// If it finds them it will return a LogicalSearchPression with Left and Right
        /// filled in and the Text will contain whatever is left over.
        /// If it cannot find any binary operators it will just return the original
        /// searchExpression.
        /// </summary>
        /// <returns></returns>
        private SearchExpression DecomposeLogicalOperators()
        {
            var match = _binaryOperatorsSearch.Match(Text);

            if (!match.Success)
            {
                // easy case first.
                return(this);
            }
            else
            {
                var searchExpressions = new Stack <SearchExpression>();
                var operators         = new Stack <Operator>();

                // we go left to right through the matches.
                for (var i = 0; i < match.Captures.Count; i++)
                {
                    var previous = i > 0 ? match.Captures[i - 1] : null;
                    var current  = match.Captures[i];
                    var next     = i < match.Captures.Count - 1 ? match.Captures[i + 1] : null;
                    //var nextNext = i < match.Captures.Count - 2 ? match.Captures[i + 2] : null;

                    var leftStart  = previous == null ? 0 : previous.Index + previous.Length;
                    var leftLength = current.Index - leftStart;
                    if (leftLength > 0)
                    {
                        searchExpressions.Push(SearchExpression.Create(Options, Text.Substring(leftStart, leftLength)));
                        Operator o;
                        var      currentValue = current.Value.Trim();
                        if (_andOperators.Contains(currentValue, StringComparer.OrdinalIgnoreCase))
                        {
                            o = Operator.And;
                        }
                        else if (_orOperators.Contains(currentValue, StringComparer.OrdinalIgnoreCase))
                        {
                            o = Operator.Or;
                        }
                        else
                        {
                            throw new InvalidOperationException($"Unknown operator '{currentValue}'");
                        }

                        operators.Push(o);
                    }

                    if (next == null)
                    {
                        // this is the last one
                        var rightStart  = current.Index + current.Length;
                        var rightLength = Text.Length - rightStart;
                        SearchExpression leftOver;
                        if (rightLength <= 0)
                        {
                            if (searchExpressions.Count > 0)
                            {
                                // nothing on the right side of the AND or OR,
                                // so we take the last left and just make it a regular SearchExpression
                                leftOver = searchExpressions.Pop();
                                operators.Pop();
                            }
                            else
                            {
                                // If here we didn't find anything at all
                                leftOver = SearchExpression.Create(Options, string.Empty);
                            }
                        }
                        else
                        {
                            leftOver = SearchExpression.Create(Options, Text.Substring(rightStart, rightLength).Trim());
                        }

                        // now we should have one more in the searchExpressions stack than in the operators stack
                        var searchExpressionCount = searchExpressions.Count;
                        if (searchExpressionCount == 0)
                        {
                            return(leftOver);
                        }
                        else if (searchExpressionCount == 1)
                        {
                            return(LogicalSearchExpression.Create(Options, searchExpressions.Pop(), leftOver, operators.Pop(), Text));
                        }
                        else
                        {
                            // if here there is at least 2 operators which we will make into a tree
                            var right             = searchExpressions.Pop();
                            var left              = searchExpressions.Pop();
                            var op                = operators.Pop();
                            var currentExpression = LogicalSearchExpression.Create(
                                Options,
                                left,
                                right,
                                op,
                                text: $"{left.Text} {op} {right.Text}");


                            while (searchExpressions.Any())
                            {
                                right             = currentExpression;
                                left              = searchExpressions.Pop();
                                op                = operators.Pop();
                                currentExpression = LogicalSearchExpression.Create(
                                    Options,
                                    left,
                                    right,
                                    op,
                                    text: $"{left.Text} {op} {right.Text}");
                            }

                            return(currentExpression);
                        }
                    }
                }

                // if we get here we made a logical error in our programming
                throw new InvalidProgramException("Error parsing logical operators from search text");
            }
        }