public void BuildBranch_ExistingBranchBuilder_AddsBranch(string branch)
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);

            Assert.Empty(joinBuilder.Branches);

            IExpression result = joinBuilder.BuildBranch(branch, ModelResolvers.ExprResolver());

            Assert.True(joinBuilder.Branches.ContainsKey(branch));
            Assert.Equal(result, joinBuilder.Branches[branch]);
        }
 public QBuilder(Func <Type, string> tableNameResolver, string aliasTablename)
 {
     TableNameResolver = tableNameResolver;
     _aliasTableName   = aliasTablename;
     TableNameAliaser  = new TableNameAliaser(tableNameResolver);
     _orderBuilder     = new OrderBuilder(this);
     _selectBuilder    = new SelectBuilder(this, "t");
     _joinBuilder      = new JoinBuilder(this);
     _whereBuilder     = new WhereBuilder(this);
     _groupBuilder     = new GroupBuilder(this);
 }
        public void Build_CrossJoinWithUsinngBranch_ThrowsException()
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);

            joinBuilder.AddMainExpr(TestExprFactory.GetExpression("join", ExpressionFactoryNameTarget.OperatorSymbol));
            joinBuilder.AddBranch("ds", ModelResolvers.ExprResolver());
            joinBuilder.AddBranch("using", ModelResolvers.ExprResolver());
            joinBuilder.Branches["main"].OperatorDefinition.Keyword = "cross";

            Assert.ThrowsAny <VtlOperatorError>(() => { joinBuilder.Build(); });
        }
        public void AddMainExpr_ScalarExpr_ThrowsException()
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);

            IExpression mainExpr = TestExprFactory.GetExpression("+", ExpressionFactoryNameTarget.OperatorSymbol);

            mainExpr.ResultName = "main";
            mainExpr.Structure  = ModelResolvers.DsResolver();
            mainExpr.Structure.Measures.Add(new StructureComponent(BasicDataType.Integer));

            Assert.ThrowsAny <Exception>(() => { joinBuilder.AddMainExpr(mainExpr); });
        }
