示例#1
0
        public void TestSelectRegexFilter()
        {
            // Arrange
            graph = new RDFGraph();
            RDFSelectQuery query;

            BuildGraph(graph);

            // Act
            query = new RDFSelectQuery();
            var x            = new RDFVariable("x");
            var y            = new RDFVariable("y");
            var z            = new RDFVariable("z");
            var patternGroup = new RDFPatternGroup("PatternGroup1").AddPattern(new RDFPattern(x, y, z));

            var filter = new RDFRegexFilter(x, new Regex(@".1$", RegexOptions.IgnoreCase)); // Filter subjects ending with 1

            patternGroup.AddFilter(filter);

            query.AddPatternGroup(patternGroup)
            .AddProjectionVariable(x)
            .AddProjectionVariable(y)
            .AddProjectionVariable(z);

            var result = query.ApplyToGraph(graph);

            // Assert
            Assert.AreEqual(3, result.SelectResultsCount);
        }
        /// <summary>
        /// Apply the filters of the given pattern group to its result table
        /// </summary>
        internal static void ApplyFilters(RDFDescribeQuery query, RDFPatternGroup patternGroup) {
            if (patternGroup.Patterns.Any() && patternGroup.Filters.Any()) {
                DataTable filteredTable  = query.PatternGroupResultTables[patternGroup].Clone();
                IEnumerator rowsEnum     = query.PatternGroupResultTables[patternGroup].Rows.GetEnumerator();

                //Iterate the rows of the pattern group's result table
                Boolean keepRow          = false;
                while (rowsEnum.MoveNext()) {

                    //Apply the pattern group's filters on the row
                    keepRow              = true;
                    IEnumerator<RDFFilter> filtersEnum       = patternGroup.Filters.GetEnumerator();
                    while (keepRow      && filtersEnum.MoveNext()) {
                        keepRow          = filtersEnum.Current.ApplyFilter((DataRow)rowsEnum.Current, false);
                    }

                    //If the row has passed all the filters, keep it in the filtered result table
                    if (keepRow) {
                        DataRow newRow   = filteredTable.NewRow();
                        newRow.ItemArray = ((DataRow)rowsEnum.Current).ItemArray;
                        filteredTable.Rows.Add(newRow);
                    }

                }

                //Save the result datatable
                query.PatternGroupResultTables[patternGroup] = filteredTable;
            }
        }
示例#3
0
        public void TestSelectNumericAggregators()
        {
            // Arrange
            graph = new RDFGraph();
            RDFSelectQuery query;

            BuildGraphWithValues(graph);

            // Act
            query = new RDFSelectQuery();
            var x             = new RDFVariable("x");
            var type          = new RDFVariable("type");
            var value         = new RDFVariable("value");
            var patternGroup1 = new RDFPatternGroup("PatternGroup1").AddPattern(new RDFPattern(x, RDF.TYPE, type));
            var patternGroup2 = new RDFPatternGroup("PatternGroup2").AddPattern(new RDFPattern(x, RDF.VALUE, value));

            query.AddPatternGroup(patternGroup1)
            .AddPatternGroup(patternGroup2)
            .AddProjectionVariable(type);

            var gm = new RDFGroupByModifier(new List <RDFVariable>()
            {
                type
            });

            gm.AddAggregator(new RDFAvgAggregator(value, new RDFVariable("avg")));
            gm.AddAggregator(new RDFSumAggregator(value, new RDFVariable("sum")));
            gm.AddAggregator(new RDFCountAggregator(value, new RDFVariable("count")));
            gm.AddAggregator(new RDFMinAggregator(value, new RDFVariable("min"), RDFQueryEnums.RDFMinMaxAggregatorFlavors.Numeric));
            gm.AddAggregator(new RDFMaxAggregator(value, new RDFVariable("max"), RDFQueryEnums.RDFMinMaxAggregatorFlavors.Numeric));

            query.AddModifier(gm);

            var result = query.ApplyToGraph(graph);

            // Assert
            var row = result.SelectResults.AsEnumerable().ElementAt(0);

            // average
            string resultStr = (string)row.ItemArray.ElementAt(1);
            int    resultNum = int.Parse(resultStr.Split('^')[0]);

            Assert.AreEqual(30, resultNum);
            // sum
            resultStr = (string)row.ItemArray.ElementAt(2);
            resultNum = int.Parse(resultStr.Split('^')[0]);
            Assert.AreEqual(150, resultNum);
            // count
            resultStr = (string)row.ItemArray.ElementAt(3);
            resultNum = int.Parse(resultStr.Split('^')[0]);
            Assert.AreEqual(5, resultNum);
            // min
            resultStr = (string)row.ItemArray.ElementAt(4);
            resultNum = int.Parse(resultStr.Split('^')[0]);
            Assert.AreEqual(10, resultNum);
            // max
            resultStr = (string)row.ItemArray.ElementAt(5);
            resultNum = int.Parse(resultStr.Split('^')[0]);
            Assert.AreEqual(50, resultNum);
        }
