//--------------------------------------------------------------------- // // 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 } }