internal ObjectResult <TResultType> Execute <TResultType>(ObjectContext context, ObjectParameterCollection parameterValues)
        {
            DbDataReader storeReader = null;

            try
            {
                // create entity command (just do this to snarf store command)
                EntityCommandDefinition commandDefinition = (EntityCommandDefinition)this.CommandDefinition;
                EntityCommand           entityCommand     = new EntityCommand((EntityConnection)context.Connection, commandDefinition);

                // pass through parameters and timeout values
                if (context.CommandTimeout.HasValue)
                {
                    entityCommand.CommandTimeout = context.CommandTimeout.Value;
                }

                if (parameterValues != null)
                {
                    foreach (ObjectParameter parameter in parameterValues)
                    {
                        int index = entityCommand.Parameters.IndexOf(parameter.Name);

                        if (index != -1)
                        {
                            entityCommand.Parameters[index].Value = parameter.Value ?? DBNull.Value;
                        }
                    }
                }

                // acquire store reader
                storeReader = commandDefinition.ExecuteStoreCommands(entityCommand, CommandBehavior.Default);

                ShaperFactory <TResultType> shaperFactory = (ShaperFactory <TResultType>) this.ResultShaperFactory;
                Shaper <TResultType>        shaper        = shaperFactory.Create(storeReader, context, context.MetadataWorkspace, this.MergeOption, true);

                // create materializer delegate
                TypeUsage resultItemEdmType;

                if (ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType)
                {
                    resultItemEdmType = ((CollectionType)ResultType.EdmType).TypeUsage;
                }
                else
                {
                    resultItemEdmType = ResultType;
                }

                return(new ObjectResult <TResultType>(shaper, this._singleEntitySet, resultItemEdmType));
            }
            catch (Exception)
            {
                if (null != storeReader)
                {
                    // Note: The caller is responsible for disposing reader if creating
                    // the enumerator fails.
                    storeReader.Dispose();
                }
                throw;
            }
        }
        public void Static_TranslateColumnMap_calls_instance_method()
        {
            var typeUsageMock = new Mock<TypeUsage>();

            var expectedShaperFactory = new ShaperFactory<object>(
                0, Objects.MockHelper.CreateCoordinatorFactory<object>(),
                new Type[0], new bool[0], MergeOption.AppendOnly);

            var translatorMock = new Mock<Translator>();
            translatorMock.Setup(
                m => m.TranslateColumnMap<object>(
                    It.IsAny<ColumnMap>(), It.IsAny<MetadataWorkspace>(),
                    It.IsAny<SpanIndex>(), It.IsAny<MergeOption>(), It.IsAny<bool>(), It.IsAny<bool>())).Returns(expectedShaperFactory);

            var actualShaperFactory = Translator.TranslateColumnMap(
                translatorMock.Object, typeof(object), 
                new ScalarColumnMap(typeUsageMock.Object, null, 0, 0), new MetadataWorkspace(),
                new SpanIndex(), MergeOption.AppendOnly, streaming: false, valueLayer: true);

            translatorMock.Verify(
                m => m.TranslateColumnMap<object>(
                    It.IsAny<ColumnMap>(), It.IsAny<MetadataWorkspace>(),
                    It.IsAny<SpanIndex>(), It.IsAny<MergeOption>(), false, true), Times.Once());
            Assert.Same(expectedShaperFactory, actualShaperFactory);
        }
        public void ExecuteAsync_sets_the_parameter_values_and_returns_the_result()
        {
            var entityCommandDefinitionMock = Mock.Get(EntityClient.MockHelper.CreateEntityCommandDefinition());

            entityCommandDefinitionMock.Setup(m => m.Parameters).Returns(
                new[]
            {
                new EntityParameter
                {
                    ParameterName = "Par1"
                }
            });

            var objectContextMock = Mock.Get(Objects.MockHelper.CreateMockObjectContext <string>());

            objectContextMock.Setup(m => m.CommandTimeout).Returns(3);

            entityCommandDefinitionMock.Setup(
                m => m.ExecuteStoreCommandsAsync(
                    It.IsAny <EntityCommand>(),
                    It.IsAny <CommandBehavior>(), It.IsAny <CancellationToken>()))
            .Returns(
                (EntityCommand ec, CommandBehavior cb, CancellationToken ct) =>
            {
                Assert.Equal(1, ec.Parameters.Count);
                Assert.Equal(2, ec.Parameters[0].Value);
                Assert.Equal(3, ec.CommandTimeout);
                Assert.Equal(new[] { objectContextMock.Object }, ec.InterceptionContext.ObjectContexts);
                return(Task.FromResult(
                           Common.Internal.Materialization.MockHelper.CreateDbDataReader(
                               new[] { new object[] { "Bar" } })));
            });

            var shaperFactory = new ShaperFactory <string>(
                1,
                Objects.MockHelper.CreateCoordinatorFactory(shaper => (string)shaper.Reader.GetValue(0)),
                new[] { typeof(string) }, new[] { true }, MergeOption.AppendOnly);

            var edmTypeMock = new Mock <EdmType>();

            edmTypeMock.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.SimpleType);

            var objectQueryExecutionPlan = new ObjectQueryExecutionPlan(
                entityCommandDefinitionMock.Object,
                shaperFactory, TypeUsage.Create(edmTypeMock.Object), MergeOption.AppendOnly, false, null, null);

            var objectParameterCollectionMock = new Mock <ObjectParameterCollection>(new ClrPerspective(new MetadataWorkspace()));

            objectParameterCollectionMock
            .Setup(m => m.GetEnumerator())
            .Returns(((IEnumerable <ObjectParameter>) new[] { new ObjectParameter("Par1", 2) }).GetEnumerator());

            var result = objectQueryExecutionPlan.ExecuteAsync <string>(
                objectContextMock.Object,
                objectParameterCollectionMock.Object, CancellationToken.None).Result;

            Assert.Equal("Bar", result.SingleAsync().Result);
        }
        private void ExecuteAsync_disposes_the_reader_on_exception(bool streaming)
        {
            var entityCommandDefinitionMock = Mock.Get(EntityClient.MockHelper.CreateEntityCommandDefinition());

            var objectContextMock = Mock.Get(Objects.MockHelper.CreateMockObjectContext <string>());

            objectContextMock.Setup(m => m.CommandTimeout).Returns(3);

            DbDataReader reader = null;

            entityCommandDefinitionMock.Setup(
                m => m.ExecuteStoreCommandsAsync(
                    It.IsAny <EntityCommand>(),
                    It.IsAny <CommandBehavior>(), It.IsAny <CancellationToken>()))
            .Returns(
                (EntityCommand ec, CommandBehavior cb, CancellationToken ct) =>
            {
                Assert.Equal(new[] { objectContextMock.Object }, ec.InterceptionContext.ObjectContexts);
                reader = Common.Internal.Materialization.MockHelper.CreateDbDataReader(
                    new[] { new object[] { "Bar" } });
                return(Task.FromResult(reader));
            });

            var shaperFactory = new ShaperFactory <string>(
                1,
                Objects.MockHelper.CreateCoordinatorFactory(shaper => (string)shaper.Reader.GetValue(0)),
                new[] { typeof(string) }, new[] { true }, MergeOption.AppendOnly);

            var edmTypeMock = new Mock <EdmType>();

            edmTypeMock.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.CollectionType);

            var objectQueryExecutionPlan = new ObjectQueryExecutionPlan(
                entityCommandDefinitionMock.Object,
                shaperFactory, TypeUsage.Create(edmTypeMock.Object), MergeOption.AppendOnly, streaming, null, null);

            var objectParameterCollectionMock = new Mock <ObjectParameterCollection>(new ClrPerspective(new MetadataWorkspace()));

            objectParameterCollectionMock
            .Setup(m => m.GetEnumerator())
            .Returns(((IEnumerable <ObjectParameter>) new[] { new ObjectParameter("Par1", 2) }).GetEnumerator());

            Assert.Throws <InvalidCastException>(
                () =>
                ExceptionHelpers.UnwrapAggregateExceptions(
                    () => objectQueryExecutionPlan.ExecuteAsync <string>(
                        objectContextMock.Object,
                        objectParameterCollectionMock.Object, CancellationToken.None).Result));

            Assert.Equal(true, reader.IsClosed);
            var readerMock = Mock.Get(reader);

            readerMock.Verify(
                m => m.GetFieldValueAsync <object>(It.IsAny <int>(), It.IsAny <CancellationToken>()), streaming ? Times.Never() : Times.Once());
        }
 /// <summary>
 ///     For testing purposes only. For anything else call <see cref="ObjectQueryExecutionPlanFactory.Prepare" />.
 /// </summary>
 public ObjectQueryExecutionPlan(
     DbCommandDefinition commandDefinition, ShaperFactory resultShaperFactory, TypeUsage resultType, MergeOption mergeOption,
     EntitySet singleEntitySet, IEnumerable <Tuple <ObjectParameter, QueryParameterExpression> > compiledQueryParameters)
 {
     CommandDefinition       = commandDefinition;
     ResultShaperFactory     = resultShaperFactory;
     ResultType              = resultType;
     MergeOption             = mergeOption;
     _singleEntitySet        = singleEntitySet;
     CompiledQueryParameters = compiledQueryParameters;
 }
        private ObjectQueryExecutionPlan(DbCommandDefinition commandDefinition, ShaperFactory resultShaperFactory, TypeUsage resultType, MergeOption mergeOption, EntitySet singleEntitySet, CompiledQueryParameters compiledQueryParameters)
        {
            Debug.Assert(commandDefinition != null, "A command definition is required");
            Debug.Assert(resultShaperFactory != null, "A result shaper factory is required");
            Debug.Assert(resultType != null, "A result type is required");

            this.CommandDefinition       = commandDefinition;
            this.ResultShaperFactory     = resultShaperFactory;
            this.ResultType              = resultType;
            this.MergeOption             = mergeOption;
            this._singleEntitySet        = singleEntitySet;
            this.CompiledQueryParameters = compiledQueryParameters;
        }
        private static KeyValuePair <Shaper <RecordState>, CoordinatorFactory <RecordState> > CreateShaperInfo(DbDataReader storeDataReader, ColumnMap columnMap, MetadataWorkspace workspace)
        {
            Debug.Assert(storeDataReader != null, "null storeDataReaders?");
            Debug.Assert(columnMap != null, "null columnMap?");
            Debug.Assert(workspace != null, "null workspace?");

            System.Data.Common.QueryCache.QueryCacheManager cacheManager = workspace.GetQueryCacheManager();
            const System.Data.Objects.MergeOption           NoTracking   = System.Data.Objects.MergeOption.NoTracking;

            ShaperFactory <RecordState> shaperFactory = Translator.TranslateColumnMap <RecordState>(cacheManager, columnMap, workspace, null, NoTracking, true);
            Shaper <RecordState>        recordShaper  = shaperFactory.Create(storeDataReader, null, workspace, System.Data.Objects.MergeOption.NoTracking, true);

            return(new KeyValuePair <Shaper <RecordState>, CoordinatorFactory <RecordState> >(recordShaper, recordShaper.RootCoordinator.TypedCoordinatorFactory));
        }
        private void ExecuteAsync_with_streaming(bool streaming)
        {
            var entityCommandDefinitionMock = Mock.Get(EntityClient.MockHelper.CreateEntityCommandDefinition());

            var objectContextMock = Mock.Get(Objects.MockHelper.CreateMockObjectContext <string>());

            objectContextMock.Setup(m => m.CommandTimeout).Returns(3);

            DbDataReader reader = null;

            entityCommandDefinitionMock.Setup(
                m => m.ExecuteStoreCommandsAsync(
                    It.IsAny <EntityCommand>(),
                    It.IsAny <CommandBehavior>(), It.IsAny <CancellationToken>()))
            .Returns(
                (EntityCommand ec, CommandBehavior cb, CancellationToken ct) =>
            {
                Assert.Equal(new[] { objectContextMock.Object }, ec.InterceptionContext.ObjectContexts);
                reader = Common.Internal.Materialization.MockHelper.CreateDbDataReader(
                    new[] { new object[] { "Bar" } });
                Assert.Equal(streaming ? CommandBehavior.Default : CommandBehavior.SequentialAccess, cb);
                return(Task.FromResult(reader));
            });

            var shaperFactory = new ShaperFactory <string>(
                1,
                Objects.MockHelper.CreateCoordinatorFactory(shaper => (string)shaper.Reader.GetValue(0)),
                new[] { typeof(string) }, new[] { true }, MergeOption.AppendOnly);

            var edmTypeMock = new Mock <EdmType>();

            edmTypeMock.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.SimpleType);

            var objectQueryExecutionPlan = new ObjectQueryExecutionPlan(
                entityCommandDefinitionMock.Object,
                shaperFactory, TypeUsage.Create(edmTypeMock.Object), MergeOption.AppendOnly, streaming, null, null);

            var objectParameterCollectionMock = new Mock <ObjectParameterCollection>(new ClrPerspective(new MetadataWorkspace()));

            objectParameterCollectionMock
            .Setup(m => m.GetEnumerator())
            .Returns(((IEnumerable <ObjectParameter>) new[] { new ObjectParameter("Par1", 2) }).GetEnumerator());

            Assert.NotNull(objectQueryExecutionPlan.ExecuteAsync <string>(
                               objectContextMock.Object,
                               objectParameterCollectionMock.Object, CancellationToken.None).Result);

            Assert.Equal(!streaming, reader.IsClosed);
        }
        public void Execute_sets_the_parameter_values_and_returns_the_result()
        {
            var entityCommandDefinitionMock = Mock.Get(EntityClient.MockHelper.CreateEntityCommandDefinition());
            entityCommandDefinitionMock.Setup(m => m.Parameters).Returns(
                new[]
                    {
                        new EntityParameter
                            {
                                ParameterName = "Par1"
                            }
                    });

            var objectContextMock = Mock.Get(Objects.MockHelper.CreateMockObjectContext<string>());
            objectContextMock.Setup(m => m.CommandTimeout).Returns(3);

            entityCommandDefinitionMock.Setup(m => m.ExecuteStoreCommands(It.IsAny<EntityCommand>(), It.IsAny<CommandBehavior>()))
                                       .Returns(
                                           (EntityCommand ec, CommandBehavior cb) =>
                                               {
                                                   Assert.Equal(1, ec.Parameters.Count);
                                                   Assert.Equal(2, ec.Parameters[0].Value);
                                                   Assert.Equal(3, ec.CommandTimeout);
                                                   Assert.Equal(new [] { objectContextMock.Object }, ec.InterceptionContext.ObjectContexts);
                                                   return Common.Internal.Materialization.MockHelper.CreateDbDataReader(
                                                       new[] { new object[] { "Bar" } });
                                               });

            var shaperFactory = new ShaperFactory<string>(
                1,
                Objects.MockHelper.CreateCoordinatorFactory(shaper => (string)shaper.Reader.GetValue(0)),
                new[] { typeof(string) }, new[] { true }, MergeOption.AppendOnly);

            var edmTypeMock = new Mock<EdmType>();
            edmTypeMock.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.SimpleType);

            var objectQueryExecutionPlan = new ObjectQueryExecutionPlan(
                entityCommandDefinitionMock.Object,
                shaperFactory, TypeUsage.Create(edmTypeMock.Object), MergeOption.AppendOnly, false, null, null);

            var objectParameterCollectionMock = new Mock<ObjectParameterCollection>(new ClrPerspective(new MetadataWorkspace()));

            objectParameterCollectionMock
                .Setup(m => m.GetEnumerator())
                .Returns(((IEnumerable<ObjectParameter>)new[] { new ObjectParameter("Par1", 2) }).GetEnumerator());

            var result = objectQueryExecutionPlan.Execute<string>(objectContextMock.Object, objectParameterCollectionMock.Object);

            Assert.Equal("Bar", result.Single());
        }
