/// <summary>
        /// Allows for Related Pages lookup using Ordering on non-MultpleDocumentQuery queries.  The given Node must be on the "left" hand side in this case for ordering.
        /// </summary>
        /// <param name="baseQuery">The Base Document Query</param>
        /// <param name="nodeGuid">The NodeGuid</param>
        /// <param name="relationshipName">Name of the relationship. If not provided documents from all relationships will be retrieved.</param>
        public static MultiDocumentQuery InRelationWithOrder(this MultiDocumentQuery baseQuery, Guid nodeGuid, string relationshipName = null)
        {
            // Get the RelationshipID and NodeID
            int?RelationshipNameID = GetRelationshipNameID(relationshipName);
            int?NodeID             = GetNodeID(nodeGuid);

            if (!NodeID.HasValue)
            {
                return(baseQuery);
            }

            // Add the Inner Join with proper alias formatting
            if (RelationshipNameID.HasValue)
            {
                baseQuery.Source((QuerySource s) => s.InnerJoin(new QuerySourceTable("CMS_Relationship"), new WhereCondition("NodeID = RightNodeID").WhereEquals("RelationshipNameID", RelationshipNameID.Value).WhereEquals("LeftNodeID", NodeID.Value)));
            }
            else
            {
                baseQuery.Source((QuerySource s) => s.InnerJoin(new QuerySourceTable("CMS_Relationship"), new WhereCondition("NodeID = RightNodeID").WhereEquals("LeftNodeID", NodeID.Value)));
            }

            // add the by the Relationship Order
            baseQuery.OrderBy("RelationshipOrder");

            return(baseQuery);
        }
示例#2
0
 public static MultiDocumentQuery AddVersionsParameters(this MultiDocumentQuery query, bool isPreview)
 {
     return(query
            .LatestVersion(isPreview)
            .Published(!isPreview)
            .OnSite(SiteContext.CurrentSiteName));
 }
        /// <summary>
        /// Gets default <see cref="DocumentQuery{TDocument}"/> configuration.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <returns>The modified query.</returns>
        private static MultiDocumentQuery GetDefaultFilter(MultiDocumentQuery query)
        {
            query
            .FilterDuplicates()
            .OrderByAscending(NodeOrdering);

            return(query);
        }
示例#4
0
        public void MultiDocumentQuery_DocumentQuery_OrderByNodeOrder_Will_Add_A_New_OrderBy_Condition()
        {
            var sut = new MultiDocumentQuery();

            var result = sut.OrderByNodeOrder();

            result.OrderByColumns.Should().Be($"NodeOrder");
        }
        /// <summary>
        /// Converts the <paramref name="query"/> to a <see cref="List{T}"/> of <see cref="TreeNode"/>
        /// </summary>
        /// <param name="query">The current MultiDocumentQuery</param>
        /// <param name="projection">Mapping function from <see cref="TreeNode"/> to <typeparamref name="TReturn" /></param>
        /// <param name="token">Optional cancellation token</param>
        /// <returns></returns>
        public static async Task <IList <TReturn> > ToListAsync <TReturn>(
            this MultiDocumentQuery query,
            Func <TreeNode, TReturn> projection,
            CancellationToken token = default)
        {
            var result = await query.GetEnumerableTypedResultAsync(cancellationToken : token);

            return(result.Select(projection).ToList());
        }
        /// <summary>
        /// Prints the provided query's full materialized query text using <see cref="LoggerExtensions.LogDebug(ILogger, string, object[])"/>
        /// </summary>
        /// <param name="query">The current MultiDocumentQuery</param>
        /// <param name="logger">The logger used to output the query</param>
        /// <param name="queryName">Optional Name for the query that will denote in the output where this specific query starts and ends.
        /// If no value is supplied, the filename containing the calling method will be used. If null or an empty string is supplied, "MultiDocumentQuery" will be used.
        /// </param>
        /// <returns></returns>
        public static MultiDocumentQuery LogQuery(this MultiDocumentQuery query, ILogger logger, [CallerFilePath] string queryName = "")
        {
            queryName = string.IsNullOrWhiteSpace(queryName)
                ? nameof(MultiDocumentQuery)
                : queryName;

            logger.LogDebug("{queryName} {queryText}", queryName, query.GetFullQueryText());

            return(query);
        }
