Beispiel #1
0
        // <summary>
        // Creates generated view object for the combination of the <paramref name="extent" /> and the <paramref name="type" />.
        // This constructor is used for regular cell-based view generation.
        // </summary>
        internal static GeneratedView CreateGeneratedView(
            EntitySetBase extent,
            EdmType type,
            DbQueryCommandTree commandTree,
            string eSQL,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config)
        {
            // If config.GenerateEsql is specified, eSQL must be non-null.
            // If config.GenerateEsql is false, commandTree is non-null except the case when loading pre-compiled eSQL views.
            Debug.Assert(!config.GenerateEsql || !String.IsNullOrEmpty(eSQL), "eSQL must be specified");

            DiscriminatorMap discriminatorMap = null;

            if (commandTree != null)
            {
                commandTree = ViewSimplifier.SimplifyView(extent, commandTree);

                // See if the view matches the "discriminated" pattern (allows simplification of generated store commands)
                if (extent.BuiltInTypeKind
                    == BuiltInTypeKind.EntitySet)
                {
                    if (DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap))
                    {
                        Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created");
                    }
                }
            }

            return(new GeneratedView(extent, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config));
        }
Beispiel #2
0
        private GeneratedView(
            EntitySetBase extent,
            EdmType type,
            DbQueryCommandTree commandTree,
            string eSQL,
            DiscriminatorMap discriminatorMap,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config)
        {
            // At least one of the commandTree or eSQL must be specified.
            // Both are specified in the case of user-defined views.
            Debug.Assert(commandTree != null || !String.IsNullOrEmpty(eSQL), "commandTree or eSQL must be specified");

            m_extent                = extent;
            m_type                  = type;
            m_commandTree           = commandTree;
            m_eSQL                  = eSQL;
            m_discriminatorMap      = discriminatorMap;
            m_mappingItemCollection = mappingItemCollection;
            m_config                = config;

            if (m_config.IsViewTracing)
            {
                var trace = new StringBuilder(1024);
                ToCompactString(trace);
                Helpers.FormatTraceLine("CQL view for {0}", trace.ToString());
            }
        }
        /// <summary>
        ///     Creates generated view object for the combination of the <paramref name="extent" /> and the <paramref name="type" />.
        ///     This constructor is used for regular cell-based view generation.
        /// </summary>
        internal static GeneratedView CreateGeneratedView(
            EntitySetBase extent,
            EdmType type,
            DbQueryCommandTree commandTree,
            string eSQL,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config)
        {
            // If config.GenerateEsql is specified, eSQL must be non-null.
            // If config.GenerateEsql is false, commandTree is non-null except the case when loading pre-compiled eSQL views.
            Debug.Assert(!config.GenerateEsql || !String.IsNullOrEmpty(eSQL), "eSQL must be specified");

            DiscriminatorMap discriminatorMap = null;
            if (commandTree != null)
            {
                commandTree = ViewSimplifier.SimplifyView(extent, commandTree);

                // See if the view matches the "discriminated" pattern (allows simplification of generated store commands)
                if (extent.BuiltInTypeKind
                    == BuiltInTypeKind.EntitySet)
                {
                    if (DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap))
                    {
                        Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created");
                    }
                }
            }

            return new GeneratedView(extent, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config);
        }
Beispiel #4
0
        internal ViewGenerator(
            Set <Cell> cellGroup,
            ConfigViewGenerator config,
            List <ForeignConstraint> foreignKeyConstraints,
            EntityContainerMapping entityContainerMapping)
        {
            this.m_cellGroup              = cellGroup;
            this.m_config                 = config;
            this.m_queryRewriterCache     = new Dictionary <EntitySetBase, QueryRewriter>();
            this.m_foreignKeyConstraints  = foreignKeyConstraints;
            this.m_entityContainerMapping = entityContainerMapping;
            Dictionary <EntityType, Set <EntityType> > inheritanceGraph = MetadataHelper.BuildUndirectedGraphOfTypes(entityContainerMapping.StorageMappingItemCollection.EdmItemCollection);

            this.SetConfiguration(entityContainerMapping);
            this.m_queryDomainMap  = new MemberDomainMap(ViewTarget.QueryView, this.m_config.IsValidationEnabled, (IEnumerable <Cell>)cellGroup, entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, this.m_config, inheritanceGraph);
            this.m_updateDomainMap = new MemberDomainMap(ViewTarget.UpdateView, this.m_config.IsValidationEnabled, (IEnumerable <Cell>)cellGroup, entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, this.m_config, inheritanceGraph);
            MemberDomainMap.PropagateUpdateDomainToQueryDomain((IEnumerable <Cell>)cellGroup, this.m_queryDomainMap, this.m_updateDomainMap);
            ViewGenerator.UpdateWhereClauseForEachCell((IEnumerable <Cell>)cellGroup, this.m_queryDomainMap, this.m_updateDomainMap, this.m_config);
            MemberDomainMap openDomain1 = this.m_queryDomainMap.GetOpenDomain();
            MemberDomainMap openDomain2 = this.m_updateDomainMap.GetOpenDomain();

            foreach (Cell cell in cellGroup)
            {
                cell.CQuery.WhereClause.FixDomainMap(openDomain1);
                cell.SQuery.WhereClause.FixDomainMap(openDomain2);
                cell.CQuery.WhereClause.ExpensiveSimplify();
                cell.SQuery.WhereClause.ExpensiveSimplify();
                cell.CQuery.WhereClause.FixDomainMap(this.m_queryDomainMap);
                cell.SQuery.WhereClause.FixDomainMap(this.m_updateDomainMap);
            }
        }
Beispiel #5
0
        private GeneratedView(
            EntitySetBase extent,
            EdmType type,
            DbQueryCommandTree commandTree,
            string eSQL,
            DiscriminatorMap discriminatorMap,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config)
        {
            this.m_extent                = extent;
            this.m_type                  = type;
            this.m_commandTree           = commandTree;
            this.m_eSQL                  = eSQL;
            this.m_discriminatorMap      = discriminatorMap;
            this.m_mappingItemCollection = mappingItemCollection;
            this.m_config                = config;
            if (!this.m_config.IsViewTracing)
            {
                return;
            }
            StringBuilder builder = new StringBuilder(1024);

            this.ToCompactString(builder);
            Helpers.FormatTraceLine("CQL view for {0}", (object)builder.ToString());
        }
 /// <summary>
 ///     Creates generated view object for the combination of the <paramref name="extent" /> and the <paramref name="type" />.
 ///     This constructor is used for FK association sets only.
 /// </summary>
 internal static GeneratedView CreateGeneratedViewForFKAssociationSet(
     EntitySetBase extent,
     EdmType type,
     DbQueryCommandTree commandTree,
     StorageMappingItemCollection mappingItemCollection,
     ConfigViewGenerator config)
 {
     return new GeneratedView(extent, type, commandTree, null, null, mappingItemCollection, config);
 }
Beispiel #7
0
 // <summary>
 // Creates generated view object for the combination of the <paramref name="extent" /> and the <paramref name="type" />.
 // This constructor is used for FK association sets only.
 // </summary>
 internal static GeneratedView CreateGeneratedViewForFKAssociationSet(
     EntitySetBase extent,
     EdmType type,
     DbQueryCommandTree commandTree,
     StorageMappingItemCollection mappingItemCollection,
     ConfigViewGenerator config)
 {
     return(new GeneratedView(extent, type, commandTree, null, null, mappingItemCollection, config));
 }
        internal static ViewGenResults GenerateViewsFromMapping(
            EntityContainerMapping containerMapping,
            ConfigViewGenerator config)
        {
            CellCreator    cellCreator = new CellCreator(containerMapping);
            List <Cell>    cells       = cellCreator.GenerateCells();
            CqlIdentifiers identifiers = cellCreator.Identifiers;

            return(ViewgenGatekeeper.GenerateViewsFromCells(cells, config, identifiers, containerMapping));
        }
        internal ViewgenContext(
            ViewTarget viewTarget,
            EntitySetBase extent,
            IList <Cell> extentCells,
            CqlIdentifiers identifiers,
            ConfigViewGenerator config,
            MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap,
            EntityContainerMapping entityContainerMapping)
        {
            foreach (Cell extentCell in (IEnumerable <Cell>)extentCells)
            {
                ;
            }
            this.m_extent                 = extent;
            this.m_viewTarget             = viewTarget;
            this.m_config                 = config;
            this.m_edmItemCollection      = entityContainerMapping.StorageMappingItemCollection.EdmItemCollection;
            this.m_entityContainerMapping = entityContainerMapping;
            this.m_identifiers            = identifiers;
            updateDomainMap               = updateDomainMap.MakeCopy();
            MemberDomainMap domainMap = viewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap;

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

            kb1.CreateVariableConstraints(extent, domainMap, this.m_edmItemCollection);
            this.m_leftFragmentQP = new FragmentQueryProcessor(kb1);
            this.m_rewritingCache = new Dictionary <FragmentQuery, Tile <FragmentQuery> >(FragmentQuery.GetEqualityComparer(this.m_leftFragmentQP));
            if (!this.CreateLeftCellWrappers(extentCells, viewTarget))
            {
                return;
            }
            FragmentQueryKBChaseSupport kb2             = new FragmentQueryKBChaseSupport();
            MemberDomainMap             memberDomainMap = viewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap;

            foreach (LeftCellWrapper cellWrapper in this.m_cellWrappers)
            {
                EntitySetBase rightExtent = cellWrapper.RightExtent;
                kb2.CreateVariableConstraints(rightExtent, memberDomainMap, this.m_edmItemCollection);
                kb2.CreateAssociationConstraints(rightExtent, memberDomainMap, this.m_edmItemCollection);
            }
            if (this.m_viewTarget == ViewTarget.UpdateView)
            {
                this.CreateConstraintsForForeignKeyAssociationsAffectingThisWrapper((FragmentQueryKB)kb2, memberDomainMap);
            }
            this.m_rightFragmentQP = new FragmentQueryProcessor(kb2);
            if (this.m_viewTarget == ViewTarget.QueryView)
            {
                this.CheckConcurrencyControlTokens();
            }
            this.m_cellWrappers.Sort(LeftCellWrapper.Comparer);
        }
 // effects: Creates a view generator object that can be used to generate views
 // based on usedCells (projectedSlotMap are useful for deciphering the fields)
 internal BasicViewGenerator(
     MemberProjectionIndex projectedSlotMap, List<LeftCellWrapper> usedCells, FragmentQuery activeDomain,
     ViewgenContext context, MemberDomainMap domainMap, ErrorLog errorLog, ConfigViewGenerator config)
 {
     Debug.Assert(usedCells.Count > 0, "No used cells");
     m_projectedSlotMap = projectedSlotMap;
     m_usedCells = usedCells;
     m_viewgenContext = context;
     m_activeDomain = activeDomain;
     m_errorLog = errorLog;
     m_config = config;
     m_domainMap = domainMap;
 }
Beispiel #11
0
 // effects: Creates a view generator object that can be used to generate views
 // based on usedCells (projectedSlotMap are useful for deciphering the fields)
 internal BasicViewGenerator(
     MemberProjectionIndex projectedSlotMap, List <LeftCellWrapper> usedCells, FragmentQuery activeDomain,
     ViewgenContext context, MemberDomainMap domainMap, ErrorLog errorLog, ConfigViewGenerator config)
 {
     Debug.Assert(usedCells.Count > 0, "No used cells");
     m_projectedSlotMap = projectedSlotMap;
     m_usedCells        = usedCells;
     m_viewgenContext   = context;
     m_activeDomain     = activeDomain;
     m_errorLog         = errorLog;
     m_config           = config;
     m_domainMap        = domainMap;
 }
        /// <summary>
        ///     Entry point for View Generation
        /// </summary>
        /// <param name="containerMapping"> </param>
        /// <param name="workSpace"> </param>
        /// <param name="config"> </param>
        /// <returns> Generated Views for EntitySets </returns>
        internal static ViewGenResults GenerateViewsFromMapping(StorageEntityContainerMapping containerMapping, ConfigViewGenerator config)
        {
            DebugCheck.NotNull(containerMapping);
            DebugCheck.NotNull(config);
            Debug.Assert(containerMapping.HasViews, "Precondition Violated: No mapping exists to generate views for!");

            //Create Cells from StorageEntityContainerMapping
            var cellCreator = new CellCreator(containerMapping);
            var cells = cellCreator.GenerateCells();
            var identifiers = cellCreator.Identifiers;

            return GenerateViewsFromCells(cells, config, identifiers, containerMapping);
        }
Beispiel #13
0
 private static void UpdateWhereClauseForEachCell(
     IEnumerable <Cell> extentCells,
     MemberDomainMap queryDomainMap,
     MemberDomainMap updateDomainMap,
     ConfigViewGenerator config)
 {
     foreach (Cell extentCell in extentCells)
     {
         extentCell.CQuery.UpdateWhereClause(queryDomainMap);
         extentCell.SQuery.UpdateWhereClause(updateDomainMap);
     }
     queryDomainMap.ReduceEnumerableDomainToEnumeratedValues(config);
     updateDomainMap.ReduceEnumerableDomainToEnumeratedValues(config);
 }