Esempio n. 5
0
        public virtual string CompileJoin(SqlResult <Q> ctx, JoinBuilder <Q> join, bool isNested = false)
        {
            var from       = join.GetOneComponent <AbstractFrom>("from", EngineCode);
            var conditions = join.GetComponents <AbstractCondition>("where", EngineCode);

            var joinTable   = CompileTableExpression(ctx, from);
            var constraints = CompileConditions(ctx, conditions);

            var onClause = conditions.Any() ? $" ON {constraints}" : "";

            return($"{join.Type} {joinTable}{onClause}");
        }
        public void AddBranch_Expr_AddsBranch()
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);
            IExpression expr        = ModelResolvers.ExprResolver();

            Assert.False(joinBuilder.Branches.ContainsKey("branch"));

            joinBuilder.AddBranch("branch", expr);

            Assert.True(joinBuilder.Branches.ContainsKey("branch"));
            Assert.Equal(expr, joinBuilder.Branches["branch"]);
            Assert.False(joinBuilder.IsCleared);
        }
        public void Build_WrongBranchesCombination_ThrowsException(params string[] branches)
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);

            joinBuilder.AddMainExpr(TestExprFactory.GetExpression("join", ExpressionFactoryNameTarget.OperatorSymbol));

            foreach (string branch in branches)
            {
                joinBuilder.AddBranch(branch, TestExprFactory.GetExpression("opt", ExpressionFactoryNameTarget.OperatorSymbol));
            }

            Assert.ThrowsAny <VtlOperatorError>(() => { joinBuilder.Build(); });
        }
        public void AddMainExpr_JoinExpr_AddsMainExpr()
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);

            IExpression mainExpr = TestExprFactory.GetExpression("join", ExpressionFactoryNameTarget.OperatorSymbol);

            mainExpr.ResultName = "main";
            mainExpr.Structure  = ModelResolvers.DsResolver();
            mainExpr.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer));
            mainExpr.Structure.Measures.Add(new StructureComponent(BasicDataType.Integer));

            joinBuilder.AddMainExpr(mainExpr);

            Assert.Equal(mainExpr.ResultName, joinBuilder.Branches["main"].ResultName);
            Assert.Equal(mainExpr.OperatorSymbol, joinBuilder.Branches["main"].OperatorSymbol);
            Assert.True(mainExpr.Structure.EqualsObj(joinBuilder.Branches["main"].Structure));
            Assert.False(joinBuilder.IsCleared);
        }
        public void AddMainExpr_NonScalarConvertableToJoinExpr_AddsMainExpr()
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);

            foreach (string symbol in JoinOperators.Operators)
            {
                IExpression mainExpr = TestExprFactory.GetExpression(symbol, ExpressionFactoryNameTarget.OperatorSymbol);
                mainExpr.ResultName = "main";
                mainExpr.Structure  = ModelResolvers.DsResolver();
                mainExpr.Structure.Identifiers.Add(new StructureComponent(BasicDataType.Integer));
                mainExpr.Structure.Measures.Add(new StructureComponent(BasicDataType.Integer));

                joinBuilder.AddMainExpr(mainExpr);

                Assert.Equal(mainExpr, joinBuilder.Branches["main"]);
                Assert.False(joinBuilder.IsCleared);
            }
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="FilterableQuery{TSource,TQuery}" /> class.
        /// </summary>
        /// <param name="alias">
        ///     The alias.
        /// </param>
        /// <param name="query">
        ///     The query.
        /// </param>
        protected FilterableQuery
        (
            string alias           = null,
            IFilterableQuery query = null
        )
            : base(alias, query)
        {
            Query = this as TQuery;

            if (Query == null)
            {
                throw new ArgumentException("The provided TQuery must the type of this instance");
            }

            Inner      = new JoinBuilder <TSource, TQuery>(this, Query, JoinType.InnerJoin);
            LeftOuter  = new JoinBuilder <TSource, TQuery>(this, Query, JoinType.LeftOuterJoin);
            RightOuter = new JoinBuilder <TSource, TQuery>(this, Query, JoinType.RightOuterJoin);
            Full       = new JoinBuilder <TSource, TQuery>(this, Query, JoinType.FullJoin);
        }
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    _selectBuilder    = null;
                    _orderBuilder     = null;
                    _joinBuilder      = null;
                    _whereBuilder     = null;
                    _aliasTableName   = string.Empty;
                    _groupBuilder     = null;
                    _suffix           = string.Empty;
                    TableNameResolver = null;
                    TableNameAliaser  = null;
                }

                // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
                // TODO: set large fields to null.

                disposedValue = true;
            }
        }
        public void Build_CorrectBranches_JoinExpr(params string[] branches)
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);

            joinBuilder.AddMainExpr(TestExprFactory.GetExpression("join", ExpressionFactoryNameTarget.OperatorSymbol));

            Assert.Empty(joinBuilder.Branches["main"].OperandsCollection);

            foreach (string branch in branches)
            {
                joinBuilder.AddBranch(branch, TestExprFactory.GetExpression("opt", ExpressionFactoryNameTarget.OperatorSymbol));
            }

            IJoinExpression result = joinBuilder.Build();

            Assert.Equal(branches.Length, joinBuilder.Branches["main"].OperandsCollection.Count);
            Assert.Equal(branches.Length, result.OperandsCollection.Count);

            foreach (string branch in branches)
            {
                Assert.True(joinBuilder.Branches["main"].Operands.ContainsKey(branch));
                Assert.True(result.Operands.ContainsKey(branch));
            }
        }
        public void Clear_ClearsBranches()
        {
            JoinBuilder joinBuilder = new JoinBuilder(ModelResolvers.JoinExprResolver, this.joinBranches);
            IExpression expr1       = ModelResolvers.ExprResolver();
            IExpression expr2       = ModelResolvers.ExprResolver();
            IExpression expr3       = ModelResolvers.ExprResolver();

            Assert.False(joinBuilder.Branches.ContainsKey("branch1"));
            Assert.False(joinBuilder.Branches.ContainsKey("branch2"));
            Assert.False(joinBuilder.Branches.ContainsKey("branch3"));

            joinBuilder.AddBranch("branch1", expr1);
            joinBuilder.AddBranch("branch2", expr2);
            joinBuilder.AddBranch("branch3", expr3);

            Assert.False(joinBuilder.IsCleared);

            joinBuilder.Clear();

            Assert.False(joinBuilder.Branches.ContainsKey("branch1"));
            Assert.False(joinBuilder.Branches.ContainsKey("branch2"));
            Assert.False(joinBuilder.Branches.ContainsKey("branch3"));
            Assert.True(joinBuilder.IsCleared);
        }
