示例#1
0
        public void Test_Cycles()
        {
            var o = new TypeWithCycles();

            o.Self       = o;
            o.MyProperty = 5;
            o.Child      = new Sub1
            {
                Parent   = o,
                SubChild = new Sub1
                {
                    Parent   = o,
                    Prop1    = 7,
                    SubChild = new Sub1 {
                    }
                }
            };

            var c = ContentFactory.Default.CreateFrom(o);

            var arr = c.Visit().ToArray();

            Assert.IsTrue(arr.Any(p => p.Path.Equals(ContentPath.Parse("$.Child.SubChild.SubChild")) &&
                                  p.Value is ContentObject));

            Assert.IsTrue(arr.Any(p => p.Path.Equals(ContentPath.Parse("$.Child.SubChild.SubChild.Prop1")) &&
                                  p.Value is ContentNumber));

            Assert.IsTrue(arr.Any(p => p.Path.Equals(ContentPath.Parse("$.Child.SubChild.Prop1")) &&
                                  p.Value is ContentNumber));

            Assert.AreEqual(10, arr.Length);
        }
示例#2
0
        public void Test_Expressions()
        {
            var d = new Dictionary <string, object>
            {
                { "name", "John" }
            };

            var scope = new ContentObject(d, d, ContentFactory.Default);

            var e = new CreateObjectExpression(new List <CreateObjectExpression.Element>
            {
                new CreateObjectExpression.Attribute
                {
                    Name  = "name",
                    Value = new PathExpression(new ScopeRootExpression(), ContentPath.Parse("$.name"))
                },

                new CreateObjectExpression.Attribute
                {
                    Name  = "age",
                    Value = new ConstantExpression(new ContentNumber(45))
                }
            });

            var issue = e.TryEvaluate(scope, out IContentNode result);

            Assert.IsNull(issue);

            var jToken = result.ToJson();

            var poco = jToken.ToObject <R>();

            Assert.AreEqual("John", poco.name);
            Assert.AreEqual(45, poco.age);
        }
示例#3
0
        public void Test_Parser()
        {
            var left = new AndFilter(
                new EqualToFilter(
                    new PathExpression(new ScopeRootExpression(), ContentPath.Parse("$.Name")),
                    new ConstantExpression(new ContentText("Ahmad contains"))),
                new ContainsFilter(
                    new PathExpression(new ScopeRootExpression(), ContentPath.Parse("$.Friends")),
                    new ConstantExpression(new ContentText("Sameer"))));
            var issues = _parser.TryParse("$.Name EQUALS \"Ahmad contains\" AND $.Friends CONTAINS \"Sameer\"", out IContentExpression actual);

            Assert.AreEqual(left, actual);


            var right = new AndFilter(
                new EqualToFilter(
                    new PathExpression(new ScopeRootExpression(), ContentPath.Parse("$.Name")),
                    new ConstantExpression(new ContentText("Suzi 34"))),
                new ContainsFilter(
                    new PathExpression(new ScopeRootExpression(), ContentPath.Parse("$.Friends")),
                    new ConstantExpression(new ContentText("Sameer"))));

            issues = _parser.TryParse(
                "($.Name EQUALS \"Ahmad contains\" AND $.Friends CONTAINS \"Sameer\")" +
                " OR " +
                "($.Name EQUALS \"Suzi 34\" AND $.Friends CONTAINS \"Sameer\")",
                out actual);

            var combined = new OrFilter(left, right);

            Assert.AreEqual(combined, actual);
        }
