//---------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @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
{
///
/// A class to capture cql blocks responsible for case statements generating multiconstants, i.e., complex types, entities, discriminators, etc.
///
internal sealed class CaseCqlBlock : CqlBlock
{
#region Constructors
///
/// Creates a containing the case statememt for the and projecting other slots as is from its child (input). CqlBlock with SELECT (slots),
///
/// indicates which slot in corresponds to the case statement being generated by this block
internal CaseCqlBlock(SlotInfo[] slots, int caseSlot, CqlBlock child, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum)
: base(slots, new List(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
}
}