Esempio n. 14
0
        private void HandleTable(Node?parent, SqlTable node, IEnumerable <string> prefix,
                                 IResolveFieldContext context, ICollection <string> selections, ICollection <string> tables,
                                 ICollection <WhereCondition> wheres, ICollection <string> orders, IEnumerable batchScope,
                                 SqlCompilerContext compilerContext)
        {
            var arguments = node.Arguments;

            // also check for batching
            if (node.Paginate == false && (node.Batch == null || node.Junction?.Batch == null || parent == null))
            {
                if (node.Junction?.Where != null)
                {
                    var whereBuilder = new WhereBuilder(_dialect.Quote(node.Junction.As), wheres);
                    node.Junction.Where.Invoke(whereBuilder, arguments, context, node);
                }

                // only add the where clause if there's no join or the join is not paginated
                if (node.Where != null)
                {
                    var whereBuilder = new WhereBuilder(_dialect.Quote(node.As), wheres);
                    node.Where.Invoke(whereBuilder, arguments, context, node);
                }
            }

            if (ThisIsNotTheEndOfThisBatch(parent, node))
            {
                if (node.Junction?.OrderBy != null)
                {
                    var junctionOrderBy = _dialect.CompileOrderBy(node.Junction.OrderBy);
                    orders.Add(junctionOrderBy);
                }

                if (node.OrderBy != null)
                {
                    var orderBy = _dialect.CompileOrderBy(node.OrderBy);
                    orders.Add(orderBy);
                }

                // if (node.Junction?.SortKey != null)
                // {
                //     var junctionOrderBy =  _dialect.CompileOrderBy(node.Junction.SortKey);
                //     orders.Add(junctionOrderBy);
                // }
                //
                // if (node.SortKey != null)
                // {
                //     var orderBy = _dialect.CompileOrderBy(node.SortKey);
                //     orders.Add(orderBy);
                // }
            }

            if (node.Join != null)
            {
                if (parent is SqlTable parentTable)
                {
                    var join = new JoinBuilder(_dialect.Quote(parentTable.Name), _dialect.Quote(parentTable.As),
                                               _dialect.Quote(node.Name), _dialect.Quote(node.As));
                    node.Join(join, arguments, context, node);

                    if (node.Paginate)
                    {
                        _dialect.HandleJoinedOneToManyPaginated(parentTable, node, arguments, context, tables, compilerContext,
                                                                join.Condition == null ? null : _dialect.CompileConditions(new[] { join.Condition }, compilerContext));
                    }
                    else if (join.Condition is RawCondition)
                    {
                        tables.Add($"{join.From} ON {_dialect.CompileConditions(new[] {join.Condition}, compilerContext)}");
                    }
                    else if (join.Condition != null)
                    {
                        tables.Add($"LEFT JOIN {_dialect.Quote(node.Name)} {_dialect.Quote(node.As)} ON {_dialect.CompileConditions(new[] {join.Condition}, compilerContext)}");
                    }

                    return;
                }
            }
            else if (node.Junction?.Batch != null)
            {
                if (parent is SqlTable parentTable)
                {
                    string columnName;

                    if (node.Junction.Batch.ParentKey.Expression != null)
                    {
                        columnName = node.Junction.Batch.ParentKey.Expression(_dialect.Quote(parentTable.As), node.Junction.Batch.ParentKey.Arguments, context, node);
                    }
                    else
                    {
                        columnName = $"{_dialect.Quote(parentTable.As)}.{_dialect.Quote(node.Junction.Batch.ParentKey.Name)}";
                    }

                    selections.Add($"{columnName} AS ${_dialect.Quote(JoinPrefix(prefix) + node.Junction.Batch.ParentKey.As)}");
                }
                else
                {
                    var join = new JoinBuilder(_dialect.Quote(node.Name), _dialect.Quote(node.As), _dialect.Quote(node.Junction.Table), _dialect.Quote(node.Junction.As));

                    if (node.Junction.Batch.Join != null)
                    {
                        node.Junction.Batch.Join(join, arguments, context, node);
                    }

                    if (join.Condition == null)
                    {
                        throw new JoinMonsterException($"The 'batch' join condition on table '{node.Name}' for junction '{node.Junction.Table}' cannot be null.");
                    }


                    var joinCondition = _dialect.CompileConditions(new[] { join.Condition }, compilerContext);

                    if (node.Paginate)
                    {
                        _dialect.HandleBatchedManyToManyPaginated(parent, node, arguments, context, tables, batchScope.Cast <object>(),
                                                                  compilerContext, joinCondition);
                    }
                    else
                    {
                        tables.Add($"FROM {_dialect.Quote(node.Junction.Table)} {_dialect.Quote(node.Junction.As)}");
                        tables.Add($"LEFT JOIN {_dialect.Quote(node.Name)} {_dialect.Quote(node.As)} ON {joinCondition}");

                        var column       = _dialect.Quote(node.Junction.Batch.ThisKey.Name);
                        var whereBuilder = new WhereBuilder(_dialect.Quote(node.Junction.As), wheres);
                        if (node.Junction.Batch.Where != null)
                        {
                            node.Junction.Batch.Where(whereBuilder, column, batchScope, arguments, context, node);
                        }
                        else
                        {
                            whereBuilder.In(column, batchScope);
                        }
                    }
                }
            }
            else if (node.Junction?.FromParent != null && node.Junction?.ToChild != null)
            {
                if (parent is SqlTable parentTable)
                {
                    // TODO: Handle batching and paging
                    var fromParentJoin = new JoinBuilder(_dialect.Quote(parentTable.Name), _dialect.Quote(parentTable.As), _dialect.Quote(node.Junction.Table), _dialect.Quote(node.Junction.As));
                    var toChildJoin    = new JoinBuilder(_dialect.Quote(parentTable.Name), _dialect.Quote(node.Junction.As), _dialect.Quote(node.Name), _dialect.Quote(node.As));
                    node.Junction.FromParent(fromParentJoin, arguments, context, node);
                    node.Junction.ToChild(toChildJoin, arguments, context, node);

                    if (fromParentJoin.Condition == null)
                    {
                        throw new JoinMonsterException($"The 'fromParent' join condition on table '{node.Name}' for junction '{node.Junction.Table}' cannot be null.");
                    }
                    if (toChildJoin.Condition == null)
                    {
                        throw new JoinMonsterException($"The 'toChild' join condition on table '{node.Name}' for junction '{node.Junction.Table}' cannot be null.");
                    }

                    var compiledFromParentJoinCondition = _dialect.CompileConditions(new[] { fromParentJoin.Condition }, compilerContext);
                    var compiledToChildJoinCondition    = _dialect.CompileConditions(new[] { toChildJoin.Condition }, compilerContext);

                    if (node.Paginate)
                    {
                        // _dialect.HandleJoinedManyToManyPaginated();
                    }
                    else
                    {
                        if (fromParentJoin.Condition is RawCondition)
                        {
                            tables.Add($"{fromParentJoin.From} ON {compiledFromParentJoinCondition}");
                        }
                        else
                        {
                            tables.Add(
                                $"LEFT JOIN {_dialect.Quote(node.Junction.Table)} {_dialect.Quote(node.Junction.As)} ON {compiledFromParentJoinCondition}");
                        }

                        if (toChildJoin.Condition is RawCondition)
                        {
                            tables.Add($"{toChildJoin.From} ON {compiledToChildJoinCondition}");
                        }
                        else
                        {
                            tables.Add($"LEFT JOIN {_dialect.Quote(node.Name)} {_dialect.Quote(node.As)} ON {compiledToChildJoinCondition}");
                        }
                    }
                }

                return;
            }
            else if (node.Batch != null)
            {
                if (parent is SqlTable parentTable)
                {
                    string columnName;

                    if (node.Batch.ParentKey.Expression != null)
                    {
                        columnName = node.Batch.ParentKey.Expression(_dialect.Quote(parentTable.As), node.Batch.ParentKey.Arguments, context, node);
                    }
                    else
                    {
                        columnName = $"{_dialect.Quote(parentTable.As)}.{_dialect.Quote(node.Batch.ParentKey.Name)}";
                    }

                    selections.Add($"{columnName} AS {_dialect.Quote(JoinPrefix(prefix) + node.Batch.ParentKey.As)}");
                }
                else if (node.Paginate)
                {
                    _dialect.HandleBatchedOneToManyPaginated(parent, node, arguments, context, tables, batchScope.Cast <object>(), compilerContext);
                }
                else
                {
                    tables.Add($"FROM {_dialect.Quote(node.Name)} AS {_dialect.Quote(node.As)}");

                    var column       = _dialect.Quote(node.Batch.ThisKey.Name);
                    var whereBuilder = new WhereBuilder(_dialect.Quote(node.As), wheres);
                    if (node.Batch.Where != null)
                    {
                        node.Batch.Where(whereBuilder, column, batchScope, arguments, context, node);
                    }
                    else
                    {
                        whereBuilder.In(column, batchScope);
                    }
                }

                return;
            }
            else if (node.Paginate)
            {
                _dialect.HandlePaginationAtRoot(parent, node, arguments, context, tables, compilerContext);
                return;
            }

            tables.Add($"FROM {_dialect.Quote(node.Name)} AS {_dialect.Quote(node.As)}");
        }
