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); }); }
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); }
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)}"); }
/// <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."); } }