Example #10
0
 public ObjectQueryExecutionPlan(
     DbCommandDefinition commandDefinition,
     ShaperFactory resultShaperFactory,
     TypeUsage resultType,
     MergeOption mergeOption,
     bool streaming,
     EntitySet singleEntitySet,
     IEnumerable <Tuple <ObjectParameter, QueryParameterExpression> > compiledQueryParameters)
 {
     this.CommandDefinition       = commandDefinition;
     this.ResultShaperFactory     = resultShaperFactory;
     this.ResultType              = resultType;
     this.MergeOption             = mergeOption;
     this.Streaming               = streaming;
     this._singleEntitySet        = singleEntitySet;
     this.CompiledQueryParameters = compiledQueryParameters;
 }
        public virtual ObjectQueryExecutionPlan Prepare(
            ObjectContext context,
            DbQueryCommandTree tree,
            Type elementType,
            MergeOption mergeOption,
            bool streaming,
            Span span,
            IEnumerable <Tuple <ObjectParameter, QueryParameterExpression> > compiledQueryParameters,
            AliasGenerator aliasGenerator)
        {
            TypeUsage    resultType = tree.Query.ResultType;
            DbExpression newQuery;
            SpanIndex    spanInfo;

            if (ObjectSpanRewriter.TryRewrite(tree, span, mergeOption, aliasGenerator, out newQuery, out spanInfo))
            {
                tree = DbQueryCommandTree.FromValidExpression(tree.MetadataWorkspace, tree.DataSpace, newQuery, tree.UseDatabaseNullSemantics);
            }
            else
            {
                spanInfo = (SpanIndex)null;
            }
            EntityCommandDefinition commandDefinition   = ObjectQueryExecutionPlanFactory.CreateCommandDefinition(context, tree);
            ShaperFactory           resultShaperFactory = System.Data.Entity.Core.Common.Internal.Materialization.Translator.TranslateColumnMap(this._translator, elementType, commandDefinition.CreateColumnMap((DbDataReader)null), context.MetadataWorkspace, spanInfo, mergeOption, streaming, false);
            EntitySet singleEntitySet = (EntitySet)null;

            if (resultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType && commandDefinition.EntitySets != null)
            {
                foreach (EntitySet entitySet in commandDefinition.EntitySets)
                {
                    if (entitySet != null && entitySet.ElementType.IsAssignableFrom(((CollectionType)resultType.EdmType).TypeUsage.EdmType))
                    {
                        if (singleEntitySet == null)
                        {
                            singleEntitySet = entitySet;
                        }
                        else
                        {
                            singleEntitySet = (EntitySet)null;
                            break;
                        }
                    }
                }
            }
            return(new ObjectQueryExecutionPlan((DbCommandDefinition)commandDefinition, resultShaperFactory, resultType, mergeOption, streaming, singleEntitySet, compiledQueryParameters));
        }
