/// <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; } }
/// <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; } }
/// <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; } } }
/// <summary> /// Apply the query modifiers to the query result table /// </summary> internal static DataTable ApplyModifiers(RDFDescribeQuery query, DataTable table) { String tablenameBak = table.TableName; //Apply the DISTINCT modifier table = new RDFDistinctModifier().ApplyModifier(table); //Apply the OFFSET modifier table = query.Modifiers.Where(m => m is RDFOffsetModifier) .Aggregate(table, (current, modifier) => modifier.ApplyModifier(current)); //Apply the LIMIT modifier table = query.Modifiers.Where(m => m is RDFLimitModifier) .Aggregate(table, (current, modifier) => modifier.ApplyModifier(current)); table.TableName = tablenameBak; return(table); }
/// <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); } }
/// <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); } }
/// <summary> /// Apply the query modifiers to the query result table /// </summary> internal static DataTable ApplyModifiers(RDFDescribeQuery query, DataTable table) { String tablenameBak = table.TableName; //Apply the DISTINCT modifier table = new RDFDistinctModifier().ApplyModifier(table); //Apply the OFFSET modifier table = query.Modifiers.Where(m => m is RDFOffsetModifier) .Aggregate(table, (current, modifier) => modifier.ApplyModifier(current)); //Apply the LIMIT modifier table = query.Modifiers.Where(m => m is RDFLimitModifier) .Aggregate(table, (current, modifier) => modifier.ApplyModifier(current)); table.TableName = tablenameBak; return table; }
/// <summary> /// Describes the terms of the given query with data from the given result table /// </summary> internal static DataTable DescribeTerms(RDFDescribeQuery describeQuery, Object graphOrStore, DataTable resultTable) { //Create the structure of the result datatable DataTable result = new DataTable("DESCRIBE_RESULTS"); result.Columns.Add("SUBJECT", Type.GetType("System.String")); result.Columns.Add("PREDICATE", Type.GetType("System.String")); result.Columns.Add("OBJECT", Type.GetType("System.String")); result.AcceptChanges(); //Query IS empty, so does not have pattern groups to fetch data from //(we can only proceed by searching for resources in the describe terms) if (describeQuery.IsEmpty) { //Iterate the describe terms of the query which are resources (variables are omitted, since useless) foreach (RDFPatternMember dt in describeQuery.DescribeTerms.Where(dterm => dterm is RDFResource)) { //Search on GRAPH if (graphOrStore is RDFGraph) { //Search as RESOURCE (S-P-O) RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)dt) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)dt)) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)dt)); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } //Search on STORE else { //Search as RESOURCE (S-P-O) RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)dt)) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)dt))) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)dt))); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } } } //Query IS NOT empty, so does have pattern groups to fetch data from else { //In case of a "Star" query, all the variables must be considered describe terms if (describeQuery.IsStar) { describeQuery.PatternGroups.ForEach(pg => pg.Variables.ForEach(v => describeQuery.AddDescribeTerm(v)) ); } //Iterate the describe terms of the query foreach (RDFPatternMember dt in describeQuery.DescribeTerms) { //The describe term is a variable if (dt is RDFVariable) { //Process the variable if(resultTable.Columns.Contains(dt.ToString())) { //Iterate the results datatable's rows to retrieve terms to be described IEnumerator rowsEnum = resultTable.Rows.GetEnumerator(); while (rowsEnum.MoveNext()) { //Row contains a value in position of the variable corresponding to the describe term if (!((DataRow)rowsEnum.Current).IsNull(dt.ToString())) { //Retrieve the term to be described RDFPatternMember term = RDFQueryUtilities.ParseRDFPatternMember(((DataRow)rowsEnum.Current)[dt.ToString()].ToString()); //Search on GRAPH if (graphOrStore is RDFGraph) { //Search as RESOURCE (S-P-O) if (term is RDFResource) { RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)term) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)term)) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)term)); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } //Search as LITERAL (L) else { RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesByLiteral((RDFLiteral)term); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } } //Search on STORE else { //Search as RESOURCE (S-P-O) if (term is RDFResource) { RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)term)) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)term))) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)term))); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } //Search as LITERAL (L) else { RDFMemoryStore desc = ((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesByLiteral((RDFLiteral)term)); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } } } } } } //The describe term is a resource else { //Search on GRAPH if (graphOrStore is RDFGraph) { //Search as RESOURCE (S-P-O) RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)dt) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)dt)) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)dt)); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } //Search on STORE else { //Search as RESOURCE (S-P-O) RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)dt)) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)dt))) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)dt))); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } } } } return result; }
/// <summary> /// Prints the string representation of a SPARQL DESCRIBE query /// </summary> internal static String PrintDescribeQuery(RDFDescribeQuery describeQuery) { StringBuilder sb = new StringBuilder(); if (describeQuery != null) { #region PREFIXES if (describeQuery.Prefixes.Any()) { describeQuery.Prefixes.ForEach(pf => { sb.Append("PREFIX " + pf.NamespacePrefix + ": <" + pf.NamespaceUri + ">\n"); }); sb.Append("\n"); } #endregion #region HEADER #region BEGINDESCRIBE sb.Append("DESCRIBE"); #endregion #region TERMS if (describeQuery.DescribeTerms.Any()) { describeQuery.DescribeTerms.ForEach(dt => { sb.Append(" " + PrintPatternMember(dt, describeQuery.Prefixes)); }); } else { sb.Append(" *"); } sb.Append("\n"); #endregion #endregion #region BODY sb.Append("WHERE {\n"); #region MEMBERS Boolean printingUnion = false; List <RDFQueryMember> evaluableQueryMembers = describeQuery.GetEvaluableQueryMembers().ToList(); RDFQueryMember lastQueryMbr = evaluableQueryMembers.LastOrDefault(); foreach (var queryMember in evaluableQueryMembers) { #region PATTERNGROUPS if (queryMember is RDFPatternGroup) { //Current pattern group is set as UNION with the next one if (((RDFPatternGroup)queryMember).JoinAsUnion) { //Current pattern group IS NOT the last of the query //(so UNION keyword must be appended at last) if (!queryMember.Equals(lastQueryMbr)) { //Begin a new Union block if (!printingUnion) { printingUnion = true; sb.Append(" {\n"); } sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 2, true, describeQuery.Prefixes)); sb.Append(" UNION\n"); } //Current pattern group IS the last of the query //(so UNION keyword must not be appended at last) else { //End the Union block if (printingUnion) { printingUnion = false; sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 2, true, describeQuery.Prefixes)); sb.Append(" }\n"); } else { sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 0, false, describeQuery.Prefixes)); } } } //Current pattern group is set as INTERSECT with the next one else { //End the Union block if (printingUnion) { printingUnion = false; sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 2, true, describeQuery.Prefixes)); sb.Append(" }\n"); } else { sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 0, false, describeQuery.Prefixes)); } } } #endregion #region SUBQUERY else if (queryMember is RDFQuery) { //Merge main query prefixes describeQuery.Prefixes.ForEach(pf1 => { if (!((RDFSelectQuery)queryMember).Prefixes.Any(pf2 => pf2.Equals(pf1))) { ((RDFSelectQuery)queryMember).AddPrefix(pf1); } }); //Current subquery is set as UNION with the next one if (((RDFSelectQuery)queryMember).JoinAsUnion) { //Current subquery IS NOT the last of the query //(so UNION keyword must be appended at last) if (!queryMember.Equals(lastQueryMbr)) { //Begin a new Union block if (!printingUnion) { printingUnion = true; sb.Append(" {\n"); } sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, true)); sb.Append(" UNION\n"); } //Current query IS the last of the query //(so UNION keyword must not be appended at last) else { //End the Union block if (printingUnion) { printingUnion = false; sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, true)); sb.Append(" }\n"); } else { sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, false)); } } } //Current query is set as INTERSECT with the next one else { //End the Union block if (printingUnion) { printingUnion = false; sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, true)); sb.Append(" }\n"); } else { sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, false)); } } } #endregion } #endregion sb.Append("}"); #endregion #region FOOTER #region MODIFIERS List <RDFModifier> modifiers = describeQuery.GetModifiers().ToList(); // LIMIT/OFFSET if (modifiers.Any(mod => mod is RDFLimitModifier || mod is RDFOffsetModifier)) { modifiers.Where(mod => mod is RDFLimitModifier) .ToList() .ForEach(lim => { sb.Append("\n"); sb.Append(lim); }); modifiers.Where(mod => mod is RDFOffsetModifier) .ToList() .ForEach(off => { sb.Append("\n"); sb.Append(off); }); } #endregion #endregion } return(sb.ToString()); }
/// <summary> /// Describes the terms of the given query with data from the given result table /// </summary> internal static DataTable DescribeTerms(RDFDescribeQuery describeQuery, Object graphOrStore, DataTable resultTable) { //Create the structure of the result datatable DataTable result = new DataTable("DESCRIBE_RESULTS"); result.Columns.Add("SUBJECT", Type.GetType("System.String")); result.Columns.Add("PREDICATE", Type.GetType("System.String")); result.Columns.Add("OBJECT", Type.GetType("System.String")); result.AcceptChanges(); //Query IS empty, so does not have pattern groups to fetch data from //(we can only proceed by searching for resources in the describe terms) if (describeQuery.IsEmpty) { //Iterate the describe terms of the query which are resources (variables are omitted, since useless) foreach (RDFPatternMember dt in describeQuery.DescribeTerms.Where(dterm => dterm is RDFResource)) { //Search on GRAPH if (graphOrStore is RDFGraph) { //Search as RESOURCE (S-P-O) RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)dt) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)dt)) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)dt)); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } //Search on STORE else { //Search as RESOURCE (S-P-O) RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)dt)) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)dt))) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)dt))); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } } } //Query IS NOT empty, so does have pattern groups to fetch data from else { //In case of a "Star" query, all the variables must be considered describe terms if (describeQuery.IsStar) { describeQuery.PatternGroups.ForEach(pg => pg.Variables.ForEach(v => describeQuery.AddDescribeTerm(v)) ); } //Iterate the describe terms of the query foreach (RDFPatternMember dt in describeQuery.DescribeTerms) { //The describe term is a variable if (dt is RDFVariable) { //Process the variable if (resultTable.Columns.Contains(dt.ToString())) { //Iterate the results datatable's rows to retrieve terms to be described IEnumerator rowsEnum = resultTable.Rows.GetEnumerator(); while (rowsEnum.MoveNext()) { //Row contains a value in position of the variable corresponding to the describe term if (!((DataRow)rowsEnum.Current).IsNull(dt.ToString())) { //Retrieve the term to be described RDFPatternMember term = RDFQueryUtilities.ParseRDFPatternMember(((DataRow)rowsEnum.Current)[dt.ToString()].ToString()); //Search on GRAPH if (graphOrStore is RDFGraph) { //Search as RESOURCE (S-P-O) if (term is RDFResource) { RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)term) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)term)) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)term)); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } //Search as LITERAL (L) else { RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesByLiteral((RDFLiteral)term); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } } //Search on STORE else { //Search as RESOURCE (S-P-O) if (term is RDFResource) { RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)term)) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)term))) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)term))); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } //Search as LITERAL (L) else { RDFMemoryStore desc = ((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesByLiteral((RDFLiteral)term)); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } } } } } } //The describe term is a resource else { //Search on GRAPH if (graphOrStore is RDFGraph) { //Search as RESOURCE (S-P-O) RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)dt) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)dt)) .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)dt)); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } //Search on STORE else { //Search as RESOURCE (S-P-O) RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)dt)) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)dt))) .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)dt))); result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add); } } } } return(result); }