/// <summary>
 /// Creates a slot with constant value being <paramref name="value"/>.
 /// </summary>
 internal ConstantProjectedSlot(Constant value, MemberPath memberPath)
 {
     Debug.Assert(value != null);
     Debug.Assert(value.IsNotNull() == false, "Cannot store NotNull in a slot - NotNull is only for conditions");
     m_constant = value;
     m_memberPath = memberPath;
 }
示例#2
0
        public void TestCanBeModifiedOrphan()
        {
            // -------------------------------------------
            // Check that CanBeModified is always true 
            // whatever are the values of the overrides
            //
            // For that set all the possible values of the overrides
            // at two first level of fields and check the reset
            // 
            // Field checked is orphan.MyClass.Value
            //
            // --------------------------------------------

            Initialize();

            var orphan = new TestAssetUpdate { MyClass = new MyClass() };
            var testValues = new[] { OverrideType.Base, OverrideType.Sealed, OverrideType.New, OverrideType.Sealed | OverrideType.New };

            var pathToValue = new MemberPath();
            pathToValue.Push(memberMyClass);
            pathToValue.Push(MemberValue);

            foreach (var value1 in testValues)
            {
                orphan.SetOverride(memberMyClass, value1);

                foreach (var value2 in testValues)
                {
                    orphan.MyClass.SetOverride(MemberValue, value2);

                    Assert.IsTrue(assetUpdater.CanBeModified(orphan, pathToValue));
                }
            }
        }
示例#3
0
        /// <summary>
        /// Indicate if the referred member can be modified or not due to sealing.
        /// </summary>
        /// <param name="asset">The asset to modify</param>
        /// <param name="path">The path to the member to modify</param>
        /// <returns><value>true</value> if it can be modified</returns>
        public bool CanBeModified(Asset asset, MemberPath path)
        {
            if (path.GetNodeOverrides(asset).Any(x => x.IsNew()))
                return true;

            var assetBase = asset.Base;
            while (assetBase != null && assetBase.Asset != null)
            {
                var parent = assetBase.Asset;
                var parentPath = path.Resolve(asset, parent).FirstOrDefault(); // if several paths exist in parent, they should be all equal (same object instance)
                if (parentPath == null)
                    break;

                var parentOverrides = parentPath.GetNodeOverrides(parent).ToList();
                if (parentOverrides.LastOrDefault().IsSealed())
                    return false;

                if (parentOverrides.Any(x => x.IsNew()))
                    break;

                assetBase = parent.Base;
            }

            return true;
        }
示例#4
0
        internal QueryRewriter(EdmType generatedType, ViewgenContext context, ViewGenMode typesGenerationMode)
        {
            Debug.Assert(typesGenerationMode != ViewGenMode.GenerateAllViews);

            _typesGenerationMode = typesGenerationMode;
            _context = context;
            _generatedType = generatedType;
            _domainMap = context.MemberMaps.LeftDomainMap;
            _config = context.Config;
            _identifiers = context.CqlIdentifiers;
            _qp = new RewritingProcessor<Tile<FragmentQuery>>(new DefaultTileProcessor<FragmentQuery>(context.LeftFragmentQP));
            _extentPath = new MemberPath(context.Extent);
            _keyAttributes = new List<MemberPath>(MemberPath.GetKeyMembers(context.Extent, _domainMap));

            // populate _fragmentQueries and _views
            foreach (var leftCellWrapper in _context.AllWrappersForExtent)
            {
                var query = leftCellWrapper.FragmentQuery;
                Tile<FragmentQuery> tile = CreateTile(query);
                _fragmentQueries.Add(query);
                _views.Add(tile);
            }
            Debug.Assert(_views.Count > 0);

            AdjustMemberDomainsForUpdateViews();

            // must be done after adjusting domains
            _domainQuery = GetDomainQuery(FragmentQueries, generatedType);

            _usedViews = new HashSet<FragmentQuery>();
        }
            public void WhenError()
            {
                var rootType = typeof(ErrorTypes.With<ErrorTypes.Parent>);
                var valueProperty = rootType.GetProperty(nameof(ErrorTypes.With<ErrorTypes.Parent>.Value));
                var childProperty = typeof(ErrorTypes.Parent).GetProperty(nameof(ErrorTypes.Parent.Child));
                var parentProperty = typeof(ErrorTypes.Child).GetProperty(nameof(ErrorTypes.Child.Parent));
                var path = new MemberPath(rootType)
                                .WithProperty(valueProperty)
                                .WithProperty(childProperty)
                                .WithProperty(parentProperty)
                                .WithProperty(childProperty);
                var referenceLoop = new ReferenceLoop(path);
                var typeErrors = ErrorBuilder.Start()
                                         .CreateIfNull(rootType)
                                         .Add(referenceLoop)
                                         .Finnish();
                var errorBuilder = new StringBuilder();
                errorBuilder.AppendNotSupported(typeErrors);
                var expected = "The property Parent.Child of type Child is in a reference loop.\r\n" +
                               "  - The loop is With<Parent>.Value.Child.Parent.Child...\r\n" +
                               "The property With<Parent>.Value of type Parent is not supported.\r\n" +
                               "The property Parent.Child of type Child is not supported.\r\n" +
                               "The property Child.Parent of type Parent is not supported.\r\n";
                var actual = errorBuilder.ToString();
                Assert.AreEqual(expected, actual);

                Assert.AreEqual(1, typeErrors.Errors.Count);
                Assert.AreEqual(7, typeErrors.AllErrors.Count);
            }
        public void RefLoopAndMemberErrors()
        {
            var rootType = typeof(ErrorTypes.With<ErrorTypes.Parent>);
            var valueProperty = rootType.GetProperty(nameof(ErrorTypes.With<ErrorTypes.Parent>.Value));
            var parentType = typeof(ErrorTypes.Parent);
            var childProperty = parentType.GetProperty(nameof(ErrorTypes.Parent.Child));
            var parentProperty = typeof(ErrorTypes.Child).GetProperty(nameof(ErrorTypes.Child.Parent));
            var path = new MemberPath(rootType)
                            .WithProperty(valueProperty);

            var loopPath = path.WithProperty(childProperty)
                               .WithProperty(parentProperty)
                               .WithProperty(childProperty);
            var referenceLoop = new ReferenceLoop(loopPath);
            var refLoopErrors = ErrorBuilder.Start()
                                     .CreateIfNull(rootType)
                                     .Add(referenceLoop)
                                     .Finnish();
            var typeMustNotifyError = TypeMustNotifyError.GetOrCreate(parentType);
            var typeErrors = new TypeErrors( parentType, typeMustNotifyError);
            var memberErrors = new MemberErrors(path, typeErrors);
            var notifyErrors = ErrorBuilder.Start()
                                           .CreateIfNull(rootType)
                                           .Add(memberErrors)
                                           .Finnish();
            var merged = ErrorBuilder.Merge(refLoopErrors, notifyErrors);
            Assert.AreEqual(2, merged.Errors.Count);
            Assert.AreEqual(8, merged.AllErrors.Count);
        }
        // requires: this to correspond to a cell relation for an entityset (m_cellQuery.Extent)
        // effects: Adds any key constraints present in this to constraints
        private void PopulateKeyConstraintsForEntitySet(BasicSchemaConstraints constraints)
        {
            var prefix = new MemberPath(m_cellQuery.Extent);
            var entityType = (EntityType)m_cellQuery.Extent.ElementType;

            // Get all the keys for the entity type and create the key constraints
            var keys = ExtentKey.GetKeysForEntityType(prefix, entityType);
            AddKeyConstraints(keys, constraints);
        }
示例#8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DataVisitorBase"/> class.
 /// </summary>
 /// <param name="typeDescriptorFactory">The type descriptor factory.</param>
 /// <exception cref="ArgumentNullException">typeDescriptorFactory</exception>
 protected DataVisitorBase(ITypeDescriptorFactory typeDescriptorFactory)
 {
     if (typeDescriptorFactory == null) throw new ArgumentNullException(nameof(typeDescriptorFactory));
     TypeDescriptorFactory = typeDescriptorFactory;
     CustomVisitors = new List<IDataCustomVisitor>();
     context.DescriptorFactory = TypeDescriptorFactory;
     context.Visitor = this;
     CurrentPath = new MemberPath(16);
 }
示例#9
0
        // effects: Determines all the keys (unique and primary for
        // entityType) for entityType and returns a key. "prefix" gives the
        // path of the extent or end of a relationship in a relationship set
        // -- prefix is prepended to the entity's key fields to get the full memberpath
        internal static List<ExtentKey> GetKeysForEntityType(MemberPath prefix, EntityType entityType)
        {
            // CHANGE_ADYA_MULTIPLE_KEYS: currently there is a single key only. Need to support
            // keys inside complex types + unique keys
            var key = GetPrimaryKeyForEntityType(prefix, entityType);

            var keys = new List<ExtentKey>();
            keys.Add(key);
            return keys;
        }
