private static void AssertResult(LuceneQueryPredicateExpression result, Occur expectedOccur)
 {
     Assert.That(result, Is.Not.Null, "Expected LuceneQueryPredicateExpression to be returned.");
     Assert.That(result, Is.Not.SameAs(predicate));
     Assert.That(result.QueryField, Is.SameAs(predicate.QueryField));
     Assert.That(result.QueryPattern, Is.SameAs(predicate.QueryPattern));
     Assert.That(result.QueryType, Is.EqualTo(predicate.QueryType));
     Assert.That(result.Occur, Is.EqualTo(expectedOccur));
     Assert.That(result.Boost, Is.EqualTo(predicate.Boost));
     Assert.That(result.AllowSpecialCharacters, Is.EqualTo(predicate.AllowSpecialCharacters));
 }
        protected virtual Expression VisitLuceneQueryPredicateExpression(LuceneQueryPredicateExpression expression)
        {
            var field = (LuceneQueryFieldExpression)VisitExpression(expression.QueryField);
            var pattern = VisitExpression(expression.QueryPattern);

            if (field != expression.QueryField || pattern != expression.QueryPattern)
            {
                return new LuceneQueryPredicateExpression(field, pattern, expression.Occur, expression.QueryType);
            }

            return expression;
        }
        public void LessThan()
        {
            var expression = new LuceneQueryPredicateExpression(
                new LuceneQueryFieldExpression(typeof(string), "Name"),
                Expression.Constant("SampleName"),
                Occur.MUST,
                QueryType.LessThan);

            builder.VisitExpression(expression);

            Assert.That(builder.Query.ToString(), Is.EqualTo("+Name:[* TO SampleName}"));
        }
        private Expression VisitQueryPredicateExpression(LuceneQueryPredicateExpression expression)
        {
            parent = expression;

            var result = base.VisitExtensionExpression(expression);

            if (allowed && result is LuceneQueryPredicateExpression)
            {
                ((LuceneQueryPredicateExpression)result).AllowSpecialCharacters = true;
            }

            parent = null;

            return result;
        }
        public void Stage1_Transform()
        {
            visitor = new BoostMethodCallTreeVisitor(1);
            var methodInfo = ReflectionUtility.GetMethod(() => false.Boost(0f));
            var fieldExpression = new LuceneQueryFieldExpression(typeof(string), "Name");
            var query = new LuceneQueryPredicateExpression(fieldExpression, Expression.Constant("foo"), BooleanClause.Occur.SHOULD);

            const float boostAmount = 0.5f;

            // (LuceneQuery[Default](+Name:"foo")).Boost(0.5f)
            var call = Expression.Call(methodInfo, query, Expression.Constant(boostAmount));

            var result = visitor.VisitExpression(call);

            Assert.That(result, Is.SameAs(query));
            Assert.That(((LuceneQueryPredicateExpression)result).Boost, Is.EqualTo(boostAmount));
        }
        protected override Expression VisitLuceneQueryPredicateExpression(LuceneQueryPredicateExpression expression)
        {
            if (expression.QueryField is LuceneQueryAnyFieldExpression)
            {
                AddMultiFieldQuery(expression);

                return base.VisitLuceneQueryPredicateExpression(expression);
            }

            var mapping = fieldMappingInfoProvider.GetMappingInfo(expression.QueryField.FieldName);

            var pattern = GetPattern(expression, mapping);

            var occur = expression.Occur;
            
            if (string.IsNullOrEmpty(pattern))
            {
                pattern = "*";
                occur = Negate(occur);
            }

            Query query;

            if (expression.QueryType == QueryType.GreaterThan || expression.QueryType == QueryType.GreaterThanOrEqual)
            {
                query = CreateRangeQuery(mapping, expression.QueryType, expression, null);
            }
            else if (expression.QueryType == QueryType.LessThan || expression.QueryType == QueryType.LessThanOrEqual)
            {
                query = CreateRangeQuery(mapping, expression.QueryType, null, expression);
            }
            else
            {
                query = mapping.CreateQuery(pattern);
            }

            var booleanQuery = new BooleanQuery();

            query.Boost = expression.Boost;
            booleanQuery.Add(query, occur);

            queries.Push(booleanQuery);

            return base.VisitLuceneQueryPredicateExpression(expression);
        }
        public void MergeExclusionaryRangeReverseOrder()
        {
            var lowerLess = new LuceneQueryPredicateExpression(new LuceneQueryFieldExpression(typeof(int), "percentile"),
                Expression.Constant(40), Occur.MUST, QueryType.LessThanOrEqual);
            var upperGreater = new LuceneQueryPredicateExpression(new LuceneQueryFieldExpression(typeof(int), "percentile"),
                Expression.Constant(60), Occur.MUST, QueryType.GreaterThanOrEqual);

            var binary = Expression.MakeBinary(ExpressionType.OrElse, upperGreater, lowerLess);

            var result = visitor.VisitExpression(binary);

            Assert.That(result, Is.InstanceOf<LuceneRangeQueryExpression>());
            var expr = (LuceneRangeQueryExpression)result;
            Assert.That(expr.Lower, Is.SameAs(lowerLess.QueryPattern));
            Assert.That(expr.LowerQueryType, Is.EqualTo(QueryType.GreaterThan));
            Assert.That(expr.Upper, Is.SameAs(upperGreater.QueryPattern));
            Assert.That(expr.UpperQueryType, Is.EqualTo(QueryType.LessThan));
            Assert.That(expr.Occur, Is.EqualTo(Occur.MUST_NOT));
        }
        private Query CreateRangeQuery(IFieldMappingInfo mapping, QueryType queryType, LuceneQueryPredicateExpression lowerBoundExpression, LuceneQueryPredicateExpression upperBoundExpression)
        {
            var lowerBound = lowerBoundExpression == null ? null : EvaluateExpression(lowerBoundExpression);
            var upperBound = upperBoundExpression == null ? null : EvaluateExpression(upperBoundExpression);

            var lowerRange = RangeType.Inclusive;
            var upperRange = (queryType == QueryType.LessThan || queryType == QueryType.GreaterThan) ? RangeType.Exclusive : RangeType.Inclusive;

            if (upperBoundExpression == null)
            {
                lowerRange = upperRange;
                upperRange = RangeType.Inclusive;
            }

            return mapping.CreateRangeQuery(lowerBound, upperBound, lowerRange, upperRange);
        }
 private void AddMultiFieldQuery(LuceneQueryPredicateExpression expression)
 {
     var query = new BooleanQuery();
     query.Add(new BooleanClause(fieldMappingInfoProvider.CreateMultiFieldQuery(GetPattern(expression, null)), expression.Occur));
     queries.Push(query);
 }
        private string GetPattern(LuceneQueryPredicateExpression expression, IFieldMappingInfo mapping)
        {
            var pattern = EvaluateExpressionToString(expression, mapping);

            switch (expression.QueryType)
            {
                case QueryType.Prefix:
                    pattern += "*";
                    break;
                case QueryType.Wildcard:
                    pattern = "*" + pattern + "*";
                    break;
                case QueryType.Suffix:
                    pattern = "*" + pattern;
                    break;
            }
            return pattern;
        }
        public void IgnoreNonRangeQueryExpression()
        {
            var equal = new LuceneQueryPredicateExpression(new LuceneQueryFieldExpression(typeof(int), "percentile"), Expression.Constant(50), Occur.MUST, QueryType.Default);
            var binary = Expression.MakeBinary(ExpressionType.AndAlso, lower, equal);

            var result = visitor.VisitExpression(binary);

            Assert.That(result, Is.SameAs(binary));
        }
        public void LessThan_DateTime()
        {
            var dateTime = new DateTime(2012, 4, 18, 11, 22, 33);

            var expression = new LuceneQueryPredicateExpression(
                new LuceneQueryFieldExpression(typeof(DateTime), "Published"),
                Expression.Constant(dateTime),
                BooleanClause.Occur.MUST,
                QueryType.LessThan);

            builder.VisitExpression(expression);

            Assert.That(builder.Query.ToString(), Is.EqualTo("+Published:[" + DateTime.MinValue.ToUniversalTime().Ticks + " TO " + dateTime.ToUniversalTime().Ticks + "}"));
        }
        public void GreaterThan_AnalyzesTerm()
        {
            fieldMappingInfoProvider.IsNumeric = false;

            var expression = new LuceneQueryPredicateExpression(
                new LuceneQueryFieldExpression(typeof(string), "Name"),
                Expression.Constant("SampleName"),
                BooleanClause.Occur.MUST,
                QueryType.GreaterThan);

            builder.VisitExpression(expression);

            Assert.That(builder.Query.ToString(), Is.EqualTo("+Name:{samplename TO *]"));
        }
 private object EvaluateExpression(LuceneQueryPredicateExpression expression)
 {
     var lambda = Expression.Lambda(expression.QueryPattern).Compile();
     return lambda.DynamicInvoke();
 }
 private static IComparable GetQueryPatternAsConstComparable(LuceneQueryPredicateExpression expression)
 {
     var constant = expression.QueryPattern as ConstantExpression;
     if (constant == null) return null;
     return constant.Value as IComparable;
 }
 private object EvaluateExpression(LuceneQueryPredicateExpression expression)
 {
     return EvaluateExpression(expression.QueryPattern);
 }
        public void IgnoreDifferentFields()
        {
            var otherUpper = new LuceneQueryPredicateExpression(new LuceneQueryFieldExpression(typeof(int), "id"), Expression.Constant(80), Occur.MUST, QueryType.LessThanOrEqual);
            var binary = Expression.MakeBinary(ExpressionType.AndAlso, lower, otherUpper);

            var result = visitor.VisitExpression(binary);

            Assert.That(result, Is.SameAs(binary));
        }
        private string EvaluateExpressionToString(LuceneQueryPredicateExpression expression, IFieldMappingInfo mapping)
        {
            var result = EvaluateExpression(expression);
            
            var str = mapping == null ? result.ToString() : mapping.ConvertToQueryExpression(result);

            if (expression.AllowSpecialCharacters)
                return str;

            return mapping != null ? mapping.EscapeSpecialCharacters(str) : str;
        }
        private void AddMultiFieldQuery(LuceneQueryPredicateExpression expression)
        {
            var query = new BooleanQuery();

            var parser = new MultiFieldQueryParser(context.Version,
                                                   fieldMappingInfoProvider.AllFields.ToArray(),
                                                   context.Analyzer);
            
            query.Add(new BooleanClause(parser.Parse(GetPattern(expression, null)), expression.Occur));

            queries.Push(query);
        }
        private Query CreateRangeQuery(IFieldMappingInfo mapping, QueryType queryType, LuceneQueryPredicateExpression lowerBoundExpression, LuceneQueryPredicateExpression upperBoundExpression)
        {
            var lowerRange = RangeType.Inclusive;
            var upperRange = (queryType == QueryType.LessThan || queryType == QueryType.GreaterThan) ? RangeType.Exclusive : RangeType.Inclusive;

            if (upperBoundExpression == null)
            {
                lowerRange = upperRange;
                upperRange = RangeType.Inclusive;
            }

            if (mapping.IsNumericField)
            {
                var lowerBound = lowerBoundExpression == null ? null : EvaluateExpression(lowerBoundExpression);
                var upperBound = upperBoundExpression == null ? null : EvaluateExpression(upperBoundExpression);
                return NumericRangeUtils.CreateNumericRangeQuery(mapping.FieldName, (ValueType)lowerBound, (ValueType)upperBound, lowerRange, upperRange);
            }
            else
            {
                var minInclusive = lowerRange == RangeType.Inclusive;
                var maxInclusive = upperRange == RangeType.Inclusive;

                var lowerBound = lowerBoundExpression == null ? null : EvaluateExpressionToStringAndAnalyze(lowerBoundExpression, mapping);
                var upperBound = upperBoundExpression == null ? null : EvaluateExpressionToStringAndAnalyze(upperBoundExpression, mapping);
                return new TermRangeQuery(mapping.FieldName, lowerBound, upperBound, minInclusive, maxInclusive);
            }
        }
 private string EvaluateExpressionToStringAndAnalyze(LuceneQueryPredicateExpression expression, IFieldMappingInfo mapping)
 {
     return context.Analyzer.Analyze(mapping.FieldName, EvaluateExpressionToString(expression, mapping));
 }
        public void GreaterThanOrEqual()
        {
            var expression = new LuceneQueryPredicateExpression(
                new LuceneQueryFieldExpression(typeof(float), "Count"),
                Expression.Constant(6f),
                BooleanClause.Occur.MUST,
                QueryType.GreaterThanOrEqual);

            builder.VisitExpression(expression);

            Assert.That(builder.Query.ToString(), Is.EqualTo("+Count:[6 TO " + float.MaxValue + "]"));
        }
        public void GreaterThan()
        {
            var expression = new LuceneQueryPredicateExpression(
                new LuceneQueryFieldExpression(typeof (int), "Count"),
                Expression.Constant(5),
                Occur.MUST,
                QueryType.GreaterThan);

            builder.VisitExpression(expression);

            Assert.That(builder.Query.ToString(), Is.EqualTo("+Count:{5 TO " + int.MaxValue + "]"));
        }
        public void LessThanOrEqual()
        {
            var expression = new LuceneQueryPredicateExpression(
                new LuceneQueryFieldExpression(typeof(DateTime), "Average"),
                Expression.Constant(11.5d),
                BooleanClause.Occur.MUST,
                QueryType.LessThanOrEqual);

            builder.VisitExpression(expression);

            Assert.That(builder.Query.ToString(), Is.EqualTo("+Average:[" + double.MinValue + " TO 11.5]"));
        }
        private string GetPattern(LuceneQueryPredicateExpression expression, IFieldMappingInfo mapping)
        {
            var pattern = EvaluateExpressionToString(expression, mapping);

            switch (expression.QueryType)
            {
                case QueryType.Prefix:
                    pattern += "*";
                    break;
                case QueryType.Wildcard:
                    pattern = "*" + pattern + "*";
                    break;
                case QueryType.Suffix:
                    pattern = "*" + pattern;
                    break;
            }

            if (expression.Fuzzy.HasValue)
            {
                pattern += string.Format(
                    CultureInfo.InvariantCulture,
                    "~{0}",
                    expression.Fuzzy.Value);
            }

            return pattern;
        }