示例#7
0
        public void MultiDocumentQuery_Tap_Will_Execute_The_Given_Action()
        {
            var sut = new MultiDocumentQuery();

            var action = Substitute.For <Action <MultiDocumentQuery> >();

            var result = sut.Tap(action);

            action.ReceivedCalls().Should().HaveCount(1);
        }
示例#8
0
        public void MultiDocumentQuery_If_Will_Execute_The_Given_Action_If_The_Condition_Is_True()
        {
            var sut = new MultiDocumentQuery();

            var action = Substitute.For <Action <MultiDocumentQuery> >();

            var result = sut.If(true, action);

            action.ReceivedCalls().Should().HaveCount(1);
        }
示例#9
0
 public static MultiDocumentQuery ColumnsNullHandled(this MultiDocumentQuery baseQuery, string[] Columns)
 {
     if (Columns == null)
     {
         return(baseQuery);
     }
     else
     {
         return(baseQuery.Columns(Columns));
     }
 }
示例#10
0
        private void _processContentConfig(BridgeContentConfig contentConfig, Stream stream)
        {
            var    serializer          = new SerializerBuilder().ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull).Build();
            var    watch               = new Stopwatch();
            string serializationFolder = BridgeConfiguration.GetConfig().SerializationFolder;

            _clearTempFolder();
            watch.Start();

            //have this driven by config
            var serializationPath     = $"{serializationFolder}/content/{contentConfig.Name}";
            var tempGUID              = DateTime.Now.Ticks.ToString();
            var tempSerializationPath = $"{serializationFolder}/temp/{tempGUID}/{contentConfig.Name}";
            var pageTypes             = contentConfig.GetPageTypes();
            var fieldsToIgnore        = contentConfig.GetIgnoreFields();
            var path = contentConfig.Query;

            //TODO: Query to see if page types exist, if DOESNT, display that...
            MultiDocumentQuery docs = DocumentHelper.GetDocuments().Path(path).Types(pageTypes.ToArray()).AllCultures().FilterDuplicates();
            var treeNodes           = docs.ToList <TreeNode>();

            foreach (var treeNode in treeNodes)
            {
                watch.Reset();
                watch.Start();
                var mappedItem = treeNode.Adapt <BridgeTreeNode>();
                mappedItem.FieldValues = new Dictionary <string, object>();

                foreach (string columnName in treeNode.ColumnNames)
                {
                    if (!fieldsToIgnore.Contains(columnName))
                    {
                        var columnValue = treeNode.GetValue(columnName);
                        if (columnValue != null)
                        {
                            mappedItem.FieldValues.Add(columnName, columnValue);
                        }
                    }
                }
                mappedItem.ParentNodeGUID = treeNode?.Parent?.NodeGUID;
                var stringBuilder = new StringBuilder();
                var res           = serializer.Serialize(mappedItem);
                stringBuilder.AppendLine(res);
                var      pathToWriteTo = $"{tempSerializationPath}/{mappedItem.NodeAliasPath}#{mappedItem.DocumentCulture}.yaml";
                var      concretePath  = this.GetRootPath(pathToWriteTo);
                FileInfo file          = new FileInfo(concretePath);
                file.Directory.Create(); // If the directory already exists, this method does nothing.
                File.WriteAllText(concretePath, res);
            }
            watch.Stop();
            _outputToStream(stream, $"Generating temp {contentConfig.Name} - {watch.ElapsedMilliseconds}ms");
            _processDifferences(stream, watch, serializationPath, tempSerializationPath);
        }
示例#11
0
        protected async Task <IEnumerable <TPage> > GetPagesOfMultipleTypesAsync(
            IEnumerable <string> types,
            SiteCulture culture,
            Action <MultiDocumentQuery>?filter = default)
        {
            MultiDocumentQuery query = GetQueryForMultipleTypes(types, culture, filter);

            return((await query
                    .GetEnumerableTypedResultAsync())
                   .Select(page => page as TPage)
                   .Where(page => page != null) !);
        }
示例#12
0
        public void MultiDocumentQuery_If_Will_Execute_The_ElseAction_If_The_Condition_Is_False()
        {
            var sut = new MultiDocumentQuery();

            var action     = Substitute.For <Action <MultiDocumentQuery> >();
            var elseAction = Substitute.For <Action <MultiDocumentQuery> >();

            var result = sut.If(false, action, elseAction);

            action.ReceivedCalls().Should().BeEmpty();
            elseAction.ReceivedCalls().Should().HaveCount(1);
        }