示例#4
0
        public void InitialTest()
        {
            //var paths = new List<Path>()
            //{
            //    new Path()
            //    {
            //        id = 199,
            //        path = "$.Audit.CreatedOn",
            //    },
            //    new Path()
            //    {
            //        id = 150,
            //        path ="$.Name",
            //    }

            //    // ...etc.
            //};
            var paths = new Dictionary <string, int>
            {
                { "$.Audit.CreatedOn", 199 },
                { "$.Name", 150 },
                { "$.Id", 155 },
                // ...etc.
            };

            var docType    = new DocumentType(typeof(Employee));
            var queryLines = new List <SearchQuery.Line>()
            {
                new SearchQuery.Line(
                    ContentPath.Parse($"$.{nameof(Employee.Name)}")
                    , SearchQuery.Op.Equals, ContentFactory.Default.CreateFrom("John Smith")),
                new SearchQuery.Line(
                    ContentPath.Parse($"$.{nameof(Employee.Id)}")
                    , SearchQuery.Op.Equals, ContentFactory.Default.CreateFrom(1)),
            };
            var query              = new SearchQuery(docType, queryLines, ContentPath.Parse($"$.{nameof(Employee.Id)}"), false, 0, 20);
            var actual             = SqlResolver.ResolveSqlText(query, (s) => paths[s], "[search].[Docs]", "[search].[DocTokens]");
            var expectedWithSpaces = $@"SELECT [B].* FROM (SELECT DISTINCT filtered.DocumentId, Sorted.ValueAsAny FROM 
                ( SELECT f1.DocumentId FROM 
                    (    
                    SELECT DocumentId FROM [search].[DocTokens]  WITH (NOLOCK)
                    WHERE ([ValueAsAny]='John Smith' AND [PathId]=150) 
                     UNION ALL  
                    SELECT DocumentId FROM [search].[DocTokens] WITH (NOLOCK)
                    WHERE ([ValueAsAny]='011.000000' AND [PathId]=155) 
                    ) as f1 
			        group by f1.DocumentId HAVING count(*) >= {query.QueryLines.Length}               
                ) as filtered 
                LEFT JOIN (SELECT DocumentId,ValueAsAny FROM [search].[DocTokens] WITH (NOLOCK)
                WHERE [PathId] = {paths["$.Id"]}) as Sorted
                ON Sorted.DocumentId = filtered.DocumentId) AS [A] 
                INNER JOIN (SELECT * FROM [search].[Docs] WITH (NOLOCK)
                WHERE [SourceType] = '{query.DocumentType.Name}') AS [B] ON [A].DocumentId = [B].Id
                ORDER BY [A].ValueAsAny
                OFFSET {query.Offset} ROWS
                FETCH NEXT {query.Limit} ROWS ONLY";

            Assert.AreEqual(Regex.Replace(expectedWithSpaces, @"\s+", string.Empty), Regex.Replace(actual, @"\s+", string.Empty));
        }
示例#5
0
 private IContentPathCacheEntry ParseCacheEntry(ContentPathCacheEntryDto entry)
 {
     return(new ContentPathCacheEntryAdapter
     {
         ContentId = entry.ContentId,
         ContentType = LoadType(entry.ContentType),
         Path = ContentPath.Parse(entry.Path),
         HasChildren = entry.HasChildren,
     });
 }
