coordinatorfactory.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / internal / materialization / coordinatorfactory.cs / 1305376 / coordinatorfactory.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System.Collections.Generic;
using System.Diagnostics; 
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Data.Objects.Internal; 

namespace System.Data.Common.Internal.Materialization 
{ 
    /// 
    /// An immutable class used to generate new coordinators. These coordinators are used 
    /// at runtime to materialize results.
    /// 
    internal abstract class CoordinatorFactory
    { 
        #region statics
 
        ///  
        /// Function of shaper that returns true; one default case when there is no explicit predicate.
        ///  
        private static readonly Func AlwaysTrue = s => true;

        /// 
        /// Function of shaper that returns false; one default case used when there is no explicit predicate. 
        /// 
        private static readonly Func AlwaysFalse = s => false; 
 
        #endregion
 
        #region state

        /// 
        /// Gets depth of the reader (0 is top-level -- which incidentally doesn't 
        /// require a coordinator...
        ///  
        internal readonly int Depth; 

        ///  
        /// Indicates which state slot in the Shaper.State is expected to hold the
        /// value for this nested reader result.
        /// 
        internal readonly int StateSlot; 

        ///  
        /// A function determining whether the current row has data for this nested result. 
        /// 
        internal readonly Func HasData; 

        /// 
        /// A function setting key values. (the return value is irrelevant)
        ///  
        internal readonly Func SetKeys;
 
        ///  
        /// A function returning true if key values match the previously set values.
        ///  
        internal readonly Func CheckKeys;

        /// 
        /// Nested results below this (at depth + 1) 
        /// 
        internal readonly System.Collections.ObjectModel.ReadOnlyCollection NestedCoordinators; 
 
        /// 
        /// Indicates whether this is a leaf reader. 
        /// 
        internal readonly bool IsLeafResult;

        ///  
        /// Indicates whether this coordinator can be managed by a simple enumerator. A simple enumerator
        /// returns a single element per row, so the following conditions disqualify the enumerator: 
        /// nested collections, data discriminators (not all rows have data), keys (not all rows have new data). 
        /// 
        internal readonly bool IsSimple; 

        /// 
        /// For value-layer queries, the factories for all the records that we can potentially process
        /// at this level in the query result. 
        /// 
        internal readonly System.Collections.ObjectModel.ReadOnlyCollection RecordStateFactories; 
 
        #endregion
 
        #region constructor

        protected CoordinatorFactory(int depth, int stateSlot, Func hasData, Func setKeys, Func checkKeys, CoordinatorFactory[] nestedCoordinators, RecordStateFactory[] recordStateFactories)
        { 
            this.Depth = depth;
            this.StateSlot = stateSlot; 
 
            // figure out if there are any nested coordinators
            this.IsLeafResult = 0 == nestedCoordinators.Length; 

            // if there is no explicit 'has data' discriminator, it means all rows contain data for the coordinator
            if (hasData == null)
            { 
                this.HasData = AlwaysTrue;
            } 
            else 
            {
                this.HasData = hasData; 
            }

            // if there is no explicit set key delegate, just return true (the value is not used anyways)
            if (setKeys == null) 
            {
                this.SetKeys = AlwaysTrue; 
            } 
            else
            { 
                this.SetKeys = setKeys;
            }

            // If there are no keys, it means different things depending on whether we are a leaf 
            // coordinator or an inner (or 'driving') coordinator. For a leaf coordinator, it means
            // that every row is a new result. For an inner coordinator, it means that there is no 
            // key to check. This should only occur where there is a SingleRowTable (in other words, 
            // all rows are elements of a single child collection).
            if (checkKeys == null) 
            {
                if (this.IsLeafResult)
                {
                    this.CheckKeys = AlwaysFalse; // every row is a new result (the keys don't match) 
                }
                else 
                { 
                    this.CheckKeys = AlwaysTrue; // every row belongs to a single child collection
                } 
            }
            else
            {
                this.CheckKeys = checkKeys; 
            }
            this.NestedCoordinators = new System.Collections.ObjectModel.ReadOnlyCollection(nestedCoordinators); 
            this.RecordStateFactories = new System.Collections.ObjectModel.ReadOnlyCollection(recordStateFactories); 

            // Determines whether this coordinator can be handled by a 'simple' enumerator. See IsSimple for details. 
            this.IsSimple = IsLeafResult && null == checkKeys && null == hasData;
        }

        #endregion 

        #region "public" surface area 
 
        /// 
        /// Creates a buffer handling state needed by this coordinator. 
        /// 
        internal abstract Coordinator CreateCoordinator(Coordinator parent, Coordinator next);

        #endregion 
    }
 