示例#10
0
 // <summary>
 // Copy Constructor
 // </summary>
 internal CellQuery(CellQuery source)
 {
     m_basicCellRelation = source.m_basicCellRelation;
     m_boolExprs = source.m_boolExprs;
     m_selectDistinct = source.m_selectDistinct;
     m_extentMemberPath = source.m_extentMemberPath;
     m_originalWhereClause = source.m_originalWhereClause;
     m_projectedSlots = source.m_projectedSlots;
     m_whereClause = source.m_whereClause;
 }
        internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
        {
            DebugCheck.NotNull(outputMember.LeafEdmMember);
            var modelTypeUsage = Helper.GetModelTypeUsage(outputMember.LeafEdmMember);
            var modelType = modelTypeUsage.EdmType;

            // Some built-in constants
            if (BuiltInTypeKind.PrimitiveType
                == modelType.BuiltInTypeKind)
            {
                var primitiveTypeKind = ((PrimitiveType)modelType).PrimitiveTypeKind;
                if (primitiveTypeKind == PrimitiveTypeKind.Boolean)
                {
                    // This better be a boolean. Else we crash!
                    var val = (bool)m_scalar;
                    var value = StringUtil.FormatInvariant("{0}", val);
                    builder.Append(value);
                    return builder;
                }
                else if (primitiveTypeKind == PrimitiveTypeKind.String)
                {
                    bool isUnicode;
                    if (!TypeHelpers.TryGetIsUnicode(modelTypeUsage, out isUnicode))
                    {
                        // If can't determine - use the safest option, assume unicode.
                        isUnicode = true;
                    }

                    if (isUnicode)
                    {
                        builder.Append('N');
                    }

                    AppendEscapedScalar(builder);
                    return builder;
                }
            }
            else if (BuiltInTypeKind.EnumType
                     == modelType.BuiltInTypeKind)
            {
                // Enumerated type - we should be able to cast it
                var enumMember = (EnumMember)m_scalar;

                builder.Append(enumMember.Name);
                return builder;
            }

            // Need to cast
            builder.Append("CAST(");
            AppendEscapedScalar(builder);
            builder.Append(" AS ");
            CqlWriter.AppendEscapedTypeName(builder, modelType);
            builder.Append(')');
            return builder;
        }
示例#12
0
        public void PathString()
        {
            var path = new MemberPath(typeof(MemberPathTypes.With<MemberPathTypes.Parent>));
            Assert.AreEqual("With<Parent>", path.PathString());

            path = path.WithProperty(ChildProperty);
            Assert.AreEqual("With<Parent>.Child", path.PathString());

            path = path.WithProperty(ParentProperty);
            Assert.AreEqual("With<Parent>.Child.Parent", path.PathString());
        }
        internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
        {
            var cqt = m_memberPath.AsCqt(row);

            TypeUsage outputMemberTypeUsage;
            if (NeedToCastCqlValue(outputMember, out outputMemberTypeUsage))
            {
                cqt = cqt.CastTo(outputMemberTypeUsage);
            }

            return cqt;
        }
 /// <summary>
 ///     Returns a non-negative index of the <paramref name="member" /> if found, otherwise -1.
 /// </summary>
 internal int IndexOf(MemberPath member)
 {
     int index;
     if (m_indexMap.TryGetValue(member, out index))
     {
         return index;
     }
     else
     {
         return -1;
     }
 }
 internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
 {
     if (m_expr.IsTrue || m_expr.IsFalse)
     {
         return m_expr.AsCqt(row);
     }
     else
     {
         // Produce "CASE WHEN boolExpr THEN True ELSE False END" in order to enforce the two-state boolean logic:
         // if boolExpr returns the boolean Unknown, it gets converted to boolean False.
         return DbExpressionBuilder.Case(new DbExpression[] { m_expr.AsCqt(row) }, new DbExpression[] { DbExpressionBuilder.True }, DbExpressionBuilder.False);
     }
 }
示例#16
0
 /// <summary>
 /// Creates a <see cref="SlotInfo"/> for a <see cref="CqlBlock"/> X with information about whether this slot is needed by X's parent
 /// (<paramref name="isRequiredByParent"/>), whether X projects it (<paramref name="isProjected"/>) along with the slot value (<paramref name="slotValue"/>) and 
 /// the output member path (<paramref name="outputMember"/> (for regular/non-boolean slots) for the slot.
 /// </summary>
 /// <param name="enforceNotNull">We need to ensure that _from variables are never null since view generation uses 2-valued boolean logic.
 /// If <paramref name="enforceNotNull"/>=true, the generated Cql adds a condition (AND <paramref name="slotValue"/> NOT NULL).
 /// This flag is used only for boolean slots.</param>
 internal SlotInfo(bool isRequiredByParent, bool isProjected, ProjectedSlot slotValue, MemberPath outputMember, bool enforceNotNull)
 {
     m_isRequiredByParent = isRequiredByParent;
     m_isProjected = isProjected;
     m_slotValue = slotValue;
     m_outputMember = outputMember;
     m_enforceNotNull = enforceNotNull;
     Debug.Assert(false == m_isRequiredByParent || m_slotValue != null, "Required slots cannot be null");
     Debug.Assert(m_slotValue is QualifiedSlot ||
                  (m_slotValue == null && m_outputMember == null) || // unused boolean slot
                  (m_slotValue is BooleanProjectedSlot) == (m_outputMember == null),
                  "If slot is boolean slot, there is no member path for it and vice-versa");
 }
示例#17
0
 // effects: Given all the fields, just sets them. 
 internal CellQuery(
     ProjectedSlot[] projectedSlots,
     BoolExpression whereClause,
     List<BoolExpression> boolExprs,
     SelectDistinct elimDupl, MemberPath rootMember)
 {
     m_boolExprs = boolExprs;
     m_projectedSlots = projectedSlots;
     m_whereClause = whereClause;
     m_originalWhereClause = whereClause;
     m_selectDistinct = elimDupl;
     m_extentMemberPath = rootMember;
 }
示例#18
0
        // effects: Returns the key for entityType prefixed with prefix (for
        // its memberPath)
        internal static ExtentKey GetPrimaryKeyForEntityType(MemberPath prefix, EntityType entityType)
        {
            var keyFields = new List<MemberPath>();
            foreach (var keyMember in entityType.KeyMembers)
            {
                Debug.Assert(keyMember != null, "Bogus key member in metadata");
                keyFields.Add(new MemberPath(prefix, keyMember));
            }

            // Just have one key for now
            var key = new ExtentKey(keyFields);
            return key;
        }
示例#19
0
        // effects: Returns a key correspnding to all the fields in different
        // ends of relationtype prefixed with "prefix"
        internal static ExtentKey GetKeyForRelationType(MemberPath prefix, AssociationType relationType)
        {
            var keyFields = new List<MemberPath>();

            foreach (var endMember in relationType.AssociationEndMembers)
            {
                var endPrefix = new MemberPath(prefix, endMember);
                var entityType = MetadataHelper.GetEntityTypeForEnd(endMember);
                var primaryKey = GetPrimaryKeyForEntityType(endPrefix, entityType);
                keyFields.AddRange(primaryKey.KeyFields);
            }
            var key = new ExtentKey(keyFields);
            return key;
        }
示例#20
0
        public void WithLoop()
        {
            var rootType = typeof(MemberPathTypes.With<MemberPathTypes.Parent>);
            var valueProperty = rootType.GetProperty(nameof(MemberPathTypes.With<MemberPathTypes.Parent>.Value));
            var childProperty = typeof(MemberPathTypes.Parent).GetProperty(nameof(MemberPathTypes.Parent.Child));
            var parentProperty = typeof(MemberPathTypes.Child).GetProperty(nameof(MemberPathTypes.Child.Parent));
            var path = new MemberPath(rootType)
                            .WithProperty(valueProperty)
                            .WithProperty(childProperty)
                            .WithProperty(parentProperty);
            Assert.AreEqual(false, path.HasLoop());

            path = path.WithProperty(childProperty);
            Assert.AreEqual(true, path.HasLoop());
        }
示例#21
0
        public void LastMember()
        {
            var rootType = typeof(MemberPathTypes.With<MemberPathTypes.Parent>);
            var path1 = new MemberPath(rootType);
            Assert.AreEqual(rootType, path1.Root.Type);
            Assert.AreEqual(null, path1.LastMember);

            var path2 = path1.WithProperty(ChildProperty);
            Assert.AreNotSame(path1, path2);
            Assert.AreEqual(rootType, path2.Root.Type);
            Assert.AreEqual(ChildProperty, path2.LastMember);

            var path3 = path2.WithProperty(ParentProperty);
            Assert.AreEqual(rootType, path3.Root.Type);
            Assert.AreEqual(ParentProperty, path3.LastMember);
        }
