103 lines
2.0 KiB
Go
103 lines
2.0 KiB
Go
package selection_queries
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
func nodeKey(termType, iri string) string {
|
|
return termType + "\x00" + iri
|
|
}
|
|
|
|
func valuesTerm(n NodeRef) string {
|
|
if n.TermType == "uri" {
|
|
if n.IRI == "" {
|
|
return ""
|
|
}
|
|
return "<" + n.IRI + ">"
|
|
}
|
|
if n.TermType == "bnode" {
|
|
if n.IRI == "" {
|
|
return ""
|
|
}
|
|
if strings.HasPrefix(n.IRI, "_:") {
|
|
return n.IRI
|
|
}
|
|
return "_:" + n.IRI
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func termKeyFromSparqlTerm(term sparqlTerm, includeBNodes bool) (string, bool) {
|
|
if term.Type == "" || term.Value == "" {
|
|
return "", false
|
|
}
|
|
if term.Type == "literal" {
|
|
return "", false
|
|
}
|
|
if term.Type == "bnode" {
|
|
if !includeBNodes {
|
|
return "", false
|
|
}
|
|
return nodeKey("bnode", "_:"+term.Value), true
|
|
}
|
|
if term.Type == "uri" {
|
|
return nodeKey("uri", term.Value), true
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
func selectedNodesFromIDs(idx Index, selectedIDs []int, includeBNodes bool) ([]NodeRef, map[int]struct{}) {
|
|
out := make([]NodeRef, 0, len(selectedIDs))
|
|
set := make(map[int]struct{}, len(selectedIDs))
|
|
for _, nid := range selectedIDs {
|
|
n, ok := idx.IDToNode[nid]
|
|
if !ok {
|
|
continue
|
|
}
|
|
if n.TermType == "bnode" && !includeBNodes {
|
|
continue
|
|
}
|
|
out = append(out, n)
|
|
set[nid] = struct{}{}
|
|
}
|
|
return out, set
|
|
}
|
|
|
|
func idsFromBindings(raw []byte, varName string, idx Index, selectedSet map[int]struct{}, includeBNodes bool) ([]int, error) {
|
|
var res sparqlResponse
|
|
if err := json.Unmarshal(raw, &res); err != nil {
|
|
return nil, fmt.Errorf("failed to parse SPARQL JSON: %w", err)
|
|
}
|
|
|
|
neighborSet := make(map[int]struct{})
|
|
for _, b := range res.Results.Bindings {
|
|
term, ok := b[varName]
|
|
if !ok {
|
|
continue
|
|
}
|
|
key, ok := termKeyFromSparqlTerm(term, includeBNodes)
|
|
if !ok {
|
|
continue
|
|
}
|
|
nid, ok := idx.KeyToID[key]
|
|
if !ok {
|
|
continue
|
|
}
|
|
if _, sel := selectedSet[nid]; sel {
|
|
continue
|
|
}
|
|
neighborSet[nid] = struct{}{}
|
|
}
|
|
|
|
ids := make([]int, 0, len(neighborSet))
|
|
for nid := range neighborSet {
|
|
ids = append(ids, nid)
|
|
}
|
|
sort.Ints(ids)
|
|
return ids, nil
|
|
}
|
|
|