示例#4
0
        public void CreatePatternGroupTest()
        {
            //Arrange
            var pg1 = new RDFPatternGroup("PG1");

            //Assert
            Assert.Equal("PG1", pg1.PatternGroupName);
        }
示例#5
0
 /// <summary>
 /// Adds the given pattern group to the query
 /// </summary>
 public RDFAskQuery AddPatternGroup(RDFPatternGroup patternGroup)
 {
     if (patternGroup != null) {
         if (!this.PatternGroups.Exists(pg => pg.PatternGroupName.Equals(patternGroup.PatternGroupName, StringComparison.Ordinal))) {
              this.PatternGroups.Add(patternGroup);
         }
     }
     return this;
 }
示例#6
0
        public void CreateComparisonFilter()
        {
            //Arrange
            var y      = new RDFVariable("y");
            var filter = new RDFComparisonFilter(RDFQueryEnums.RDFComparisonFlavors.LessThan, y, new RDFPlainLiteral("25"));
            var pg1    = new RDFPatternGroup("PG1");

            //Act
            pg1.AddFilter(filter);

            //Assert
            Assert.Contains(filter.ToString(), pg1.ToString());
        }
示例#7
0
        public void CreateIsNumericFilter()
        {
            //Arrange
            var x      = new RDFVariable("x");
            var filter = new RDFIsUriFilter(x);
            var pg1    = new RDFPatternGroup("PG1");

            //Act
            pg1.AddFilter(filter);

            //Assert
            Assert.Contains(filter.ToString(), pg1.ToString());
        }
示例#8
0
        public void CreateLangMatchesFilter()
        {
            //Arrange
            var n      = new RDFVariable("n");
            var filter = new RDFLangMatchesFilter(n, "it-IT");
            var pg1    = new RDFPatternGroup("PG1");

            //Act
            pg1.AddFilter(filter);

            //Assert
            Assert.Contains(filter.ToString(), pg1.ToString());
        }
示例#9
0
        public void CreateRegexFilter()
        {
            //Arrange
            var n      = new RDFVariable("n");
            var filter = new RDFRegexFilter(n, new Regex(@"Mouse", RegexOptions.IgnoreCase));
            var pg1    = new RDFPatternGroup("PG1");

            //Act
            pg1.AddFilter(filter);

            //Assert
            Assert.Contains(filter.ToString(), pg1.ToString());
        }
示例#10
0
        public void CreateSameTermFilter()
        {
            //Arrange
            var x      = new RDFVariable("x");
            var filter = new RDFSameTermFilter(x, donaldduck);
            var pg1    = new RDFPatternGroup("PG1");

            //Act
            pg1.AddFilter(filter);

            //Assert
            Assert.Contains(filter.ToString(), pg1.ToString());
        }
示例#11
0
        public void AskQueryResultFalseTest()
        {
            //Arrange
            var y            = new RDFVariable("y");
            var askQuery     = new RDFAskQuery();
            var patternGroup = new RDFPatternGroup("PatternGroup");

            patternGroup.AddPattern(new RDFPattern(donaldduck, y, new RDFTypedLiteral("90", RDFModelEnums.RDFDatatypes.XSD_INTEGER)));
            askQuery.AddPatternGroup(patternGroup);

            //Act
            var result = askQuery.ApplyToGraph(graph);

            //Assert
            Assert.False(result.AskResult);
        }
示例#12
0
        public void SelectQueryResultTest()
        {
            //Arrange
            var x            = new RDFVariable("x");
            var q            = new RDFSelectQuery();
            var patternGroup = new RDFPatternGroup("PatternGroup");

            patternGroup.AddPattern(new RDFPattern(x, RDFVocabulary.FOAF.AGE, new RDFTypedLiteral("85", RDFModelEnums.RDFDatatypes.XSD_INTEGER)));
            q.AddPatternGroup(patternGroup);

            //Act
            var selectResult = q.ApplyToGraph(graph);

            //Assert
            Assert.Equal(2, selectResult.SelectResultsCount);
        }
        /// <summary>
        /// Get the intermediate result tables of the given pattern group
        /// </summary>
        internal static void EvaluatePatterns(RDFDescribeQuery query, RDFPatternGroup patternGroup, Object graphOrStore) {
            query.PatternResultTables[patternGroup] = new List<DataTable>();

            //Iterate over the patterns of the pattern group
            foreach (RDFPattern pattern in patternGroup.Patterns) {

                //Apply the pattern to the graph/store
                DataTable patternResultsTable       = graphOrStore is RDFGraph ? RDFQueryEngine.ApplyPattern(pattern, (RDFGraph)graphOrStore)
                                                                               : RDFQueryEngine.ApplyPattern(pattern, (RDFStore)graphOrStore);

                //Set the name and the optionality metadata of the result datatable
                patternResultsTable.TableName       = pattern.ToString();
                patternResultsTable.ExtendedProperties.Add("IsOptional", pattern.IsOptional);
                patternResultsTable.ExtendedProperties.Add("JoinAsUnion", pattern.JoinAsUnion);

                //Save the result datatable
                query.PatternResultTables[patternGroup].Add(patternResultsTable);

            }
        }