示例#22
0
        internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
        {
            AsCql(
                // createRef action
                (refScopeEntitySet, keyMemberOutputPaths) =>
                    {
                        // Construct a scoped reference: CreateRef(CPerson1Set, NewRow(pid1, pid2), CPerson1)
                        var refEntityType = (EntityType)(((RefType)outputMember.EdmType).ElementType);
                        builder.Append("CreateRef(");
                        CqlWriter.AppendEscapedQualifiedName(builder, refScopeEntitySet.EntityContainer.Name, refScopeEntitySet.Name);
                        builder.Append(", row(");
                        for (var i = 0; i < keyMemberOutputPaths.Count; ++i)
                        {
                            if (i > 0)
                            {
                                builder.Append(", ");
                            }
                            // Given the member, we need its aliased name
                            var fullFieldAlias = CqlWriter.GetQualifiedName(blockAlias, keyMemberOutputPaths[i].CqlFieldAlias);
                            builder.Append(fullFieldAlias);
                        }
                        builder.Append("), ");
                        CqlWriter.AppendEscapedTypeName(builder, refEntityType);
                        builder.Append(')');
                    },
                // createType action
                (membersOutputPaths) =>
                    {
                        // Construct an entity/complex/Association type in the Members order for fields: CPerson(CPerson1_Pid, CPerson1_Name)
                        CqlWriter.AppendEscapedTypeName(builder, m_edmType);
                        builder.Append('(');
                        for (var i = 0; i < membersOutputPaths.Count; ++i)
                        {
                            if (i > 0)
                            {
                                builder.Append(", ");
                            }
                            // Given the member, we need its aliased name: CPerson1_Pid
                            var fullFieldAlias = CqlWriter.GetQualifiedName(blockAlias, membersOutputPaths[i].CqlFieldAlias);
                            builder.Append(fullFieldAlias);
                        }
                        builder.Append(')');
                    },
                outputMember);

            return builder;
        }
 internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias, int indentLevel)
 {
     TypeUsage outputMemberStoreTypeUsage;
     if (NeedToCastCqlValue(outputMember, out outputMemberStoreTypeUsage))
     {
         builder.Append("CAST(");
         m_memberPath.AsEsql(builder, blockAlias);
         builder.Append(" AS ");
         CqlWriter.AppendEscapedTypeName(builder, outputMemberStoreTypeUsage.EdmType);
         builder.Append(')');
     }
     else
     {
         m_memberPath.AsEsql(builder, blockAlias);
     }
     return builder;
 }
 internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias, int indentLevel)
 {
     if (m_expr.IsTrue || m_expr.IsFalse)
     {
         // No Case statement for TRUE and FALSE
         m_expr.AsEsql(builder, blockAlias);
     }
     else
     {
         // Produce "CASE WHEN boolExpr THEN True ELSE False END" in order to enforce the two-state boolean logic:
         // if boolExpr returns the boolean Unknown, it gets converted to boolean False.
         builder.Append("CASE WHEN ");
         m_expr.AsEsql(builder, blockAlias);
         builder.Append(" THEN True ELSE False END");
     }
     return builder;
 }
示例#25
0
        public ReferenceLoop(MemberPath path)
        {
            this.Path = path;
            var errors = new List<Error>();
            var typeErrors = path.OfType<ITypedNode>()
                                   .Select(x => x.Type)
                                   .Append(path.RootType)
                                   .Distinct()
                                   .Select(t => new TypeErrors(t));
            errors.AddRange(typeErrors);

            var memberErrors = path.OfType<IMemberItem>()
                                     .Select(x => x.Member)
                                     .Distinct()
                                     .Select(m => new MemberErrors(m));
            errors.AddRange(memberErrors);
            this.Errors = errors;
        }
        // effects: Creates a foreign key constraint of the form:
        // <i_childTable, i_childColumns> --> <i_parentTable, i_childColumns>
        // i_fkeySet is the name of the constraint
        internal ForeignConstraint(AssociationSet i_fkeySet, EntitySet i_parentTable, EntitySet i_childTable,
                                   ReadOnlyMetadataCollection<EdmProperty> i_parentColumns, ReadOnlyMetadataCollection<EdmProperty> i_childColumns)
        {
            m_fKeySet = i_fkeySet;
            m_parentTable = i_parentTable;
            m_childTable = i_childTable;
            m_childColumns = new List<MemberPath>();
            // Create parent and child paths using the table names
            foreach (EdmProperty property in i_childColumns)
            {
                MemberPath path = new MemberPath(m_childTable, property);
                m_childColumns.Add(path);
            }

            m_parentColumns = new List<MemberPath>();
            foreach (EdmProperty property in i_parentColumns)
            {
                MemberPath path = new MemberPath(m_parentTable, property);
                m_parentColumns.Add(path);
            }
        }
 internal override string GetCqlFieldAlias(MemberPath outputMember)
 {
     return(this.m_originalCell.SlotName);
 }
示例#28
0
            internal override bool VisitLeaf(LeafCellTreeNode node, bool dummy)
            {
                CellQuery         rightCellQuery1 = this.m_wrapper.RightCellQuery;
                CellQuery         rightCellQuery2 = node.LeftCellWrapper.RightCellQuery;
                List <MemberPath> memberPathList  = new List <MemberPath>();

                if (rightCellQuery1 != rightCellQuery2)
                {
                    for (int slotNum = 0; slotNum < rightCellQuery1.NumProjectedSlots; ++slotNum)
                    {
                        MemberProjectedSlot memberProjectedSlot1 = rightCellQuery1.ProjectedSlotAt(slotNum) as MemberProjectedSlot;
                        if (memberProjectedSlot1 != null)
                        {
                            MemberProjectedSlot memberProjectedSlot2 = rightCellQuery2.ProjectedSlotAt(slotNum) as MemberProjectedSlot;
                            if (memberProjectedSlot2 != null)
                            {
                                MemberPath projectedSlot = this.m_viewgenContext.MemberMaps.ProjectedSlotMap[slotNum];
                                if (!projectedSlot.IsPartOfKey && !MemberPath.EqualityComparer.Equals(memberProjectedSlot1.MemberPath, memberProjectedSlot2.MemberPath))
                                {
                                    memberPathList.Add(projectedSlot);
                                }
                            }
                        }
                    }
                }
                if (memberPathList.Count > 0)
                {
                    this.m_errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.NonKeyProjectedWithOverlappingPartitions, Strings.ViewGen_NonKeyProjectedWithOverlappingPartitions((object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>)memberPathList, false)), (IEnumerable <LeftCellWrapper>) new LeftCellWrapper[2]
                    {
                        this.m_wrapper,
                        node.LeftCellWrapper
                    }, string.Empty));
                }
                return(true);
            }
示例#29
0
        private static bool IsBooleanMember(MemberPath path)
        {
            var primitive = path.EdmType as PrimitiveType;

            return(primitive != null && primitive.PrimitiveTypeKind == PrimitiveTypeKind.Boolean);
        }
示例#30
0
 // <summary>
 // Not supported in this class.
 // </summary>
 internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
 {
     Debug.Fail("Should not be called.");
     return(null);
 }
示例#31
0
 // <summary>
 // Not supported in this class.
 // </summary>
 internal override string GetCqlFieldAlias(MemberPath outputMember)
 {
     Debug.Fail("Should not be called.");
     return(null); // To keep the compiler happy
 }
示例#32
0
        public PathMap FindOrCreatePathMapFor(LambdaExpression destinationExpression, MemberPath path, TypeMap typeMap)
        {
            _pathMaps ??= new();
            var pathMap = _pathMaps.GetValueOrDefault(path);

            if (pathMap == null)
            {
                pathMap = new(destinationExpression, path, typeMap);
                AddPathMap(pathMap);
            }
            return(pathMap);
        }
示例#33
0
 internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias, int indentLevel)
 {
     Debug.Assert(blockAlias == null || m_block.CqlAlias == blockAlias, "QualifiedSlot: blockAlias mismatch");
     builder.Append(GetQualifiedCqlName(outputMember));
     return(builder);
 }