Esempio n. 15
0
        /// <inheritdoc />
        public override void HandleJoinedOneToManyPaginated(SqlTable parent, SqlTable node,
                                                            IReadOnlyDictionary <string, object> arguments, IResolveFieldContext context, ICollection <string> tables,
                                                            SqlCompilerContext compilerContext, string?joinCondition)
        {
            if (parent == null)
            {
                throw new ArgumentNullException(nameof(parent));
            }
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (arguments == null)
            {
                throw new ArgumentNullException(nameof(arguments));
            }
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (tables == null)
            {
                throw new ArgumentNullException(nameof(tables));
            }

            if (node.Join == null)
            {
                throw new JoinMonsterException($"{nameof(node)}.{nameof(node.Join)} on table '{node.Name}' cannot be null.");
            }

            var join = new JoinBuilder(Quote(parent.Name), Quote(parent.As), Quote(node.Name), Quote(node.As));

            node.Join(join, arguments, context, node);

            if (join.Condition == null)
            {
                throw new JoinMonsterException($"The join condition on table '{node.Name}' cannot be null.");
            }

            var pagingWhereConditions = new List <WhereCondition>
            {
                join.Condition
            };

            if (node.Where != null)
            {
                var whereBuilder = new WhereBuilder(Quote(node.As), pagingWhereConditions);
                node.Where.Invoke(whereBuilder, arguments, context, node);
            }

            if (node.SortKey != null)
            {
                var(limit, order, whereCondition) = InterpretForKeysetPaging(node, arguments, context);
                if (whereCondition != null)
                {
                    pagingWhereConditions.Add(whereCondition);
                }
                tables.Add(KeysetPagingSelect(node.Name, pagingWhereConditions, order, limit, node.As, joinCondition, "LEFT", compilerContext));
            }
            else if (node.OrderBy != null)
            {
                var(limit, offset, order) = InterpretForOffsetPaging(node, arguments, context);
                tables.Add(OffsetPagingSelect(node.Name, pagingWhereConditions, order, limit, offset,
                                              node.As, joinCondition, "LEFT", compilerContext));
            }
            else
            {
                throw new JoinMonsterException("Cannot paginate without a SortKey or an OrderBy clause.");
            }
        }