示例#14
0
        private RDFSelectQuery BuildSelectAllQuery(RDFFilter filter = null)
        {
            var query        = new RDFSelectQuery();
            var x            = new RDFVariable("x");
            var y            = new RDFVariable("y");
            var z            = new RDFVariable("z");
            var patternGroup = new RDFPatternGroup("PatternGroup1").AddPattern(new RDFPattern(x, y, z));

            if (filter != null)
            {
                patternGroup.AddFilter(filter);
            }

            query.AddPatternGroup(patternGroup)
            .AddProjectionVariable(x)
            .AddProjectionVariable(y)
            .AddProjectionVariable(z);

            return(query);
        }
        /// <summary>
        /// Get the result table of the given pattern group
        /// </summary>
        internal static void CombinePatterns(RDFDescribeQuery query, RDFPatternGroup patternGroup) {
            if (patternGroup.Patterns.Any()) {

                //Populate pattern group result table
                DataTable patternGroupResultTable                      = RDFQueryEngine.CombineTables(query.PatternResultTables[patternGroup], false);

                //Add it to the list of pattern group result tables
                query.PatternGroupResultTables.Add(patternGroup, patternGroupResultTable);

                //Populate its metadata
                query.PatternGroupResultTables[patternGroup].TableName = patternGroup.ToString();
                if (!query.PatternGroupResultTables[patternGroup].ExtendedProperties.ContainsKey("IsOptional")) {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties.Add("IsOptional", patternGroup.IsOptional);
                }
                else {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties["IsOptional"]  = patternGroup.IsOptional;
                }
                if (!query.PatternGroupResultTables[patternGroup].ExtendedProperties.ContainsKey("JoinAsUnion")) {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties.Add("JoinAsUnion", patternGroup.JoinAsUnion);
                }
                else {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties["JoinAsUnion"] = patternGroup.JoinAsUnion;
                }

            }
        }