示例#34
0
        // requires: all columns in constraint.ParentColumns and
        // constraint.ChildColumns must have been mapped in some cell in m_cellGroup
        // effects: Given the foreign key constraint, checks if the
        // constraint.ChildColumns are mapped to the constraint.ParentColumns
        // in m_cellGroup in the right oder. If not, adds an error to m_errorLog and returns
        // false. Else returns true
        private bool CheckForeignKeyColumnOrder(Set <Cell> cells, ErrorLog errorLog)
        {
            // Go through every cell and find the cells that are relevant to
            // parent and those that are relevant to child
            // Then for each cell pair (parent, child) make sure that the
            // projected foreign keys columns in C-space are aligned

            List <Cell> parentCells = new List <Cell>();
            List <Cell> childCells  = new List <Cell>();

            foreach (Cell cell in cells)
            {
                if (cell.SQuery.Extent.Equals(ChildTable))
                {
                    childCells.Add(cell);
                }

                if (cell.SQuery.Extent.Equals(ParentTable))
                {
                    parentCells.Add(cell);
                }
            }

            // Make sure that all child cells and parent cells align on
            // the columns, i.e., for each DISTINCT pair C and P, get the columns
            // on the S-side. Then get the corresponding fields on the
            // C-side. The fields on the C-side should match

            bool foundParentCell = false;
            bool foundChildCell  = false;

            foreach (Cell childCell in childCells)
            {
                List <List <int> > allChildSlotNums = GetSlotNumsForColumns(childCell, ChildColumns);

                if (allChildSlotNums.Count == 0)
                { // slots in present in S-side, ignore
                    continue;
                }

                List <MemberPath> childPaths  = null;
                List <MemberPath> parentPaths = null;
                Cell errorParentCell          = null;

                foreach (List <int> childSlotNums in allChildSlotNums)
                {
                    foundChildCell = true;

                    // Get the fields on the C-side
                    childPaths = new List <MemberPath>(childSlotNums.Count);
                    foreach (int childSlotNum in childSlotNums)
                    {
                        // Initial slots only have JoinTreeSlots
                        MemberProjectedSlot childSlot = (MemberProjectedSlot)childCell.CQuery.ProjectedSlotAt(childSlotNum);
                        Debug.Assert(childSlot != null);
                        childPaths.Add(childSlot.MemberPath);
                    }

                    foreach (Cell parentCell in parentCells)
                    {
                        List <List <int> > allParentSlotNums = GetSlotNumsForColumns(parentCell, ParentColumns);
                        if (allParentSlotNums.Count == 0)
                        {
                            // * Parent and child cell are the same - we do not
                            // need to check since we want to check the foreign
                            // key constraint mapping across cells
                            // * Some slots not in present in S-side, ignore
                            continue;
                        }
                        foreach (List <int> parentSlotNums in allParentSlotNums)
                        {
                            foundParentCell = true;

                            parentPaths = new List <MemberPath>(parentSlotNums.Count);
                            foreach (int parentSlotNum in parentSlotNums)
                            {
                                MemberProjectedSlot parentSlot = (MemberProjectedSlot)parentCell.CQuery.ProjectedSlotAt(parentSlotNum);
                                Debug.Assert(parentSlot != null);
                                parentPaths.Add(parentSlot.MemberPath);
                            }

                            // Make sure that the last member of each of these is the same
                            // or the paths are essentially equivalent via referential constraints
                            // We need to check that the last member is essentially the same because it could
                            // be a regular scenario where aid is mapped to PersonAddress and Address - there
                            // is no ref constraint. So when projected into C-Space, we will get Address.aid
                            // and PersonAddress.Address.aid
                            if (childPaths.Count == parentPaths.Count)
                            {
                                bool notAllPathsMatched = false;
                                for (int i = 0; i < childPaths.Count && !notAllPathsMatched; i++)
                                {
                                    MemberPath parentPath = parentPaths[i];
                                    MemberPath childPath  = childPaths[i];

                                    if (!parentPath.LeafEdmMember.Equals(childPath.LeafEdmMember)) //Child path did not match
                                    {
                                        if (parentPath.IsEquivalentViaRefConstraint(childPath))
                                        {
                                            //Specifying the referential constraint once in the C space should be enough.
                                            //This is the only way possible today.
                                            //We might be able to derive more knowledge by using boolean logic
                                            return(true);
                                        }
                                        else
                                        {
                                            notAllPathsMatched = true;
                                        }
                                    }
                                }

                                if (!notAllPathsMatched)
                                {
                                    return(true); //all childPaths matched parentPaths
                                }
                                else
                                {
                                    //If not this one, some other Parent Cell may match.
                                    errorParentCell = parentCell;
                                }
                            }
                        }
                    } //foreach parentCell
                }

                //If execution is at this point, no parent cell's end has matched (otherwise it would have returned true)

                Debug.Assert(childPaths != null, "child paths should be set");
                Debug.Assert(parentPaths != null, "parent paths should be set");
                Debug.Assert(errorParentCell != null, "errorParentCell should be set");
                // using EntityRes. instead of Strings. because the generated method includes 6 instead of 9 parameters
                string message = EntityRes.GetString(EntityRes.ViewGen_Foreign_Key_ColumnOrder_Incorrect,
                                                     ToUserString(),
                                                     MemberPath.PropertiesToUserString(ChildColumns, false),
                                                     ChildTable.Name,
                                                     MemberPath.PropertiesToUserString(childPaths, false),
                                                     childCell.CQuery.Extent.Name,
                                                     MemberPath.PropertiesToUserString(ParentColumns, false),
                                                     ParentTable.Name,
                                                     MemberPath.PropertiesToUserString(parentPaths, false),
                                                     errorParentCell.CQuery.Extent.Name);
                ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ForeignKeyColumnOrderIncorrect, message, new Cell[] { errorParentCell, childCell }, String.Empty);
                errorLog.AddEntry(record);
                return(false);
            }
            Debug.Assert(foundParentCell == true, "Some cell that mapped the parent's key must be present!");
            Debug.Assert(foundChildCell == true, "Some cell that mapped the child's foreign key must be present according to the requires clause!");
            return(true);
        }
示例#35
0
 public PathMap(LambdaExpression destinationExpression, MemberPath memberPath, TypeMap typeMap)
 {
     MemberPath            = memberPath;
     TypeMap               = typeMap;
     DestinationExpression = destinationExpression;
 }
示例#36
0
        // requires: "properties" corresponds to all the properties that are
        // inside cNode.Value, e.g., cNode corresponds to an extent Person,
        // properties contains all the properties inside Person (recursively)
        // effects: Given C-side and S-side Cell Query for a cell, generates
        // the projected slots on both sides corresponding to
        // properties. Also updates the C-side whereclause corresponding to
        // discriminator properties on the C-side, e.g, isHighPriority
        private void ExtractProperties(
            IEnumerable <StoragePropertyMapping> properties,
            MemberPath cNode, List <ProjectedSlot> cSlots,
            ref BoolExpression cQueryWhereClause,
            MemberPath sRootExtent,
            List <ProjectedSlot> sSlots,
            ref BoolExpression sQueryWhereClause)
        {
            // For each property mapping, we add an entry to the C and S cell queries
            foreach (var propMap in properties)
            {
                var scalarPropMap              = propMap as StorageScalarPropertyMapping;
                var complexPropMap             = propMap as StorageComplexPropertyMapping;
                var associationEndPropertypMap = propMap as StorageEndPropertyMapping;
                var conditionMap = propMap as StorageConditionPropertyMapping;

                Debug.Assert(
                    scalarPropMap != null ||
                    complexPropMap != null ||
                    associationEndPropertypMap != null ||
                    conditionMap != null, "Unimplemented property mapping");

                if (scalarPropMap != null)
                {
                    Debug.Assert(scalarPropMap.ColumnProperty != null, "ColumnMember for a Scalar Property can not be null");
                    // Add an attribute node to node

                    var cAttributeNode = new MemberPath(cNode, scalarPropMap.EdmProperty);
                    // Add a column (attribute) node the sQuery
                    // unlike the C side, there is no nesting. Hence we
                    // did not need an internal node
                    var sAttributeNode = new MemberPath(sRootExtent, scalarPropMap.ColumnProperty);
                    cSlots.Add(new MemberProjectedSlot(cAttributeNode));
                    sSlots.Add(new MemberProjectedSlot(sAttributeNode));
                }

                // Note: S-side constants are not allowed since they can cause
                // problems -- for example, if such a cell says 5 for the
                // third field, we cannot guarantee the fact that an
                // application may not set that field to 7 in the C-space

                // Check if the property mapping is for a complex types
                if (complexPropMap != null)
                {
                    foreach (var complexTypeMap in complexPropMap.TypeMappings)
                    {
                        // Create a node for the complex type property and call recursively
                        var complexMemberNode = new MemberPath(cNode, complexPropMap.EdmProperty);
                        //Get the list of types that this type map represents
                        var allTypes = new Set <EdmType>();
                        // Gather a set of all explicit types for an entity
                        // type mapping in allTypes.
                        var exactTypes = Helpers.AsSuperTypeList <ComplexType, EdmType>(complexTypeMap.Types);
                        allTypes.AddRange(exactTypes);
                        foreach (EdmType type in complexTypeMap.IsOfTypes)
                        {
                            allTypes.AddRange(
                                MetadataHelper.GetTypeAndSubtypesOf(
                                    type, m_containerMapping.StorageMappingItemCollection.EdmItemCollection, false /*includeAbstractTypes*/));
                        }
                        var complexInTypes = BoolExpression.CreateLiteral(new TypeRestriction(complexMemberNode, allTypes), null);
                        cQueryWhereClause = BoolExpression.CreateAnd(cQueryWhereClause, complexInTypes);
                        // Now extract the properties of the complex type
                        // (which could have other complex types)
                        ExtractProperties(
                            complexTypeMap.AllProperties, complexMemberNode, cSlots,
                            ref cQueryWhereClause, sRootExtent, sSlots, ref sQueryWhereClause);
                    }
                }

                // Check if the property mapping is for an associaion
                if (associationEndPropertypMap != null)
                {
                    // create join tree node representing this relation end
                    var associationEndNode = new MemberPath(cNode, associationEndPropertypMap.EndMember);
                    // call recursively
                    ExtractProperties(
                        associationEndPropertypMap.Properties, associationEndNode, cSlots,
                        ref cQueryWhereClause, sRootExtent, sSlots, ref sQueryWhereClause);
                }

                //Check if the this is a condition and add it to the Where clause
                if (conditionMap != null)
                {
                    if (conditionMap.ColumnProperty != null)
                    {
                        //Produce a Condition Expression for the Condition Map.
                        var conditionExpression = GetConditionExpression(sRootExtent, conditionMap);
                        //Add the condition expression to the exisiting S side Where clause using an "And"
                        sQueryWhereClause = BoolExpression.CreateAnd(sQueryWhereClause, conditionExpression);
                    }
                    else
                    {
                        Debug.Assert(conditionMap.EdmProperty != null);
                        //Produce a Condition Expression for the Condition Map.
                        var conditionExpression = GetConditionExpression(cNode, conditionMap);
                        //Add the condition expression to the exisiting C side Where clause using an "And"
                        cQueryWhereClause = BoolExpression.CreateAnd(cQueryWhereClause, conditionExpression);
                    }
                }
            }
        }