示例#13
0
        private void _processContentConfig(BridgeContentConfig contentConfig, Stream stream)
        {
            var    serializer          = new SerializerBuilder().ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull).Build();
            var    watch               = new Stopwatch();
            string serializationFolder = BridgeConfiguration.GetConfig().SerializationFolder;

            //have this driven by config
            var serializationPath = $"{serializationFolder}/content/{contentConfig.Name}";
            var pageTypes         = contentConfig.GetPageTypes();
            var fieldsToIgnore    = contentConfig.GetIgnoreFields();
            var path = contentConfig.Query;

            MultiDocumentQuery docs = DocumentHelper.GetDocuments().Path(path).Types(pageTypes.ToArray()).AllCultures().FilterDuplicates();
            var treeNodes           = docs.ToList <TreeNode>();

            foreach (var treeNode in treeNodes)
            {
                watch.Reset();
                watch.Start();
                var mappedItem = treeNode.Adapt <BridgeTreeNode>();
                mappedItem.FieldValues = new Dictionary <string, object>();

                foreach (string columnName in treeNode.ColumnNames)
                {
                    if (!fieldsToIgnore.Contains(columnName))
                    {
                        var columnValue = treeNode.GetValue(columnName);
                        if (columnValue != null)
                        {
                            mappedItem.FieldValues.Add(columnName, columnValue);
                        }
                    }
                }
                mappedItem.ParentNodeGUID = treeNode?.Parent?.NodeGUID;
                var stringBuilder = new StringBuilder();
                var res           = serializer.Serialize(mappedItem);
                stringBuilder.AppendLine(res);
                var      pathToWriteTo = $"{serializationPath}/{mappedItem.NodeAliasPath}#{mappedItem.DocumentCulture}.yaml";
                var      concretePath  = this.GetRootPath(pathToWriteTo);
                FileInfo file          = new FileInfo(concretePath);
                file.Directory.Create(); // If the directory already exists, this method does nothing.
                File.WriteAllText(concretePath, res);
                watch.Stop();
                byte[] bytes = Encoding.UTF8.GetBytes($"Serialized {contentConfig.Name}: {mappedItem.NodeAliasPath}#{mappedItem.DocumentCulture}.yaml ({mappedItem.NodeGUID}) - {watch.ElapsedMilliseconds}ms");
                stream.Write(bytes, 0, bytes.Length);
                stream.WriteByte(10);
                stream.Flush();
            }
        }
示例#14
0
        public void MultiDocumentQuery_WhereDocumentIDEquals_Will_Add_A_New_Where_Condition()
        {
            var fixture    = new Fixture();
            int documentID = fixture.Create <int>();

            var sut = new MultiDocumentQuery();

            var result = sut.WhereDocumentIDEquals(documentID);

            var param = result.Parameters.Single();

            param.Name.Should().Be("@DocumentID");
            param.Value.Should().Be(documentID);
            result.WhereCondition.Should().Be($"[DocumentID] = @DocumentID");
        }