    ///  
    /// Typed 
    ///  
    internal sealed class CoordinatorFactory : CoordinatorFactory
    {
        #region state
 
        /// 
        /// Reads a single element of the result from the given reader state object, returning the 
        /// result as a wrapped entity.  May be null if the element is not available as a wrapped entity. 
        /// 
        internal readonly Func WrappedElement; 

        /// 
        /// Reads a single element of the result from the given reader state object.
        /// May be null if the element is available as a wrapped entity instead. 
        /// 
        internal readonly Func Element; 
 
        /// 
        /// Same as Element but uses slower patterns to provide better exception messages (e.g. 
        /// using reader.GetValue + type check rather than reader.GetInt32)
        /// 
        internal readonly Func ElementWithErrorHandling;
 
        /// 
        /// Initializes the collection storing results from this coordinator. 
        ///  
        internal readonly Func> InitializeCollection;
 
        /// 
        /// Description of this CoordinatorFactory, used for debugging only; while this is not
        /// needed in retail code, it is pretty important because it's the only description we'll
        /// have once we compile the Expressions; debugging a problem with retail bits would be 
        /// pretty hard without this.
        ///  
        private readonly string Description; 

        #endregion 

        #region constructor

        public CoordinatorFactory(int depth, int stateSlot, Expression hasData, Expression setKeys, Expression checkKeys, CoordinatorFactory[] nestedCoordinators, Expression element, Expression elementWithErrorHandling, Expression initializeCollection, RecordStateFactory[] recordStateFactories) 
            : base(depth, stateSlot, CompilePredicate(hasData), CompilePredicate(setKeys), CompilePredicate(checkKeys), nestedCoordinators, recordStateFactories)
        { 
            // If we are in a case where a wrapped entity is available, then use it; otherwise use the raw element. 
            // However, in both cases, use the raw element for the error handling case where what we care about is
            // getting the appropriate exception message. 
            if (typeof(IEntityWrapper).IsAssignableFrom(element.Type))
            {
                this.WrappedElement = Translator.Compile(element);
                elementWithErrorHandling = Translator.Emit_UnwrapAndEnsureType(elementWithErrorHandling, typeof(TElement)); 
            }
            else 
            { 
                this.Element = Translator.Compile(element);
            } 
            this.ElementWithErrorHandling = Translator.Compile(elementWithErrorHandling);
            this.InitializeCollection = null == initializeCollection
                ? s => new List()
                : Translator.Compile>(initializeCollection); 

            this.Description = new StringBuilder() 
                                    .Append("HasData: ") 
                                    .AppendLine(DescribeExpression(hasData))
                                    .Append("SetKeys: ") 
                                    .AppendLine(DescribeExpression(setKeys))
                                    .Append("CheckKeys: ")
                                    .AppendLine(DescribeExpression(checkKeys))
                                    .Append("Element: ") 
                                    .AppendLine(DescribeExpression(element))
                                    .Append("ElementWithExceptionHandling: ") 
                                    .AppendLine(DescribeExpression(elementWithErrorHandling)) 
                                    .Append("InitializeCollection: ")
                                    .AppendLine(DescribeExpression(initializeCollection)) 
                                    .ToString();
        }

        #endregion 

        #region expression helpers 
 
        /// 
        /// Return the compiled expression for the predicate 
        /// 
        private static Func CompilePredicate(Expression predicate)
        {
            Func result; 
            if (null == predicate)
            { 
                result = null; 
            }
            else 
            {
                result = Translator.Compile(predicate);
            }
            return result; 
        }
 
        ///  
        /// Returns a string representation of the expression
        ///  
        private static string DescribeExpression(Expression expression)
        {
            string result;
            if (null == expression) 
            {
                result = "undefined"; 
            } 
            else
            { 
                result = expression.ToString();
            }
            return result;
        } 

        #endregion 
 
        #region "public" surface area
 
        /// 
        /// Create a coordinator used for materialization of collections. Unlike the CoordinatorFactory,
        /// the Coordinator contains mutable state.
        ///  
        internal override Coordinator CreateCoordinator(Coordinator parent, Coordinator next)
        { 
            return new Coordinator(this, parent, next); 
        }
 
        /// 
        /// Returns the "default" record state (that is, the one we use for PreRead/PastEnd reader states
        /// 
        internal RecordState GetDefaultRecordState(Shaper shaper) 
        {
            RecordState result = null; 
            if (this.RecordStateFactories.Count > 0) 
            {
                // 

                result = (RecordState)shaper.State[this.RecordStateFactories[0].StateSlotNumber];
                Debug.Assert(null != result, "did you initialize the record states?");
                result.ResetToDefaultState(); 
            }
            return result; 
        } 

        public override string ToString() 
        {
            return Description;
        }
 
        #endregion
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK