Beispiel #1
0
        public SelectManyQuery(IDocumentSchema schema, IQueryableDocument mapping, QueryModel query, int index)
        {
            Index = index;

            _schema = schema;
            _query  = query;

            _from = query.BodyClauses[index - 1].As <AdditionalFromClause>();

            var members = FindMembers.Determine(_from.FromExpression);

            _field = mapping.FieldFor(members);

            IsDistinct = query.HasOperator <DistinctResultOperator>();

            var next = query.BodyClauses.Skip(index + 1).FirstOrDefault(x => x is AdditionalFromClause);

            if (next != null)
            {
                throw new NotSupportedException("Not yet supporting SelectMany().SelectMany()");
            }
            else
            {
                _take = _query.BodyClauses.Count - index;
            }


            _tableAlias   = "sub" + Index;
            _documentType = _field.MemberType.GetElementType();
            _document     = _schema.StoreOptions.GetChildDocument(_tableAlias + ".x", _documentType);
        }
Beispiel #2
0
        protected override Expression VisitBinary(BinaryExpression node)
        {
            if (node.NodeType == ExpressionType.Equal)
            {
                var param = _parameterSetters.OfType <IContainmentParameterSetter>().LastOrDefault() ?? addParameter();

                var members = FindMembers.Determine(node.Left);
                var keys    = members.Select(x => x.Name).ToArray();

                if (node.Right.NodeType == ExpressionType.Constant)
                {
                    param.Constant(keys, node.Right.As <ConstantExpression>().Value);
                }
                else
                {
                    var member = FindMembers.Determine(node.Right).LastOrDefault();
                    if (member == null)
                    {
                        throw new NotSupportedException("Marten does not yet support this type of child collection querying");
                    }

                    param.AddElement(keys, member);
                }
            }


            return(base.VisitBinary(node));
        }
        public static void CreateDictionaryForSearch(IDictionary <string, object> dict, Expression memberExpression,
                                                     object expressionValue, ISerializer serializer)
        {
            var visitor = new FindMembers();

            visitor.Visit(memberExpression);

            var members = visitor.Members;

            if (members.Count > 1)
            {
                var temp   = new Dictionary <string, object>();
                var member = members.Last();
                var value  = GetMemberValue(member, expressionValue, serializer.EnumStorage);

                temp.Add(member.Name, value);

                members.Reverse().Skip(1).Each(m => { temp = new Dictionary <string, object> {
                                                          { m.Name, temp }
                                                      }; });

                var topMemberName = members.First().Name;
                dict.Add(topMemberName, temp[topMemberName]);
            }
            else
            {
                var member = members.Single();
                var value  = GetMemberValue(member, expressionValue, serializer.EnumStorage);

                dict.Add(member.Name, value);
            }
        }
Beispiel #4
0
        public void UniqueIndex(UniqueIndexType indexType, string indexName,
                                TenancyScope tenancyScope = TenancyScope.Global, params Expression <Func <T, object> >[] expressions)
        {
            var members = expressions
                          .Select(e =>
            {
                var visitor = new FindMembers();
                visitor.Visit(e);
                return(visitor.Members.ToArray());
            })
                          .ToArray();

            if (members.Length == 0)
            {
                throw new InvalidOperationException(
                          $"Unique index on {typeof(T)} requires at least one property/field");
            }

            AddUniqueIndex(
                members,
                indexType,
                indexName,
                IndexMethod.btree,
                tenancyScope);
        }