示例#15
0
        protected MultiDocumentQuery GetQueryForMultipleTypes(
            IEnumerable <string> types,
            SiteCulture?culture,
            Action <MultiDocumentQuery>?filter)
        {
            var query = new MultiDocumentQuery();

            query = FilterFor(query, culture)
                    .Types(types.ToArray())
                    .WithCoupledColumns();

            filter?.Invoke(query);

            return(query);
        }
        /// <summary>
        /// Executes the <paramref name="ifTrueAction" /> if the <paramref name="condition" /> is true, otherwise executes
        /// the <paramref name="elseAction" /> if it is provided.
        /// </summary>
        /// <param name="query"></param>
        /// <param name="condition"></param>
        /// <param name="ifTrueAction"></param>
        /// <param name="elseAction"></param>
        /// <returns></returns>
        public static MultiDocumentQuery If(
            this MultiDocumentQuery query, bool condition,
            Action <MultiDocumentQuery> ifTrueAction,
            Action <MultiDocumentQuery>?elseAction = null)
        {
            if (condition)
            {
                ifTrueAction(query);
            }
            else if (elseAction is object)
            {
                elseAction(query);
            }

            return(query);
        }
        /// <summary>
        /// Prints the provided query's full materialized query text using <see cref="Debug.WriteLine(object?)"/>
        /// </summary>
        /// <param name="query">The current MultiDocumentQuery</param>
        /// <param name="queryName">Optional Name for the query that will denote in the output where this specific query starts and ends.
        /// If no value is supplied, the filename containing the calling method will be used. If null or an empty string is supplied, "MultiDocumentQuery" will be used.
        /// </param>
        /// <example>
        /// DocumentHelper
        ///     .GetDocuments()
        ///     .TopN(1)
        ///     .DebugQuery("First Document");
        ///
        ///
        /// ~~~ QUERY [First Document] START ~~~
        ///
        ///
        /// DECLARE @DocumentCulture nvarchar(max) = N'en-US';
        ///
        /// SELECT TOP 1 *
        /// FROM View_CMS_Tree_Joined AS V WITH (NOLOCK, NOEXPAND) LEFT OUTER JOIN COM_SKU AS S WITH (NOLOCK) ON [V].[NodeSKUID] = [S].[SKUID]
        /// WHERE [DocumentCulture] = @DocumentCulture
        ///
        ///
        /// ~~~ QUERY [Dirst Document] END ~~~
        ///
        /// </example>
        /// <returns></returns>
        public static MultiDocumentQuery DebugQuery(this MultiDocumentQuery query, [CallerFilePath] string queryName = "")
        {
            queryName = string.IsNullOrWhiteSpace(queryName)
                ? nameof(MultiDocumentQuery)
                : queryName;

            Debug.WriteLine(Environment.NewLine);
            Debug.WriteLine($"~~~ BEGIN [{queryName}] QUERY ~~~");
            Debug.WriteLine(Environment.NewLine);

            Debug.WriteLine(Environment.NewLine);
            Debug.WriteLine(query.GetFullQueryText());
            Debug.WriteLine(Environment.NewLine);

            Debug.WriteLine(Environment.NewLine);
            Debug.WriteLine($"~~~ END [{queryName}] QUERY ~~~");
            Debug.WriteLine(Environment.NewLine);

            return(query);
        }
 /// <summary>
 /// Returns the <see cref="MultiDocumentQuery"/> filtered to a single Node with a <see cref="TreeNode.NodeID"/> matching the provided value
 /// </summary>
 /// <param name="query">The current MultiDocumentQuery</param>
 /// <param name="nodeID">Value of the <see cref="TreeNode.NodeID" /> to filter by</param>
 /// <returns></returns>
 public static MultiDocumentQuery WhereNodeIDEquals(this MultiDocumentQuery query, int nodeID) =>
 query.WhereEquals(nameof(TreeNode.NodeID), nodeID);
示例#19
0
 public static MultiDocumentQuery GetLatestSiteDocuments(this MultiDocumentQuery query, IDocumentQueryContext context) =>
 query.LatestVersion(context.IsPreviewEnabled)
 .Published(!context.IsPreviewEnabled)
 .OnSite(context.SiteName)
 .CombineWithDefaultCulture();
        /// <summary>
        /// Converts the <paramref name="query"/> to a <see cref="List{T}"/> of <see cref="TreeNode"/>
        /// </summary>
        /// <param name="query">The current MultiDocumentQuery</param>
        /// <param name="token">Optional cancellation token</param>
        /// <returns></returns>
        public static async Task <IList <TreeNode> > ToListAsync(this MultiDocumentQuery query, CancellationToken token = default)
        {
            var result = await query.GetEnumerableTypedResultAsync(cancellationToken : token);

            return(result.ToList());
        }
        /// <summary>
        /// Returns the first item of the <paramref name="query"/> as a <see cref="TreeNode"/> and null if no items were returned.
        /// </summary>
        /// <param name="query">The current MultiDocumentQuery</param>
        /// <param name="token">Optional cancellation token</param>
        /// <returns></returns>
        public static async Task <TreeNode?> FirstOrDefaultAsync(this MultiDocumentQuery query, CancellationToken token = default)
        {
            var result = await query.GetEnumerableTypedResultAsync(cancellationToken : token);

            return(result?.FirstOrDefault());
        }