Example #12
0
        internal virtual async Task <ObjectResult <TResultType> > ExecuteAsync <TResultType>(
            ObjectContext context,
            ObjectParameterCollection parameterValues,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            DbDataReader               storeReader    = (DbDataReader)null;
            BufferedDataReader         bufferedReader = (BufferedDataReader)null;
            ObjectResult <TResultType> objectResult;

            try
            {
                using (EntityCommand entityCommand = this.PrepareEntityCommand(context, parameterValues))
                    storeReader = await entityCommand.GetCommandDefinition().ExecuteStoreCommandsAsync(entityCommand, this.Streaming ? CommandBehavior.Default : CommandBehavior.SequentialAccess, cancellationToken).WithCurrentCulture <DbDataReader>();
                ShaperFactory <TResultType> shaperFactory = (ShaperFactory <TResultType>) this.ResultShaperFactory;
                Shaper <TResultType>        shaper;
                if (this.Streaming)
                {
                    shaper = shaperFactory.Create(storeReader, context, context.MetadataWorkspace, this.MergeOption, true, this.Streaming);
                }
                else
                {
                    StoreItemCollection storeItemCollection = (StoreItemCollection)context.MetadataWorkspace.GetItemCollection(DataSpace.SSpace);
                    DbProviderServices  providerServices    = DbConfiguration.DependencyResolver.GetService <DbProviderServices>((object)storeItemCollection.ProviderInvariantName);
                    bufferedReader = new BufferedDataReader(storeReader);
                    await bufferedReader.InitializeAsync(storeItemCollection.ProviderManifestToken, providerServices, shaperFactory.ColumnTypes, shaperFactory.NullableColumns, cancellationToken).WithCurrentCulture();

                    shaper = shaperFactory.Create((DbDataReader)bufferedReader, context, context.MetadataWorkspace, this.MergeOption, true, this.Streaming);
                }
                TypeUsage resultItemEdmType = this.ResultType.EdmType.BuiltInTypeKind != BuiltInTypeKind.CollectionType ? this.ResultType : ((CollectionType)this.ResultType.EdmType).TypeUsage;
                objectResult = new ObjectResult <TResultType>(shaper, this._singleEntitySet, resultItemEdmType);
            }
            catch (Exception ex)
            {
                if (this.Streaming && storeReader != null)
                {
                    storeReader.Dispose();
                }
                if (!this.Streaming && bufferedReader != null)
                {
                    bufferedReader.Dispose();
                }
                throw;
            }
            return(objectResult);
        }