Beispiel #5
0
        private static IField GetField(IFieldMapping mapping, MethodCallExpression expression)
        {
            IField GetField(Expression e)
            {
                var visitor = new FindMembers();

                visitor.Visit(e);

                var field = mapping.FieldFor(visitor.Members);

                return(field);
            }

            if (!expression.Method.IsStatic && expression.Object != null && expression.Object.NodeType != ExpressionType.Constant)
            {
                // x.member.Equals(...)
                return(GetField(expression.Object));
            }
            if (expression.Arguments[0].NodeType == ExpressionType.Constant)
            {
                // type.Equals("value", x.member) [decimal]
                return(GetField(expression.Arguments[1]));
            }
            // type.Equals(x.member, "value") [decimal]
            return(GetField(expression.Arguments[0]));
        }
        public void can_add_a_parameter_to_a_db_command()
        {
            var serializer = new JsonNetSerializer {
                EnumStorage = EnumStorage.AsString
            };

            var setter = new ContainmentParameterSetter <Target>(serializer, new MemberInfo[] { FindMembers.Member <Target>(x => x.Children) });

            setter.AddElement(new[] { "color" }, FindMembers.Member <Target>(x => x.Color));
            setter.AddElement(new[] { "name" }, FindMembers.Member <Target>(x => x.String));
            setter.AddElement(new[] { "rank" }, FindMembers.Member <Target>(x => x.Number));

            var target = new Target
            {
                Color  = Colors.Blue,
                String = "Ronald McDonald",
                Number = 5
            };

            var command = new NpgsqlCommand();
            var builder = new CommandBuilder(command);

            var parameter = setter.AddParameter(target, builder);

            parameter.NpgsqlDbType.ShouldBe(NpgsqlDbType.Jsonb);
            parameter.Value.ShouldBe("{\"Children\":[{\"color\":\"Blue\",\"name\":\"Ronald McDonald\",\"rank\":5}]}");
        }
        public void can_build_out_the_dictionary()
        {
            var serializer = new JsonNetSerializer {
                EnumStorage = EnumStorage.AsString
            };

            var setter = new ContainmentParameterSetter <Target>(serializer, new MemberInfo[0]);

            setter.AddElement(new [] { "color" }, FindMembers.Member <Target>(x => x.Color));
            setter.AddElement(new [] { "name" }, FindMembers.Member <Target>(x => x.String));
            setter.AddElement(new [] { "rank" }, FindMembers.Member <Target>(x => x.Number));

            var target = new Target
            {
                Color  = Colors.Blue,
                String = "Ronald McDonald",
                Number = 5
            };

            var dict = setter.BuildDictionary(target);

            dict["color"].ShouldBe(Colors.Blue);
            dict["name"].ShouldBe(target.String);
            dict["rank"].ShouldBe(5);
        }
Beispiel #8
0
            public DocumentMappingExpression <T> ForeignKey(Expression <Func <T, object> > expression, string schemaName,
                                                            string tableName, string columnName,
                                                            Action <ForeignKey>?foreignKeyConfiguration = null)
            {
                _builder.Alter = m =>
                {
                    var members = FindMembers.Determine(expression);

                    var duplicateField = m.DuplicateField(members);

                    var foreignKey =
                        new ForeignKey($"{m.TableName.Name}_{duplicateField.ColumnName}_fkey")
                    {
                        LinkedTable = new DbObjectName(schemaName ?? m.DatabaseSchemaName, tableName),
                        ColumnNames = new[] { duplicateField.ColumnName },
                        LinkedNames = new[] { columnName }
                    };


                    foreignKeyConfiguration?.Invoke(foreignKey);
                    m.ForeignKeys.Add(foreignKey);
                };

                return(this);
            }
Beispiel #9
0
        private string toPath(Expression expression)
        {
            var visitor = new FindMembers();

            visitor.Visit(expression);

            return(visitor.Members.Select(x => x.Name).Join("."));
        }
        private DuplicatedField duplicateField(Expression <Func <IEvent, object> > property, string columnName)
        {
            var finder = new FindMembers();

            finder.Visit(property);

            return(DuplicateField(finder.Members.ToArray(), columnName: columnName));
        }
Beispiel #11
0
        public static SetMemberGrammar For <T>(Expression <Func <T, object> > expression)
        {
            var finder = new FindMembers();

            finder.Visit(expression);

            return(new SetMemberGrammar(finder.Members.ToArray()));
        }
Beispiel #12
0
        /// <summary>
        /// Adds an ngram index.
        /// </summary>
        /// <param name="expression">Document field that should be use by ngram index</param>
        public NgramIndex NgramIndex(Expression <Func <T, object> > expression)
        {
            var visitor = new FindMembers();

            visitor.Visit(expression);

            return(AddNgramIndex(visitor.Members.ToArray()));
        }
Beispiel #13
0
        private string toPath(Expression expression)
        {
            var visitor = new FindMembers();

            visitor.Visit(expression);

            return(visitor.Members.Select(x => x.Name.FormatCase(_serializer.Casing)).Join("."));
        }
