2015-04-07 09:35:12 +01:00
//---------------------------------------------------------------------
// <copyright file="CaseCqlBlock.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Data.Mapping.ViewGeneration.Structures ;
using System.Text ;
using System.Collections.Generic ;
using System.Data.Common.CommandTrees ;
using System.Data.Common.CommandTrees.ExpressionBuilder ;
using System.Data.Common.Utils ;
using System.Diagnostics ;
namespace System.Data.Mapping.ViewGeneration.CqlGeneration
{
/// <summary>
/// A class to capture cql blocks responsible for case statements generating multiconstants, i.e., complex types, entities, discriminators, etc.
/// </summary>
internal sealed class CaseCqlBlock : CqlBlock
{
#region Constructors
/// <summary>
/// Creates a <see cref="CqlBlock"/> containing the case statememt for the <paramref name="caseSlot"/> and projecting other slots as is from its child (input). CqlBlock with SELECT (slots),
/// </summary>
/// <param name="caseSlot">indicates which slot in <paramref name="slots"/> corresponds to the case statement being generated by this block</param>
internal CaseCqlBlock ( SlotInfo [ ] slots , int caseSlot , CqlBlock child , BoolExpression whereClause , CqlIdentifiers identifiers , int blockAliasNum )
: base ( slots , new List < CqlBlock > ( new CqlBlock [ ] { child } ) , whereClause , identifiers , blockAliasNum )
{
m_caseSlotInfo = slots [ caseSlot ] ;
}
#endregion
#region Fields
private readonly SlotInfo m_caseSlotInfo ;
#endregion
#region Methods
internal override StringBuilder AsEsql ( StringBuilder builder , bool isTopLevel , int indentLevel )
{
// The SELECT part
StringUtil . IndentNewLine ( builder , indentLevel ) ;
builder . Append ( "SELECT " ) ;
if ( isTopLevel )
{
builder . Append ( "VALUE " ) ;
}
Debug . Assert ( m_caseSlotInfo . OutputMember ! = null , "We only construct member slots, not boolean slots." ) ;
builder . Append ( "-- Constructing " ) . Append ( m_caseSlotInfo . OutputMember . LeafName ) ;
Debug . Assert ( Children . Count = = 1 , "CaseCqlBlock can have exactly one child." ) ;
CqlBlock childBlock = Children [ 0 ] ;
base . GenerateProjectionEsql ( builder , childBlock . CqlAlias , true , indentLevel , isTopLevel ) ;
// The FROM part: FROM (ChildView) AS AliasName
builder . Append ( "FROM (" ) ;
childBlock . AsEsql ( builder , false , indentLevel + 1 ) ;
StringUtil . IndentNewLine ( builder , indentLevel ) ;
builder . Append ( ") AS " ) . Append ( childBlock . CqlAlias ) ;
// Get the WHERE part only when the expression is not simply TRUE.
if ( false = = BoolExpression . EqualityComparer . Equals ( this . WhereClause , BoolExpression . True ) )
{
StringUtil . IndentNewLine ( builder , indentLevel ) ;
builder . Append ( "WHERE " ) ;
this . WhereClause . AsEsql ( builder , childBlock . CqlAlias ) ;
}
return builder ;
}
internal override DbExpression AsCqt ( bool isTopLevel )
{
Debug . Assert ( m_caseSlotInfo . OutputMember ! = null , "We only construct real slots not boolean slots" ) ;
// The FROM part: FROM (childBlock)
Debug . Assert ( Children . Count = = 1 , "CaseCqlBlock can have exactly one child." ) ;
CqlBlock childBlock = this . Children [ 0 ] ;
DbExpression cqt = childBlock . AsCqt ( false ) ;
// Get the WHERE part only when the expression is not simply TRUE.
if ( ! BoolExpression . EqualityComparer . Equals ( this . WhereClause , BoolExpression . True ) )
{
cqt = cqt . Where ( row = > this . WhereClause . AsCqt ( row ) ) ;
}
// The SELECT part.
return cqt . Select ( row = > GenerateProjectionCqt ( row , isTopLevel ) ) ;
}
#endregion
}
}