Beispiel #14
0
        // effects: Creates a ViewGenerator object that is capable of
        // producing query or update mapping views given the relevant schema
        // given the "cells"
        internal ViewGenerator(
            CellGroup cellGroup, ConfigViewGenerator config,
            List <ForeignConstraint> foreignKeyConstraints,
            EntityContainerMapping entityContainerMapping)
        {
            m_cellGroup              = cellGroup;
            m_config                 = config;
            m_queryRewriterCache     = new Dictionary <EntitySetBase, QueryRewriter>();
            m_foreignKeyConstraints  = foreignKeyConstraints;
            m_entityContainerMapping = entityContainerMapping;

            var inheritanceGraph =
                MetadataHelper.BuildUndirectedGraphOfTypes(entityContainerMapping.StorageMappingItemCollection.EdmItemCollection);

            SetConfiguration(entityContainerMapping);

            // We fix all the cells at this point
            m_queryDomainMap = new MemberDomainMap(
                ViewTarget.QueryView, m_config.IsValidationEnabled, cellGroup,
                entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, m_config, inheritanceGraph);
            m_updateDomainMap = new MemberDomainMap(
                ViewTarget.UpdateView, m_config.IsValidationEnabled, cellGroup,
                entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, m_config, inheritanceGraph);

            // We now go and fix the queryDomain map so that it has all the
            // values from the S-side as well -- this is needed for domain
            // constraint propagation, i.e., values from the S-side get
            // propagated to te oneOfConst on the C-side. So we better get
            // the "possibleValues" stuff to contain those constants as well
            MemberDomainMap.PropagateUpdateDomainToQueryDomain(cellGroup, m_queryDomainMap, m_updateDomainMap);

            UpdateWhereClauseForEachCell(cellGroup, m_queryDomainMap, m_updateDomainMap, m_config);

            // We need to simplify cell queries, yet we don't want the conditions to disappear
            // So, add an extra value to the domain, temporarily
            var queryOpenDomain  = m_queryDomainMap.GetOpenDomain();
            var updateOpenDomain = m_updateDomainMap.GetOpenDomain();

            // Make sure the WHERE clauses of the cells reflect the changes
            foreach (var cell in cellGroup)
            {
                cell.CQuery.WhereClause.FixDomainMap(queryOpenDomain);
                cell.SQuery.WhereClause.FixDomainMap(updateOpenDomain);
                cell.CQuery.WhereClause.ExpensiveSimplify();
                cell.SQuery.WhereClause.ExpensiveSimplify();
                cell.CQuery.WhereClause.FixDomainMap(m_queryDomainMap);
                cell.SQuery.WhereClause.FixDomainMap(m_updateDomainMap);
            }
        }
Beispiel #15
0
        // effects: Given the extent cells and a map for the domains of all
        // variables in it, fixes the cell constant domains of the where
        // clauses in the left queries of cells (left is defined using viewTarget)
        private static void UpdateWhereClauseForEachCell(
            IEnumerable <Cell> extentCells, MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap, ConfigViewGenerator config)
        {
            foreach (var cell in extentCells)
            {
                cell.CQuery.UpdateWhereClause(queryDomainMap);
                cell.SQuery.UpdateWhereClause(updateDomainMap);
            }

            // Fix enumerable domains - currently it is only applicable to boolean type. Note that it is
            // not applicable to enumerated types since we allow any value of the underlying type of the enum type.
            queryDomainMap.ReduceEnumerableDomainToEnumeratedValues(config);
            updateDomainMap.ReduceEnumerableDomainToEnumeratedValues(config);
        }
Beispiel #16
0
        // effects: Creates a ViewGenerator object that is capable of
        // producing query or update mapping views given the relevant schema
        // given the "cells"
        internal ViewGenerator(
            CellGroup cellGroup, ConfigViewGenerator config,
            List<ForeignConstraint> foreignKeyConstraints,
            StorageEntityContainerMapping entityContainerMapping)
        {
            m_cellGroup = cellGroup;
            m_config = config;
            m_queryRewriterCache = new Dictionary<EntitySetBase, QueryRewriter>();
            m_foreignKeyConstraints = foreignKeyConstraints;
            m_entityContainerMapping = entityContainerMapping;

            var inheritanceGraph =
                MetadataHelper.BuildUndirectedGraphOfTypes(entityContainerMapping.StorageMappingItemCollection.EdmItemCollection);
            SetConfiguration(entityContainerMapping);

            // We fix all the cells at this point
            m_queryDomainMap = new MemberDomainMap(
                ViewTarget.QueryView, m_config.IsValidationEnabled, cellGroup,
                entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, m_config, inheritanceGraph);
            m_updateDomainMap = new MemberDomainMap(
                ViewTarget.UpdateView, m_config.IsValidationEnabled, cellGroup,
                entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, m_config, inheritanceGraph);

            // We now go and fix the queryDomain map so that it has all the
            // values from the S-side as well -- this is needed for domain
            // constraint propagation, i.e., values from the S-side get
            // propagated to te oneOfConst on the C-side. So we better get
            // the "possiblveValues" stuff to contain those constants as well
            MemberDomainMap.PropagateUpdateDomainToQueryDomain(cellGroup, m_queryDomainMap, m_updateDomainMap);

            UpdateWhereClauseForEachCell(cellGroup, m_queryDomainMap, m_updateDomainMap, m_config);

            // We need to simplify cell queries, yet we don't want the conditions to disappear
            // So, add an extra value to the domain, temporarily
            var queryOpenDomain = m_queryDomainMap.GetOpenDomain();
            var updateOpenDomain = m_updateDomainMap.GetOpenDomain();

            // Make sure the WHERE clauses of the cells reflect the changes
            foreach (var cell in cellGroup)
            {
                cell.CQuery.WhereClause.FixDomainMap(queryOpenDomain);
                cell.SQuery.WhereClause.FixDomainMap(updateOpenDomain);
                cell.CQuery.WhereClause.ExpensiveSimplify();
                cell.SQuery.WhereClause.ExpensiveSimplify();
                cell.CQuery.WhereClause.FixDomainMap(m_queryDomainMap);
                cell.SQuery.WhereClause.FixDomainMap(m_updateDomainMap);
            }
        }
 internal BasicViewGenerator(
     MemberProjectionIndex projectedSlotMap,
     List <LeftCellWrapper> usedCells,
     FragmentQuery activeDomain,
     ViewgenContext context,
     MemberDomainMap domainMap,
     ErrorLog errorLog,
     ConfigViewGenerator config)
 {
     this.m_projectedSlotMap = projectedSlotMap;
     this.m_usedCells        = usedCells;
     this.m_viewgenContext   = context;
     this.m_activeDomain     = activeDomain;
     this.m_errorLog         = errorLog;
     this.m_config           = config;
     this.m_domainMap        = domainMap;
 }
Beispiel #18
0
 private static bool TryParseView(
     string eSQL,
     bool isUserSpecified,
     EntitySetBase extent,
     StorageMappingItemCollection mappingItemCollection,
     ConfigViewGenerator config,
     out DbQueryCommandTree commandTree,
     out DiscriminatorMap discriminatorMap,
     out Exception parserException)
 {
     commandTree      = (DbQueryCommandTree)null;
     discriminatorMap = (DiscriminatorMap)null;
     parserException  = (Exception)null;
     config.StartSingleWatch(PerfType.ViewParsing);
     try
     {
         ParserOptions.CompilationMode compilationMode = ParserOptions.CompilationMode.RestrictedViewGenerationMode;
         if (isUserSpecified)
         {
             compilationMode = ParserOptions.CompilationMode.UserViewGenerationMode;
         }
         commandTree = (DbQueryCommandTree)ExternalCalls.CompileView(eSQL, mappingItemCollection, compilationMode);
         commandTree = ViewSimplifier.SimplifyView(extent, commandTree);
         if (extent.BuiltInTypeKind == BuiltInTypeKind.EntitySet)
         {
             DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap);
         }
     }
     catch (Exception ex)
     {
         if (ex.IsCatchableExceptionType())
         {
             parserException = ex;
         }
         else
         {
             throw;
         }
     }
     finally
     {
         config.StopSingleWatch(PerfType.ViewParsing);
     }
     return(parserException == null);
 }
