private ScoreDoc[] GetDocsUnderTree(string path, bool recurse)
        {
            var field = recurse ? "InTree" : "Path";

            var queryContext = SnQueryContext.CreateDefault();
            var snQuery      = SnQuery.Parse($"{field}:'{path.ToLower()}'", null);

            var lq = Compile(snQuery, queryContext); //LucQuery.Parse(String.Format("{0}:'{1}'", field, path.ToLower()));

            using (var readerFrame = LuceneSearchManager.GetIndexReaderFrame())
            {
                var idxReader = readerFrame.IndexReader;
                var searcher  = new IndexSearcher(idxReader);
                var numDocs   = idxReader.NumDocs();
                try
                {
                    var collector = TopScoreDocCollector.Create(numDocs, false);
                    searcher.Search(lq.Query, collector);
                    var topDocs = collector.TopDocs(0, numDocs);
                    return(topDocs.ScoreDocs);
                }
                finally
                {
                    searcher.Close();
                }
            }
        }
예제 #2
0
        private void RewritingTest(string inputQuery, bool isValid, string expected)
        {
            var context = new TestQueryContext(QuerySettings.AdminSettings, 0, _indexingInfo, new TestQueryEngine(null, null));

            using (SenseNet.Tests.Tools.Swindle(typeof(SnQuery), "_permissionFilterFactory", new EverythingAllowedPermissionFilterFactory()))
            {
                var queryIn    = SnQuery.Parse(inputQuery, context);
                var snQueryAcc = new PrivateType(typeof(SnQuery));
                snQueryAcc.InvokeStatic("PrepareQuery", queryIn, context);

                var     hasError = false;
                var     visitor  = new SharingVisitor();
                SnQuery queryOut = null;
                try
                {
                    queryOut = SnQuery.Create(visitor.Visit(queryIn.QueryTree));
                }
                catch (InvalidContentSharingQueryException)
                {
                    hasError = true;
                }

                Assert.AreNotEqual(isValid, hasError);
                if (!hasError)
                {
                    Assert.AreEqual(expected, queryOut.ToString());
                }
            }
        }
예제 #3
0
        private void NormalizerVisitorTest(string inputQuery, string expectedQuery)
        {
            var context = new TestQueryContext(QuerySettings.AdminSettings, 0, _indexingInfo, new TestQueryEngine(null, null));

            using (SenseNet.Tests.Tools.Swindle(typeof(SnQuery), "_permissionFilterFactory",
                                                new EverythingAllowedPermissionFilterFactory()))
            {
                var queryIn = SnQuery.Parse(inputQuery, context);
                NormalizerVisitorTest(queryIn, context, expectedQuery);
            }
        }
예제 #4
0
        public void Sharing_Query_Rewriting_FieldNames()
        {
            var    inputQuery    = "-a:a Sharing:s0 SharedWith:123 SharedBy:s2 SharingMode:s3 SharingLevel:s4";
            var    expectedQuery = "-a:a Sharing:s0 Sharing:I123 Sharing:s2 Sharing:s3 Sharing:s4";
            string actualQuery;

            var context = new TestQueryContext(QuerySettings.AdminSettings, 0, _indexingInfo, new TestQueryEngine(null, null));

            using (SenseNet.Tests.Tools.Swindle(typeof(SnQuery), "_permissionFilterFactory", new EverythingAllowedPermissionFilterFactory()))
            {
                var queryIn    = SnQuery.Parse(inputQuery, context);
                var snQueryAcc = new PrivateType(typeof(SnQuery));
                snQueryAcc.InvokeStatic("PrepareQuery", queryIn, context);

                var visitor = new SharingVisitor();
                var newTree = visitor.Visit(queryIn.QueryTree);

                var snQuery = SnQuery.Create(newTree);
                actualQuery = snQuery.ToString();
            }

            Assert.AreEqual(expectedQuery, actualQuery);
        }
예제 #5
0
        /// <summary>
        /// Add or edit a saved content query.
        /// </summary>
        /// <param name="content">A query content to modify, a user, or any content under a workspace.</param>
        /// <param name="query">Query text.</param>
        /// <param name="displayName">Display name for the saved query.</param>
        /// <param name="queryType">Type of the query.</param>
        /// <returns></returns>
        public static object SaveQuery(Content content, string query, string displayName, QueryType queryType)
        {
            if (content == null)
            {
                throw new ArgumentNullException("content");
            }

            if (query == null)
            {
                throw new ArgumentNullException("query");
            }

            try
            {
                // We need to validate the query to avoid saving unknown texts.
                SnQuery.Parse(query, new SnQueryContext(QuerySettings.Default, User.Current.Id));
            }
            catch (Exception ex)
            {
                SnLog.WriteWarning("Content query parse error during query save.", EventId.Querying,
                                   properties: new Dictionary <string, object>
                {
                    { "User", User.Current.Name },
                    { "Query text", query },
                    { "Error", ex.Message }
                });

                return(string.Empty);
            }

            ContentList queryContainer = null;
            Content     queryContent   = null;

            switch (queryType)
            {
            case QueryType.Private:

                // load the user and his profile
                var user = content.ContentHandler as User ?? (User)User.Current;
                if (!user.IsProfileExist())
                {
                    user.CreateProfile();
                }

                var profile = user.Profile;
                if (profile == null)
                {
                    throw new InvalidOperationException("User profile could not be created.");
                }

                queryContainer = GetQueryContainer(profile);
                break;

            case QueryType.Public:
                // store the query under the current workspace
                queryContainer = GetQueryContainer(((GenericContent)content.ContentHandler).Workspace);
                if (queryContainer == null)
                {
                    throw new InvalidOperationException("Query container could not be created for a public query. Content: " + content.Path);
                }
                break;

            case QueryType.NonDefined:
                if (!content.ContentType.IsInstaceOfOrDerivedFrom(QueryTypeName))
                {
                    throw new InvalidOperationException("If the query type is nondefined, the content must be a query to save.");
                }
                queryContent = content;
                break;

            default:
                throw new InvalidOperationException("Unknown query type: " + queryType);
            }

            if (queryContainer != null)
            {
                // create a new query under the previously found container
                queryContent = Content.CreateNew(QueryTypeName, queryContainer, null);
            }

            if (queryContent == null)
            {
                throw new InvalidOperationException("No query content to save.");
            }

            // Elevation: a simple user does not necessarily have
            // 'Add' permission for the public queries folder.
            using (new SystemAccount())
            {
                if (!string.IsNullOrEmpty(displayName))
                {
                    queryContent.DisplayName = displayName;
                }

                queryContent["Query"] = query;
                queryContent.Save();
            }

            return(queryContent);
        }