示例#6
0
        public void NotNull()
        {
            var paths = new Dictionary <string, int>
            {
                { "$.Audit.CreatedOn", 199 },
                { "$.Name", 150 },
                { "$.Id", 155 },
                { "$.StartDate", 156 }
                // ...etc.
            };
            var docType    = new DocumentType(typeof(Employee));
            var queryLines = new List <SearchQuery.Line>()
            {
                new SearchQuery.Line(
                    ContentPath.Parse($"$.{nameof(Employee.StartDate)}")
                    , SearchQuery.Op.NotEquals, ContentFactory.Default.CreateFrom(null)),
                new SearchQuery.Line(
                    ContentPath.Parse($"$.{nameof(Employee.Name)}")
                    , SearchQuery.Op.GreaterThanOrEquals, ContentFactory.Default.CreateFrom(new DateTime(2019, 08, 01))),

                new SearchQuery.Line(
                    ContentPath.Parse($"$.{nameof(Employee.Name)}")
                    , SearchQuery.Op.LessThanOrEquals, ContentFactory.Default.CreateFrom(new DateTime(2019, 11, 27)))
            };
            var query  = new SearchQuery(docType, queryLines, ContentPath.Parse($"$.{nameof(Employee.Id)}"), true, 0, 20);
            var actual = SqlResolver.ResolveSqlText(query, (s) => paths[s], "[search].[Docs]", "[search].[DocTokens]");

            var expectedWithSpaces = $@"SELECT [B].* FROM (SELECT DISTINCT filtered.DocumentId, Sorted.ValueAsAny FROM 
                (
                     SELECT f1.DocumentId FROM 
                    (    
                        SELECT DocumentId FROM [search].[DocTokens] WITH (NOLOCK) 
                        WHERE ([ValueAsAny] IS NOT NULL AND [PathId]=156)
                        UNION ALL
                        SELECT DocumentId FROM [search].[DocTokens] WITH (NOLOCK) 
                            WHERE ([ValueAsAny]>='2019-08-01T00:00:00.0000000' AND [PathId]=150)
                        UNION ALL
                        SELECT DocumentId FROM [search].[DocTokens] WITH (NOLOCK) 
                        WHERE ([ValueAsAny]<='2019-11-27T00:00:00.0000000' AND [PathId]=150)
                    ) as f1 
			        group by f1.DocumentId HAVING count(*) >= {query.QueryLines.Length} 
                     
                ) as filtered 
                LEFT JOIN (SELECT DocumentId,ValueAsAny FROM [search].[DocTokens] WITH (NOLOCK)
                WHERE [PathId] = {paths["$.Id"]}) as Sorted
                ON Sorted.DocumentId = filtered.DocumentId
                ) AS [A] 
                INNER JOIN (SELECT * FROM [search].[Docs] WITH (NOLOCK)
                WHERE [SourceType] = '{query.DocumentType}') AS [B] ON [A].DocumentId = [B].Id
                ORDER BY [A].ValueAsAny DESC 
                OFFSET {query.Offset} ROWS
                FETCH NEXT {query.Limit} ROWS ONLY";

            Assert.AreEqual(Regex.Replace(expectedWithSpaces, @"\s+", string.Empty), Regex.Replace(actual, @"\s+", string.Empty));
        }
示例#7
0
 public void GetChildrenByPath()
 {
     foreach (var root in _testContext.Roots)
     {
         foreach (var child in root.Children)
         {
             var contentInfo = _contentManager.GetContentByPath(_testContext, ContentPath.Parse(child.Alias));
             Assert.Equal(child, contentInfo.Content);
         }
     }
 }
示例#8
0
        public void Test_Parser()
        {
            var subObject = new CreateObjectExpression(new List <CreateObjectExpression.Element>
            {
                new CreateObjectExpression.Attribute
                {
                    Name  = "subName",
                    Value = new PathExpression(new ScopeRootExpression(), ContentPath.Parse("$.name"))
                },

                new CreateObjectExpression.Attribute
                {
                    Name  = "subAge",
                    Value = new ConstantExpression(new ContentNumber(45))
                }
            });

            Test("{ name: $.name, age: 45, ...{ subName: $.name, subAge: 45 } }", new CreateObjectExpression(new List <CreateObjectExpression.Element>
            {
                new CreateObjectExpression.Attribute
                {
                    Name  = "name",
                    Value = new PathExpression(new ScopeRootExpression(), ContentPath.Parse("$.name"))
                },

                new CreateObjectExpression.Attribute
                {
                    Name  = "age",
                    Value = new ConstantExpression(new ContentNumber(45))
                },

                new CreateObjectExpression.Object
                {
                    SubObject = subObject
                }
            }));

            Test("{}", new CreateObjectExpression(new CreateObjectExpression.Element[] { }));

            Test("[]", new CreateListExpression(new CreateListExpression.Element[] { }));

            Test("\"Yaser\"", new ConstantExpression(ContentFactory.Default.CreateFrom("Yaser")));

            Test("[45]", new CreateListExpression(new CreateListExpression.Element[]
            {
                new CreateListExpression.ListItem
                {
                    Value = new ConstantExpression(ContentFactory.Default.CreateFrom(45))
                }
            }));
        }
        public void Test_QueryHandlerAnyOf()
        {
            var list = ContentFactory.Default.CreateFrom(new[] { "123", "456" });

            var a = (list as ContentList).ToArray();

            Assert.IsInstanceOfType(a[0], typeof(ContentText));

            Assert.IsInstanceOfType(a[1], typeof(ContentText));

            var line = new SearchQuery.Line(ContentPath.Parse("$.Number.Value"), SearchQuery.Op.AnyOf, list);

            //var expr = QueryConversionHelper.BuildCriteriaExpr(line);
        }
