backend: support external SPARQL and named-graph snapshots
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
package graph_queries
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"visualizador_instanciados/backend_go/queryscope"
|
||||
)
|
||||
|
||||
func defaultEdgeQuery(limit int, offset int, includeBNodes bool) string {
|
||||
bnodeFilter := ""
|
||||
@@ -8,30 +12,33 @@ func defaultEdgeQuery(limit int, offset int, includeBNodes bool) string {
|
||||
bnodeFilter = "FILTER(!isBlank(?s) && !isBlank(?o))"
|
||||
}
|
||||
|
||||
pattern := queryscope.NamedGraph(`
|
||||
{
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
}
|
||||
UNION
|
||||
{
|
||||
VALUES ?p { rdfs:subClassOf }
|
||||
?s ?p ?o .
|
||||
}
|
||||
`)
|
||||
|
||||
return fmt.Sprintf(`
|
||||
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
||||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
||||
|
||||
SELECT ?s ?p ?o
|
||||
SELECT DISTINCT ?s ?p ?o
|
||||
WHERE {
|
||||
{
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
?o rdf:type owl:Class .
|
||||
}
|
||||
UNION
|
||||
{
|
||||
VALUES ?p { rdfs:subClassOf }
|
||||
?s ?p ?o .
|
||||
}
|
||||
%s
|
||||
FILTER(!isLiteral(?o))
|
||||
%s
|
||||
}
|
||||
ORDER BY ?s ?p ?o
|
||||
LIMIT %d
|
||||
OFFSET %d
|
||||
`, bnodeFilter, limit, offset)
|
||||
`, pattern, bnodeFilter, limit, offset)
|
||||
}
|
||||
|
||||
func defaultPredicateQuery(includeBNodes bool) string {
|
||||
@@ -40,6 +47,18 @@ func defaultPredicateQuery(includeBNodes bool) string {
|
||||
bnodeFilter = "FILTER(!isBlank(?s) && !isBlank(?o))"
|
||||
}
|
||||
|
||||
pattern := queryscope.NamedGraph(`
|
||||
{
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
}
|
||||
UNION
|
||||
{
|
||||
VALUES ?p { rdfs:subClassOf }
|
||||
?s ?p ?o .
|
||||
}
|
||||
`)
|
||||
|
||||
return fmt.Sprintf(`
|
||||
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
||||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
@@ -47,19 +66,10 @@ PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
||||
|
||||
SELECT DISTINCT ?p
|
||||
WHERE {
|
||||
{
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
?o rdf:type owl:Class .
|
||||
}
|
||||
UNION
|
||||
{
|
||||
VALUES ?p { rdfs:subClassOf }
|
||||
?s ?p ?o .
|
||||
}
|
||||
%s
|
||||
FILTER(!isLiteral(?o))
|
||||
%s
|
||||
}
|
||||
ORDER BY ?p
|
||||
`, bnodeFilter)
|
||||
`, pattern, bnodeFilter)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package graph_queries
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"visualizador_instanciados/backend_go/queryscope"
|
||||
)
|
||||
|
||||
func hierarchyEdgeQuery(limit int, offset int, includeBNodes bool) string {
|
||||
bnodeFilter := ""
|
||||
@@ -8,20 +12,31 @@ func hierarchyEdgeQuery(limit int, offset int, includeBNodes bool) string {
|
||||
bnodeFilter = "FILTER(!isBlank(?s) && !isBlank(?o))"
|
||||
}
|
||||
|
||||
pattern := queryscope.NamedGraph(`
|
||||
{
|
||||
VALUES ?p { rdfs:subClassOf }
|
||||
?s ?p ?o .
|
||||
}
|
||||
UNION
|
||||
{
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
}
|
||||
`)
|
||||
|
||||
return fmt.Sprintf(`
|
||||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
|
||||
SELECT ?s ?p ?o
|
||||
SELECT DISTINCT ?s ?p ?o
|
||||
WHERE {
|
||||
VALUES ?p { rdfs:subClassOf }
|
||||
?s ?p ?o .
|
||||
%s
|
||||
FILTER(!isLiteral(?o))
|
||||
%s
|
||||
}
|
||||
ORDER BY ?s ?p ?o
|
||||
LIMIT %d
|
||||
OFFSET %d
|
||||
`, bnodeFilter, limit, offset)
|
||||
`, pattern, bnodeFilter, limit, offset)
|
||||
}
|
||||
|
||||
func hierarchyPredicateQuery(includeBNodes bool) string {
|
||||
@@ -30,16 +45,27 @@ func hierarchyPredicateQuery(includeBNodes bool) string {
|
||||
bnodeFilter = "FILTER(!isBlank(?s) && !isBlank(?o))"
|
||||
}
|
||||
|
||||
pattern := queryscope.NamedGraph(`
|
||||
{
|
||||
VALUES ?p { rdfs:subClassOf }
|
||||
?s ?p ?o .
|
||||
}
|
||||
UNION
|
||||
{
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
}
|
||||
`)
|
||||
|
||||
return fmt.Sprintf(`
|
||||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
|
||||
SELECT DISTINCT ?p
|
||||
WHERE {
|
||||
VALUES ?p { rdfs:subClassOf }
|
||||
?s ?p ?o .
|
||||
%s
|
||||
FILTER(!isLiteral(?o))
|
||||
%s
|
||||
}
|
||||
ORDER BY ?p
|
||||
`, bnodeFilter)
|
||||
`, pattern, bnodeFilter)
|
||||
}
|
||||
|
||||
49
backend_go/graph_queries/named_graph_test.go
Normal file
49
backend_go/graph_queries/named_graph_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package graph_queries
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEdgeQueriesUseNamedGraphsAndDistinct(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
query string
|
||||
}{
|
||||
{name: "default", query: defaultEdgeQuery(100, 25, false)},
|
||||
{name: "hierarchy", query: hierarchyEdgeQuery(100, 25, false)},
|
||||
{name: "types_only", query: typesOnlyEdgeQuery(100, 25, false)},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
if !strings.Contains(tt.query, "SELECT DISTINCT ?s ?p ?o") {
|
||||
t.Fatalf("%s edge query should de-duplicate triples across named graphs:\n%s", tt.name, tt.query)
|
||||
}
|
||||
if !strings.Contains(tt.query, "GRAPH ?g") {
|
||||
t.Fatalf("%s edge query should read from named graphs:\n%s", tt.name, tt.query)
|
||||
}
|
||||
if strings.Contains(tt.query, "owl:Class") {
|
||||
t.Fatalf("%s edge query should no longer require owl:Class declarations:\n%s", tt.name, tt.query)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPredicateQueriesUseNamedGraphs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
query string
|
||||
}{
|
||||
{name: "default", query: defaultPredicateQuery(false)},
|
||||
{name: "hierarchy", query: hierarchyPredicateQuery(false)},
|
||||
{name: "types_only", query: typesOnlyPredicateQuery(false)},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
if !strings.Contains(tt.query, "SELECT DISTINCT ?p") {
|
||||
t.Fatalf("%s predicate query should remain distinct:\n%s", tt.name, tt.query)
|
||||
}
|
||||
if !strings.Contains(tt.query, "GRAPH ?g") {
|
||||
t.Fatalf("%s predicate query should read from named graphs:\n%s", tt.name, tt.query)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
package graph_queries
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"visualizador_instanciados/backend_go/queryscope"
|
||||
)
|
||||
|
||||
func typesOnlyEdgeQuery(limit int, offset int, includeBNodes bool) string {
|
||||
bnodeFilter := ""
|
||||
@@ -8,22 +12,25 @@ func typesOnlyEdgeQuery(limit int, offset int, includeBNodes bool) string {
|
||||
bnodeFilter = "FILTER(!isBlank(?s) && !isBlank(?o))"
|
||||
}
|
||||
|
||||
pattern := queryscope.NamedGraph(`
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
`)
|
||||
|
||||
return fmt.Sprintf(`
|
||||
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
||||
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
||||
|
||||
SELECT ?s ?p ?o
|
||||
SELECT DISTINCT ?s ?p ?o
|
||||
WHERE {
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
?o rdf:type owl:Class .
|
||||
%s
|
||||
FILTER(!isLiteral(?o))
|
||||
%s
|
||||
}
|
||||
ORDER BY ?s ?p ?o
|
||||
LIMIT %d
|
||||
OFFSET %d
|
||||
`, bnodeFilter, limit, offset)
|
||||
`, pattern, bnodeFilter, limit, offset)
|
||||
}
|
||||
|
||||
func typesOnlyPredicateQuery(includeBNodes bool) string {
|
||||
@@ -32,18 +39,21 @@ func typesOnlyPredicateQuery(includeBNodes bool) string {
|
||||
bnodeFilter = "FILTER(!isBlank(?s) && !isBlank(?o))"
|
||||
}
|
||||
|
||||
pattern := queryscope.NamedGraph(`
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
`)
|
||||
|
||||
return fmt.Sprintf(`
|
||||
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
||||
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
||||
|
||||
SELECT DISTINCT ?p
|
||||
WHERE {
|
||||
VALUES ?p { rdf:type }
|
||||
?s ?p ?o .
|
||||
?o rdf:type owl:Class .
|
||||
%s
|
||||
FILTER(!isLiteral(?o))
|
||||
%s
|
||||
}
|
||||
ORDER BY ?p
|
||||
`, bnodeFilter)
|
||||
`, pattern, bnodeFilter)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user