Example #13
0
        internal virtual ObjectResult <TResultType> Execute <TResultType>(
            ObjectContext context,
            ObjectParameterCollection parameterValues)
        {
            DbDataReader       reader             = (DbDataReader)null;
            BufferedDataReader bufferedDataReader = (BufferedDataReader)null;

            try
            {
                using (EntityCommand entityCommand = this.PrepareEntityCommand(context, parameterValues))
                    reader = entityCommand.GetCommandDefinition().ExecuteStoreCommands(entityCommand, this.Streaming ? CommandBehavior.Default : CommandBehavior.SequentialAccess);
                ShaperFactory <TResultType> resultShaperFactory = (ShaperFactory <TResultType>) this.ResultShaperFactory;
                Shaper <TResultType>        shaper;
                if (this.Streaming)
                {
                    shaper = resultShaperFactory.Create(reader, context, context.MetadataWorkspace, this.MergeOption, true, this.Streaming);
                }
                else
                {
                    StoreItemCollection itemCollection = (StoreItemCollection)context.MetadataWorkspace.GetItemCollection(DataSpace.SSpace);
                    DbProviderServices  service        = DbConfiguration.DependencyResolver.GetService <DbProviderServices>((object)itemCollection.ProviderInvariantName);
                    bufferedDataReader = new BufferedDataReader(reader);
                    bufferedDataReader.Initialize(itemCollection.ProviderManifestToken, service, resultShaperFactory.ColumnTypes, resultShaperFactory.NullableColumns);
                    shaper = resultShaperFactory.Create((DbDataReader)bufferedDataReader, context, context.MetadataWorkspace, this.MergeOption, true, this.Streaming);
                }
                TypeUsage resultItemType = this.ResultType.EdmType.BuiltInTypeKind != BuiltInTypeKind.CollectionType ? this.ResultType : ((CollectionType)this.ResultType.EdmType).TypeUsage;
                return(new ObjectResult <TResultType>(shaper, this._singleEntitySet, resultItemType));
            }
            catch (Exception ex)
            {
                if (this.Streaming && reader != null)
                {
                    reader.Dispose();
                }
                if (!this.Streaming && bufferedDataReader != null)
                {
                    bufferedDataReader.Dispose();
                }
                throw;
            }
        }
        private void Execute_with_streaming(bool streaming)
        {
            var entityCommandDefinitionMock = Mock.Get(EntityClient.MockHelper.CreateEntityCommandDefinition());

            var objectContextMock = Mock.Get(Objects.MockHelper.CreateMockObjectContext<string>());
            objectContextMock.Setup(m => m.CommandTimeout).Returns(3);

            DbDataReader reader = null;
            entityCommandDefinitionMock.Setup(m => m.ExecuteStoreCommands(It.IsAny<EntityCommand>(), It.IsAny<CommandBehavior>()))
                                       .Returns(
                                           (EntityCommand ec, CommandBehavior cb) =>
                                               {
                                                   Assert.Equal(new[] { objectContextMock.Object }, ec.InterceptionContext.ObjectContexts);
                                                   reader = Common.Internal.Materialization.MockHelper.CreateDbDataReader(
                                                       new[] { new object[] { "Bar" } });
                                                   Assert.Equal(streaming ? CommandBehavior.Default : CommandBehavior.SequentialAccess, cb);
                                                   return reader;
                                               });

            var shaperFactory = new ShaperFactory<string>(
                1,
                Objects.MockHelper.CreateCoordinatorFactory(shaper => (string)shaper.Reader.GetValue(0)),
                new[] { typeof(string) }, new[] { true }, MergeOption.AppendOnly);

            var edmTypeMock = new Mock<EdmType>();
            edmTypeMock.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.SimpleType);

            var objectQueryExecutionPlan = new ObjectQueryExecutionPlan(
                entityCommandDefinitionMock.Object,
                shaperFactory, TypeUsage.Create(edmTypeMock.Object), MergeOption.AppendOnly, streaming, null, null);

            var objectParameterCollectionMock = new Mock<ObjectParameterCollection>(new ClrPerspective(new MetadataWorkspace()));

            objectParameterCollectionMock
                .Setup(m => m.GetEnumerator())
                .Returns(((IEnumerable<ObjectParameter>)new ObjectParameter[0]).GetEnumerator());

            objectQueryExecutionPlan.Execute<string>(objectContextMock.Object, objectParameterCollectionMock.Object);

            Assert.Equal(!streaming, reader.IsClosed);
        }
        private void ExecuteAsync_disposes_the_reader_on_exception(bool streaming)
        {
            var entityCommandDefinitionMock = Mock.Get(EntityClient.MockHelper.CreateEntityCommandDefinition());

            var objectContextMock = Mock.Get(Objects.MockHelper.CreateMockObjectContext<string>());
            objectContextMock.Setup(m => m.CommandTimeout).Returns(3);

            DbDataReader reader = null;
            entityCommandDefinitionMock.Setup(
                m => m.ExecuteStoreCommandsAsync(
                    It.IsAny<EntityCommand>(),
                    It.IsAny<CommandBehavior>(), It.IsAny<CancellationToken>()))
                                       .Returns(
                                           (EntityCommand ec, CommandBehavior cb, CancellationToken ct) =>
                                               {
                                                   Assert.Equal(new[] { objectContextMock.Object }, ec.InterceptionContext.ObjectContexts);
                                                   reader = Common.Internal.Materialization.MockHelper.CreateDbDataReader(
                                                       new[] { new object[] { "Bar" } });
                                                   return Task.FromResult(reader);
                                               });

            var shaperFactory = new ShaperFactory<string>(
                1,
                Objects.MockHelper.CreateCoordinatorFactory(shaper => (string)shaper.Reader.GetValue(0)),
                new[] { typeof(string) }, new[] { true }, MergeOption.AppendOnly);

            var edmTypeMock = new Mock<EdmType>();
            edmTypeMock.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.CollectionType);

            var objectQueryExecutionPlan = new ObjectQueryExecutionPlan(
                entityCommandDefinitionMock.Object,
                shaperFactory, TypeUsage.Create(edmTypeMock.Object), MergeOption.AppendOnly, streaming, null, null);

            var objectParameterCollectionMock = new Mock<ObjectParameterCollection>(new ClrPerspective(new MetadataWorkspace()));

            objectParameterCollectionMock
                .Setup(m => m.GetEnumerator())
                .Returns(((IEnumerable<ObjectParameter>)new[] { new ObjectParameter("Par1", 2) }).GetEnumerator());

            Assert.Throws<InvalidCastException>(
                () =>
                ExceptionHelpers.UnwrapAggregateExceptions(
                    () => objectQueryExecutionPlan.ExecuteAsync<string>(
                        objectContextMock.Object,
                        objectParameterCollectionMock.Object, CancellationToken.None).Result));

            Assert.Equal(true, reader.IsClosed);
            var readerMock = Mock.Get(reader);
            readerMock.Verify(
                m => m.GetFieldValueAsync<object>(It.IsAny<int>(), It.IsAny<CancellationToken>()), streaming ? Times.Never() : Times.Once());
        }
        internal static ObjectQueryExecutionPlan Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Span span, CompiledQueryParameters compiledQueryParameters, AliasGenerator aliasGenerator)
        {
            TypeUsage treeResultType = tree.Query.ResultType;

            // Rewrite this tree for Span?
            DbExpression spannedQuery = null;
            SpanIndex    spanInfo;

            if (ObjectSpanRewriter.TryRewrite(tree, span, mergeOption, aliasGenerator, out spannedQuery, out spanInfo))
            {
                tree = DbQueryCommandTree.FromValidExpression(tree.MetadataWorkspace, tree.DataSpace, spannedQuery);
            }
            else
            {
                spanInfo = null;
            }

            DbConnection        connection = context.Connection;
            DbCommandDefinition definition = null;

            // The connection is required to get to the CommandDefinition builder.
            if (connection == null)
            {
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.ObjectQuery_InvalidConnection);
            }

            DbProviderServices services = DbProviderServices.GetProviderServices(connection);

            try
            {
                definition = services.CreateCommandDefinition(tree);
            }
            catch (EntityCommandCompilationException)
            {
                // If we're running against EntityCommand, we probably already caught the providers'
                // exception and wrapped it, we don't want to do that again, so we'll just rethrow
                // here instead.
                throw;
            }
            catch (Exception e)
            {
                // we should not be wrapping all exceptions
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    // we don't wan't folks to have to know all the various types of exceptions that can
                    // occur, so we just rethrow a CommandDefinitionException and make whatever we caught
                    // the inner exception of it.
                    throw EntityUtil.CommandCompilation(System.Data.Entity.Strings.EntityClient_CommandDefinitionPreparationFailed, e);
                }
                throw;
            }

            if (definition == null)
            {
                throw EntityUtil.ProviderDoesNotSupportCommandTrees();
            }

            EntityCommandDefinition entityDefinition = (EntityCommandDefinition)definition;
            QueryCacheManager       cacheManager     = context.Perspective.MetadataWorkspace.GetQueryCacheManager();

            ShaperFactory shaperFactory = ShaperFactory.Create(elementType, cacheManager, entityDefinition.CreateColumnMap(null),
                                                               context.MetadataWorkspace, spanInfo, mergeOption, false);

            // attempt to determine entity information for this query (e.g. which entity type and which entity set)
            //EntityType rootEntityType = null;

            EntitySet singleEntitySet = null;

            if (treeResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType)
            {
                // determine if the entity set is unambiguous given the entity type
                if (null != entityDefinition.EntitySets)
                {
                    foreach (EntitySet entitySet in entityDefinition.EntitySets)
                    {
                        if (null != entitySet)
                        {
                            if (entitySet.ElementType.IsAssignableFrom(((CollectionType)treeResultType.EdmType).TypeUsage.EdmType))
                            {
                                if (singleEntitySet == null)
                                {
                                    // found a single match
                                    singleEntitySet = entitySet;
                                }
                                else
                                {
                                    // there's more than one matching entity set
                                    singleEntitySet = null;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return(new ObjectQueryExecutionPlan(definition, shaperFactory, treeResultType, mergeOption, singleEntitySet, compiledQueryParameters));
        }
        public void ApplySubstitution(FontMetrics fontMetrics, GlyphSubstitutionCollection collection, KerningMode kerningMode)
        {
            for (ushort i = 0; i < collection.Count; i++)
            {
                // Choose a shaper based on the script.
                // This determines which features to apply to which glyphs.
                ScriptClass current = CodePoint.GetScriptClass(collection.GetGlyphShapingData(i).CodePoint);
                BaseShaper  shaper  = ShaperFactory.Create(current, kerningMode);

                ushort index = i;
                ushort count = 1;
                while (i < collection.Count - 1)
                {
                    // We want to assign the same feature lookups to individual sections of the text rather
                    // than the text as a whole to ensure that different language shapers do not interfere
                    // with each other when the text contains multiple languages.
                    GlyphShapingData nextData = collection.GetGlyphShapingData(i + 1);
                    ScriptClass      next     = CodePoint.GetScriptClass(nextData.CodePoint);
                    if (next is not ScriptClass.Common and not ScriptClass.Unknown and not ScriptClass.Inherited && next != current)
                    {
                        break;
                    }

                    i++;
                    count++;
                }

                // Assign Substitution features to each glyph.
                shaper.AssignFeatures(collection, index, count);
                IEnumerable <Tag> stageFeatures = shaper.GetShapingStageFeatures();

                int currentCount = collection.Count;
                SkippingGlyphIterator iterator = new(fontMetrics, collection, index, default);
                foreach (Tag stageFeature in stageFeatures)
                {
                    List <(Tag Feature, ushort Index, LookupTable LookupTable)> lookups = this.GetFeatureLookups(in stageFeature, current);
                    if (lookups.Count == 0)
                    {
                        continue;
                    }

                    // Apply features in order.
                    foreach ((Tag Feature, ushort Index, LookupTable LookupTable)featureLookup in lookups)
                    {
                        Tag feature = featureLookup.Feature;
                        iterator.Reset(index, featureLookup.LookupTable.LookupFlags);

                        while (iterator.Index < index + count)
                        {
                            List <TagEntry> glyphFeatures = collection.GetGlyphShapingData(iterator.Index).Features;
                            if (!HasFeature(glyphFeatures, in feature))
                            {
                                iterator.Next();
                                continue;
                            }

                            featureLookup.LookupTable.TrySubstitution(fontMetrics, this, collection, featureLookup.Feature, iterator.Index, count - (iterator.Index - index));
                            iterator.Next();

                            // Account for substitutions changing the length of the collection.
                            if (collection.Count != currentCount)
                            {
                                count        = (ushort)(count - (currentCount - collection.Count));
                                currentCount = collection.Count;
                            }
                        }
                    }
                }
            }
        }
        public bool TryUpdatePositions(FontMetrics fontMetrics, GlyphPositioningCollection collection, KerningMode kerningMode, out bool kerned)
        {
            kerned = false;
            bool updated = false;

            for (ushort i = 0; i < collection.Count; i++)
            {
                if (!collection.ShouldProcess(fontMetrics, i))
                {
                    continue;
                }

                ScriptClass current = CodePoint.GetScriptClass(collection.GetGlyphShapingData(i).CodePoint);
                BaseShaper  shaper  = ShaperFactory.Create(current, kerningMode);

                ushort index = i;
                ushort count = 1;
                while (i < collection.Count - 1)
                {
                    // We want to assign the same feature lookups to individual sections of the text rather
                    // than the text as a whole to ensure that different language shapers do not interfere
                    // with each other when the text contains multiple languages.
                    GlyphShapingData nextData = collection.GetGlyphShapingData(i + 1);
                    ScriptClass      next     = CodePoint.GetScriptClass(nextData.CodePoint);
                    if (next is not ScriptClass.Common and not ScriptClass.Unknown and not ScriptClass.Inherited && next != current)
                    {
                        break;
                    }

                    i++;
                    count++;
                }

                if (shaper.MarkZeroingMode == MarkZeroingMode.PreGPos)
                {
                    ZeroMarkAdvances(fontMetrics, collection, index, count);
                }

                // Assign Substitution features to each glyph.
                shaper.AssignFeatures(collection, index, count);
                IEnumerable <Tag>     stageFeatures = shaper.GetShapingStageFeatures();
                SkippingGlyphIterator iterator      = new(fontMetrics, collection, index, default);
                foreach (Tag stageFeature in stageFeatures)
                {
                    List <(Tag Feature, ushort Index, LookupTable LookupTable)> lookups = this.GetFeatureLookups(in stageFeature, current);
                    if (lookups.Count == 0)
                    {
                        continue;
                    }

                    // Apply features in order.
                    foreach ((Tag Feature, ushort Index, LookupTable LookupTable)featureLookup in lookups)
                    {
                        Tag feature = featureLookup.Feature;
                        iterator.Reset(index, featureLookup.LookupTable.LookupFlags);

                        while (iterator.Index < index + count)
                        {
                            List <TagEntry> glyphFeatures = collection.GetGlyphShapingData(iterator.Index).Features;
                            if (!HasFeature(glyphFeatures, in feature))
                            {
                                iterator.Next();
                                continue;
                            }

                            bool success = featureLookup.LookupTable.TryUpdatePosition(fontMetrics, this, collection, featureLookup.Feature, iterator.Index, count - (iterator.Index - index));
                            kerned  |= success && (feature == KernTag || feature == VKernTag);
                            updated |= success;
                            iterator.Next();
                        }
                    }
                }

                if (shaper.MarkZeroingMode == MarkZeroingMode.PostGpos)
                {
                    ZeroMarkAdvances(fontMetrics, collection, index, count);
                }

                FixCursiveAttachment(collection, index, count);
                FixMarkAttachment(collection, index, count);
                if (updated)
                {
                    UpdatePositions(fontMetrics, collection, index, count);
                }
            }

            return(updated);
        }