Ejemplo n.º 1
0
        // <summary>
        // Performs projection for a single row. Evaluates each projection argument against the specified
        // row, returning a result with the specified type.
        // </summary>
        // <param name="node"> Projection expression. </param>
        // <param name="row"> Row to project. </param>
        // <param name="resultType"> Type of the projected row. </param>
        // <returns> Projected row. </returns>
        private static PropagatorResult Project(DbProjectExpression node, PropagatorResult row, TypeUsage resultType)
        {
            DebugCheck.NotNull(node);

            DebugCheck.NotNull(node.Projection);

            var projection = node.Projection as DbNewInstanceExpression;

            if (null == projection)
            {
                throw new NotSupportedException(Strings.Update_UnsupportedProjection(node.Projection.ExpressionKind));
            }

            // Initialize empty structure containing space for every element of the projection.
            var projectedValues = new PropagatorResult[projection.Arguments.Count];

            // Extract value from the input row for every projection argument requested.
            for (var ordinal = 0; ordinal < projectedValues.Length; ordinal++)
            {
                projectedValues[ordinal] = Evaluator.Evaluate(projection.Arguments[ordinal], row);
            }

            // Return a new row containing projected values.
            var projectedRow = PropagatorResult.CreateStructuralValue(projectedValues, (StructuralType)resultType.EdmType, false);

            return(projectedRow);
        }
            // <summary>
            // Given default values for children members, produces a new default expression for the requested (parent) member.
            // </summary>
            // <param name="node"> Parent member </param>
            // <returns> Default value for parent member </returns>
            internal PropagatorResult Visit(EdmMember node)
            {
                PropagatorResult result;
                var nodeType = Helper.GetModelTypeUsage(node);

                if (Helper.IsScalarType(nodeType.EdmType))
                {
                    GetPropagatorResultForPrimitiveType(Helper.AsPrimitive(nodeType.EdmType), out result);
                }
                else
                {
                    // Construct a new 'complex type' (really any structural type) member.
                    var structuralType = (StructuralType)nodeType.EdmType;
                    var members        = TypeHelpers.GetAllStructuralMembers(structuralType);

                    var args = new PropagatorResult[members.Count];
                    for (var ordinal = 0; ordinal < members.Count; ordinal++)
                    //                    foreach (EdmMember member in members)
                    {
                        args[ordinal] = Visit(members[ordinal]);
                    }

                    result = PropagatorResult.CreateStructuralValue(args, structuralType, false);
                }

                return(result);
            }
            // <summary>
            // Specialization of <see cref="CreatePlaceholder" /> for a relationship set extent.
            // </summary>
            private PropagatorResult CreateAssociationSetPlaceholder(AssociationSet associationSet)
            {
                DebugCheck.NotNull(associationSet);

                var endMetadata        = associationSet.ElementType.AssociationEndMembers;
                var endReferenceValues = new PropagatorResult[endMetadata.Count];

                // Create a reference expression for each end in the relationship
                for (var endOrdinal = 0; endOrdinal < endMetadata.Count; endOrdinal++)
                {
                    var end        = endMetadata[endOrdinal];
                    var entityType = (EntityType)((RefType)end.TypeUsage.EdmType).ElementType;

                    // Retrieve key values for this end
                    var keyValues = new PropagatorResult[entityType.KeyMembers.Count];
                    for (var memberOrdinal = 0; memberOrdinal < entityType.KeyMembers.Count; memberOrdinal++)
                    {
                        var keyMember = entityType.KeyMembers[memberOrdinal];
                        var keyValue  = CreateMemberPlaceholder(keyMember);
                        keyValues[memberOrdinal] = keyValue;
                    }

                    var endType = entityType.GetKeyRowType();
                    var refKeys = PropagatorResult.CreateStructuralValue(keyValues, endType, false);

                    endReferenceValues[endOrdinal] = refKeys;
                }

                var result = PropagatorResult.CreateStructuralValue(endReferenceValues, associationSet.ElementType, false);

                return(result);
            }