示例#10
0
        public void AnyOf()
        {
            var paths = new Dictionary <string, int>
            {
                { "$.Audit.CreatedOn", 199 },
                { "$.Name", 150 },
                { "$.Id", 155 },
                { "$.Phones", 156 },
                // ...etc.
            };
            var docType    = new DocumentType(typeof(Employee));
            var queryLines = new List <SearchQuery.Line>()
            {
                new SearchQuery.Line(
                    ContentPath.Parse($"$.{nameof(Employee.Phones)}")
                    , SearchQuery.Op.AnyOf, ContentFactory.Default.CreateFrom(new string[] { "0001ddd", "0002ddd", "0003ddd" })),

                new SearchQuery.Line(
                    ContentPath.Parse($"$.{nameof(Employee.Name)}")
                    , SearchQuery.Op.AnyOf, ContentFactory.Default.CreateFrom(new int[] { 1, 2, 3 }))
            };
            var query = new SearchQuery(docType, queryLines, ContentPath.Parse($"$.{nameof(Employee.Id)}"), true, 0, 20);

            var actual             = SqlResolver.ResolveSqlText(query, (s) => paths[s], "[search].[Docs]", "[search].[DocTokens]");
            var expectedWithSpaces = $@"SELECT [B].* FROM (SELECT DISTINCT filtered.DocumentId, Sorted.ValueAsAny FROM 
                (
                    SELECT f1.DocumentId FROM 
                    (    
                        SELECT DocumentId FROM [search].[DocTokens] WITH (NOLOCK) 
                        WHERE ([ValueAsAny] IN ('0001ddd','0002ddd','0003ddd') AND [PathId]=156) 
                        UNION ALL
                        SELECT DocumentId FROM [search].[DocTokens] WITH (NOLOCK)
                        WHERE ([ValueAsAny] IN ('011.000000','012.000000','013.000000') AND [PathId]=150) 
                    ) as f1 
			        group by f1.DocumentId HAVING count(*) >= {query.QueryLines.Length}  
                ) as filtered 
                LEFT JOIN (SELECT DocumentId,ValueAsAny FROM [search].[DocTokens] WITH (NOLOCK)
                WHERE [PathId] = 155) as Sorted
                ON Sorted.DocumentId = filtered.DocumentId
               ) AS [A] 
                INNER JOIN (SELECT * FROM [search].[Docs] WITH (NOLOCK)
                WHERE [SourceType] = '{query.DocumentType.Name}') AS [B] ON [A].DocumentId = [B].Id
                ORDER BY [A].ValueAsAny DESC
                OFFSET {query.Offset} ROWS
                FETCH NEXT {query.Limit} ROWS ONLY";

            Assert.AreEqual(Regex.Replace(expectedWithSpaces, @"\s+", string.Empty), Regex.Replace(actual, @"\s+", string.Empty));
        }