示例#37
0
 internal override string GetCqlFieldAlias(MemberPath outputMember)
 {
     return(this.GetOriginalSlot().GetCqlFieldAlias(outputMember));
 }
示例#38
0
 internal string GetQualifiedCqlName(MemberPath outputMember)
 {
     return(CqlWriter.GetQualifiedName(this.m_block.CqlAlias, this.GetCqlFieldAlias(outputMember)));
 }
        private void CreateVariableConstraintsRecursion(
            EdmType edmType, MemberPath currentPath, MemberDomainMap domainMap, EdmItemCollection edmItemCollection)
        {
            // Add the types can member have, i.e., its type and its subtypes
            var possibleTypes = new HashSet <EdmType>();

            possibleTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(edmType, edmItemCollection, true));

            foreach (var possibleType in possibleTypes)
            {
                // determine type domain

                var derivedTypes = new HashSet <EdmType>();
                derivedTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(possibleType, edmItemCollection, false));
                if (derivedTypes.Count != 0)
                {
                    var typeCondition           = CreateIsOfTypeCondition(currentPath, derivedTypes, domainMap);
                    var typeConditionComplement = BoolExpression.CreateNot(typeCondition);
                    if (false == typeConditionComplement.IsSatisfiable())
                    {
                        continue;
                    }

                    var structuralType = (StructuralType)possibleType;
                    foreach (var childProperty in structuralType.GetDeclaredOnlyMembers <EdmProperty>())
                    {
                        var childPath = new MemberPath(currentPath, childProperty);
                        var isScalar  = MetadataHelper.IsNonRefSimpleMember(childProperty);

                        if (domainMap.IsConditionMember(childPath) ||
                            domainMap.IsProjectedConditionMember(childPath))
                        {
                            BoolExpression nullCondition;
                            var            childDomain = new List <Constant>(domainMap.GetDomain(childPath));
                            if (isScalar)
                            {
                                nullCondition = BoolExpression.CreateLiteral(
                                    new ScalarRestriction(
                                        new MemberProjectedSlot(childPath),
                                        new Domain(Constant.Undefined, childDomain)), domainMap);
                            }
                            else
                            {
                                nullCondition = BoolExpression.CreateLiteral(
                                    new TypeRestriction(
                                        new MemberProjectedSlot(childPath),
                                        new Domain(Constant.Undefined, childDomain)), domainMap);
                            }
                            // Properties not occuring in type are UNDEFINED
                            AddEquivalence(typeConditionComplement.Tree, nullCondition.Tree);
                        }

                        // recurse into complex types
                        if (false == isScalar)
                        {
                            CreateVariableConstraintsRecursion(childPath.EdmType, childPath, domainMap, edmItemCollection);
                        }
                    }
                }
            }
        }
        // <summary>
        // Returns an array of size <see cref="TotalSlots" /> which indicates the slots that are needed to constuct value at
        // <paramref
        //     name="caseMemberPath" />
        // ,
        // e.g., CPerson may need pid and name (say slots 2 and 5 - then bools[2] and bools[5] will be true.
        // </summary>
        // <param name="caseMemberPath">
        // must be part of <see cref="m_caseStatements" />
        // </param>
        private void GetRequiredSlotsForCaseMember(MemberPath caseMemberPath, bool[] requiredSlots)
        {
            Debug.Assert(m_caseStatements.ContainsKey(caseMemberPath), "Constructing case for regular field?");
            Debug.Assert(requiredSlots.Length == TotalSlots, "Invalid array size for populating required slots");

            var statement = m_caseStatements[caseMemberPath];

            // Find the required slots from the when then clause conditions
            // and values
            var requireThisSlot = false;

            foreach (var clause in statement.Clauses)
            {
                clause.Condition.GetRequiredSlots(m_projectedSlotMap, requiredSlots);
                var slot = clause.Value;
                if (!(slot is ConstantProjectedSlot))
                {
                    // If this slot is a scalar and a non-constant,
                    // we need the lower down blocks to generate it for us
                    requireThisSlot = true;
                }
            }

            var edmType = caseMemberPath.EdmType;

            if (Helper.IsEntityType(edmType) ||
                Helper.IsComplexType(edmType))
            {
                foreach (var instantiatedType in statement.InstantiatedTypes)
                {
                    foreach (EdmMember childMember in Helper.GetAllStructuralMembers(instantiatedType))
                    {
                        var slotNum = GetSlotIndex(caseMemberPath, childMember);
                        requiredSlots[slotNum] = true;
                    }
                }
            }
            else if (caseMemberPath.IsScalarType())
            {
                // A scalar does not need anything per se to be constructed
                // unless it is referring to a field in the tree below, i.e., the THEN
                // slot is not a constant slot
                if (requireThisSlot)
                {
                    var caseMemberSlotNum = m_projectedSlotMap.IndexOf(caseMemberPath);
                    requiredSlots[caseMemberSlotNum] = true;
                }
            }
            else if (Helper.IsAssociationType(edmType))
            {
                // For an association, get the indices of the ends, e.g.,
                // CProduct and CCategory in CProductCategory1
                // Need just it's ends
                var associationSet  = (AssociationSet)caseMemberPath.Extent;
                var associationType = associationSet.ElementType;
                foreach (var endMember in associationType.AssociationEndMembers)
                {
                    var slotNum = GetSlotIndex(caseMemberPath, endMember);
                    requiredSlots[slotNum] = true;
                }
            }
            else
            {
                // For a reference, all we need are the keys
                var refType = edmType as RefType;
                Debug.Assert(refType != null, "What other non scalars do we have? Relation end must be a reference type");

                var refElementType = refType.ElementType;
                // Go through all the members of elementType and get the key properties

                foreach (var entityMember in refElementType.KeyMembers)
                {
                    var slotNum = GetSlotIndex(caseMemberPath, entityMember);
                    requiredSlots[slotNum] = true;
                }
            }
        }
        /// <summary>
        /// Checks:
        ///  1) Concurrency token is not defined in this Extent's ElementTypes' derived types
        ///  2) Members with concurrency token should not have conditions specified
        /// </summary>
        private void CheckConcurrencyControlTokens()
        {
            Debug.Assert(m_viewTarget == ViewTarget.QueryView);
            // Get the token fields for this extent

            EntityTypeBase   extentType   = m_extent.ElementType;
            Set <EdmMember>  tokenMembers = MetadataHelper.GetConcurrencyMembersForTypeHierarchy(extentType, m_edmItemCollection);
            Set <MemberPath> tokenPaths   = new Set <MemberPath>(MemberPath.EqualityComparer);

            foreach (EdmMember tokenMember in tokenMembers)
            {
                if (!tokenMember.DeclaringType.IsAssignableFrom(extentType))
                {
                    string          message = System.Data.Entity.Strings.ViewGen_Concurrency_Derived_Class(tokenMember.Name, tokenMember.DeclaringType.Name, m_extent);
                    ErrorLog.Record record  = new ErrorLog.Record(true, ViewGenErrorCode.ConcurrencyDerivedClass, message, m_cellWrappers, String.Empty);
                    ExceptionHelpers.ThrowMappingException(record, m_config);
                }
                tokenPaths.Add(new MemberPath(m_extent, tokenMember));
            }

            if (tokenMembers.Count > 0)
            {
                foreach (LeftCellWrapper wrapper in m_cellWrappers)
                {
                    Set <MemberPath> conditionMembers = new Set <MemberPath>(
                        wrapper.OnlyInputCell.CQuery.WhereClause.MemberRestrictions.Select(oneOf => oneOf.RestrictedMemberSlot.MemberPath),
                        MemberPath.EqualityComparer);
                    conditionMembers.Intersect(tokenPaths);
                    if (conditionMembers.Count > 0)
                    {
                        // There is a condition on concurrency tokens. Throw an exception.
                        StringBuilder builder = new StringBuilder();
                        builder.AppendLine(Strings.ViewGen_Concurrency_Invalid_Condition(MemberPath.PropertiesToUserString(conditionMembers, false), m_extent.Name));
                        ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ConcurrencyTokenHasCondition, builder.ToString(), new LeftCellWrapper[] { wrapper }, String.Empty);
                        ExceptionHelpers.ThrowMappingException(record, m_config);
                    }
                }
            }
        }