Beispiel #19
0
        internal static bool TryParseUserSpecifiedView(
            EntitySetBaseMapping setMapping,
            EntityTypeBase type,
            string eSQL,
            bool includeSubtypes,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config,
            IList <EdmSchemaError> errors,
            out GeneratedView generatedView)
        {
            bool flag = false;
            DbQueryCommandTree commandTree;
            DiscriminatorMap   discriminatorMap;
            Exception          parserException;

            if (!GeneratedView.TryParseView(eSQL, true, setMapping.Set, mappingItemCollection, config, out commandTree, out discriminatorMap, out parserException))
            {
                EdmSchemaError edmSchemaError = new EdmSchemaError(Strings.Mapping_Invalid_QueryView2((object)setMapping.Set.Name, (object)parserException.Message), 2068, EdmSchemaErrorSeverity.Error, setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition, parserException);
                errors.Add(edmSchemaError);
                flag = true;
            }
            else
            {
                foreach (EdmSchemaError edmSchemaError in ViewValidator.ValidateQueryView(commandTree, setMapping, type, includeSubtypes))
                {
                    errors.Add(edmSchemaError);
                    flag = true;
                }
                CollectionType edmType = commandTree.Query.ResultType.EdmType as CollectionType;
                if (edmType == null || !setMapping.Set.ElementType.IsAssignableFrom(edmType.TypeUsage.EdmType))
                {
                    EdmSchemaError edmSchemaError = new EdmSchemaError(Strings.Mapping_Invalid_QueryView_Type((object)setMapping.Set.Name), 2069, EdmSchemaErrorSeverity.Error, setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition);
                    errors.Add(edmSchemaError);
                    flag = true;
                }
            }
            if (!flag)
            {
                generatedView = new GeneratedView(setMapping.Set, (EdmType)type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config);
                return(true);
            }
            generatedView = (GeneratedView)null;
            return(false);
        }
        /// <summary>
        /// Entry point for View Generation
        /// </summary>
        /// <param name="containerMapping"></param>
        /// <param name="workSpace"></param>
        /// <param name="config"></param>
        /// <returns>Generated Views for EntitySets</returns>
        internal static ViewGenResults GenerateViewsFromMapping(StorageEntityContainerMapping containerMapping, ConfigViewGenerator config)
        {
            Contract.Requires(containerMapping != null);
            Contract.Requires(config != null);
            Debug.Assert(containerMapping.HasViews, "Precondition Violated: No mapping exists to generate views for!");

#if DEBUG
            if (config.IsNormalTracing)
            {
                containerMapping.Print(0);
            }
#endif

            //Create Cells from StorageEntityContainerMapping
            var cellCreator = new CellCreator(containerMapping);
            var cells = cellCreator.GenerateCells();
            var identifiers = cellCreator.Identifiers;

            return GenerateViewsFromCells(cells, config, identifiers, containerMapping);
        }
Beispiel #21
0
        internal static GeneratedView CreateGeneratedView(
            EntitySetBase extent,
            EdmType type,
            DbQueryCommandTree commandTree,
            string eSQL,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config)
        {
            DiscriminatorMap discriminatorMap = (DiscriminatorMap)null;

            if (commandTree != null)
            {
                commandTree = ViewSimplifier.SimplifyView(extent, commandTree);
                if (extent.BuiltInTypeKind == BuiltInTypeKind.EntitySet)
                {
                    DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap);
                }
            }
            return(new GeneratedView(extent, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config));
        }
        private static ViewGenResults GenerateViewsFromCells(
            List <Cell> cells,
            ConfigViewGenerator config,
            CqlIdentifiers identifiers,
            EntityContainerMapping containerMapping)
        {
            EntityContainer storageEntityContainer = containerMapping.StorageEntityContainer;
            ViewGenResults  viewGenResults         = new ViewGenResults();
            ErrorLog        errorLog1 = ViewgenGatekeeper.EnsureAllCSpaceContainerSetsAreMapped((IEnumerable <Cell>)cells, containerMapping);

            if (errorLog1.Count > 0)
            {
                viewGenResults.AddErrors(errorLog1);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                return(viewGenResults);
            }
            List <ForeignConstraint> foreignConstraints = ForeignConstraint.GetForeignConstraints(storageEntityContainer);

            foreach (Set <Cell> groupRelatedCell in new CellPartitioner((IEnumerable <Cell>)cells, (IEnumerable <ForeignConstraint>)foreignConstraints).GroupRelatedCells())
            {
                ViewGenerator viewGenerator = (ViewGenerator)null;
                ErrorLog      errorLog2     = new ErrorLog();
                try
                {
                    viewGenerator = new ViewGenerator(groupRelatedCell, config, foreignConstraints, containerMapping);
                }
                catch (InternalMappingException ex)
                {
                    errorLog2 = ex.ErrorLog;
                }
                if (errorLog2.Count == 0)
                {
                    errorLog2 = viewGenerator.GenerateAllBidirectionalViews(viewGenResults.Views, identifiers);
                }
                if (errorLog2.Count != 0)
                {
                    viewGenResults.AddErrors(errorLog2);
                }
            }
            return(viewGenResults);
        }
        private GeneratedView(
            EntitySetBase extent,
            EdmType type,
            DbQueryCommandTree commandTree,
            string eSQL,
            DiscriminatorMap discriminatorMap,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config)
        {
            // At least one of the commandTree or eSQL must be specified. 
            // Both are specified in the case of user-defined views.
            Debug.Assert(commandTree != null || !String.IsNullOrEmpty(eSQL), "commandTree or eSQL must be specified");

            m_extent = extent;
            m_type = type;
            m_commandTree = commandTree;
            m_eSQL = eSQL;
            m_discriminatorMap = discriminatorMap;
            m_mappingItemCollection = mappingItemCollection;
            m_config = config;

            if (m_config.IsViewTracing)
            {
                var trace = new StringBuilder(1024);
                ToCompactString(trace);
                Helpers.FormatTraceLine("CQL view for {0}", trace.ToString());
            }
        }
        /// <summary>
        ///     Given an extent and its corresponding view, invokes the parser to check if the view definition is syntactically correct.
        ///     Iff parsing succeeds: <paramref name="commandTree" /> and <paramref name="discriminatorMap" /> are set to the parse result and method returns true,
        ///     otherwise if parser has thrown a catchable exception, it is returned via <paramref name="parserException" /> parameter,
        ///     otherwise exception is re-thrown.
        /// </summary>
        private static bool TryParseView(
            string eSQL,
            bool isUserSpecified,
            EntitySetBase extent,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config,
            out DbQueryCommandTree commandTree,
            out DiscriminatorMap discriminatorMap,
            out Exception parserException)
        {
            commandTree = null;
            discriminatorMap = null;
            parserException = null;

            // We do not catch any internal exceptions any more
            config.StartSingleWatch(PerfType.ViewParsing);
            try
            {
                // If it is a user specified view, allow all queries. Otherwise parse the view in the restricted mode.
                var compilationMode = ParserOptions.CompilationMode.RestrictedViewGenerationMode;
                if (isUserSpecified)
                {
                    compilationMode = ParserOptions.CompilationMode.UserViewGenerationMode;
                }

                Debug.Assert(!String.IsNullOrEmpty(eSQL), "eSQL query is not specified");
                commandTree = (DbQueryCommandTree)ExternalCalls.CompileView(eSQL, mappingItemCollection, compilationMode);

                // For non user-specified views, perform simplification.
                if (!isUserSpecified)
                {
                    commandTree = ViewSimplifier.SimplifyView(extent, commandTree);
                }

                // See if the view matches the "discriminated" pattern (allows simplification of generated store commands)
                if (extent.BuiltInTypeKind
                    == BuiltInTypeKind.EntitySet)
                {
                    if (DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap))
                    {
                        Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created");
                    }
                }
            }
            catch (Exception e)
            {
                // Catching all the exception types since Query parser seems to be throwing veriety of
                // exceptions - EntityException, ArgumentException, ArgumentNullException etc.
                if (e.IsCatchableExceptionType())
                {
                    parserException = e;
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                config.StopSingleWatch(PerfType.ViewParsing);
            }

            Debug.Assert(commandTree != null || parserException != null, "Either commandTree or parserException is expected.");
            // Note: m_commandTree might have been initialized by a previous call to this method, so in consequent calls it might occur that
            // both m_commandTree and parserException are not null - this would mean that the last parse attempt failed, but m_commandTree value is 
            // preserved from the previous call.

            return parserException == null;
        }
