SqlJoinedTable represents a joined data source in a SqlStatement.
SqlJoinedTable implements ITableInfo because in SqlPreparationFromExpressionVisitor.VisitMemberExpression, a SqlTable is created that needs to preserve all information about a join (causes by a member access in a from expression). The SqlJoinedTable is used as an adapter between IJoinInfo and ITableInfo. (Refactoring this is definitely possible, e.g., by writing a dedicated adapter class.)
Inheritance: SqlTableBase, ITableInfo
    public void DifferentType ()
    {
      var oldJoinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook();
      var sqlJoinedTable = new SqlJoinedTable (oldJoinInfo, JoinSemantics.Left);
      var newJoinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenRestaurant();

      sqlJoinedTable.JoinInfo = newJoinInfo;
    }
    public ITableInfo VisitSqlJoinedTable (SqlJoinedTable joinedTable)
    {
      ArgumentUtility.CheckNotNull ("joinedTable", joinedTable);

      var newJoinInfo = _stage.ApplyContext (joinedTable.JoinInfo, _expressionContext, _mappingResolutionContext); 
      joinedTable.JoinInfo = newJoinInfo;

      return joinedTable;
    }
    public void SameType ()
    {
      var oldJoinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook();
      var sqlJoinedTable = new SqlJoinedTable (oldJoinInfo, JoinSemantics.Left);

      var newJoinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_CookSubstitution ();
      sqlJoinedTable.JoinInfo = newJoinInfo;

      Assert.That (sqlJoinedTable.JoinInfo.ItemType, Is.EqualTo (newJoinInfo.ItemType));
      Assert.That (sqlJoinedTable.JoinSemantics, Is.EqualTo (JoinSemantics.Left));
    }
    private static void GenerateTextForSqlJoinedTable (IJoinInfoVisitor visitor, SqlJoinedTable joinedTable, ISqlCommandBuilder commandBuilder)
    {
      ArgumentUtility.CheckNotNull ("joinedTable", joinedTable);

      // TODO RMLNQSQL-4: This check can be removed.
      if (joinedTable.JoinSemantics == JoinSemantics.Inner)
        throw new NotSupportedException ("SqlJoinedTables with INNER JoinSemantics are currently not supported. (RMLNQSQL-4)");

      commandBuilder.Append (" LEFT OUTER JOIN ");

      joinedTable.JoinInfo.Accept (visitor);
    }
    public void Accept_VisitorSupportingExpressionType ()
    {
      var oldJoinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook ();
      var sqlJoinedTable = new SqlJoinedTable (oldJoinInfo, JoinSemantics.Left);

      var visitorMock = MockRepository.GenerateMock<ISqlTableBaseVisitor> ();
      visitorMock.Expect (mock => mock.VisitSqlJoinedTable (sqlJoinedTable));
      visitorMock.Replay ();

      sqlJoinedTable.Accept (visitorMock);

      visitorMock.VerifyAllExpectations ();
      Assert.That (sqlJoinedTable.JoinSemantics, Is.EqualTo (JoinSemantics.Left));
    }
    public void Accept_ITableInfoVisitor ()
    {
      var oldJoinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook();
      var sqlJoinedTable = new SqlJoinedTable (oldJoinInfo, JoinSemantics.Left);
      var fakeResult = new ResolvedSimpleTableInfo (typeof (Cook), "CookTable", "c");

      var visitorMock = MockRepository.GenerateMock<ITableInfoVisitor>();
      visitorMock
          .Expect (mock => mock.VisitSqlJoinedTable (sqlJoinedTable))
          .Return (fakeResult);

      var result = ((ITableInfo) sqlJoinedTable).Accept (visitorMock);

      visitorMock.VerifyAllExpectations();
      Assert.That (result, Is.SameAs (fakeResult));
    }
    protected override Expression VisitMemberExpression (MemberExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var preparedMemberExpression = (MemberExpression) TranslateExpression (expression, Context, Stage, MethodCallTransformerProvider);

      var joinInfo = new UnresolvedCollectionJoinInfo (preparedMemberExpression.Expression, preparedMemberExpression.Member);
      var joinedTable = new SqlJoinedTable (joinInfo, JoinSemantics.Inner);
      var oldStyleJoinedTable = _tableGenerator (joinedTable);
      var sqlTableReferenceExpression = new SqlTableReferenceExpression (oldStyleJoinedTable);
      FromExpressionInfo = new FromExpressionInfo (
          oldStyleJoinedTable, new Ordering[0], sqlTableReferenceExpression, new JoinConditionExpression (joinedTable));

      return sqlTableReferenceExpression;
    }
 // TODO RMLNQSQL-4: This method can be removed.
 ITableInfo ITableInfoVisitor.VisitSqlJoinedTable (SqlJoinedTable joinedTable)
 {
   throw new InvalidOperationException ("SqlJoinedTable as TableInfo is not valid at this point.");
 }
    public ITableInfo VisitSqlJoinedTable (SqlJoinedTable joinedTable)
    {
      ArgumentUtility.CheckNotNull ("joinedTable", joinedTable);

      var resolvedJoinInfo = _stage.ResolveJoinInfo (joinedTable.JoinInfo, _context);
      joinedTable.JoinInfo = resolvedJoinInfo;

      return joinedTable.GetResolvedTableInfo ();
    }
    public new void ToString ()
    {
      var joinedTable = new SqlJoinedTable (SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook(), JoinSemantics.Left);

      var result = joinedTable.ToString ();

      Assert.That (result, Is.EqualTo ("LEFT JOIN Kitchen.Cook"));
    }
    public void ResolveJoinedTable ()
    {
      var joinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook();
      var joinedTable = new SqlJoinedTable (joinInfo, JoinSemantics.Left);

      var fakeJoinInfo = SqlStatementModelObjectMother.CreateResolvedJoinInfo();
      
      _stageMock
          .Expect (mock => mock.ResolveJoinInfo (joinInfo, _mappingResolutionContext))
          .Return (fakeJoinInfo);
      _stageMock.Replay();

      _visitor.ResolveJoinedTable (joinedTable);

      Assert.That (joinedTable.JoinInfo, Is.SameAs (fakeJoinInfo));
    }
    public void ToString_WithJoins ()
    {
      var joinedTable = new SqlJoinedTable (SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook(), JoinSemantics.Left);
      var joinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook ();
      var memberInfo = typeof (Kitchen).GetProperty ("Cook");
      joinedTable.GetOrAddLeftJoin (joinInfo, memberInfo);

      var result = joinedTable.ToString ();
      Assert.That (result, Is.EqualTo ("LEFT JOIN Kitchen.Cook LEFT JOIN Kitchen.Cook"));
    }
    public void VisitJoinConditionExpression ()
    {
      var resolvedTableInfo = new ResolvedSimpleTableInfo (typeof (Cook), "CookTable", "c");
      var leftKey = new SqlColumnDefinitionExpression (typeof (Cook), "c", "ID", false);
      var rightKey = new SqlColumnDefinitionExpression (typeof (Cook), "a", "FK", false);
      var joinInfo = new ResolvedJoinInfo (resolvedTableInfo, Expression.Equal (leftKey, rightKey));
      var sqlTable = new SqlJoinedTable (joinInfo, JoinSemantics.Left);
      var joinConditionExpression = new JoinConditionExpression (sqlTable);

      _entityIdentityResolverMock
          .Expect (
              mock => mock.ResolvePotentialEntityComparison (
                  Arg<BinaryExpression>.Matches (b => b.Left == leftKey && b.Right == rightKey)))
          .Return (null)
          .WhenCalled (mi => mi.ReturnValue = mi.Arguments[0]);
      _compoundComparisonSplitterMock
          .Expect (
              mock => mock.SplitPotentialCompoundComparison (
                  Arg<BinaryExpression>.Matches (b => b.Left == leftKey && b.Right == rightKey)))
          .Return (null)
          .WhenCalled (mi => mi.ReturnValue = mi.Arguments[0]);

      var result = _visitor.VisitExpression (joinConditionExpression);

      _entityIdentityResolverMock.VerifyAllExpectations();
      _compoundComparisonSplitterMock.VerifyAllExpectations();

      var expectedExpression = Expression.Equal (leftKey, rightKey);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedExpression, result);
    }
    public void ResolveTableInfo_SqlJoinedTable ()
    {
      var joinInfo = SqlStatementModelObjectMother.CreateResolvedJoinInfo();
      var sqlJoinedTable = new SqlJoinedTable (joinInfo, JoinSemantics.Left);

      _stageMock
          .Expect (mock => mock.ResolveJoinInfo(joinInfo, _mappingResolutionContext))
          .Return(joinInfo);
      _resolverMock.Replay();

      var result = ResolvingTableInfoVisitor.ResolveTableInfo (sqlJoinedTable, _resolverMock, _generator, _stageMock, _mappingResolutionContext);

      _stageMock.VerifyAllExpectations();
      Assert.That (result, Is.SameAs (joinInfo.ForeignTableInfo));
    }
 public new void ResolveJoinedTable (SqlJoinedTable joinedTable)
 {
   base.ResolveJoinedTable (joinedTable);
 }
    public void ToString_SqlJoinedTableWithResolvedJoinInfo ()
    {
      var sqlTable =
          new SqlJoinedTable (
              new ResolvedJoinInfo (
                  new ResolvedSimpleTableInfo (typeof (Cook), "CookTable", "c"), Expression.Constant (true)),
              JoinSemantics.Left);
      var expression = new SqlTableReferenceExpression (sqlTable);
      var result = expression.ToString();

      Assert.That (result, Is.EqualTo ("TABLE-REF(c)"));
    }
    public void ToString_SqlJoinedTableWithUnresolvedJoinInfo ()
    {
      var sqlTable = new SqlJoinedTable (SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook(), JoinSemantics.Left);
      var expression = new SqlTableReferenceExpression (sqlTable);
      var result = expression.ToString();

      Assert.That (result, Is.EqualTo ("TABLE-REF(UnresolvedJoinInfo(Cook))"));
    }
    public void ApplyContext_SqlJoinedTable_NewJoinInfo ()
    {
      var joinInfo = SqlStatementModelObjectMother.CreateResolvedJoinInfo();
      var sqlJoinedTable = new SqlJoinedTable (joinInfo, JoinSemantics.Left);
      var fakeJoinInfo = SqlStatementModelObjectMother.CreateResolvedJoinInfo();

      _stageMock
          .Expect (mock => mock.ApplyContext (joinInfo, SqlExpressionContext.ValueRequired, _mappingresolutionContext))
          .Return (fakeJoinInfo);
      _stageMock.Replay ();

      var result = SqlContextTableInfoVisitor.ApplyContext (sqlJoinedTable, SqlExpressionContext.ValueRequired, _stageMock, _mappingresolutionContext);

      _stageMock.VerifyAllExpectations ();
      Assert.That (((SqlJoinedTable) result).JoinInfo, Is.SameAs (fakeJoinInfo));
    }