Beispiel #14
0
        public static CheckPropertyGrammar For <T>(Expression <Func <T, object> > expression)
        {
            var finder = new FindMembers();

            finder.Visit(expression);
            var members = finder.Members.ToArray();

            return(new CheckPropertyGrammar(members));
        }
Beispiel #15
0
        public EventTableColumn(string name, Expression <Func <IEvent, object> > eventMemberExpression) : base(name, "varchar")
        {
            _eventMemberExpression = eventMemberExpression;
            _member = FindMembers.Determine(eventMemberExpression).Single();
            var memberType = _member.GetMemberType();

            Type         = PostgresqlProvider.Instance.GetDatabaseType(memberType, EnumStorage.AsInteger);
            NpgsqlDbType = PostgresqlProvider.Instance.ToParameterType(memberType);
        }
Beispiel #16
0
        public ISqlFragment Parse(IFieldMapping mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var members = FindMembers.Determine(expression);

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

            return(new WhereFragment($"mt_grams_vector({locator}) @@ mt_grams_query(?)", values));
        }
Beispiel #17
0
        public StreamTableColumn(string name, Expression <Func <StreamAction, object> > memberExpression) : base(name, "varchar")
        {
            _memberExpression = memberExpression;
            _member           = FindMembers.Determine(memberExpression).Single();
            var memberType = _member.GetMemberType();

            Type         = TypeMappings.GetPgType(memberType, EnumStorage.AsInteger);
            NpgsqlDbType = TypeMappings.ToDbType(memberType);
        }
Beispiel #18
0
        private string toPath(Expression expression)
        {
            var visitor = new FindMembers();

            visitor.Visit(expression);

            // TODO -- don't like this. Smells like duplication in logic
            return(visitor.Members.Select(x => x.Name.FormatCase(_session.Serializer.Casing)).Join("."));
        }
        public static void AssignMemberFromReaderAsync <T>(this GeneratedMethod method, GeneratedType generatedType, int index,
                                                           Expression <Func <T, object> > memberExpression)
        {
            var member       = FindMembers.Determine(memberExpression).Single();
            var variableName = member.Name.ToCamelCase();

            method.Frames.Code($"var {variableName} = await reader.GetFieldValueAsync<{member.GetMemberType().FullNameInCode()}>({index}, {{0}});", Use.Type <CancellationToken>());

            method.Frames.SetMemberValue(member, variableName, typeof(T), generatedType);
        }
        public void add_element_for_property()
        {
            var property = FindMembers.Member <Target>(x => x.String);

            var setter = new ContainmentParameterSetter <Target>(new JsonNetSerializer(), new MemberInfo[0]);

            setter.AddElement(new[] { "position" }, property);

            setter.Elements[0].Member.Name.ShouldBe(nameof(Target.String));
        }
Beispiel #21
0
        public static string JsonLocator(this IQueryableDocument mapping, Expression expression)
        {
            var visitor = new FindMembers();

            visitor.Visit(expression);

            var field = mapping.FieldFor(visitor.Members);

            return(field.SqlLocator);
        }
Beispiel #22
0
                    public void MapTo(Expression <Func <T, TProperty> > memberExpression)
                    {
                        var member = FindMembers.Determine(memberExpression).Single();

                        _parent._builder.Alter = m =>
                        {
                            var metadataColumn = _source(m.Metadata);
                            metadataColumn.Enabled = true;
                            metadataColumn.Member  = member;
                        };
                    }
Beispiel #23
0
        public IWhereFragment Parse(IDocumentMapping mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var finder = new FindMembers();
            finder.Visit(expression);

            var members = finder.Members;

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

            return new WhereFragment($"{locator} = ANY(?)", values);
        }
Beispiel #24
0
        public async Task can_order_by_array_length()
        {
            var targets = Target.GenerateRandomData(100).ToArray();

            theStore.BulkInsert(targets);

            Expression <Func <Target, int> > expression = x => x.Children.Length;
            var memberInfos = FindMembers.Determine(expression.Body);

            memberInfos.Length.ShouldBe(2);

            (await theSession.Query <Target>().OrderBy(x => x.Children.Length).ToListAsync()).ShouldNotBeNull();
        }