Beispiel #25
0
        // <summary>
        // Given an extent and its corresponding view, invokes the parser to check if the view definition is syntactically correct.
        // Iff parsing succeeds: <paramref name="commandTree" /> and <paramref name="discriminatorMap" /> are set to the parse result and method returns true,
        // otherwise if parser has thrown a catchable exception, it is returned via <paramref name="parserException" /> parameter,
        // otherwise exception is re-thrown.
        // </summary>
        private static bool TryParseView(
            string eSQL,
            bool isUserSpecified,
            EntitySetBase extent,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config,
            out DbQueryCommandTree commandTree,
            out DiscriminatorMap discriminatorMap,
            out Exception parserException)
        {
            commandTree      = null;
            discriminatorMap = null;
            parserException  = null;

            // We do not catch any internal exceptions any more
            config.StartSingleWatch(PerfType.ViewParsing);
            try
            {
                // If it is a user specified view, allow all queries. Otherwise parse the view in the restricted mode.
                var compilationMode = ParserOptions.CompilationMode.RestrictedViewGenerationMode;
                if (isUserSpecified)
                {
                    compilationMode = ParserOptions.CompilationMode.UserViewGenerationMode;
                }

                Debug.Assert(!String.IsNullOrEmpty(eSQL), "eSQL query is not specified");
                commandTree = (DbQueryCommandTree)ExternalCalls.CompileView(eSQL, mappingItemCollection, compilationMode);

                commandTree = ViewSimplifier.SimplifyView(extent, commandTree);

                // See if the view matches the "discriminated" pattern (allows simplification of generated store commands)
                if (extent.BuiltInTypeKind
                    == BuiltInTypeKind.EntitySet)
                {
                    if (DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap))
                    {
                        Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created");
                    }
                }
            }
            catch (Exception e)
            {
                // Catching all the exception types since Query parser seems to be throwing a variety of
                // exceptions - EntityException, ArgumentException, ArgumentNullException etc.
                if (e.IsCatchableExceptionType())
                {
                    parserException = e;
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                config.StopSingleWatch(PerfType.ViewParsing);
            }

            Debug.Assert(commandTree != null || parserException != null, "Either commandTree or parserException is expected.");
            // Note: m_commandTree might have been initialized by a previous call to this method, so in consequent calls it might occur that
            // both m_commandTree and parserException are not null - this would mean that the last parse attempt failed, but m_commandTree value is
            // preserved from the previous call.

            return(parserException == null);
        }
        /// <summary>
        ///     Creates generated view object for the combination of the <paramref name="setMapping" />.Set and the
        ///     <paramref
        ///         name="type" />
        ///     .
        ///     This constructor is used for user-defined query views only.
        /// </summary>
        internal static bool TryParseUserSpecifiedView(
            StorageSetMapping setMapping,
            EntityTypeBase type,
            string eSQL,
            bool includeSubtypes,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config,
            /*out*/ IList<EdmSchemaError> errors,
            out GeneratedView generatedView)
        {
            var failed = false;

            DbQueryCommandTree commandTree;
            DiscriminatorMap discriminatorMap;
            Exception parserException;
            if (
                !TryParseView(
                    eSQL, true, setMapping.Set, mappingItemCollection, config, out commandTree, out discriminatorMap, out parserException))
            {
                var error = new EdmSchemaError(
                    Strings.Mapping_Invalid_QueryView2(setMapping.Set.Name, parserException.Message),
                    (int)StorageMappingErrorCode.InvalidQueryView, EdmSchemaErrorSeverity.Error,
                    setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition,
                    parserException);
                errors.Add(error);
                failed = true;
            }
            else
            {
                Debug.Assert(commandTree != null, "commandTree not set after parsing the view");

                // Verify that all expressions appearing in the view are supported.
                foreach (var error in ViewValidator.ValidateQueryView(commandTree, setMapping, type, includeSubtypes))
                {
                    errors.Add(error);
                    failed = true;
                }

                // Verify that the result type of the query view is assignable to the element type of the entityset
                var queryResultType = (commandTree.Query.ResultType.EdmType) as CollectionType;
                if ((queryResultType == null)
                    || (!setMapping.Set.ElementType.IsAssignableFrom(queryResultType.TypeUsage.EdmType)))
                {
                    var error = new EdmSchemaError(
                        Strings.Mapping_Invalid_QueryView_Type(setMapping.Set.Name),
                        (int)StorageMappingErrorCode.InvalidQueryViewResultType, EdmSchemaErrorSeverity.Error,
                        setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition);
                    errors.Add(error);
                    failed = true;
                }
            }

            if (!failed)
            {
                generatedView = new GeneratedView(setMapping.Set, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config);
                return true;
            }
            else
            {
                generatedView = null;
                return false;
            }
        }
