private bool IsConstraintRelevantForCells(IEnumerable <Cell> cells)
        {
            bool flag = false;

            foreach (Cell cell in cells)
            {
                EntitySetBase extent = cell.SQuery.Extent;
                if (extent.Equals((object)this.m_parentTable) || extent.Equals((object)this.m_childTable))
                {
                    flag = true;
                    break;
                }
            }
            return(flag);
        }
Beispiel #2
0
        // effects: Returns true iff there is a foreign key constraint
        // between cell1 and cell2's S extents
        private bool OverlapViaForeignKeys(Cell cell1, Cell cell2)
        {
            EntitySetBase sExtent1 = cell1.SQuery.Extent;
            EntitySetBase sExtent2 = cell2.SQuery.Extent;

            foreach (ForeignConstraint constraint in m_foreignKeyConstraints)
            {
                if (sExtent1.Equals(constraint.ParentTable) && sExtent2.Equals(constraint.ChildTable) ||
                    sExtent2.Equals(constraint.ParentTable) && sExtent1.Equals(constraint.ChildTable))
                {
                    return(true);
                }
            }
            return(false);
        }
        // effects: Returns true iff some cell in this refers to the
        // constraint's parent table or child table
        private bool IsConstraintRelevantForCells(IEnumerable <Cell> cells)
        {
            // if the constraint does not deal with any cell in this group,
            // return false
            bool found = false;

            foreach (Cell cell in cells)
            {
                EntitySetBase table = cell.SQuery.Extent;
                if (table.Equals(m_parentTable) || table.Equals(m_childTable))
                {
                    found = true;
                    break;
                }
            }
            return(found);
        }
Beispiel #4
0
        // effects: Given a list of cells, segments them into multiple
        // "groups" such that view generation (including validation) of one
        // group can be done independently of another group. Returns the
        // groups as a list (uses the foreign key information as well)
        internal List <CellGroup> GroupRelatedCells()
        {
            // If two cells share the same C or S, we place them in the same group
            // For each cell, determine the Cis and Sis that it refers
            // to. For every Ci (Si), keep track of the cells that Ci is
            // contained in. At the end, run through the Cis and Sis and do a
            // "connected components" algorithm to determine partitions

            // Now form a graph between different cells -- then compute the connected
            // components in it
            UndirectedGraph <Cell> graph = new UndirectedGraph <Cell>(EqualityComparer <Cell> .Default);

            List <Cell> alreadyAddedCells = new List <Cell>();

            // For each extent, add an edge between it and all previously
            // added extents with which it overlaps

            foreach (Cell cell in m_cells)
            {
                graph.AddVertex(cell);
                // Add an edge from this cell to the already added cells
                EntitySetBase firstCExtent = cell.CQuery.Extent;
                EntitySetBase firstSExtent = cell.SQuery.Extent;
                foreach (Cell existingCell in alreadyAddedCells)
                {
                    EntitySetBase secondCExtent = existingCell.CQuery.Extent;
                    EntitySetBase secondSExtent = existingCell.SQuery.Extent;

                    // Add an edge between cell and existingCell if
                    // * They have the same C or S extent
                    // * They are linked via a foreign key between the S extents
                    // * They are linked via a relationship
                    bool sameExtent          = secondCExtent.Equals(firstCExtent) || secondSExtent.Equals(firstSExtent);
                    bool linkViaForeignKey   = OverlapViaForeignKeys(cell, existingCell);
                    bool linkViaRelationship = AreCellsConnectedViaRelationship(cell, existingCell);

                    if (sameExtent || linkViaForeignKey || linkViaRelationship)
                    {
                        graph.AddEdge(existingCell, cell);
                    }
                }
                alreadyAddedCells.Add(cell);
            }

            // Now determine the connected components of this graph
            List <CellGroup> result = GenerateConnectedComponents(graph);

            return(result);
        }
        internal ViewgenContext(
            ViewTarget viewTarget, EntitySetBase extent, IList <Cell> extentCells,
            CqlIdentifiers identifiers, ConfigViewGenerator config, MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap, StorageEntityContainerMapping entityContainerMapping)
        {
            foreach (var cell in extentCells)
            {
                Debug.Assert(extent.Equals(cell.GetLeftQuery(viewTarget).Extent));
                Debug.Assert(cell.CQuery.NumProjectedSlots == cell.SQuery.NumProjectedSlots);
            }

            m_extent                 = extent;
            m_viewTarget             = viewTarget;
            m_config                 = config;
            m_edmItemCollection      = entityContainerMapping.StorageMappingItemCollection.EdmItemCollection;
            m_entityContainerMapping = entityContainerMapping;
            m_identifiers            = identifiers;

            // create a copy of updateDomainMap so generation of query views later on is not affected
            // it is modified in QueryRewriter.AdjustMemberDomainsForUpdateViews
            updateDomainMap = updateDomainMap.MakeCopy();

            // Create a signature generator that handles all the
            // multiconstant work and generating the signatures
            var domainMap = viewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap;

            m_memberMaps = new MemberMaps(
                viewTarget, MemberProjectionIndex.Create(extent, m_edmItemCollection), queryDomainMap, updateDomainMap);

            // Create left fragment KB: includes constraints for the extent to be constructed
            var leftKB = new FragmentQueryKBChaseSupport();

            leftKB.CreateVariableConstraints(extent, domainMap, m_edmItemCollection);
            m_leftFragmentQP = new FragmentQueryProcessor(leftKB);
            m_rewritingCache = new Dictionary <FragmentQuery, Tile <FragmentQuery> >(
                FragmentQuery.GetEqualityComparer(m_leftFragmentQP));

            // Now using the signatures, create new cells such that
            // "extent's" query (C or S) is described in terms of multiconstants
            if (!CreateLeftCellWrappers(extentCells, viewTarget))
            {
                return;
            }

            // Create right fragment KB: includes constraints for all extents and association roles of right queries
            var rightKB        = new FragmentQueryKBChaseSupport();
            var rightDomainMap = viewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap;

            foreach (var leftCellWrapper in m_cellWrappers)
            {
                var rightExtent = leftCellWrapper.RightExtent;
                rightKB.CreateVariableConstraints(rightExtent, rightDomainMap, m_edmItemCollection);
                rightKB.CreateAssociationConstraints(rightExtent, rightDomainMap, m_edmItemCollection);
            }

            if (m_viewTarget == ViewTarget.UpdateView)
            {
                CreateConstraintsForForeignKeyAssociationsAffectingThisWrapper(rightKB, rightDomainMap);
            }

            m_rightFragmentQP = new FragmentQueryProcessor(rightKB);

            // Check for concurrency control tokens
            if (m_viewTarget == ViewTarget.QueryView)
            {
                CheckConcurrencyControlTokens();
            }
            // For backward compatibility -
            // order wrappers by increasing domain size, decreasing number of attributes
            m_cellWrappers.Sort(LeftCellWrapper.Comparer);
        }