Ejemplo n.º 4
0
        // Note that this is called only for association ends. Entities have key values inline.
        private PropagatorResult CreateEntityKeyResult(IEntityStateEntry stateEntry, EntityKey entityKey)
        {
            // get metadata for key
            var entityType = entityKey.GetEntitySet(m_translator.MetadataWorkspace).ElementType;
            var keyRowType = entityType.GetKeyRowType();

            var keyMetadata    = m_translator.GetExtractorMetadata(stateEntry.EntitySet, keyRowType);
            var keyMemberCount = keyRowType.Properties.Count;
            var keyValues      = new PropagatorResult[keyMemberCount];

            for (var ordinal = 0; ordinal < keyRowType.Properties.Count; ordinal++)
            {
                EdmMember keyMember = keyRowType.Properties[ordinal];
                // retrieve information about this key value
                var keyMemberInformation = keyMetadata.m_memberMap[ordinal];

                var keyIdentifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, ordinal, keyRowType.Properties.Count);

                object keyValue = null;
                if (entityKey.IsTemporary)
                {
                    // If the EntityKey is temporary, we need to retrieve the appropriate
                    // key value from the entity itself (or in this case, the IEntityStateEntry).
                    var entityEntry = stateEntry.StateManager.GetEntityStateEntry(entityKey);
                    Debug.Assert(
                        entityEntry.State == EntityState.Added,
                        "The corresponding entry for a temp EntityKey should be in the Added State.");
                    keyValue = entityEntry.CurrentValues[keyMember.Name];
                }
                else
                {
                    // Otherwise, we extract the value from within the EntityKey.
                    keyValue = entityKey.FindValueByName(keyMember.Name);
                }
                Debug.Assert(keyValue != null, "keyValue should've been retrieved.");

                // construct propagator result
                keyValues[ordinal] = PropagatorResult.CreateKeyValue(
                    keyMemberInformation.Flags,
                    keyValue,
                    stateEntry,
                    keyIdentifier);

                // see UpdateTranslator.Identifiers for information on key identifiers and ordinals
            }

            return(PropagatorResult.CreateStructuralValue(keyValues, keyMetadata.m_type, false));
        }
            // <summary>
            // Specialization of <see cref="CreatePlaceholder" /> for an entity set extent.
            // </summary>
            private PropagatorResult CreateEntitySetPlaceholder(EntitySet entitySet)
            {
                DebugCheck.NotNull(entitySet);
                var members      = entitySet.ElementType.Properties;
                var memberValues = new PropagatorResult[members.Count];

                for (var ordinal = 0; ordinal < members.Count; ordinal++)
                {
                    var memberValue = CreateMemberPlaceholder(members[ordinal]);
                    memberValues[ordinal] = memberValue;
                }

                var result = PropagatorResult.CreateStructuralValue(memberValues, entitySet.ElementType, false);

                return(result);
            }
        private PropagatorResult CreateEntityKeyResult(
            IEntityStateEntry stateEntry,
            EntityKey entityKey)
        {
            RowType           keyRowType        = entityKey.GetEntitySet(this.m_translator.MetadataWorkspace).ElementType.GetKeyRowType();
            ExtractorMetadata extractorMetadata = this.m_translator.GetExtractorMetadata(stateEntry.EntitySet, (StructuralType)keyRowType);

            PropagatorResult[] values = new PropagatorResult[keyRowType.Properties.Count];
            for (int memberOffset = 0; memberOffset < keyRowType.Properties.Count; ++memberOffset)
            {
                EdmMember property = (EdmMember)keyRowType.Properties[memberOffset];
                ExtractorMetadata.MemberInformation member = extractorMetadata.m_memberMap[memberOffset];
                int    identifierForMemberOffset           = this.m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, memberOffset, keyRowType.Properties.Count);
                object obj = !entityKey.IsTemporary ? entityKey.FindValueByName(property.Name) : stateEntry.StateManager.GetEntityStateEntry(entityKey).CurrentValues[property.Name];
                values[memberOffset] = PropagatorResult.CreateKeyValue(member.Flags, obj, stateEntry, identifierForMemberOffset);
            }
            return(PropagatorResult.CreateStructuralValue(values, extractorMetadata.m_type, false));
        }