예제 #6
0
 public bool IsTrue(string predication)
 {
     return(IsTrue(SnQuery.Parse(predication, _queryContext)));
 }
예제 #7
0
        private static SnQuery BuildSnQuery(Expression expression, Type sourceCollectionItemType, string contextPath, ChildrenDefinition childrenDef, out string elementSelection)
        {
            SnQueryPredicate q0 = null;

            elementSelection = null;

            SnLinqVisitor v = null;

            // #1 compiling linq expression
            if (expression != null)
            {
                var v1    = new SetExecVisitor();
                var expr1 = v1.Visit(expression);
                var expr2 = expr1;
                if (v1.HasParameter)
                {
                    var v2 = new ExecutorVisitor(v1.GetExpressions());
                    expr2 = v2.Visit(expr1);
                }
                v = new SnLinqVisitor();
                v.Visit(expr2);
                q0 = v.GetPredicate(sourceCollectionItemType, childrenDef);
                elementSelection = v.ElementSelection;
            }

            // #2 combining with additional query clause
            SnQuery lq = null;

            if (!string.IsNullOrEmpty(childrenDef?.ContentQuery))
            {
                var queryText = TemplateManager.Replace(typeof(ContentQueryTemplateReplacer), childrenDef.ContentQuery);

                lq = SnQuery.Parse(queryText, new SnQueryContext(QuerySettings.Default, User.Current.Id));
                q0 = q0 == null
                    ? lq.QueryTree
                    : CombineQueries(q0, lq.QueryTree);
            }

            // #3 combining with context path
            if (q0 == null)
            {
                if (childrenDef != null && childrenDef.PathUsage != PathUsageMode.NotUsed && contextPath != null)
                {
                    q0 = GetPathPredicate(contextPath, childrenDef.PathUsage == PathUsageMode.InTreeAnd || childrenDef.PathUsage == PathUsageMode.InTreeOr);
                }
            }
            else
            {
                if (childrenDef != null && childrenDef.PathUsage != PathUsageMode.NotUsed && contextPath != null)
                {
                    q0 = CombinePathPredicate(q0, contextPath, childrenDef.PathUsage);
                }
            }

            // #4 empty query substitution
            if (q0 == null)
            {
                q0 = new RangePredicate(IndexFieldName.NodeId, new IndexValue(0), null, true, false);
            }

            var q1 = OptimizeBooleans(q0);

            // #5 configuring query by linq expression (the smallest priority)
            var query = SnQuery.Create(q1);

            if (v != null)
            {
                query.Skip          = v.Skip;
                query.Top           = v.Top;
                query.CountOnly     = v.CountOnly;
                query.Sort          = v.Sort.ToArray();
                query.ThrowIfEmpty  = v.ThrowIfEmpty;
                query.ExistenceOnly = v.ExistenceOnly;
            }
            // #6 configuring query by children definition
            if (childrenDef != null)
            {
                if (childrenDef.Skip > 0)
                {
                    query.Skip = childrenDef.Skip;
                }
                if (childrenDef.Top > 0)
                {
                    query.Top = childrenDef.Top;
                }
                if (childrenDef.Sort != null)
                {
                    query.Sort = childrenDef.Sort.ToArray();
                }
                if (childrenDef.CountAllPages != null)
                {
                    query.CountAllPages = childrenDef.CountAllPages.Value;
                }
                if (childrenDef.EnableAutofilters != FilterStatus.Default)
                {
                    query.EnableAutofilters = childrenDef.EnableAutofilters;
                }
                if (childrenDef.EnableLifespanFilter != FilterStatus.Default)
                {
                    query.EnableLifespanFilter = childrenDef.EnableLifespanFilter;
                }
                if (childrenDef.QueryExecutionMode != QueryExecutionMode.Default)
                {
                    query.QueryExecutionMode = childrenDef.QueryExecutionMode;
                }
            }

            // #7 configuring query by additional query clause (the biggest priority)
            if (lq != null)
            {
                if (lq.Skip > 0)
                {
                    query.Skip = lq.Skip;
                }
                if (lq.Top > 0 && lq.Top != int.MaxValue)
                {
                    query.Top = lq.Top;
                }
                if (lq.Sort != null && lq.Sort.Length > 0)
                {
                    query.Sort = lq.Sort;
                }
                if (lq.EnableAutofilters != FilterStatus.Default)
                {
                    query.EnableAutofilters = lq.EnableAutofilters;
                }
                if (lq.EnableLifespanFilter != FilterStatus.Default)
                {
                    query.EnableLifespanFilter = lq.EnableLifespanFilter;
                }
                if (lq.QueryExecutionMode != QueryExecutionMode.Default)
                {
                    query.QueryExecutionMode = lq.QueryExecutionMode;
                }
                if (lq.AllVersions)
                {
                    query.AllVersions = true;
                }
            }

            return(query);
        }