示例#22
0
        /// <summary>
        /// Allow the caller to specify an action that has access to the full query text at the point
        /// at which this method is called. Useful for custom logging of the query.
        /// </summary>
        /// <param name="query"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static MultiDocumentQuery TapQueryText <TNode>(this MultiDocumentQuery query, Action <string> action)
        {
            action(query.GetFullQueryText());

            return(query);
        }
示例#23
0
        public IEnumerable <ITreeNode> GetDocuments(string SinglePath, PathSelectionEnum PathType, string[] PageTypes = null, string OrderBy = null, string WhereCondition = null, int MaxLevel = -1, int TopNumber = -1, string[] Columns = null, bool IncludeCoupledColumns = false)
        {
            using (MultiDocumentQuery Query = new MultiDocumentQuery())
            {
                if (PageTypes != null && PageTypes.Length > 0)
                {
                    if (PageTypes.Length == 1)
                    {
                        Query.Type(PageTypes[0]);
                    }
                    else
                    {
                        Query.Types(PageTypes);
                    }
                }
                if (IncludeCoupledColumns)
                {
                    Query.ExpandColumns();
                }

                // Handle culture and versioning and site
                Query.Culture(cultureName)
                .CombineWithDefaultCulture()
                .CombineWithAnyCulture()
                .Published(!latestVersionEnabled)
                .LatestVersion(latestVersionEnabled)
                .OnSite(_SiteRepo.CurrentSiteName());

                PathTypeEnum KenticoPathType = PathTypeEnum.Explicit;
                switch (PathType)
                {
                case PathSelectionEnum.ChildrenOnly:
                    KenticoPathType = PathTypeEnum.Children;
                    break;

                case PathSelectionEnum.ParentAndChildren:
                    KenticoPathType = PathTypeEnum.Section;
                    break;

                case PathSelectionEnum.ParentOnly:
                    KenticoPathType = PathTypeEnum.Single;
                    break;
                }
                Query.Path(SinglePath, KenticoPathType);

                if (!string.IsNullOrWhiteSpace(OrderBy))
                {
                    Query.OrderBy(OrderBy);
                }
                if (!string.IsNullOrWhiteSpace(WhereCondition))
                {
                    Query.Where(WhereCondition);
                }
                if (Columns != null && Columns.Length > 0)
                {
                    Query.Columns(Columns);
                }
                if (MaxLevel >= 0)
                {
                    Query.NestingLevel(MaxLevel);
                }
                if (TopNumber >= 0)
                {
                    Query.TopN(TopNumber);
                }
                return(Query.TypedResult);
            }
        }
        /// <summary>
        /// Allow the caller to specify an action that has access to the query.
        /// </summary>
        /// <param name="query"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static MultiDocumentQuery Tap(this MultiDocumentQuery query, Action <MultiDocumentQuery> action)
        {
            action(query);

            return(query);
        }
 /// <summary>
 /// Returns the <see cref="MultiDocumentQuery"/> ordered by <see cref="TreeNode.NodeOrder"/>
 /// </summary>
 /// <param name="query">The current MultiDocumentQuery</param>
 /// <returns></returns>
 public static MultiDocumentQuery OrderByNodeOrder(this MultiDocumentQuery query) =>
 query.OrderBy(nameof(TreeNode.NodeOrder));
 /// <summary>
 /// Returns the <see cref="MultiDocumentQuery"/> filtered to a single Node with a <see cref="TreeNode.DocumentID"/> matching the provided value
 /// </summary>
 /// <param name="query">The current MultiDocumentQuery</param>
 /// <param name="documentID">Value of the <see cref="TreeNode.DocumentID" /> to filter by</param>
 /// <returns></returns>
 public static MultiDocumentQuery WhereDocumentIDEquals(this MultiDocumentQuery query, int documentID) =>
 query.WhereEquals(nameof(TreeNode.DocumentID), documentID);
 /// <summary>
 /// Returns the <see cref="MultiDocumentQuery"/> filtered to a single Node with a <see cref="TreeNode.NodeGUID"/> matching the provided value
 /// </summary>
 /// <param name="query">The current MultiDocumentQuery</param>
 /// <param name="nodeGuid">Value of the <see cref="TreeNode.NodeGUID" /> to filter by</param>
 /// <returns></returns>
 public static MultiDocumentQuery WhereNodeGUIDEquals(this MultiDocumentQuery query, Guid nodeGuid) =>
 query.WhereEquals(nameof(TreeNode.NodeGUID), nodeGuid);