Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / CaseStatement.cs / 2 / CaseStatement.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Common.Utils; using System.Linq; using System.Text; using System.Collections.Generic; using System.Data.Mapping.ViewGeneration.CqlGeneration; using System.Data.Metadata.Edm; using System.Diagnostics; namespace System.Data.Mapping.ViewGeneration.Structures { // effects: A class to denote a case statement // CASE // WHENTHEN // WHEN THEN // ... // ENDCASE internal class CaseStatement : InternalBase { #region Constructors /// /// effects: Creates a case statement for the field "memberPath" /// with no clauses /// internal CaseStatement(MemberPath memberPath) { m_memberPath = memberPath; m_clauses = new List(); } #endregion #region Fields private MemberPath m_memberPath; // The field private List m_clauses; // All the WHEN THENs private ProjectedSlot m_elseValue; // Value for the else clause #endregion #region Properties internal MemberPath MemberPath { get { return m_memberPath; } } // CHANGE_[....]_IMPROVE: This can actually be removed if we refactor // CqlGenerator a little bit more internal List Clauses { get { return m_clauses; } } internal ProjectedSlot ElseValue { get { return m_elseValue; } } #endregion #region Methods // effects: Converts all "relevant" ProjectedSlots in this (including // this) to aliased slots for CqlBlock "block". A slot type is // relevant if it is not a constant. "outputPath" is the output path // of this case statement in the final view internal CaseStatement MakeCaseWithAliasedSlots(CqlBlock block, MemberPath outputPath, int slotNum) { // Go through the whenthens and else and make a new case statement with // aliased slots as needed CaseStatement result = new CaseStatement(m_memberPath); foreach (WhenThen whenThen in m_clauses) { WhenThen newClause = whenThen.ReplaceWithAliasedSlot(block, outputPath, slotNum); result.m_clauses.Add(newClause); } if (m_elseValue != null) { result.m_elseValue = m_elseValue.MakeAliasedSlot(block, outputPath, slotNum); } return result; } // requires: condition has not been added to this // effects: Adds an expression of the form WHEN THEN // for this variable internal void AddWhenThen(BoolExpression condition, ProjectedSlot value) { // We should probably validate that the expression is not there? Debug.Assert(value != null); condition.ExpensiveSimplify(); m_clauses.Add(new WhenThen(condition, value)); } // effects: returns true if the case statement requires the value of the member // in THEN or ELSE internal bool DependsOnMemberValue { get { if (m_elseValue is JoinTreeSlot) { return true; } foreach (WhenThen whenThen in m_clauses) { if (whenThen.Value is JoinTreeSlot) { return true; } } return false; } } internal IEnumerable InstantiatedTypes { get { foreach (WhenThen whenThen in m_clauses) { EdmType type; if (TryGetInstantiatedType(whenThen.Value, out type)) { yield return type; } } EdmType elseType; if (TryGetInstantiatedType(m_elseValue, out elseType)) { yield return elseType; } } } private bool TryGetInstantiatedType(ProjectedSlot slot, out EdmType type) { type = null; ConstantSlot constantSlot = slot as ConstantSlot; if (constantSlot != null) { TypeConstant typeConstant = constantSlot.CellConstant as TypeConstant; if (typeConstant != null) { type = typeConstant.CdmType; return true; } } return false; } // effects: Simplifies the case statement so that unnecessary when // thens for nulls/undefined values are eliminated. Also, adds an // else clause if possible. internal void Simplify() { // TODDO_[....]_LOW: Make this call idempotent? Debug.Assert(m_elseValue == null, "Already been simplified -- call is not idempotent yet"); List clauses = new List (); // remove all WHEN clauses where the value gets set to "undefined" // We eliminate the last clause for now - we could determine the // "most complicated" WHEN clause and eliminate it bool eliminatedNullClauses = false; foreach (WhenThen clause in m_clauses) { ConstantSlot constantSlot = clause.Value as ConstantSlot; // If null or undefined, remove it if (constantSlot != null && (constantSlot.CellConstant.IsNull() || constantSlot.CellConstant.IsUndefined())) { eliminatedNullClauses = true; } else { clauses.Add(clause); if (clause.Condition.IsTrue) { // none of subsequent case statements will be evaluated - ignore them break; } } } if (eliminatedNullClauses && clauses.Count == 0) { // There is nothing left -- we should add a null as the value m_elseValue = new ConstantSlot(CellConstant.Null); } // If we eliminated some undefined or null clauses, we do not want an else clause if (clauses.Count > 0 && false == eliminatedNullClauses) { // turn the last WHEN clause into an ELSE int lastIndex = clauses.Count - 1; m_elseValue = clauses[lastIndex].Value; clauses.RemoveAt(lastIndex); } m_clauses = clauses; } // effects: Given a caseStatement, generates the CQL for // it. blockAlias is used whenever the value in the WHEN or THEN is not an aliased slot internal StringBuilder AsCql(StringBuilder builder, IEnumerable withStatements, string blockAlias, int indentLevel) { // If the variable is a relation end, we will gets it scope Extent, e.g., CPerson1 for an // the CPerson end of CPersonAddress1 StringUtil.IndentNewLine(builder, indentLevel + 1); if (Clauses.Count == 0) { // this is just a single ELSE: no condition at all CaseSlotValueAsCql(builder, ElseValue, MemberPath, blockAlias); AppendWithBlock(builder, withStatements, blockAlias, indentLevel, ElseValue); return builder; } // Generate the Case WHEN .. THEN ..., WHEN ... THEN ..., END builder.Append("CASE"); foreach (CaseStatement.WhenThen clause in Clauses) { StringUtil.IndentNewLine(builder, indentLevel + 2); builder.Append("WHEN "); clause.Condition.AsCql(builder, blockAlias); builder.Append(" THEN "); CaseSlotValueAsCql(builder, clause.Value, MemberPath, blockAlias); AppendWithBlock(builder, withStatements, blockAlias, indentLevel + 2, clause.Value); } if (ElseValue != null) { StringUtil.IndentNewLine(builder, indentLevel + 2); builder.Append("ELSE "); CaseSlotValueAsCql(builder, ElseValue, MemberPath, blockAlias); AppendWithBlock(builder, withStatements, blockAlias, indentLevel + 2, ElseValue); } StringUtil.IndentNewLine(builder, indentLevel + 1); builder.Append("END"); return builder; } private void AppendWithBlock(StringBuilder builder, IEnumerable withStatements, string blockAlias, int indentLevel, ProjectedSlot projectedSlot) { if ((withStatements != null) && (withStatements.Count() > 0)) { ConstantSlot typeConstantSlot = projectedSlot as ConstantSlot; if (typeConstantSlot != null) { TypeConstant typeConstant = typeConstantSlot.CellConstant as TypeConstant; if (typeConstant != null) { AppendWithBlock(builder, withStatements, typeConstant.CdmType, blockAlias, indentLevel); } else { Debug.Assert(false, "with block should be there for type constant only"); } } else { Debug.Assert(false, "with block should be there for type constant slot only"); } } } private void AppendWithBlock(StringBuilder builder, IEnumerable withStatements, EdmType fromType, string blockAlias, int indentLevel) { bool appendWithKeyword = true; foreach (WithStatement withStatement in withStatements) { //Add With statement for the types that participate in the association if (withStatement.EntityTypeForFromEnd.IsAssignableFrom(fromType)) { if (appendWithKeyword) { appendWithKeyword = false; builder.Append(" WITH "); } withStatement.AsCql(builder, blockAlias, indentLevel); } } } // requires: This method is called by CaseSlotValuetoCql and // slot is not a boolean slot // effects: Given a slot and its corresponding outputMember, modifies // builder to contain the slot value private static StringBuilder CaseSlotValueAsCql(StringBuilder builder, ProjectedSlot slot, MemberPath outputMember, string blockAlias) { // CHANGE_[....]_DESIGN: We will never have THEN as a boolean slot Debug.Assert(slot is JoinTreeSlot || slot is AliasedSlot || slot is ConstantSlot, "Case statement THEN can only have constants or members"); slot.AsCql(builder, outputMember, blockAlias, 1); return builder; } // Repeat of AsCql but don't have all the info internal override void ToCompactString(StringBuilder builder) { // We have to duplicate the functionality of AsCql here since // ToCompactString can get called at times when the THEN parts contain // Undefined values -- in that case, a Debug.Assert in CellConstant's AsCql // fires off builder.AppendLine("CASE"); foreach (WhenThen clause in m_clauses) { builder.Append(" WHEN "); clause.Condition.ToCompactString(builder); builder.Append(" THEN "); clause.Value.ToCompactString(builder); builder.AppendLine(); } if (m_elseValue != null) { builder.Append(" ELSE "); m_elseValue.ToCompactString(builder); builder.AppendLine(); } builder.Append("END AS "); m_memberPath.ToCompactString(builder); } #endregion // effects: A class that stores WHEN THEN internal class WhenThen : InternalBase { #region Constructor // effects: Creates WHEN THEN internal WhenThen(BoolExpression condition, ProjectedSlot value) { m_condition = condition; m_value = value; } #endregion #region Fields private BoolExpression m_condition; private ProjectedSlot m_value; #endregion #region Properties /// /// effects: Returns the when condition /// internal BoolExpression Condition { get { return m_condition; } } ////// effects: Returns the value for the when case /// internal ProjectedSlot Value { get { return m_value; } } #endregion #region String Methods internal WhenThen ReplaceWithAliasedSlot(CqlBlock block, MemberPath outputPath, int slotNum) { // Change the THEN part ProjectedSlot newValue = m_value.MakeAliasedSlot(block, outputPath, slotNum); return new WhenThen(m_condition, newValue); } internal override void ToCompactString(StringBuilder builder) { builder.Append("WHEN "); m_condition.ToCompactString(builder); builder.Append("THEN "); m_value.ToCompactString(builder); } #endregion } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Common.Utils; using System.Linq; using System.Text; using System.Collections.Generic; using System.Data.Mapping.ViewGeneration.CqlGeneration; using System.Data.Metadata.Edm; using System.Diagnostics; namespace System.Data.Mapping.ViewGeneration.Structures { // effects: A class to denote a case statement // CASE // WHENTHEN // WHEN THEN // ... // ENDCASE internal class CaseStatement : InternalBase { #region Constructors /// /// effects: Creates a case statement for the field "memberPath" /// with no clauses /// internal CaseStatement(MemberPath memberPath) { m_memberPath = memberPath; m_clauses = new List(); } #endregion #region Fields private MemberPath m_memberPath; // The field private List m_clauses; // All the WHEN THENs private ProjectedSlot m_elseValue; // Value for the else clause #endregion #region Properties internal MemberPath MemberPath { get { return m_memberPath; } } // CHANGE_[....]_IMPROVE: This can actually be removed if we refactor // CqlGenerator a little bit more internal List Clauses { get { return m_clauses; } } internal ProjectedSlot ElseValue { get { return m_elseValue; } } #endregion #region Methods // effects: Converts all "relevant" ProjectedSlots in this (including // this) to aliased slots for CqlBlock "block". A slot type is // relevant if it is not a constant. "outputPath" is the output path // of this case statement in the final view internal CaseStatement MakeCaseWithAliasedSlots(CqlBlock block, MemberPath outputPath, int slotNum) { // Go through the whenthens and else and make a new case statement with // aliased slots as needed CaseStatement result = new CaseStatement(m_memberPath); foreach (WhenThen whenThen in m_clauses) { WhenThen newClause = whenThen.ReplaceWithAliasedSlot(block, outputPath, slotNum); result.m_clauses.Add(newClause); } if (m_elseValue != null) { result.m_elseValue = m_elseValue.MakeAliasedSlot(block, outputPath, slotNum); } return result; } // requires: condition has not been added to this // effects: Adds an expression of the form WHEN THEN // for this variable internal void AddWhenThen(BoolExpression condition, ProjectedSlot value) { // We should probably validate that the expression is not there? Debug.Assert(value != null); condition.ExpensiveSimplify(); m_clauses.Add(new WhenThen(condition, value)); } // effects: returns true if the case statement requires the value of the member // in THEN or ELSE internal bool DependsOnMemberValue { get { if (m_elseValue is JoinTreeSlot) { return true; } foreach (WhenThen whenThen in m_clauses) { if (whenThen.Value is JoinTreeSlot) { return true; } } return false; } } internal IEnumerable InstantiatedTypes { get { foreach (WhenThen whenThen in m_clauses) { EdmType type; if (TryGetInstantiatedType(whenThen.Value, out type)) { yield return type; } } EdmType elseType; if (TryGetInstantiatedType(m_elseValue, out elseType)) { yield return elseType; } } } private bool TryGetInstantiatedType(ProjectedSlot slot, out EdmType type) { type = null; ConstantSlot constantSlot = slot as ConstantSlot; if (constantSlot != null) { TypeConstant typeConstant = constantSlot.CellConstant as TypeConstant; if (typeConstant != null) { type = typeConstant.CdmType; return true; } } return false; } // effects: Simplifies the case statement so that unnecessary when // thens for nulls/undefined values are eliminated. Also, adds an // else clause if possible. internal void Simplify() { // TODDO_[....]_LOW: Make this call idempotent? Debug.Assert(m_elseValue == null, "Already been simplified -- call is not idempotent yet"); List clauses = new List (); // remove all WHEN clauses where the value gets set to "undefined" // We eliminate the last clause for now - we could determine the // "most complicated" WHEN clause and eliminate it bool eliminatedNullClauses = false; foreach (WhenThen clause in m_clauses) { ConstantSlot constantSlot = clause.Value as ConstantSlot; // If null or undefined, remove it if (constantSlot != null && (constantSlot.CellConstant.IsNull() || constantSlot.CellConstant.IsUndefined())) { eliminatedNullClauses = true; } else { clauses.Add(clause); if (clause.Condition.IsTrue) { // none of subsequent case statements will be evaluated - ignore them break; } } } if (eliminatedNullClauses && clauses.Count == 0) { // There is nothing left -- we should add a null as the value m_elseValue = new ConstantSlot(CellConstant.Null); } // If we eliminated some undefined or null clauses, we do not want an else clause if (clauses.Count > 0 && false == eliminatedNullClauses) { // turn the last WHEN clause into an ELSE int lastIndex = clauses.Count - 1; m_elseValue = clauses[lastIndex].Value; clauses.RemoveAt(lastIndex); } m_clauses = clauses; } // effects: Given a caseStatement, generates the CQL for // it. blockAlias is used whenever the value in the WHEN or THEN is not an aliased slot internal StringBuilder AsCql(StringBuilder builder, IEnumerable withStatements, string blockAlias, int indentLevel) { // If the variable is a relation end, we will gets it scope Extent, e.g., CPerson1 for an // the CPerson end of CPersonAddress1 StringUtil.IndentNewLine(builder, indentLevel + 1); if (Clauses.Count == 0) { // this is just a single ELSE: no condition at all CaseSlotValueAsCql(builder, ElseValue, MemberPath, blockAlias); AppendWithBlock(builder, withStatements, blockAlias, indentLevel, ElseValue); return builder; } // Generate the Case WHEN .. THEN ..., WHEN ... THEN ..., END builder.Append("CASE"); foreach (CaseStatement.WhenThen clause in Clauses) { StringUtil.IndentNewLine(builder, indentLevel + 2); builder.Append("WHEN "); clause.Condition.AsCql(builder, blockAlias); builder.Append(" THEN "); CaseSlotValueAsCql(builder, clause.Value, MemberPath, blockAlias); AppendWithBlock(builder, withStatements, blockAlias, indentLevel + 2, clause.Value); } if (ElseValue != null) { StringUtil.IndentNewLine(builder, indentLevel + 2); builder.Append("ELSE "); CaseSlotValueAsCql(builder, ElseValue, MemberPath, blockAlias); AppendWithBlock(builder, withStatements, blockAlias, indentLevel + 2, ElseValue); } StringUtil.IndentNewLine(builder, indentLevel + 1); builder.Append("END"); return builder; } private void AppendWithBlock(StringBuilder builder, IEnumerable withStatements, string blockAlias, int indentLevel, ProjectedSlot projectedSlot) { if ((withStatements != null) && (withStatements.Count() > 0)) { ConstantSlot typeConstantSlot = projectedSlot as ConstantSlot; if (typeConstantSlot != null) { TypeConstant typeConstant = typeConstantSlot.CellConstant as TypeConstant; if (typeConstant != null) { AppendWithBlock(builder, withStatements, typeConstant.CdmType, blockAlias, indentLevel); } else { Debug.Assert(false, "with block should be there for type constant only"); } } else { Debug.Assert(false, "with block should be there for type constant slot only"); } } } private void AppendWithBlock(StringBuilder builder, IEnumerable withStatements, EdmType fromType, string blockAlias, int indentLevel) { bool appendWithKeyword = true; foreach (WithStatement withStatement in withStatements) { //Add With statement for the types that participate in the association if (withStatement.EntityTypeForFromEnd.IsAssignableFrom(fromType)) { if (appendWithKeyword) { appendWithKeyword = false; builder.Append(" WITH "); } withStatement.AsCql(builder, blockAlias, indentLevel); } } } // requires: This method is called by CaseSlotValuetoCql and // slot is not a boolean slot // effects: Given a slot and its corresponding outputMember, modifies // builder to contain the slot value private static StringBuilder CaseSlotValueAsCql(StringBuilder builder, ProjectedSlot slot, MemberPath outputMember, string blockAlias) { // CHANGE_[....]_DESIGN: We will never have THEN as a boolean slot Debug.Assert(slot is JoinTreeSlot || slot is AliasedSlot || slot is ConstantSlot, "Case statement THEN can only have constants or members"); slot.AsCql(builder, outputMember, blockAlias, 1); return builder; } // Repeat of AsCql but don't have all the info internal override void ToCompactString(StringBuilder builder) { // We have to duplicate the functionality of AsCql here since // ToCompactString can get called at times when the THEN parts contain // Undefined values -- in that case, a Debug.Assert in CellConstant's AsCql // fires off builder.AppendLine("CASE"); foreach (WhenThen clause in m_clauses) { builder.Append(" WHEN "); clause.Condition.ToCompactString(builder); builder.Append(" THEN "); clause.Value.ToCompactString(builder); builder.AppendLine(); } if (m_elseValue != null) { builder.Append(" ELSE "); m_elseValue.ToCompactString(builder); builder.AppendLine(); } builder.Append("END AS "); m_memberPath.ToCompactString(builder); } #endregion // effects: A class that stores WHEN THEN internal class WhenThen : InternalBase { #region Constructor // effects: Creates WHEN THEN internal WhenThen(BoolExpression condition, ProjectedSlot value) { m_condition = condition; m_value = value; } #endregion #region Fields private BoolExpression m_condition; private ProjectedSlot m_value; #endregion #region Properties /// /// effects: Returns the when condition /// internal BoolExpression Condition { get { return m_condition; } } ////// effects: Returns the value for the when case /// internal ProjectedSlot Value { get { return m_value; } } #endregion #region String Methods internal WhenThen ReplaceWithAliasedSlot(CqlBlock block, MemberPath outputPath, int slotNum) { // Change the THEN part ProjectedSlot newValue = m_value.MakeAliasedSlot(block, outputPath, slotNum); return new WhenThen(m_condition, newValue); } internal override void ToCompactString(StringBuilder builder) { builder.Append("WHEN "); m_condition.ToCompactString(builder); builder.Append("THEN "); m_value.ToCompactString(builder); } #endregion } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- IntSecurity.cs
- ManagementOperationWatcher.cs
- Registry.cs
- InfoCardProofToken.cs
- BinaryFormatterWriter.cs
- _AutoWebProxyScriptWrapper.cs
- AppSettingsSection.cs
- CodeParameterDeclarationExpression.cs
- BooleanExpr.cs
- UIElementParagraph.cs
- FrameworkRichTextComposition.cs
- Triangle.cs
- UIElement3DAutomationPeer.cs
- SerializableTypeCodeDomSerializer.cs
- ConsoleTraceListener.cs
- OleDbCommand.cs
- UnsafeMethods.cs
- EntityStoreSchemaGenerator.cs
- XmlSchemaAnnotated.cs
- ProcessHostConfigUtils.cs
- SingleObjectCollection.cs
- SystemWebCachingSectionGroup.cs
- PeerPresenceInfo.cs
- TableRowGroupCollection.cs
- SQLBytesStorage.cs
- TextTreeRootTextBlock.cs
- MemoryPressure.cs
- DataBindingExpressionBuilder.cs
- EnglishPluralizationService.cs
- ChangeTracker.cs
- IdnElement.cs
- SoapUnknownHeader.cs
- Hashtable.cs
- WebPartDescription.cs
- EdmItemError.cs
- PopOutPanel.cs
- NativeActivityFaultContext.cs
- Psha1DerivedKeyGenerator.cs
- Header.cs
- WebPartZoneAutoFormat.cs
- Flowchart.cs
- EventMappingSettingsCollection.cs
- Rect3D.cs
- Repeater.cs
- SortDescription.cs
- OwnerDrawPropertyBag.cs
- TextPenaltyModule.cs
- PipelineComponent.cs
- LayoutTableCell.cs
- TransformValueSerializer.cs
- DurableDispatcherAddressingFault.cs
- PersonalizationEntry.cs
- StorageEntityContainerMapping.cs
- GradientPanel.cs
- HtmlControl.cs
- HotSpotCollection.cs
- IODescriptionAttribute.cs
- UpDownEvent.cs
- CommonProperties.cs
- ExceptQueryOperator.cs
- XmlAttribute.cs
- ArglessEventHandlerProxy.cs
- AutoGeneratedFieldProperties.cs
- ColorConverter.cs
- SortQueryOperator.cs
- ValidationError.cs
- Aggregates.cs
- ResourceExpressionBuilder.cs
- Win32KeyboardDevice.cs
- PkcsMisc.cs
- CellLabel.cs
- DocumentXPathNavigator.cs
- COM2PropertyDescriptor.cs
- DataGridColumnHeadersPresenterAutomationPeer.cs
- LogSwitch.cs
- MutexSecurity.cs
- ReadOnlyAttribute.cs
- HostProtectionException.cs
- Vector3dCollection.cs
- SqlSelectClauseBuilder.cs
- MessageContractAttribute.cs
- DesigntimeLicenseContext.cs
- ProfileModule.cs
- HtmlHead.cs
- ConcatQueryOperator.cs
- WindowsPrincipal.cs
- StandardCommandToolStripMenuItem.cs
- XmlValidatingReaderImpl.cs
- AppearanceEditorPart.cs
- StructuralCache.cs
- StrokeCollectionDefaultValueFactory.cs
- ToggleProviderWrapper.cs
- OperandQuery.cs
- FrugalList.cs
- ConfigPathUtility.cs
- ButtonFieldBase.cs
- Effect.cs
- SettingsPropertyIsReadOnlyException.cs
- FilterEventArgs.cs
- Clause.cs