Ejemplo n.º 7
0
        // <summary>
        // Converts a record to a propagator result
        // </summary>
        // <param name="stateEntry"> state manager entry containing the record </param>
        // <param name="isModified"> Indicates whether the root element is modified (i.e., whether the type has changed) </param>
        // <param name="record"> Record to convert </param>
        // <param name="useCurrentValues"> Indicates whether we are retrieving current or original values. </param>
        // <param name="translator"> Translator for session context; registers new metadata for the record type if none exists </param>
        // <param name="modifiedPropertiesBehavior"> Indicates how to determine whether a property is modified. </param>
        // <returns> Result corresponding to the given record </returns>
        internal static PropagatorResult ExtractResultFromRecord(
            IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record,
            bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            var structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType;
            var metadata       = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType);
            var key            = stateEntry.EntityKey;

            var nestedValues = new PropagatorResult[record.FieldCount];

            for (var ordinal = 0; ordinal < nestedValues.Length; ordinal++)
            {
                nestedValues[ordinal] = metadata.RetrieveMember(
                    stateEntry, record, useCurrentValues, key,
                    ordinal, modifiedPropertiesBehavior);
            }

            return(PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified));
        }
Ejemplo n.º 8
0
            // <summary>
            // Produce a tuple containing joined rows.
            // </summary>
            // <param name="left"> Left row. </param>
            // <param name="right"> Right row. </param>
            // <param name="result"> Result change node; used for type information. </param>
            // <returns> Result of joining the input rows. </returns>
            private PropagatorResult CreateResultTuple(
                Tuple <CompositeKey, PropagatorResult> left, Tuple <CompositeKey, PropagatorResult> right, ChangeNode result)
            {
                // using ref compare to avoid triggering value based
                var leftKey  = left.Item1;
                var rightKey = right.Item1;
                Dictionary <PropagatorResult, PropagatorResult> map = null;

                if (!ReferenceEquals(null, leftKey)
                    &&
                    !ReferenceEquals(null, rightKey)
                    &&
                    !ReferenceEquals(leftKey, rightKey))
                {
                    // Merge key values from the left and the right (since they're equal, there's a possibility we'll
                    // project values only from the left or the right hand side and lose important context.)
                    var mergedKey = leftKey.Merge(m_parent.m_updateTranslator.KeyManager, rightKey);
                    // create a dictionary so that we can replace key values with merged key values (carrying context
                    // from both sides)
                    map = new Dictionary <PropagatorResult, PropagatorResult>();
                    for (var i = 0; i < leftKey.KeyComponents.Length; i++)
                    {
                        map[leftKey.KeyComponents[i]]  = mergedKey.KeyComponents[i];
                        map[rightKey.KeyComponents[i]] = mergedKey.KeyComponents[i];
                    }
                }

                var joinRecordValues = new PropagatorResult[2];

                joinRecordValues[0] = left.Item2;
                joinRecordValues[1] = right.Item2;
                var join = PropagatorResult.CreateStructuralValue(joinRecordValues, (StructuralType)result.ElementType.EdmType, false);

                // replace with merged key values as appropriate
                if (null != map)
                {
                    PropagatorResult replacement;
                    join = join.Replace(original => map.TryGetValue(original, out replacement) ? replacement : original);
                }

                return(join);
            }