示例#16
0
        /// <summary>
        /// WORKING WITH SPARQL QUERIES
        /// </summary>
        private void WorkingWithQueries(RDFGraph graph, RDFResource donaldduck)
        {
            RDFSelectQuery selectQuery = new RDFSelectQuery();

            // CREATE VARIABLE
            var x = new RDFVariable("x"); // ?X
            var y = new RDFVariable("y"); // ?Y
            var n = new RDFVariable("n"); // ?N
            var c = new RDFVariable("c"); // ?C

            // CREATE PATTERNS
            var dogOf       = new RDFResource(RDFVocabulary.DC.BASE_URI + "dogOf");
            var y_dogOf_x   = new RDFPattern(y, dogOf, x);    // TRIPLE PATTERN
            var c_y_dogOf_x = new RDFPattern(c, y, dogOf, x); // QUADRUPLE PATTERN


            // CREATE EMPTY PATTERN GROUP
            var pg1 = new RDFPatternGroup("PG1");

            // CREATE PATTERN GROUP FROM A LIST OF PATTERNS
            var patterns = new List <RDFPattern>()
            {
                y_dogOf_x
            };
            var pg2 = new RDFPatternGroup("PG2", patterns);

            // ADD PATTERNS TO PATTERN GROUP
            pg1.AddPattern(y_dogOf_x);
            pg1.AddPattern(c_y_dogOf_x);


            // ADD PATTERN GROUPS TO QUERY
            selectQuery.AddPatternGroup(pg1);
            selectQuery.AddPatternGroup(pg2);

            // ADD FILTERS TO PATTERN GROUP
            pg1.AddFilter(new RDFSameTermFilter(new RDFVariable("character"), donaldduck));
            pg1.AddFilter(new RDFLangMatchesFilter(n, "it-IT"));


            // ADD MODIFIERS TO QUERY
            selectQuery.AddModifier(new RDFOrderByModifier(n, RDFQueryEnums.RDFOrderByFlavors.ASC));
            selectQuery.AddModifier(new RDFDistinctModifier());
            selectQuery.AddModifier(new RDFGroupByModifier(new List <RDFVariable> {
                x
            }));
            selectQuery.AddModifier(new RDFLimitModifier(100));
            selectQuery.AddModifier(new RDFOffsetModifier(25));


            // INITIALIZE PROPERTY PATH (VARIABLE TERMS)
            var variablePropPath = new RDFPropertyPath(new RDFVariable("START"), new RDFVariable("END"));
            // INITIALIZE PROPERTY PATH (MIXED TERMS)
            var mixedPropPath = new RDFPropertyPath(new RDFResource("http://res.org/"), new RDFVariable("END"));


            //ADD SEQUENCE STEPS TO PROPERTY PATH
            variablePropPath.AddSequenceStep(new
                                             RDFPropertyPathStep(new RDFResource("rdf:P1")));
            variablePropPath.AddSequenceStep(new
                                             RDFPropertyPathStep(new RDFResource("rdf:P2")));

            //ADD ALTERNATIVE STEPS TO PROPERTY PATH
            var altSteps = new List <RDFPropertyPathStep>();

            altSteps.Add(new RDFPropertyPathStep(new
                                                 RDFResource("rdf:P3")));
            altSteps.Add(new RDFPropertyPathStep(new
                                                 RDFResource("rdf:P7")));
            variablePropPath.AddAlternativeSteps(altSteps);


            // ADD INVERSE SEQUENCE STEP TO PROPERTY PATH: ?START ^rdf:INVP ?END
            variablePropPath.AddSequenceStep(new RDFPropertyPathStep(new RDFResource("rdf:INVP")).Inverse());

            //ADD ALTERNATIVE STEPS (ONE INVERSE) TO PROPERTY PATH: ?START (rdf:P3|^rdf:INVP3) ?END
            var altSteps2 = new List <RDFPropertyPathStep>();

            altSteps2.Add(new RDFPropertyPathStep(new RDFResource("rdf:P3")));
            altSteps2.Add(new RDFPropertyPathStep(new RDFResource("rdf:INVP3")).Inverse());
            variablePropPath.AddAlternativeSteps(altSteps2);

            // ADD SUBQUERY TO QUERY
            RDFSelectQuery mySubQuery = new RDFSelectQuery();

            selectQuery.AddSubQuery(mySubQuery);


            // ADD AGGREGATORS TO GROUPBY MODIFIER
            RDFGroupByModifier gm = new RDFGroupByModifier(new List <RDFVariable> {
                x
            });

            gm.AddAggregator(new RDFAvgAggregator(new RDFVariable("age"), new RDFVariable("avg_age")));
            gm.AddAggregator(new RDFCountAggregator(new RDFVariable("dept"), new RDFVariable("count_dept")));
            gm.AddAggregator(new RDFGroupConcatAggregator(new RDFVariable("name"), new RDFVariable("gc_name"), "-"));
            gm.AddAggregator(new RDFSampleAggregator(new RDFVariable("name"), new RDFVariable("sample_name")));
            gm.AddAggregator(new RDFSumAggregator(new RDFVariable("salary"), new RDFVariable("sum_salary")));
            gm.AddAggregator(new RDFMinAggregator(new RDFVariable("age"), new RDFVariable("min_age"),
                                                  RDFQueryEnums.RDFMinMaxAggregatorFlavors.Numeric)); //?age is expected to have numeric typedliterals
            gm.AddAggregator(new RDFMinAggregator(new RDFVariable("city"), new RDFVariable("min_city"),
                                                  RDFQueryEnums.RDFMinMaxAggregatorFlavors.String));
            gm.AddAggregator(new RDFMaxAggregator(new RDFVariable("salary"), new RDFVariable("max_salary"),
                                                  RDFQueryEnums.RDFMinMaxAggregatorFlavors.Numeric)); //?salary is expected to have numeric typedliterals
            gm.AddAggregator(new RDFMaxAggregator(new RDFVariable("city"), new RDFVariable("min_city"),
                                                  RDFQueryEnums.RDFMinMaxAggregatorFlavors.String));


            // It is possible to filter a group - by partitioned set of SPARQL results by applying the SetHavingClause operator on desired aggregators:

            // ADD AGGREGATORS TO GROUPBY MODIFIER
            RDFModelEnums.RDFDatatypes xsdDbl = RDFModelEnums.RDFDatatypes.XSD_DOUBLE;
            RDFModelEnums.RDFDatatypes xsdInt = RDFModelEnums.RDFDatatypes.XSD_INT;
            gm.AddAggregator(new RDFAvgAggregator(new RDFVariable("age"), new RDFVariable("avg_age"))
                             .SetHavingClause(RDFQueryEnums.RDFComparisonFlavors.GreaterThan, new RDFTypedLiteral("25.5", xsdDbl))
                             );
            gm.AddAggregator(new RDFCountAggregator(new RDFVariable("dept"), new RDFVariable("count_dept"))
                             .SetHavingClause(RDFQueryEnums.RDFComparisonFlavors.EqualTo, new RDFTypedLiteral("4", xsdInt))
                             );


            //Declare the following SPARQL values:

            /*
             * VALUES (?a ?b ?c) {
             * ("1" "2" "3")
             * ("2" "4" "6")
             * ("3" "6" UNDEF)
             * }
             */
            RDFValues myValues = new RDFValues()
                                 .AddColumn(new RDFVariable("a"),
                                            new List <RDFPatternMember>()
            {
                new RDFPlainLiteral("1"),
                new RDFPlainLiteral("2"),
                new RDFPlainLiteral("3")
            })
                                 .AddColumn(new RDFVariable("b"),
                                            new List <RDFPatternMember>()
            {
                new RDFPlainLiteral("2"),
                new RDFPlainLiteral("4"),
                new RDFPlainLiteral("6")
            })
                                 .AddColumn(new RDFVariable("c"),
                                            new List <RDFPatternMember>()
            {
                new RDFPlainLiteral("3"),
                new RDFPlainLiteral("6"),
                null     //UNDEF
            });

            // ADD PROPERTY PATH TO PATTERN GROUP
            pg1.AddValues(myValues);

            // CREATING AND EXECUTING SELECT QUERIES



            // APPLY SELECT QUERY TO GRAPH
            RDFSelectQueryResult selectQueryResult = selectQuery.ApplyToGraph(graph);

            // APPLY SELECT QUERY TO STORE
            //RDFSelectQueryResult selectQueryResult = selectQuery.ApplyToStore(store);
            // APPLY SELECT QUERY TO FEDERATION
            //RDFSelectQueryResult selectQueryResult = selectQuery.ApplyToFederation(federation);

            // EXPORT SELECT QUERY RESULTS TO SPARQL XML FORMAT (FILE)
            selectQueryResult.ToSparqlXmlResult(@"C:\TMP\select_results.srq");
            // EXPORT SELECT QUERY RESULTS TO SPARQL XML FORMAT (STREAM)
            //selectQueryResult.ToSparqlXmlResult(myStream);
            // IMPORT SELECT QUERY RESULTS FROM SPARQL XML FORMAT (FILE)
            selectQueryResult = RDFSelectQueryResult.FromSparqlXmlResult(@"C:\TMP\select_results.srq");
            // IMPORT SELECT QUERY RESULTS FROM SPARQL XML FORMAT (STREAM)
            //selectQueryResult = RDFSelectQueryResult.FromSparqlXmlResult(myStream);
        }
        public void Test1()
        {
            string   filePath = GetPath(@"Files\Test1.ttl");
            RDFGraph graph    = RDFGraph.FromFile(RDFModelEnums.RDFFormats.Turtle, filePath);

            RDFSelectQuery selectQuery = new RDFSelectQuery();

            // PREFIX foaf: <http://xmlns.com/foaf/0.1/>
            selectQuery.AddPrefix(RDFNamespaceRegister.GetByPrefix("foaf"));

            // ?NAME
            var name = new RDFVariable("name");
            // ?FRIEND
            var friend = new RDFVariable("friend");
            // ?PERSON
            var person = new RDFVariable("person");

            // ?PERSON foaf:name ?NAME .
            var person_foaf_name_name = new RDFPattern(person, RDFVocabulary.FOAF.NAME, name);
            // ?PERSON foaf:knows ?FRIEND .
            var person_foaf_knows_friend = new RDFPattern(person, RDFVocabulary.FOAF.KNOWS, friend);

// WHERE {
//  {
//    ?PERSON foaf:name? NAME .
//    ?PERSON foaf:knows? FRIEND .
//  }
// }
            var pg1 = new RDFPatternGroup("PG1");

            pg1.AddPattern(person_foaf_name_name);
            pg1.AddPattern(person_foaf_knows_friend);

            selectQuery.AddPatternGroup(pg1);

            // SELECT ?PERSON ?NAME ?FRIEND
            selectQuery.AddProjectionVariable(person);
            selectQuery.AddProjectionVariable(name);
            selectQuery.AddProjectionVariable(friend);

            var sparqlCommand = selectQuery.ToString();

            #region Generated SPARQL command

            /*
             * Generates this sparql command
             *
             * PREFIX foaf: <http://xmlns.com/foaf/0.1/>
             *
             * SELECT ?PERSON ?NAME ?FRIEND
             * WHERE {
             * {
             * ?PERSON foaf:name ?NAME .
             * ?PERSON foaf:knows ?FRIEND .
             * }
             * }
             *
             */
            #endregion

            // APPLY SELECT QUERY TO GRAPH
            RDFSelectQueryResult selectQueryResult = selectQuery.ApplyToGraph(graph);

            // EXPORT SELECT QUERY RESULTS TO SPARQL XML FORMAT (FILE)
            //selectQueryResult.ToSparqlXmlResult(@"C:\TEMP\Test1.srq");

            #region Generated result file

            /*
             * <?xml version="1.0" encoding="utf-8"?>
             * <sparql xmlns="http://www.w3.org/2005/sparql-results#">
             * <head>
             *  <variable name="?PERSON" />
             *  <variable name="?NAME" />
             *  <variable name="?FRIEND" />
             * </head>
             * <results>
             *  <result>
             *    <binding name="?PERSON">
             *      <uri>http://example.org/alice#me</uri>
             *    </binding>
             *    <binding name="?NAME">
             *      <literal>Alice</literal>
             *    </binding>
             *    <binding name="?FRIEND">
             *      <uri>http://example.org/bob#me</uri>
             *    </binding>
             *  </result>
             *  <result>
             *    <binding name="?PERSON">
             *      <uri>http://example.org/alice#me</uri>
             *    </binding>
             *    <binding name="?NAME">
             *      <literal>Alice</literal>
             *    </binding>
             *    <binding name="?FRIEND">
             *      <uri>http://example.org/charlie#me</uri>
             *    </binding>
             *  </result>
             *  <result>
             *    <binding name="?PERSON">
             *      <uri>http://example.org/alice#me</uri>
             *    </binding>
             *    <binding name="?NAME">
             *      <literal>Alice</literal>
             *    </binding>
             *    <binding name="?FRIEND">
             *      <uri>http://example.org/snoopy</uri>
             *    </binding>
             *  </result>
             *  <result>
             *    <binding name="?PERSON">
             *      <uri>http://example.org/bob#me</uri>
             *    </binding>
             *    <binding name="?NAME">
             *      <literal>Bob</literal>
             *    </binding>
             *    <binding name="?FRIEND">
             *      <uri>http://example.org/alice#me</uri>
             *    </binding>
             *  </result>
             *  <result>
             *    <binding name="?PERSON">
             *      <uri>http://example.org/charlie#me</uri>
             *    </binding>
             *    <binding name="?NAME">
             *      <literal>Charlie</literal>
             *    </binding>
             *    <binding name="?FRIEND">
             *      <uri>http://example.org/alice#me</uri>
             *    </binding>
             *  </result>
             * </results>
             * </sparql>
             */
            #endregion

            Assert.Equal(5, selectQueryResult.SelectResultsCount);
        }
        public void Test2()
        {
            string   filePath = GetPath(@"Files\Test1.ttl");
            RDFGraph graph    = RDFGraph.FromFile(RDFModelEnums.RDFFormats.Turtle, filePath);

            RDFSelectQuery selectQuery = new RDFSelectQuery();

            selectQuery.AddPrefix(RDFNamespaceRegister.GetByPrefix("foaf"));

            var name   = new RDFVariable("name");
            var friend = new RDFVariable("friend");
            var count  = new RDFVariable("count");
            var person = new RDFVariable("person");

            // ?person foaf:name ?name .
            var person_foaf_name_name = new RDFPattern(person, RDFVocabulary.FOAF.NAME, name);
            // ?person foaf:knows ?friend .
            var person_foaf_knows_friend = new RDFPattern(person, RDFVocabulary.FOAF.KNOWS, friend);

            var pg1 = new RDFPatternGroup("PG1");

            pg1.AddPattern(person_foaf_name_name);
            pg1.AddPattern(person_foaf_knows_friend);

            selectQuery.AddPatternGroup(pg1);


            selectQuery.AddProjectionVariable(name);
            //selectQuery.AddProjectionVariable(count);

            // GROUP BY ?PERSON ?NAME
            // var gm = new RDFGroupByModifier(new List<RDFVariable>() { person, name });
            // GROUP BY ?NAME
            var gm = new RDFGroupByModifier(new List <RDFVariable>()
            {
                name
            });

            // (COUNT(?friend) AS ?count)
            gm.AddAggregator(new RDFCountAggregator(friend, count));

            selectQuery.AddModifier(gm);


            var sparqlCommand = selectQuery.ToString();

            #region Target query in the SPARQL 1.1 documentation

            /*
             * Target query in the document
             *
             * PREFIX foaf: <http://xmlns.com/foaf/0.1/>
             * SELECT ?name (COUNT(?friend) AS ?count)
             * WHERE {
             * ?person foaf:name ?name .
             * ?person foaf:knows ?friend .
             * } GROUP BY ?person ?name
             */
            #endregion

            #region Managed to build this command

            /*
             * PREFIX foaf: <http://xmlns.com/foaf/0.1/>
             *
             * SELECT ?NAME (COUNT(?FRIEND) AS ?COUNT)
             * WHERE {
             * {
             * ?PERSON foaf:name ?NAME .
             * ?PERSON foaf:knows ?FRIEND .
             * }
             * }
             * GROUP BY ?NAME
             */
            #endregion

            #region Managed to build this command

            /*
             * Managed to build this command
             *
             * PREFIX foaf: <http://xmlns.com/foaf/0.1/>
             *
             * SELECT ?PERSON ?NAME (COUNT(?FRIEND) AS ?COUNT)
             * WHERE {
             * {
             * ?PERSON foaf:name ?NAME .
             * ?PERSON foaf:knows ?FRIEND .
             * }
             * }
             * GROUP BY ?PERSON ?NAME
             */
            #endregion

            // APPLY SELECT QUERY TO GRAPH
            RDFSelectQueryResult selectQueryResult = selectQuery.ApplyToGraph(graph);

            // EXPORT SELECT QUERY RESULTS TO SPARQL XML FORMAT (FILE)
            //selectQueryResult.ToSparqlXmlResult(@"C:\TEMP\Test2.srq");

            #region Got result

            /*
             * Got result
             *
             * <?xml version="1.0" encoding="utf-8"?>
             * <sparql xmlns="http://www.w3.org/2005/sparql-results#">
             * <head>
             * <variable name="?NAME" />
             * <variable name="?COUNT" />
             * </head>
             * <results>
             * <result>
             * <binding name="?NAME">
             * <literal>Alice</literal>
             * </binding>
             * <binding name="?COUNT">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#decimal">3</literal>
             * </binding>
             * </result>
             * <result>
             * <binding name="?NAME">
             * <literal>Bob</literal>
             * </binding>
             * <binding name="?COUNT">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#decimal">1</literal>
             * </binding>
             * </result>
             * <result>
             * <binding name="?NAME">
             * <literal>Charlie</literal>
             * </binding>
             * <binding name="?COUNT">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#decimal">1</literal>
             * </binding>
             * </result>
             * </results>
             * </sparql>
             *
             */
            #endregion

            #region Got result

            /*
             *
             *
             * <?xml version="1.0" encoding="utf-8"?>
             * <sparql xmlns="http://www.w3.org/2005/sparql-results#">
             * <head>
             * <variable name="?PERSON" />
             * <variable name="?NAME" />
             * <variable name="?COUNT" />
             * </head>
             * <results>
             * <result>
             * <binding name="?PERSON">
             * <uri>http://example.org/alice#me</uri>
             * </binding>
             * <binding name="?NAME">
             * <literal>Alice</literal>
             * </binding>
             * <binding name="?COUNT">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#decimal">3</literal>
             * </binding>
             * </result>
             * <result>
             * <binding name="?PERSON">
             * <uri>http://example.org/bob#me</uri>
             * </binding>
             * <binding name="?NAME">
             * <literal>Bob</literal>
             * </binding>
             * <binding name="?COUNT">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#decimal">1</literal>
             * </binding>
             * </result>
             * <result>
             * <binding name="?PERSON">
             * <uri>http://example.org/charlie#me</uri>
             * </binding>
             * <binding name="?NAME">
             * <literal>Charlie</literal>
             * </binding>
             * <binding name="?COUNT">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#decimal">1</literal>
             * </binding>
             * </result>
             * </results>
             * </sparql>
             *
             */
            #endregion

            #region Target result from SPARQL 1.1 documentation

            /*
             * Target result
             * 3 Different query results formats supported by SPARQL 1.1 (XML, JSON, CSV, TSV)
             *
             * <?xml version="1.0"?>
             * <sparql xmlns="http://www.w3.org/2005/sparql-results#">
             * <head>
             * <variable name="name"/>
             * <variable name="count"/>
             * </head>
             * <results>
             * <result>
             * <binding name="name">
             * <literal>Alice</literal>
             * </binding>
             * <binding name="count">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#integer">3</literal>
             * </binding>
             * </result>
             * <result>
             * <binding name="name">
             * <literal>Bob</literal>
             * </binding>
             * <binding name="count">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#integer">1</literal>
             * </binding>
             * </result>
             * <result>
             * <binding name="name">
             * <literal>Charlie</literal>
             * </binding>
             * <binding name="count">
             * <literal datatype="http://www.w3.org/2001/XMLSchema#integer">1</literal>
             * </binding>
             * </result>
             * </results>
             * </sparql>
             */
            #endregion

            Assert.Equal(3, selectQueryResult.SelectResultsCount);
        }
        public void SelectDogs()
        {
            // CREATE SELECT QUERY
            RDFSelectQuery selectQuery = new RDFSelectQuery();

            selectQuery.AddPrefix(RDFNamespaceRegister.GetByPrefix("dc"));
            selectQuery.AddPrefix(RDFNamespaceRegister.GetByPrefix("foaf"));

            var x = new RDFVariable("x");
            var y = new RDFVariable("y");

            RDFPatternMember predicate = GraphBuilder2.dogOf;

            var x_dogOf_y = new RDFPattern(x, predicate, y);

            // CREATE PATTERN GROUP FROM A LIST OF PATTERNS
            var patterns = new List <RDFPattern>()
            {
                x_dogOf_y
            };
            var pg1 = new RDFPatternGroup("PG1", patterns);

            // ADD PATTERN GROUPS TO QUERY
            selectQuery.AddPatternGroup(pg1);

            selectQuery.AddProjectionVariable(x);
            selectQuery.AddProjectionVariable(y);

            // APPLY SELECT QUERY TO GRAPH

            var sparqlCommand = selectQuery.ToString();

            /*
             * Generates this sparql command
             *
             * PREFIX dc: <http://purl.org/dc/elements/1.1/>
             * PREFIX foaf: <http://xmlns.com/foaf/0.1/>
             *
             * SELECT ?X ?Y
             * WHERE {
             * {
             * ?X dc:dogOf ?Y .
             * }
             * }
             */

            RDFSelectQueryResult selectQueryResult = selectQuery.ApplyToGraph(graph);

            // EXPORT SELECT QUERY RESULTS TO SPARQL XML FORMAT (FILE)
            selectQueryResult.ToSparqlXmlResult(@"C:\TEMP\select_results.srq");

            Assert.Equal(1, selectQueryResult.SelectResultsCount);

            DataRow row    = selectQueryResult.SelectResults.Rows[0];
            var     dog    = row[0].ToString();
            var     person = row[1].ToString();

            Assert.Equal(pluto.URI.ToString(), dog);
            Assert.Equal(mickeyMouse.URI.ToString(), person);


            /*
             * Generates this file content
             *
             * <?xml version="1.0" encoding="utf-8"?>
             * <sparql xmlns="http://www.w3.org/2005/sparql-results#">
             * <head>
             * <variable name="?X" />
             * <variable name="?Y" />
             * </head>
             * <results>
             * <result>
             * <binding name="?X">
             * <uri>https://en.wikipedia.org/wiki/Pluto_(Disney)</uri>
             * </binding>
             * <binding name="?Y">
             * <uri>https://en.wikipedia.org/wiki/Mickey_Mouse</uri>
             * </binding>
             * </result>
             * </results>
             * </sparql>
             */
        }
        public void SelectDogsOrCats_UnionWithNext_Test()
        {
            // CREATE SELECT QUERY
            RDFSelectQuery selectQuery = new RDFSelectQuery();

            selectQuery.AddPrefix(RDFNamespaceRegister.GetByPrefix("dc"));
            selectQuery.AddPrefix(RDFNamespaceRegister.GetByPrefix("foaf"));

            var x = new RDFVariable("x");
            var y = new RDFVariable("y");

            RDFPatternMember dogOfPredicate = GraphBuilder2.dogOf;
            RDFPatternMember catOfPredicate = GraphBuilder2.catOf;

            var x_dogOf_y = new RDFPattern(x, dogOfPredicate, y);
            var x_catOf_y = new RDFPattern(x, catOfPredicate, y);

            //var orFilter = new RDFBooleanOrFilter(x_dogOf_y, x_catOf_y);

            // CREATE PATTERN GROUP FROM A LIST OF PATTERNS
            var pg1 = new RDFPatternGroup("PG1");

            pg1.AddPattern(x_dogOf_y.UnionWithNext());
            pg1.AddPattern(x_catOf_y);

            selectQuery.AddPatternGroup(pg1);

            selectQuery.AddProjectionVariable(x);
            selectQuery.AddProjectionVariable(y);

            selectQuery.AddModifier(new RDFOrderByModifier(x, RDFQueryEnums.RDFOrderByFlavors.ASC));



            var sparqlCommand = selectQuery.ToString();

            /*
             * Generates this sparql command
             *
             * PREFIX dc: <http://purl.org/dc/elements/1.1/>
             * PREFIX foaf: <http://xmlns.com/foaf/0.1/>
             *
             * SELECT ?X ?Y
             * WHERE {
             * {
             * { ?X dc:dogOf ?Y }
             * UNION
             * { ?X dc:catOf ?Y }
             * }
             * }
             * ORDER BY ASC(?X)
             */

            // APPLY SELECT QUERY TO GRAPH
            RDFSelectQueryResult selectQueryResult = selectQuery.ApplyToGraph(graph);

            // EXPORT SELECT QUERY RESULTS TO SPARQL XML FORMAT (FILE)
            selectQueryResult.ToSparqlXmlResult(@"C:\TEMP\select_results.srq");

            Assert.Equal(2, selectQueryResult.SelectResultsCount);

            //DataRow row = selectQueryResult.SelectResults.Rows[0];
            //var dog = row[0].ToString();
            //var person = row[1].ToString();
            //Assert.Equal(pluto.URI.ToString(), dog);
            //Assert.Equal(mickeyMouse.URI.ToString(), person);


            /*
             * Generates this file content
             *
             * <?xml version="1.0" encoding="utf-8"?>
             * <sparql xmlns="http://www.w3.org/2005/sparql-results#">
             * <head>
             * <variable name="?X" />
             * <variable name="?Y" />
             * </head>
             * <results>
             * <result>
             * <binding name="?X">
             * <uri>https://en.wikipedia.org/wiki/Figaro_(Disney)</uri>
             * </binding>
             * <binding name="?Y">
             * <uri>https://en.wikipedia.org/wiki/Minnie_Mouse</uri>
             * </binding>
             * </result>
             * <result>
             * <binding name="?X">
             * <uri>https://en.wikipedia.org/wiki/Pluto_(Disney)</uri>
             * </binding>
             * <binding name="?Y">
             * <uri>https://en.wikipedia.org/wiki/Mickey_Mouse</uri>
             * </binding>
             * </result>
             * </results>
             * </sparql>
             */
        }