示例#42
0
 public UnloadableItem(IUnloadable o, MemberPath memberPath)
 {
     UnloadableObject = o;
     MemberPath       = memberPath;
 }
        /// <summary>
        /// Given the <paramref name="viewBlock"/> tree generated by the cell merging process and the <paramref name="parentRequiredSlots"/>,
        /// generates the block tree for the case statement at or past the startSlotNum, i.e., only for case statements that are beyond startSlotNum.
        /// </summary>
        private CqlBlock ConstructCaseBlocks(CqlBlock viewBlock, int startSlotNum, bool[] parentRequiredSlots, IEnumerable <WithRelationship> withRelationships)
        {
            int numMembers = m_projectedSlotMap.Count;
            // Find the next slot for which we have a case statement, i.e.,
            // which was in the multiconstants
            int foundSlot = FindNextCaseStatementSlot(startSlotNum, parentRequiredSlots, numMembers);

            if (foundSlot == -1)
            {
                // We have bottomed out - no more slots to generate cases for
                // Just get the base view block
                return(viewBlock);
            }

            // Compute the requiredSlots for this member, i.e., what slots are needed to produce this member.
            MemberPath thisMember = m_projectedSlotMap[foundSlot];

            bool[] thisRequiredSlots = new bool[TotalSlots];
            GetRequiredSlotsForCaseMember(thisMember, thisRequiredSlots);
            Debug.Assert(thisRequiredSlots.Length == parentRequiredSlots.Length &&
                         thisRequiredSlots.Length == TotalSlots,
                         "Number of slots in array should not vary across blocks");

            // Merge parent's requirements with this requirements
            for (int i = 0; i < TotalSlots; i++)
            {
                // We do ask the children to generate the slot that we are
                // producing if it is available
                if (parentRequiredSlots[i])
                {
                    thisRequiredSlots[i] = true;
                }
            }

            // If current case statement depends on its slot value, then make sure the value is produced by the child block.
            CaseStatement thisCaseStatement = m_caseStatements[thisMember];

            thisRequiredSlots[foundSlot] = thisCaseStatement.DependsOnMemberValue;

            // Recursively, determine the block tree for slots beyond foundSlot.
            CqlBlock childBlock = ConstructCaseBlocks(viewBlock, foundSlot + 1, thisRequiredSlots, null);

            // For each slot, create a SlotInfo object
            SlotInfo[] slotInfos = CreateSlotInfosForCaseStatement(parentRequiredSlots, foundSlot, childBlock, thisCaseStatement, withRelationships);
            m_currentBlockNum++;

            // We have a where clause only at the top level
            BoolExpression whereClause = startSlotNum == 0 ? m_topLevelWhereClause : BoolExpression.True;

            if (startSlotNum == 0)
            {
                // only slot #0 is required by parent; reset all 'required by parent' booleans introduced above
                for (int i = 1; i < slotInfos.Length; i++)
                {
                    slotInfos[i].ResetIsRequiredByParent();
                }
            }

            CaseCqlBlock result = new CaseCqlBlock(slotInfos, foundSlot, childBlock, whereClause, m_identifiers, m_currentBlockNum);

            return(result);
        }
示例#44
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AssetReferenceLink" /> class.
 /// </summary>
 /// <param name="path">The path.</param>
 /// <param name="reference">The reference.</param>
 /// <param name="updateReference">The update reference.</param>
 public AssetReferenceLink(MemberPath path, object reference, Func <Guid?, string, object> updateReference)
 {
     Path                 = path;
     this.reference       = reference;
     this.updateReference = updateReference;
 }
示例#45
0
 // <summary>
 // Not supported in this class.
 // </summary>
 internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias, int indentLevel)
 {
     Debug.Fail("Should not be called.");
     return(null); // To keep the compiler happy
 }
示例#46
0
 // <summary>
 // Creates a <see cref="SlotInfo" /> for a <see cref="CqlBlock" /> X with information about whether this slot is needed by X's parent
 // (<paramref name="isRequiredByParent" />), whether X projects it (<paramref name="isProjected" />) along with the slot value (
 // <paramref
 //     name="slotValue" />
 // ) and
 // the output member path (<paramref name="outputMember" /> (for regular/non-boolean slots) for the slot.
 // </summary>
 // <param name="enforceNotNull">
 // We need to ensure that _from variables are never null since view generation uses 2-valued boolean logic. If
 // <paramref
 //     name="enforceNotNull" />
 // =true, the generated Cql adds a condition (AND <paramref name="slotValue" /> NOT NULL). This flag is used only for boolean slots.
 // </param>
 internal SlotInfo(bool isRequiredByParent, bool isProjected, ProjectedSlot slotValue, MemberPath outputMember, bool enforceNotNull)
 {
     m_isRequiredByParent = isRequiredByParent;
     m_isProjected        = isProjected;
     m_slotValue          = slotValue;
     m_outputMember       = outputMember;
     m_enforceNotNull     = enforceNotNull;
     Debug.Assert(false == m_isRequiredByParent || m_slotValue != null, "Required slots cannot be null");
     Debug.Assert(
         m_slotValue is QualifiedSlot ||
         (m_slotValue == null && m_outputMember == null) || // unused boolean slot
         (m_slotValue is BooleanProjectedSlot) == (m_outputMember == null),
         "If slot is boolean slot, there is no member path for it and vice-versa");
 }
示例#47
0
 public PathConfigurationExpression(LambdaExpression destinationExpression)
 {
     _destinationExpression = destinationExpression;
     MemberPath             = new MemberPath(MemberVisitor.GetMemberPath(destinationExpression).Reverse());
 }
示例#48
0
 // <summary>
 // Creates a <see cref="SlotInfo" /> for a <see cref="CqlBlock" /> X with information about whether this slot is needed by X's parent
 // (<paramref name="isRequiredByParent" />), whether X projects it (<paramref name="isProjected" />) along with the slot value (
 // <paramref
 //     name="slotValue" />
 // ) and
 // the output member path (<paramref name="outputMember" /> (for regular/non-boolean slots) for the slot.
 // </summary>
 internal SlotInfo(bool isRequiredByParent, bool isProjected, ProjectedSlot slotValue, MemberPath outputMember)
     : this(isRequiredByParent, isProjected, slotValue, outputMember, false /* enforceNotNull */)
 {
 }
示例#49
0
 public EntityLink(ComponentBase referencer, EntityComponent entityComponent, MemberPath path)
 {
     Referencer      = referencer;
     Entity          = null;
     EntityScript    = null;
     EntityComponent = entityComponent;
     Path            = path;
 }
示例#50
0
        private void GetFolderIds()
        {
            var folderItems = GetFolderInformation(AppRootFolder);

            if (!folderItems.Collection.Any())
            {
                return;
            }

            _toPublishFolderId = folderItems.Collection.First(f => f.Folder != null && f.Name.ToLower() == ToPublishPath.ToLower()).Id;
            var internPathId = folderItems.Collection.First(f => f.Folder != null && f.Name.ToLower() == InternalPath.ToLower()).Id;
            var folders      = GetFolderInformation("/drive/items/" + internPathId);

            _photosFolderId = folders.Collection.First(f => f.Folder != null && f.Name.ToLower() == PhotoPath.ToLower()).Id;
            _memberPathOrId = folders.Collection.First(f => f.Folder != null && f.Name.ToLower() == MemberPath.ToLower()).Id;
        }
示例#51
0
 public MemberValueBinding(MemberPath member, Constant value)
 {
     this.Member = member;
     this.Value  = value;
 }