Ejemplo n.º 9
0
            public void Returns_rows_affected_when_there_is_a_reader()
            {
                var mockPrimitiveType = new Mock <PrimitiveType>();

                mockPrimitiveType.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.PrimitiveType);
                mockPrimitiveType.Setup(m => m.PrimitiveTypeKind).Returns(PrimitiveTypeKind.Int32);
                mockPrimitiveType.Setup(m => m.DataSpace).Returns(DataSpace.CSpace);
                var memberName  = "property";
                var edmProperty = new EdmProperty(memberName, TypeUsage.Create(mockPrimitiveType.Object));

                var entityType = new EntityType("", "", DataSpace.CSpace, Enumerable.Empty <string>(), new[] { edmProperty });

                entityType.SetReadOnly();

                var mockUpdateTranslator = new Mock <UpdateTranslator>(MockBehavior.Strict);

                mockUpdateTranslator.Setup(m => m.CommandTimeout).Returns(() => null);
                var entityConnection = new Mock <EntityConnection>().Object;

                mockUpdateTranslator.Setup(m => m.Connection).Returns(entityConnection);

                var mockDbModificationCommandTree = new Mock <DbModificationCommandTree>();

                mockDbModificationCommandTree.SetupGet(m => m.HasReader).Returns(true);

                var mockDynamicUpdateCommand = new Mock <DynamicUpdateCommand>(
                    new Mock <TableChangeProcessor>().Object, mockUpdateTranslator.Object,
                    ModificationOperator.Delete, PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, value: 0),
                    PropagatorResult.CreateStructuralValue(
                        new[] { PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, value: 0) },
                        entityType,
                        isModified: false),
                    mockDbModificationCommandTree.Object, /*outputIdentifiers*/ null)
                {
                    CallBase = true
                };

                var mockDbCommand = new Mock <DbCommand>();

                var dbValue          = 66;
                var mockDbDataReader = new Mock <DbDataReader>();

                mockDbDataReader.Setup(m => m.GetFieldValueAsync <object>(It.IsAny <int>(), It.IsAny <CancellationToken>()))
                .Returns(Task.FromResult <object>(dbValue));
                var rowsToRead = 2;

                mockDbDataReader.Setup(m => m.ReadAsync(It.IsAny <CancellationToken>())).Returns(
                    () =>
                {
                    rowsToRead--;
                    return(Task.FromResult(rowsToRead > 0));
                });
                mockDbDataReader.Setup(m => m.FieldCount).Returns(1);
                mockDbDataReader.Setup(m => m.GetName(0)).Returns(memberName);
                mockDbDataReader.Setup(m => m.NextResultAsync(It.IsAny <CancellationToken>())).Returns(Task.FromResult(false));

                mockDbCommand.Protected()
                .Setup <Task <DbDataReader> >("ExecuteDbDataReaderAsync", CommandBehavior.SequentialAccess, It.IsAny <CancellationToken>())
                .Returns(Task.FromResult(mockDbDataReader.Object));

                var identifierValues = new Dictionary <int, object>();

                mockDynamicUpdateCommand.Protected().Setup <DbCommand>("CreateCommand", identifierValues).Returns(mockDbCommand.Object);

                var generatedValues = new List <KeyValuePair <PropagatorResult, object> >();

                var rowsAffectedResult =
                    mockDynamicUpdateCommand.Object.ExecuteAsync(identifierValues, generatedValues, CancellationToken.None).Result;

                Assert.Equal(1, rowsAffectedResult);
                Assert.Equal(1, generatedValues.Count);
                Assert.Equal(dbValue, generatedValues[0].Value);
                Assert.Equal(0, generatedValues[0].Key.GetSimpleValue());
            }