Beispiel #27
0
        /// <summary>
        ///     Entry point for Type specific generation of Query Views
        /// </summary>
        internal static ViewGenResults GenerateTypeSpecificQueryView(
            StorageEntityContainerMapping containerMapping,
            ConfigViewGenerator config,
            EntitySetBase entity,
            EntityTypeBase type,
            bool includeSubtypes,
            out bool success)
        {
            DebugCheck.NotNull(containerMapping);
            DebugCheck.NotNull(config);
            DebugCheck.NotNull(entity);
            DebugCheck.NotNull(type);
            Debug.Assert(!type.Abstract, "Can not generate OfType/OfTypeOnly query view for and abstract type");

            if (config.IsNormalTracing)
            {
                Helpers.StringTraceLine("");
                Helpers.StringTraceLine(
                    "<<<<<<<< Generating Query View for Entity [" + entity.Name + "] OfType" + (includeSubtypes ? "" : "Only") + "("
                    + type.Name + ") >>>>>>>");
            }

            if (containerMapping.GetEntitySetMapping(entity.Name).QueryView != null)
            {
                //Type-specific QV does not exist in the cache, but
                // there is a EntitySet QV. So we can't generate the view (no mapping exists for this EntitySet)
                // and we rely on Query to call us again to get the EntitySet View.
                success = false;
                return(null);
            }

            //Compute Cell Groups or get it from Memoizer
            var args   = new InputForComputingCellGroups(containerMapping, config);
            var result = containerMapping.GetCellgroups(args);

            success = result.Success;

            if (!success)
            {
                return(null);
            }

            var foreignKeyConstraints = result.ForeignKeyConstraints;
            // Get a Clone of cell groups from cache since cells are modified during viewgen, and we dont want the cached copy to change
            var cellGroups  = result.CellGroups.Select(setOfcells => new CellGroup(setOfcells.Select(cell => new Cell(cell)))).ToList();
            var cells       = result.Cells;
            var identifiers = result.Identifiers;

            var viewGenResults = new ViewGenResults();
            var tmpLog         = EnsureAllCSpaceContainerSetsAreMapped(cells, containerMapping);

            if (tmpLog.Count > 0)
            {
                viewGenResults.AddErrors(tmpLog);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                success = true; //atleast we tried successfully
                return(viewGenResults);
            }

            foreach (var cellGroup in cellGroups)
            {
                if (!DoesCellGroupContainEntitySet(cellGroup, entity))
                {
                    continue;
                }

                ViewGenerator viewGenerator = null;
                var           groupErrorLog = new ErrorLog();
                try
                {
                    viewGenerator = new ViewGenerator(cellGroup, config, foreignKeyConstraints, containerMapping);
                }
                catch (InternalMappingException exception)
                {
                    // All exceptions have mapping errors in them
                    Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                    groupErrorLog = exception.ErrorLog;
                }

                if (groupErrorLog.Count > 0)
                {
                    break;
                }
                Debug.Assert(viewGenerator != null); //make sure there is no exception thrown that does not add error to log

                var mode = includeSubtypes ? ViewGenMode.OfTypeViews : ViewGenMode.OfTypeOnlyViews;

                groupErrorLog = viewGenerator.GenerateQueryViewForSingleExtent(viewGenResults.Views, identifiers, entity, type, mode);

                if (groupErrorLog.Count != 0)
                {
                    viewGenResults.AddErrors(groupErrorLog);
                }
            }

            success = true;
            return(viewGenResults);
        }
        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);
        }
        internal static ViewGenResults GenerateTypeSpecificQueryView(
            EntityContainerMapping containerMapping,
            ConfigViewGenerator config,
            EntitySetBase entity,
            EntityTypeBase type,
            bool includeSubtypes,
            out bool success)
        {
            if (config.IsNormalTracing)
            {
                Helpers.StringTraceLine("");
                Helpers.StringTraceLine("<<<<<<<< Generating Query View for Entity [" + entity.Name + "] OfType" + (includeSubtypes ? "" : "Only") + "(" + type.Name + ") >>>>>>>");
            }
            if (containerMapping.GetEntitySetMapping(entity.Name).QueryView != null)
            {
                success = false;
                return((ViewGenResults)null);
            }
            InputForComputingCellGroups args       = new InputForComputingCellGroups(containerMapping, config);
            OutputFromComputeCellGroups cellgroups = containerMapping.GetCellgroups(args);

            success = cellgroups.Success;
            if (!success)
            {
                return((ViewGenResults)null);
            }
            List <ForeignConstraint> foreignKeyConstraints = cellgroups.ForeignKeyConstraints;
            List <Set <Cell> >       list = cellgroups.CellGroups.Select <Set <Cell>, Set <Cell> >((Func <Set <Cell>, Set <Cell> >)(setOfcells => new Set <Cell>(setOfcells.Select <Cell, Cell>((Func <Cell, Cell>)(cell => new Cell(cell)))))).ToList <Set <Cell> >();
            List <Cell>    cells          = cellgroups.Cells;
            CqlIdentifiers identifiers    = cellgroups.Identifiers;
            ViewGenResults viewGenResults = new ViewGenResults();
            ErrorLog       errorLog1      = ViewgenGatekeeper.EnsureAllCSpaceContainerSetsAreMapped((IEnumerable <Cell>)cells, containerMapping);

            if (errorLog1.Count > 0)
            {
                viewGenResults.AddErrors(errorLog1);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                success = true;
                return(viewGenResults);
            }
            foreach (Set <Cell> set in list)
            {
                if (ViewgenGatekeeper.DoesCellGroupContainEntitySet(set, entity))
                {
                    ViewGenerator viewGenerator = (ViewGenerator)null;
                    ErrorLog      errorLog2     = new ErrorLog();
                    try
                    {
                        viewGenerator = new ViewGenerator(set, config, foreignKeyConstraints, containerMapping);
                    }
                    catch (InternalMappingException ex)
                    {
                        errorLog2 = ex.ErrorLog;
                    }
                    if (errorLog2.Count <= 0)
                    {
                        ViewGenMode mode = includeSubtypes ? ViewGenMode.OfTypeViews : ViewGenMode.OfTypeOnlyViews;
                        ErrorLog    viewForSingleExtent = viewGenerator.GenerateQueryViewForSingleExtent(viewGenResults.Views, identifiers, entity, type, mode);
                        if (viewForSingleExtent.Count != 0)
                        {
                            viewGenResults.AddErrors(viewForSingleExtent);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            success = true;
            return(viewGenResults);
        }
 // requires: cells are not normalized, i.e., no slot is null in the cell queries
 // effects: Constructs a validator object that is capable of
 // validating all the schema cells together
 internal CellGroupValidator(IEnumerable<Cell> cells, ConfigViewGenerator config)
 {
     m_cells = cells;
     m_config = config;
     m_errorLog = new ErrorLog();
 }
        internal ViewgenContext(
            ViewTarget viewTarget, EntitySetBase extent, IList<Cell> extentCells,
            CqlIdentifiers identifiers, ConfigViewGenerator config, MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap, EntityContainerMapping 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);
        }
Beispiel #32
0
        // effects: Given a list of cells in the schema, generates the query and
        // update mapping views for OFTYPE(Extent, Type) combinations in this schema
        // container. Returns a list of generated query and update views.
        // If it is false and some columns in a table are unmapped, an
        // exception is raised
        private static ViewGenResults GenerateViewsFromCells(
            List <Cell> cells, ConfigViewGenerator config,
            CqlIdentifiers identifiers,
            StorageEntityContainerMapping containerMapping)
        {
            DebugCheck.NotNull(cells);
            DebugCheck.NotNull(config);
            Debug.Assert(cells.Count > 0, "There must be at least one cell in the container mapping");

            // Go through each table and determine their foreign key constraints
            var container = containerMapping.StorageEntityContainer;

            Debug.Assert(container != null);

            var viewGenResults = new ViewGenResults();
            var tmpLog         = EnsureAllCSpaceContainerSetsAreMapped(cells, containerMapping);

            if (tmpLog.Count > 0)
            {
                viewGenResults.AddErrors(tmpLog);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                return(viewGenResults);
            }

            var foreignKeyConstraints = ForeignConstraint.GetForeignConstraints(container);

            var partitioner = new CellPartitioner(cells, foreignKeyConstraints);
            var cellGroups  = partitioner.GroupRelatedCells();

            foreach (var cellGroup in cellGroups)
            {
                ViewGenerator viewGenerator = null;
                var           groupErrorLog = new ErrorLog();
                try
                {
                    viewGenerator = new ViewGenerator(cellGroup, config, foreignKeyConstraints, containerMapping);
                }
                catch (InternalMappingException exception)
                {
                    // All exceptions have mapping errors in them
                    Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                    groupErrorLog = exception.ErrorLog;
                }

                if (groupErrorLog.Count == 0)
                {
                    Debug.Assert(viewGenerator != null);
                    groupErrorLog = viewGenerator.GenerateAllBidirectionalViews(viewGenResults.Views, identifiers);
                }

                if (groupErrorLog.Count != 0)
                {
                    viewGenResults.AddErrors(groupErrorLog);
                }
            }
            // We used to print the errors here. Now we trace them as they are being thrown
            //if (viewGenResults.HasErrors && config.IsViewTracing) {
            //    Helpers.StringTraceLine(viewGenResults.ErrorsToString());
            //}
            return(viewGenResults);
        }
Beispiel #33
0
        // <summary>
        // Creates generated view object for the combination of the <paramref name="setMapping" />.Set and the
        // <paramref
        //     name="type" />
        // .
        // This constructor is used for user-defined query views only.
        // </summary>
        internal static bool TryParseUserSpecifiedView(
            EntitySetBaseMapping setMapping,
            EntityTypeBase type,
            string eSQL,
            bool includeSubtypes,
            StorageMappingItemCollection mappingItemCollection,
            ConfigViewGenerator config,
            /*out*/ IList <EdmSchemaError> errors,
            out GeneratedView generatedView)
        {
            var failed = false;

            DbQueryCommandTree commandTree;
            DiscriminatorMap   discriminatorMap;
            Exception          parserException;

            if (
                !TryParseView(
                    eSQL, true, setMapping.Set, mappingItemCollection, config, out commandTree, out discriminatorMap, out parserException))
            {
                var error = new EdmSchemaError(
                    Strings.Mapping_Invalid_QueryView2(setMapping.Set.Name, parserException.Message),
                    (int)MappingErrorCode.InvalidQueryView, EdmSchemaErrorSeverity.Error,
                    setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition,
                    parserException);
                errors.Add(error);
                failed = true;
            }
            else
            {
                Debug.Assert(commandTree != null, "commandTree not set after parsing the view");

                // Verify that all expressions appearing in the view are supported.
                foreach (var error in ViewValidator.ValidateQueryView(commandTree, setMapping, type, includeSubtypes))
                {
                    errors.Add(error);
                    failed = true;
                }

                // Verify that the result type of the query view is assignable to the element type of the entityset
                var queryResultType = (commandTree.Query.ResultType.EdmType) as CollectionType;
                if ((queryResultType == null) ||
                    (!setMapping.Set.ElementType.IsAssignableFrom(queryResultType.TypeUsage.EdmType)))
                {
                    var error = new EdmSchemaError(
                        Strings.Mapping_Invalid_QueryView_Type(setMapping.Set.Name),
                        (int)MappingErrorCode.InvalidQueryViewResultType, EdmSchemaErrorSeverity.Error,
                        setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition);
                    errors.Add(error);
                    failed = true;
                }
            }

            if (!failed)
            {
                generatedView = new GeneratedView(setMapping.Set, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config);
                return(true);
            }
            else
            {
                generatedView = null;
                return(false);
            }
        }
Beispiel #34
0
        // effects: Given the extent cells and a map for the domains of all
        // variables in it, fixes the cell constant domains of the where
        // clauses in the left queries of cells (left is defined using viewTarget)
        private static void UpdateWhereClauseForEachCell(
            IEnumerable<Cell> extentCells, MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap, ConfigViewGenerator config)
        {
            foreach (var cell in extentCells)
            {
                cell.CQuery.UpdateWhereClause(queryDomainMap);
                cell.SQuery.UpdateWhereClause(updateDomainMap);
            }

            // Fix enumerable domains - currently it is only applicable to boolean type. Note that it is 
            // not applicable to enumerated types since we allow any value of the underlying type of the enum type.
            queryDomainMap.ReduceEnumerableDomainToEnumeratedValues(config);
            updateDomainMap.ReduceEnumerableDomainToEnumeratedValues(config);
        }
        // effects: Given a list of cells in the schema, generates the query and
        // update mapping views for OFTYPE(Extent, Type) combinations in this schema
        // container. Returns a list of generated query and update views.
        // If it is false and some columns in a table are unmapped, an
        // exception is raised
        private static ViewGenResults GenerateViewsFromCells(
            List<Cell> cells, ConfigViewGenerator config,
            CqlIdentifiers identifiers,
            EntityContainerMapping containerMapping)
        {
            DebugCheck.NotNull(cells);
            DebugCheck.NotNull(config);
            Debug.Assert(cells.Count > 0, "There must be at least one cell in the container mapping");

            // Go through each table and determine their foreign key constraints
            var container = containerMapping.StorageEntityContainer;
            Debug.Assert(container != null);

            var viewGenResults = new ViewGenResults();
            var tmpLog = EnsureAllCSpaceContainerSetsAreMapped(cells, containerMapping);
            if (tmpLog.Count > 0)
            {
                viewGenResults.AddErrors(tmpLog);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                return viewGenResults;
            }

            var foreignKeyConstraints = ForeignConstraint.GetForeignConstraints(container);

            var partitioner = new CellPartitioner(cells, foreignKeyConstraints);
            var cellGroups = partitioner.GroupRelatedCells();
            foreach (var cellGroup in cellGroups)
            {
                ViewGenerator viewGenerator = null;
                var groupErrorLog = new ErrorLog();
                try
                {
                    viewGenerator = new ViewGenerator(cellGroup, config, foreignKeyConstraints, containerMapping);
                }
                catch (InternalMappingException exception)
                {
                    // All exceptions have mapping errors in them
                    Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                    groupErrorLog = exception.ErrorLog;
                }

                if (groupErrorLog.Count == 0)
                {
                    Debug.Assert(viewGenerator != null);
                    groupErrorLog = viewGenerator.GenerateAllBidirectionalViews(viewGenResults.Views, identifiers);
                }

                if (groupErrorLog.Count != 0)
                {
                    viewGenResults.AddErrors(groupErrorLog);
                }
            }
            // We used to print the errors here. Now we trace them as they are being thrown
            //if (viewGenResults.HasErrors && config.IsViewTracing) {
            //    Helpers.StringTraceLine(viewGenResults.ErrorsToString());
            //}
            return viewGenResults;
        }
        // <summary>
        // Entry point for Type specific generation of Query Views
        // </summary>
        internal static ViewGenResults GenerateTypeSpecificQueryView(
            EntityContainerMapping containerMapping,
            ConfigViewGenerator config,
            EntitySetBase entity,
            EntityTypeBase type,
            bool includeSubtypes,
            out bool success)
        {
            DebugCheck.NotNull(containerMapping);
            DebugCheck.NotNull(config);
            DebugCheck.NotNull(entity);
            DebugCheck.NotNull(type);
            Debug.Assert(!type.Abstract, "Can not generate OfType/OfTypeOnly query view for and abstract type");

            if (config.IsNormalTracing)
            {
                Helpers.StringTraceLine("");
                Helpers.StringTraceLine(
                    "<<<<<<<< Generating Query View for Entity [" + entity.Name + "] OfType" + (includeSubtypes ? "" : "Only") + "("
                    + type.Name + ") >>>>>>>");
            }

            if (containerMapping.GetEntitySetMapping(entity.Name).QueryView != null)
            {
                //Type-specific QV does not exist in the cache, but
                // there is a EntitySet QV. So we can't generate the view (no mapping exists for this EntitySet)
                // and we rely on Query to call us again to get the EntitySet View.
                success = false;
                return null;
            }

            //Compute Cell Groups or get it from Memoizer
            var args = new InputForComputingCellGroups(containerMapping, config);
            var result = containerMapping.GetCellgroups(args);
            success = result.Success;

            if (!success)
            {
                return null;
            }

            var foreignKeyConstraints = result.ForeignKeyConstraints;
            // Get a Clone of cell groups from cache since cells are modified during viewgen, and we dont want the cached copy to change
            var cellGroups = result.CellGroups.Select(setOfcells => new CellGroup(setOfcells.Select(cell => new Cell(cell)))).ToList();
            var cells = result.Cells;
            var identifiers = result.Identifiers;

            var viewGenResults = new ViewGenResults();
            var tmpLog = EnsureAllCSpaceContainerSetsAreMapped(cells, containerMapping);
            if (tmpLog.Count > 0)
            {
                viewGenResults.AddErrors(tmpLog);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                success = true; //atleast we tried successfully
                return viewGenResults;
            }

            foreach (var cellGroup in cellGroups)
            {
                if (!DoesCellGroupContainEntitySet(cellGroup, entity))
                {
                    continue;
                }

                ViewGenerator viewGenerator = null;
                var groupErrorLog = new ErrorLog();
                try
                {
                    viewGenerator = new ViewGenerator(cellGroup, config, foreignKeyConstraints, containerMapping);
                }
                catch (InternalMappingException exception)
                {
                    // All exceptions have mapping errors in them
                    Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                    groupErrorLog = exception.ErrorLog;
                }

                if (groupErrorLog.Count > 0)
                {
                    break;
                }
                Debug.Assert(viewGenerator != null); //make sure there is no exception thrown that does not add error to log

                var mode = includeSubtypes ? ViewGenMode.OfTypeViews : ViewGenMode.OfTypeOnlyViews;

                groupErrorLog = viewGenerator.GenerateQueryViewForSingleExtent(viewGenResults.Views, identifiers, entity, type, mode);

                if (groupErrorLog.Count != 0)
                {
                    viewGenResults.AddErrors(groupErrorLog);
                }
            }

            success = true;
            return viewGenResults;
        }
        // <summary>
        // This method compiles all the user defined query views in the <paramref name="entityContainerMapping" />.
        // </summary>
        private static void CompileUserDefinedQueryViews(
            EntityContainerMapping entityContainerMapping,
            Dictionary<EntitySetBase, GeneratedView> userDefinedQueryViewsDict,
            Dictionary<OfTypeQVCacheKey, GeneratedView> userDefinedQueryViewsOfTypeDict,
            IList<EdmSchemaError> errors)
        {
            var config = new ConfigViewGenerator();
            foreach (var setMapping in entityContainerMapping.AllSetMaps)
            {
                if (setMapping.QueryView != null)
                {
                    GeneratedView generatedView;
                    if (!userDefinedQueryViewsDict.TryGetValue(setMapping.Set, out generatedView))
                    {
                        // Parse the view so that we will get back any errors in the view.
                        if (GeneratedView.TryParseUserSpecifiedView(
                            setMapping,
                            setMapping.Set.ElementType,
                            setMapping.QueryView,
                            true, // includeSubtypes
                            entityContainerMapping.StorageMappingItemCollection,
                            config,
                            /*out*/ errors,
                            out generatedView))
                        {
                            // Add first QueryView
                            userDefinedQueryViewsDict.Add(setMapping.Set, generatedView);
                        }

                        // Add all type-specific QueryViews
                        foreach (var key in setMapping.GetTypeSpecificQVKeys())
                        {
                            Debug.Assert(key.First.Equals(setMapping.Set));

                            if (GeneratedView.TryParseUserSpecifiedView(
                                setMapping,
                                key.Second.First, // type
                                setMapping.GetTypeSpecificQueryView(key),
                                key.Second.Second, // includeSubtypes
                                entityContainerMapping.StorageMappingItemCollection,
                                config,
                                /*out*/ errors,
                                out generatedView))
                            {
                                userDefinedQueryViewsOfTypeDict.Add(key, generatedView);
                            }
                        }
                    }
                }
            }
        }
Beispiel #38
0
 // requires: cells are not normalized, i.e., no slot is null in the cell queries
 // effects: Constructs a validator object that is capable of
 // validating all the schema cells together
 internal CellGroupValidator(IEnumerable <Cell> cells, ConfigViewGenerator config)
 {
     m_cells    = cells;
     m_config   = config;
     m_errorLog = new ErrorLog();
 }
Beispiel #39
0
        /// <summary>
        ///     Entry point for View Generation
        /// </summary>
        /// <param name="containerMapping"> </param>
        /// <param name="workSpace"> </param>
        /// <param name="config"> </param>
        /// <returns> Generated Views for EntitySets </returns>
        internal static ViewGenResults GenerateViewsFromMapping(StorageEntityContainerMapping containerMapping, ConfigViewGenerator config)
        {
            DebugCheck.NotNull(containerMapping);
            DebugCheck.NotNull(config);
            Debug.Assert(containerMapping.HasViews, "Precondition Violated: No mapping exists to generate views for!");

            //Create Cells from StorageEntityContainerMapping
            var cellCreator = new CellCreator(containerMapping);
            var cells       = cellCreator.GenerateCells();
            var identifiers = cellCreator.Identifiers;

            return(GenerateViewsFromCells(cells, config, identifiers, containerMapping));
        }