Beispiel #25
0
            /// <summary>
            /// Marks a property or field on this document type as a searchable field that is also duplicated in the
            /// database document table
            /// </summary>
            /// <param name="expression"></param>
            /// <param name="pgType">Optional, overrides the Postgresql column type for the duplicated field</param>
            /// <param name="configure">Optional, allows you to customize the Postgresql database index configured for the duplicated field</param>
            /// <returns></returns>
            public DocumentMappingExpression <T> Searchable(Expression <Func <T, object> > expression, string pgType = null, Action <IndexDefinition> configure = null)
            {
                var visitor = new FindMembers();

                visitor.Visit(expression);

                alter = mapping =>
                {
                    var index = mapping.DuplicateField(visitor.Members.ToArray(), pgType);
                    configure?.Invoke(index);
                };

                return(this);
            }
Beispiel #26
0
        public ISqlFragment Parse(IFieldMapping mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var members = FindMembers.Determine(expression);

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

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

            return(new WhereFragment($"{locator} = ANY(?)", values));
        }
Beispiel #27
0
            public DocumentMappingExpression <T> Index(Expression <Func <T, object> > expression, Action <ComputedIndex> configure = null)
            {
                var visitor = new FindMembers();

                visitor.Visit(expression);

                alter = mapping =>
                {
                    var index = new ComputedIndex(mapping, visitor.Members.ToArray());
                    configure?.Invoke(index);
                    mapping.Indexes.Add(index);
                };

                return(this);
            }
Beispiel #28
0
            public DocumentMappingExpression <T> Identity(Expression <Func <T, object> > member)
            {
                alter = mapping =>
                {
                    var members = FindMembers.Determine(member);
                    if (members.Length != 1)
                    {
                        throw new InvalidOperationException($"The expression {member} is not valid as an id column in Marten");
                    }

                    mapping.IdMember = members.Single();
                };

                return(this);
            }
Beispiel #29
0
        public void can_build_getter_for_deep_expression()
        {
            Expression <Func <Target, int> > expression = t => t.Inner.Number;

            var visitor = new FindMembers();

            visitor.Visit(expression);

            var members = visitor.Members.ToArray();

            var getter = LambdaBuilder.Getter <Target, int>(EnumStorage.AsInteger, members);

            var target = Target.Random(true);

            getter(target).ShouldBe(target.Inner.Number);
        }
Beispiel #30
0
        public void can_set_property_one_deep()
        {
            var prop = FindMembers.Member <DictTarget>(x => x.Property);

            var element = new DictionaryElement <DictTarget, string>(EnumStorage.AsString, new[] { "foo" }, prop);

            var target = new DictTarget
            {
                Property = "baz"
            };

            var dict = new Dictionary <string, object>();

            element.Write(target, dict);

            dict["foo"].ShouldBe("baz");
        }
Beispiel #31
0
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var finder = new FindMembers();
            finder.Visit(expression);

            var members = finder.Members;

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

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

            return new WhereFragment($"{locator} = ANY(?)", values);
        }
Beispiel #32
0
        private static void canBuildGetterForDeepEnumExpression <T>(EnumStorage enumStorage)
        {
            Expression <Func <Target, object> > expression = t => t.Inner.Color;
            var visitor = new FindMembers();

            visitor.Visit(expression);

            var members = visitor.Members.ToArray();
            var getter  = LambdaBuilder.Getter <Target, T>(enumStorage, members);
            var target  = new Target {
                Inner = new Target {
                    Color = Colors.Blue
                }
            };

            getter(target).ShouldBeOfType(typeof(T));
        }
        public IWhereFragment Parse(IQueryableDocument mapping, ISerializer serializer, MethodCallExpression expression)
        {
            var finder = new FindMembers();
            finder.Visit(expression);
            var members = finder.Members;
            var fieldlocator = mapping.FieldFor(members).SqlLocator;

            if (IsCollectionContainsWithStringKey(expression.Method))
            {
                return QueryFromICollectionContains(expression, fieldlocator, serializer);
            }
            else if (IsDictionaryContainsKey(expression.Method))
            {
                return QueryFromDictionaryContainsKey(expression, fieldlocator);
            }
            else throw new NotImplementedException("Could not understand the format of the dictionary access");
        }