Ejemplo n.º 10
0
            public void Returns_rows_affected_when_there_are_result_columns()
            {
                var mockPrimitiveType = new Mock <PrimitiveType>();

                mockPrimitiveType.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.PrimitiveType);
                mockPrimitiveType.Setup(m => m.PrimitiveTypeKind).Returns(PrimitiveTypeKind.Int32);
                mockPrimitiveType.Setup(m => m.DataSpace).Returns(DataSpace.CSpace);
                var edmProperty = new EdmProperty("property", TypeUsage.Create(mockPrimitiveType.Object));

                var entityType = new EntityType("", "", DataSpace.CSpace, Enumerable.Empty <string>(), new[] { edmProperty });

                entityType.SetReadOnly();

                var stateEntry = new ExtractedStateEntry(
                    EntityState.Unchanged,
                    PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, value: 0),
                    PropagatorResult.CreateStructuralValue(
                        new[] { PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, value: 0) },
                        entityType,
                        isModified: false),
                    new Mock <IEntityStateEntry>().Object);

                var updateTranslatorMock = new Mock <UpdateTranslator>();

                updateTranslatorMock.Setup(m => m.CommandTimeout).Returns(() => null);
                var entityConnection = new Mock <EntityConnection>().Object;

                updateTranslatorMock.Setup(m => m.Connection).Returns(entityConnection);
                updateTranslatorMock.Setup(m => m.InterceptionContext).Returns(new DbInterceptionContext());

                var dbCommandMock = new Mock <DbCommand>();
                var stateEntries  = new ReadOnlyCollection <IEntityStateEntry>(new List <IEntityStateEntry>());

                var mockFunctionUpdateCommand = new Mock <FunctionUpdateCommand>(
                    updateTranslatorMock.Object, stateEntries, stateEntry, dbCommandMock.Object)
                {
                    CallBase = true
                };

                var dbValue          = 66;
                var dbDataReaderMock = new Mock <DbDataReader>();

                dbDataReaderMock.Setup(m => m.GetValue(It.IsAny <int>())).Returns(dbValue);
                var rowsToRead = 2;

                dbDataReaderMock.Setup(m => m.Read()).Returns(
                    () =>
                {
                    rowsToRead--;
                    return(rowsToRead > 0);
                });
                dbCommandMock.Protected().Setup <DbDataReader>("ExecuteDbDataReader", CommandBehavior.SequentialAccess).Returns(
                    dbDataReaderMock.Object);

                var timesSetInputIdentifiers = 0;
                var identifierValues         = new Dictionary <int, object>();

                mockFunctionUpdateCommand.Setup(m => m.SetInputIdentifiers(It.IsAny <Dictionary <int, object> >()))
                .Callback <Dictionary <int, object> >(
                    identifierValuesPassed =>
                {
                    timesSetInputIdentifiers++;
                    Assert.Same(identifierValues, identifierValuesPassed);
                });

                var generatedValues        = new List <KeyValuePair <PropagatorResult, object> >();
                var mockObjectStateManager = new Mock <ObjectStateManager>();
                var objectStateEntryMock   = new Mock <ObjectStateEntry>(mockObjectStateManager.Object, null, EntityState.Unchanged);
                var currentValueRecordMock = new Mock <CurrentValueRecord>(objectStateEntryMock.Object);

                var idColumn = new KeyValuePair <string, PropagatorResult>(
                    "ID",
                    PropagatorResult.CreateServerGenSimpleValue(
                        PropagatorFlags.NoFlags, /*value:*/ 0, currentValueRecordMock.Object, recordOrdinal: 0));

                mockFunctionUpdateCommand.Protected().Setup <List <KeyValuePair <string, PropagatorResult> > >("ResultColumns")
                .Returns((new[] { idColumn }).ToList());

                var rowsAffectedResult = mockFunctionUpdateCommand.Object.Execute(identifierValues, generatedValues);

                Assert.Equal(1, rowsAffectedResult);
                Assert.Equal(1, timesSetInputIdentifiers);
                Assert.Equal(1, generatedValues.Count);
                Assert.Same(idColumn.Value, generatedValues[0].Key);
                Assert.Equal(dbValue, generatedValues[0].Value);
            }