示例#52
0
 internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
 {
     return((DbExpression)this.m_block.GetInput(row).Property(this.GetCqlFieldAlias(outputMember)));
 }
        /// <summary>
        /// Starting at the <paramref name="member"/>, recursively generates <see cref="MemberPath"/>s for the fields embedded in it.
        /// </summary>
        /// <param name="member">corresponds to a value of an Entity or Complex or Association type</param>
        /// <param name="needKeysOnly">indicates whether we need to only collect members that are keys</param>
        private static void GatherPartialSignature(MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, bool needKeysOnly)
        {
            EdmType memberType = member.EdmType;
            ComplexType complexTypemember = memberType as ComplexType;
            Debug.Assert(complexTypemember != null ||
                         memberType is EntityType || // for entity sets
                         memberType is AssociationType || // For association sets
                         memberType is RefType, // for association ends
                         "GatherPartialSignature can be called only for complex types, entity sets, association ends");

            if (memberType is ComplexType && needKeysOnly)
            {
                // Check if the complex type needs to be traversed or not. If not, just return 
                // from here. Else we need to continue to the code below. Right now, we do not
                // allow keys inside complex types
                return;
            }

            // Make sure that this member is in the slot map before any of its embedded objects.
            index.CreateIndex(member);

            // Consider each possible type value -- each type value conributes to a tuple in the result.
            // For that possible type, add all the type members into the signature.
            foreach (EdmType possibleType in MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/))
            {
                StructuralType possibleStructuralType = possibleType as StructuralType;
                Debug.Assert(possibleStructuralType != null, "Non-structural subtype?");

                GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleStructuralType, needKeysOnly);
            }
        }
 // <summary>
 // Creates a scalar member restriction with the meaning "<paramref name="member" /> = <paramref name="value" />".
 // This constructor is used for creating discriminator type conditions.
 // </summary>
 internal ScalarRestriction(MemberPath member, Constant value)
     : base(new MemberProjectedSlot(member), value)
 {
     Debug.Assert(
         value is ScalarConstant || value.IsNull() || value.IsNotNull(), "value is expected to be ScalarConstant, NULL, or NOT_NULL.");
 }
示例#55
0
        public void TestMyClass()
        {
            Initialize();

            var testClass = new MyClass
            {
                Sub  = new MyClass(),
                Maps = { ["XXX"] = new MyClass() }
            };

            testClass.Subs.Add(new MyClass());

            // 1) MyClass.Value = 1
            var memberPath = new MemberPath();

            memberPath.Push(MemberValue);

            object value;

            Assert.True(memberPath.Apply(testClass, MemberPathAction.ValueSet, 1));
            Assert.True(memberPath.TryGetValue(testClass, out value));
            Assert.Equal(1, value);
            Assert.Equal(1, testClass.Value);
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 2) MyClass.Sub.Value = 1
            memberPath.Clear();
            memberPath.Push(MemberSub);
            memberPath.Push(MemberValue);

            Assert.True(memberPath.Apply(testClass, MemberPathAction.ValueSet, 1));
            Assert.True(memberPath.TryGetValue(testClass, out value));
            Assert.Equal(1, value);
            Assert.Equal(1, testClass.Sub.Value);
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 3) MyClass.Struct.X = 1
            memberPath.Clear();
            memberPath.Push(MemberStruct);
            memberPath.Push(MemberX);

            Assert.True(memberPath.Apply(testClass, MemberPathAction.ValueSet, 1));
            Assert.True(memberPath.TryGetValue(testClass, out value));
            Assert.Equal(1, value);
            Assert.Equal(1, testClass.Struct.X);
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 3) MyClass.Maps["XXX"].Value = 1
            memberPath.Clear();
            memberPath.Push(MemberMaps);
            memberPath.Push(MapClassDesc, "XXX");
            memberPath.Push(MemberValue);

            Assert.True(memberPath.Apply(testClass, MemberPathAction.ValueSet, 1));
            Assert.True(memberPath.TryGetValue(testClass, out value));
            Assert.Equal(1, value);
            Assert.Equal(1, testClass.Maps["XXX"].Value);
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 4) MyClass.Subs[0].Value = 1
            memberPath.Clear();
            memberPath.Push(MemberSubs);
            memberPath.Push(ListClassDesc, 0);
            memberPath.Push(MemberValue);

            Assert.True(memberPath.Apply(testClass, MemberPathAction.ValueSet, 1));
            Assert.True(memberPath.TryGetValue(testClass, out value));
            Assert.Equal(1, value);
            Assert.Equal(1, testClass.Subs[0].Value);
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 5) MyClass.Subs[0].X (invalid)
            memberPath.Clear();
            memberPath.Push(MemberSubs);
            memberPath.Push(ListClassDesc, 0);
            memberPath.Push(MemberX);

            Assert.False(memberPath.TryGetValue(testClass, out value));
            Assert.False(memberPath.Apply(testClass, MemberPathAction.ValueSet, 1));
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 6) Remove key MyClass.Maps.Remove("XXX")
            memberPath.Clear();
            memberPath.Push(MemberMaps);
            memberPath.Push(MapClassDesc, "XXX");
            Assert.True(memberPath.Apply(testClass, MemberPathAction.DictionaryRemove, null));
            Assert.False(testClass.Maps.ContainsKey("XXX"));
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 7) Re-add a value to the dictionary
            Assert.True(memberPath.Apply(testClass, MemberPathAction.ValueSet, new MyClass()));
            Assert.True(testClass.Maps.ContainsKey("XXX"));
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 8) Remove key MyClass.Subs.Remove(0)
            memberPath.Clear();
            memberPath.Push(MemberSubs);
            memberPath.Push(ListClassDesc, 0);
            Assert.True(memberPath.Apply(testClass, MemberPathAction.CollectionRemove, null));
            Assert.Empty(testClass.Subs);
            Assert.True(memberPath.Match(memberPath.Clone()));

            // 9) Add a key MyClass.Subs.Add(new MyClass())
            memberPath.Clear();
            memberPath.Push(MemberSubs);
            memberPath.Push(ListClassDesc, 0);
            Assert.True(memberPath.Apply(testClass, MemberPathAction.CollectionAdd, new MyClass()));
            Assert.Single(testClass.Subs);
            Assert.True(memberPath.Match(memberPath.Clone()));
        }