示例#11
0
        public void Test_ContentPathParsing()
        {
            Assert.IsFalse(ContentPath.TryParse("", out ContentPath _));
            Assert.IsFalse(ContentPath.TryParse(".", out _));
            Assert.IsFalse(ContentPath.TryParse(".ff", out _));
            Assert.IsFalse(ContentPath.TryParse("3ff.", out _));

            var p1 = ContentPath.Parse("$.a.FAERF_Ar");
            var p2 = ContentPath.Root.Append("a").Append("FAERF_Ar");

            Assert.IsTrue(p1.Equals(p2));

            Assert.IsTrue(ContentPath.Parse("$").Equals(ContentPath.Root));


            Assert.IsTrue(p1.Equals(ContentPath.Parse(p1.ToString())));
            Assert.IsTrue(ContentPath.Root.Equals(ContentPath.Parse(ContentPath.Root.ToString())));
        }
示例#12
0
        public void Test_Evaluation()
        {
            var employee = Employee.Sample;

            var document = ContentFactory.Default.CreateFrom(employee);

            IContentNode actual = null;

            document.TryEvaluate(ContentPath.Parse("$.Name"), out actual);
            Assert.AreEqual(new ContentText(employee.Name), actual);

            document.TryEvaluate(ContentPath.Parse("$.Data.FavColor"), out actual);
            Assert.AreEqual(new ContentText("red"), actual);

            var result = document.TryEvaluate(ContentPath.Parse("$.Data.Start_ingSalary.Amount"), out actual);

            Assert.IsFalse(result);

            document.TryEvaluate(ContentPath.Parse("$.Data.StartingSalary.Amount"), out actual);
            Assert.AreEqual(new ContentNumber(500.57m), actual);

            // Test JSON

            var jsonText = JsonConvert.SerializeObject(employee);

            var jToken = JsonConvert.DeserializeObject <JToken>(jsonText);

            document = ContentFactory.Default.CreateFrom(jToken);

            document.TryEvaluate(ContentPath.Parse("$.Name"), out actual);
            Assert.AreEqual(new ContentText(employee.Name), actual);

            document.TryEvaluate(ContentPath.Parse("$.Data.FavColor"), out actual);
            Assert.AreEqual(new ContentText("red"), actual);

            result = document.TryEvaluate(ContentPath.Parse("$.Data.Start_ingSalary.Amount"), out actual);
            Assert.IsFalse(result);

            document.TryEvaluate(ContentPath.Parse("$.Data.StartingSalary.Amount"), out actual);
            Assert.AreEqual(new ContentNumber(500.57m), actual);
        }
示例#13
0
        public void EmptyQuery()
        {
            var paths = new Dictionary <string, int>
            {
                { "$.Audit.CreatedOn", 199 },
                { "$.Id", 155 },


                // ...etc.
            };
            var docType    = new DocumentType(typeof(Employee));
            var queryLines = new List <SearchQuery.Line>();

            var query  = new SearchQuery(docType, queryLines, ContentPath.Parse($"$.{nameof(Employee.Id)}"), true, 0, 20);
            var actual = SqlResolver.ResolveSqlText(query, (s) => paths[s], "[search].[Docs]", "[search].[DocTokens]");

            var expectedWithSpaces = $@"SELECT [B].* FROM (SELECT DISTINCT filtered.DocumentId, Sorted.ValueAsAny FROM 
                (
                     SELECT f1.DocumentId FROM 
                        (    
                            SELECT DocumentId FROM [search].[DocTokens] WITH (NOLOCK) Group by [DocumentId]

                        ) as f1 
			        group by f1.DocumentId HAVING count(*) >= {query.QueryLines.Length} 
                ) as filtered 
                LEFT JOIN (SELECT DocumentId,ValueAsAny FROM [search].[DocTokens] WITH (NOLOCK)
                WHERE [PathId] = {paths["$.Id"]}) as Sorted
                ON Sorted.DocumentId = filtered.DocumentId
                ) AS [A] 
                INNER JOIN (SELECT * FROM [search].[Docs] WITH (NOLOCK)
                WHERE [SourceType] = '{query.DocumentType}') AS [B] ON [A].DocumentId = [B].Id 
                ORDER BY [A].ValueAsAny DESC
                OFFSET 0 ROWS
                FETCH NEXT 20 ROWS ONLY";

            Assert.AreEqual(Regex.Replace(expectedWithSpaces, @"\s+", string.Empty), Regex.Replace(actual, @"\s+", string.Empty));
        }
