예제 #1
0
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var members = FindMembers.Determine(expression);

            var field = mapping.FieldFor(members);

            return(new WhereFragment($"({field.SelectionLocator} is null or jsonb_array_length({field.SelectionLocator}) = 0)"));
        }
예제 #2
0
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var members = FindMembers.Determine(expression);

            var locator = mapping.FieldFor(members).SqlLocator;
            var value   = expression.Arguments.Last().Value();

            return(new WhereFragment($"{locator} ~~* ?", value.As <string>()));
        }
예제 #3
0
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, BinaryExpression expression)
        {
            var isValueExpressionOnRight = expression.Right.IsValueExpression();
            var jsonLocatorExpression    = isValueExpressionOnRight ? expression.Left : expression.Right;
            var valueExpression          = isValueExpressionOnRight ? expression.Right : expression.Left;

            var members = FindMembers.Determine(jsonLocatorExpression);

            var field = mapping.FieldFor(members);


            var value       = field.GetValue(valueExpression);
            var jsonLocator = field.SqlLocator;

            var useContainment = mapping.PropertySearching == PropertySearching.ContainmentOperator || field.ShouldUseContainmentOperator();

            var isDuplicated = (mapping.FieldFor(members) is DuplicatedField);

            if (useContainment &&
                expression.NodeType == ExpressionType.Equal && value != null && !isDuplicated)
            {
                return(new ContainmentWhereFragment(serializer, expression, _wherePrefix));
            }


            if (value == null)
            {
                var sql = expression.NodeType == ExpressionType.NotEqual
                    ? $"({jsonLocator}) is not null"
                    : $"({jsonLocator}) {_isOperator} null";

                return(new WhereFragment(sql));
            }

            var op = _operators[expression.NodeType];

            if (jsonLocatorExpression.NodeType == ExpressionType.Modulo)
            {
                var byValue      = moduloByValue((isValueExpressionOnRight ? expression.Left : expression.Right) as BinaryExpression);
                var moduloFormat = isValueExpressionOnRight ? "{0} % {1} {2} ?" : "? {2} {0} % {1}";
                return(new WhereFragment(moduloFormat.ToFormat(jsonLocator, byValue, op), value));
            }

            // ! == -> <>

            if (expression.Left.NodeType == ExpressionType.Not && expression.NodeType == ExpressionType.Equal)
            {
                op = _operators[ExpressionType.NotEqual];
            }

            var whereFormat = isValueExpressionOnRight ? "{0} {1} ?" : "? {1} {0}";

            return(new WhereFragment($"{_wherePrefix}{whereFormat.ToFormat(jsonLocator, op)}", value));


            return(value == null ? new WhereFragment($"({jsonLocator}) {_isOperator} null") : new WhereFragment($"{_wherePrefix}({jsonLocator}) {op} ?", value));
        }
예제 #4
0
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, MethodCallExpression expression)
        {
            MemberInfo[] members = FindMembers.Determine(expression);

            string locator = mapping.FieldFor(members).SqlLocator;
            object values  = expression.Arguments.Last().Value();

            string json = serializer.ToJson(values);

            return(new CustomizableWhereFragment($"{locator} @> ?", "?", Tuple.Create <object, NpgsqlDbType?>(json, NpgsqlDbType.Jsonb)));
        }
예제 #5
0
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var members = FindMembers.Determine(expression);

            var locator = mapping.FieldFor(members).SqlLocator;
            var values  = expression.Arguments.Last().Value();

            if (members.Last().GetMemberType().IsEnum)
            {
                return(new EnumIsNotOneOfWhereFragment(values, serializer.EnumStorage, locator));
            }

            return(new WhereFragment($"NOT({locator} = ANY(?))", values));
        }
예제 #6
0
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, BinaryExpression expression)
        {
            var areBothMemberExpressions = !expression.Left.IsValueExpression() && !expression.Right.IsValueExpression();
            var isValueExpressionOnRight = areBothMemberExpressions || expression.Right.IsValueExpression();
            var jsonLocatorExpression    = isValueExpressionOnRight ? expression.Left : expression.Right;
            var valueExpression          = isValueExpressionOnRight ? expression.Right : expression.Left;

            var members = FindMembers.Determine(jsonLocatorExpression);

            var field = mapping.FieldFor(members);

            object value;

            if (valueExpression is MemberExpression memberAccess)
            {
                var membersOther = FindMembers.Determine(memberAccess);
                var fieldOther   = mapping.FieldFor(membersOther);
                value = fieldOther.SqlLocator;
            }
            else
            {
                memberAccess = null;
                value        = field.GetValue(valueExpression);
            }

            var jsonLocator = field.SqlLocator;

            var useContainment = mapping.PropertySearching == PropertySearching.ContainmentOperator || field.ShouldUseContainmentOperator();

            var isDuplicated = (mapping.FieldFor(members) is DuplicatedField);
            var isEnumString = field.MemberType.GetTypeInfo().IsEnum&& serializer.EnumStorage == EnumStorage.AsString;

            if (useContainment &&
                expression.NodeType == ExpressionType.Equal && value != null && !isDuplicated && !isEnumString)
            {
                return(new ContainmentWhereFragment(serializer, expression, _wherePrefix));
            }

            if (value == null)
            {
                var sql = expression.NodeType == ExpressionType.NotEqual
                    ? $"({jsonLocator}) is not null"
                    : $"({jsonLocator}) {_isOperator} null";

                return(new WhereFragment(sql));
            }

            var op = _operators[expression.NodeType];

            if (jsonLocatorExpression.NodeType == ExpressionType.Modulo)
            {
                var byValue      = moduloByValue((isValueExpressionOnRight ? expression.Left : expression.Right) as BinaryExpression);
                var moduloFormat = isValueExpressionOnRight ? "{0} % {1} {2} ?" : "? {2} {0} % {1}";
                return(new WhereFragment(moduloFormat.ToFormat(jsonLocator, byValue, op), value));
            }

            // ! == -> <>

            if (expression.Left.NodeType == ExpressionType.Not && expression.NodeType == ExpressionType.Equal)
            {
                op = _operators[ExpressionType.NotEqual];
            }

            if (memberAccess != null)
            {
                return(new WhereFragment($"{_wherePrefix}{jsonLocator} {op} {value}"));
            }
            var whereFormat = isValueExpressionOnRight ? "{0} {1} ?" : "? {1} {0}";

            return(new WhereFragment($"{_wherePrefix}{whereFormat.ToFormat(jsonLocator, op)}", value));

            //return value == null ? new WhereFragment($"({jsonLocator}) {_isOperator} null") : new WhereFragment($"{_wherePrefix}({jsonLocator}) {op} ?", value);
        }
예제 #7
0
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var value = expression.Arguments.Single().Value();

            return(ContainmentWhereFragment.SimpleArrayContains(FindMembers.Determine(expression.Object), serializer, expression.Object, value));
        }