示例#56
0
        /// <summary>
        ///     Given a cell, a member and a boolean condition on that member, creates additional cell
        ///     which with the specified restriction on the member in addition to original condition.
        ///     e.i conjunction of original condition AND member in newCondition
        ///     Creation fails when the original condition contradicts new boolean condition
        ///     ViewTarget tells whether MemberPath is in Cquery or SQuery
        /// </summary>
        private bool TryCreateAdditionalCellWithCondition(
            Cell originalCell, MemberPath memberToExpand, bool conditionValue, ViewTarget viewTarget, out Cell result)
        {
            DebugCheck.NotNull(originalCell);
            DebugCheck.NotNull(memberToExpand);
            result = null;

            //Create required structures
            var leftExtent  = originalCell.GetLeftQuery(viewTarget).SourceExtentMemberPath;
            var rightExtent = originalCell.GetRightQuery(viewTarget).SourceExtentMemberPath;

            //Now for the given left-side projected member, find corresponding right-side member that it is mapped to
            var indexOfBooLMemberInProjection =
                originalCell.GetLeftQuery(viewTarget).GetProjectedMembers().TakeWhile(path => !path.Equals(memberToExpand)).Count();
            var rightConditionMemberSlot =
                ((MemberProjectedSlot)originalCell.GetRightQuery(viewTarget).ProjectedSlotAt(indexOfBooLMemberInProjection));
            var rightSidePath = rightConditionMemberSlot.MemberPath;

            var leftSlots  = new List <ProjectedSlot>();
            var rightSlots = new List <ProjectedSlot>();

            //Check for impossible conditions (otehrwise we get inaccurate pre-validation errors)
            var negatedCondition = new ScalarConstant(!conditionValue);

            if (originalCell.GetLeftQuery(viewTarget).Conditions
                .Where(restriction => restriction.RestrictedMemberSlot.MemberPath.Equals(memberToExpand))
                .Where(restriction => restriction.Domain.Values.Contains(negatedCondition)).Any() ||
                originalCell.GetRightQuery(viewTarget).Conditions
                .Where(restriction => restriction.RestrictedMemberSlot.MemberPath.Equals(rightSidePath))
                .Where(restriction => restriction.Domain.Values.Contains(negatedCondition)).Any())
            {
                return(false);
            }
            //End check

            //Create Projected Slots
            // Map all slots in original cell (not just keys) because some may be required (non nullable and no default)
            // and others may have not_null condition so MUST be projected. Rely on the user doing the right thing, otherwise
            // they will get the error message anyway
            for (var i = 0; i < originalCell.GetLeftQuery(viewTarget).NumProjectedSlots; i++)
            {
                leftSlots.Add(originalCell.GetLeftQuery(viewTarget).ProjectedSlotAt(i));
            }

            for (var i = 0; i < originalCell.GetRightQuery(viewTarget).NumProjectedSlots; i++)
            {
                rightSlots.Add(originalCell.GetRightQuery(viewTarget).ProjectedSlotAt(i));
            }

            //Create condition boolena expressions
            var leftQueryWhereClause =
                BoolExpression.CreateLiteral(new ScalarRestriction(memberToExpand, new ScalarConstant(conditionValue)), null);

            leftQueryWhereClause = BoolExpression.CreateAnd(originalCell.GetLeftQuery(viewTarget).WhereClause, leftQueryWhereClause);

            var rightQueryWhereClause =
                BoolExpression.CreateLiteral(new ScalarRestriction(rightSidePath, new ScalarConstant(conditionValue)), null);

            rightQueryWhereClause = BoolExpression.CreateAnd(originalCell.GetRightQuery(viewTarget).WhereClause, rightQueryWhereClause);

            //Create additional Cells
            var rightQuery = new CellQuery(
                rightSlots, rightQueryWhereClause, rightExtent, originalCell.GetRightQuery(viewTarget).SelectDistinctFlag);
            var leftQuery = new CellQuery(
                leftSlots, leftQueryWhereClause, leftExtent, originalCell.GetLeftQuery(viewTarget).SelectDistinctFlag);

            Cell newCell;

            if (viewTarget == ViewTarget.UpdateView)
            {
                newCell = Cell.CreateCS(rightQuery, leftQuery, originalCell.CellLabel, m_currentCellNumber);
            }
            else
            {
                newCell = Cell.CreateCS(leftQuery, rightQuery, originalCell.CellLabel, m_currentCellNumber);
            }

            m_currentCellNumber++;
            result = newCell;
            return(true);
        }
        /// <summary>
        /// Given the <paramref name="member"/> and one of its <paramref name="possibleType"/>s, determine the attributes that are relevant
        /// for this <paramref name="possibleType"/> and return a <see cref="MemberPath"/> signature corresponding to the <paramref name="possibleType"/> and the attributes.
        /// If <paramref name="needKeysOnly"/>=true, collect the key fields only.
        /// </summary>
        /// <param name="possibleType">the <paramref name="member"/>'s type or one of its subtypes</param>
        private static void GatherSignatureFromTypeStructuralMembers(MemberProjectionIndex index,
                                                                     EdmItemCollection edmItemCollection,
                                                                     MemberPath member, 
                                                                     StructuralType possibleType, 
                                                                     bool needKeysOnly)
        {
            // For each child member of this type, collect all the relevant scalar fields
            foreach (EdmMember structuralMember in Helper.GetAllStructuralMembers(possibleType))
            {
                if (MetadataHelper.IsNonRefSimpleMember(structuralMember))
                {
                    if (!needKeysOnly || MetadataHelper.IsPartOfEntityTypeKey(structuralMember))
                    {
                        MemberPath nonStructuredMember = new MemberPath(member, structuralMember);
                        // Note: scalarMember's parent has already been added to the projectedSlotMap
                        index.CreateIndex(nonStructuredMember);
                    }
                }
                else
                {
                    Debug.Assert(structuralMember.TypeUsage.EdmType is ComplexType ||
                                 structuralMember.TypeUsage.EdmType is RefType, // for association ends
                                 "Only non-scalars expected - complex types, association ends");

                    

                    MemberPath structuredMember = new MemberPath(member, structuralMember);
                    GatherPartialSignature(index, 
                                           edmItemCollection, 
                                           structuredMember,
                                           // Only keys are required for entities referenced by association ends of an association.
                                           needKeysOnly || Helper.IsAssociationEndMember(structuralMember));
                }
            }
        }
示例#58
0
        public PathMap FindOrCreatePathMapFor(LambdaExpression destinationExpression, MemberPath path, TypeMap typeMap)
        {
            var pathMap = _pathMaps.SingleOrDefault(p => p.MemberPath == path);

            if (pathMap == null)
            {
                pathMap = new PathMap(destinationExpression, path, typeMap);
                _pathMaps.Add(pathMap);
            }
            return(pathMap);
        }
 // <summary>
 // Creates a scalar member restriction with the meaning "<paramref name="member" /> in <paramref name="values" />".
 // </summary>
 internal ScalarRestriction(MemberPath member, IEnumerable<Constant> values, IEnumerable<Constant> possibleValues)
     : base(new MemberProjectedSlot(member), values, possibleValues)
 {
 }
示例#60
0
        // effects: Ensures that there is a relationship mapped into the C-space for some cell in m_cellGroup. Else
        // adds an error to errorLog
        private void GuaranteeMappedRelationshipForForeignKey(QueryRewriter childRewriter, QueryRewriter parentRewriter,
                                                              IEnumerable <Cell> cells,
                                                              ErrorLog errorLog, ConfigViewGenerator config)
        {
            ViewgenContext childContext  = childRewriter.ViewgenContext;
            ViewgenContext parentContext = parentRewriter.ViewgenContext;

            // Find a cell where this foreign key is mapped as a relationship
            MemberPath prefix     = new MemberPath(ChildTable);
            ExtentKey  primaryKey = ExtentKey.GetPrimaryKeyForEntityType(prefix, ChildTable.ElementType);
            IEnumerable <MemberPath> primaryKeyFields = primaryKey.KeyFields;
            bool foundCell = false;

            bool foundValidParentColumnsForForeignKey = false; //we need to find only one, dont error on any one check being false
            List <ErrorLog.Record> errorListForInvalidParentColumnsForForeignKey = null;

            foreach (Cell cell in cells)
            {
                if (cell.SQuery.Extent.Equals(ChildTable) == false)
                {
                    continue;
                }

                // The childtable is mapped to a relationship in the C-space in cell
                // Check that all the columns of the foreign key and the primary key in the child table are mapped to some
                // property in the C-space

                AssociationEndMember parentEnd = GetRelationEndForColumns(cell, ChildColumns);
                if (parentEnd != null && CheckParentColumnsForForeignKey(cell, cells, parentEnd, ref errorListForInvalidParentColumnsForForeignKey) == false)
                {
                    // Not an error unless we find no valid case
                    continue;
                }
                else
                {
                    foundValidParentColumnsForForeignKey = true;
                }

                AssociationEndMember childEnd = GetRelationEndForColumns(cell, primaryKeyFields);
                Debug.Assert(childEnd == null || parentEnd != childEnd,
                             "Ends are same => PKey and child columns are same - code should gone to other method");
                // Note: If both of them are not-null, they are mapped to the
                // same association set -- since we checked that particular cell

                if (childEnd != null && parentEnd != null &&
                    FindEntitySetForColumnsMappedToEntityKeys(cells, primaryKeyFields) != null)
                {
                    foundCell = true;
                    CheckConstraintWhenParentChildMapped(cell, errorLog, parentEnd, config);
                    break; // Done processing for the foreign key - either it was mapped correctly or it was not
                }
                else if (parentEnd != null)
                {
                    // At this point, we know cell corresponds to an association set
                    AssociationSet assocSet  = (AssociationSet)cell.CQuery.Extent;
                    EntitySet      parentSet = MetadataHelper.GetEntitySetAtEnd(assocSet, parentEnd);
                    foundCell = CheckConstraintWhenOnlyParentMapped(cell, parentSet, assocSet, parentEnd, childRewriter, parentRewriter, config);
                    if (foundCell)
                    {
                        break;
                    }
                }
            }

            //CheckParentColumnsForForeignKey has returned no matches, Error.
            if (!foundValidParentColumnsForForeignKey)
            {
                Debug.Assert(errorListForInvalidParentColumnsForForeignKey != null && errorListForInvalidParentColumnsForForeignKey.Count > 0);
                foreach (var errorRecord in errorListForInvalidParentColumnsForForeignKey)
                {
                    errorLog.AddEntry(errorRecord);
                }
                return;
            }

            if (foundCell == false)
            {
                // No cell found -- Declare error
                string message = System.Data.Entity.Strings.ViewGen_Foreign_Key_Missing_Relationship_Mapping(ToUserString());

                IEnumerable <LeftCellWrapper> parentWrappers     = GetWrappersFromContext(parentContext, ParentTable);
                IEnumerable <LeftCellWrapper> childWrappers      = GetWrappersFromContext(childContext, ChildTable);
                Set <LeftCellWrapper>         bothExtentWrappers =
                    new Set <LeftCellWrapper>(parentWrappers);
                bothExtentWrappers.AddRange(childWrappers);
                ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ForeignKeyMissingRelationshipMapping, message, bothExtentWrappers, String.Empty);
                errorLog.AddEntry(record);
            }
        }