示例#14
0
        IContentExpression ParseExpression(Queue <DslToken> q, Func <DslToken, bool> terminate)
        {
            IContentExpression exp = null;

            while (q.Count > 0)
            {
                var lookAhead = q.Peek();

                if (terminate(lookAhead))
                {
                    break;
                }

                else if (lookAhead.IsConstant())
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(Utils.ConstantTokens);
                    exp = CreateConstant(token);
                }

                else if (lookAhead.TokenType == TokenType.Equals)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.Equals);
                    exp = new EqualToFilter(exp,
                                            ParseExpression(q, t => t.TokenType == TokenType.And || t.TokenType == TokenType.Or || terminate(t)));
                }

                else if (lookAhead.TokenType == TokenType.Contains)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.Contains);
                    exp = new ContainsFilter(exp,
                                             ParseExpression(q, t => t.TokenType == TokenType.And || t.TokenType == TokenType.Or || terminate(t)));
                }

                else if (lookAhead.TokenType == TokenType.MatchRegex)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token   = q.DequeueAndValidate(TokenType.MatchRegex);
                    var pattern = q.DequeueAndValidate(TokenType.String);
                    exp = new RegexFilter(exp, pattern.Value);
                }

                else if (lookAhead.TokenType == TokenType.And)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.And);
                    if (exp is IContentFilter leftBool)
                    {
                        var right = ParseExpression(q, terminate);
                        if (right is IContentFilter rightBool)
                        {
                            exp = new AndFilter(leftBool, rightBool);
                        }
                        else
                        {
                            throw new ParserException("AND cannot have a right operand that does not yield boolean", token);
                        }
                    }
                    else
                    {
                        throw new ParserException("AND cannot have a left operand that does not yield boolean", token);
                    }
                }

                else if (lookAhead.TokenType == TokenType.Or)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.Or);
                    if (exp is IContentFilter leftBool)
                    {
                        var right = ParseExpression(q, terminate);
                        if (right is IContentFilter rightBool)
                        {
                            exp = new OrFilter(leftBool, rightBool);
                        }
                        else
                        {
                            throw new ParserException("OR cannot have a right operand that does not yield boolean", token);
                        }
                    }
                    else
                    {
                        throw new ParserException("OR cannot have a left operand that does not yield boolean", token);
                    }
                }

                else if (lookAhead.TokenType == TokenType.Path)
                {
                    if (exp == null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    var token = q.DequeueAndValidate(TokenType.Path);
                    exp = new PathExpression(exp, ContentPath.Parse($"$.{token.Value.TrimStart('.')}"));
                }

                else if (lookAhead.TokenType == TokenType.DollarSign)
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    q.DequeueAndValidate(TokenType.DollarSign);
                    exp = new ScopeRootExpression();
                }

                else if (lookAhead.TokenType == TokenType.OpenCurly)
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    exp = CreateObjectExpression(q);
                }

                else if (lookAhead.TokenType == TokenType.OpenSquareBracket)
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    exp = CreateListExpression(q);
                }

                else if (lookAhead.TokenType == TokenType.OpenBracket)
                {
                    if (exp != null)
                    {
                        throw new ParserException($"Unexpected token", lookAhead);
                    }
                    q.DequeueAndValidate(TokenType.OpenBracket);  // open bracket (
                    exp = ParseExpression(q, t => t.TokenType == TokenType.CloseBracket);
                    q.DequeueAndValidate(TokenType.CloseBracket); // close bracket )
                }
                else
                {
                    throw new ParserException($"Unexpected token", lookAhead);
                }
            }

            if (exp == null)
            {
                throw new ParserException($"Unexpected end", null);
            }

            return(exp);
        }