package selection_queries import ( "context" "fmt" "strings" ) func neighborsQuery(selectedNodes []NodeRef, includeBNodes bool) string { valuesTerms := make([]string, 0, len(selectedNodes)) for _, n := range selectedNodes { t := valuesTerm(n) if t == "" { continue } valuesTerms = append(valuesTerms, t) } if len(valuesTerms) == 0 { return "SELECT ?nbr WHERE { FILTER(false) }" } bnodeFilter := "" if !includeBNodes { bnodeFilter = "FILTER(!isBlank(?nbr))" } values := strings.Join(valuesTerms, " ") return fmt.Sprintf(` PREFIX rdf: PREFIX rdfs: PREFIX owl: SELECT DISTINCT ?nbr WHERE { VALUES ?sel { %s } { ?sel rdf:type ?o . ?o rdf:type owl:Class . BIND(?o AS ?nbr) } UNION { ?s rdf:type ?sel . ?sel rdf:type owl:Class . BIND(?s AS ?nbr) } UNION { ?sel rdfs:subClassOf ?o . BIND(?o AS ?nbr) } UNION { ?s rdfs:subClassOf ?sel . BIND(?s AS ?nbr) } FILTER(!isLiteral(?nbr)) FILTER(?nbr != ?sel) %s } `, values, bnodeFilter) } func runNeighbors(ctx context.Context, q Querier, idx Index, selectedIDs []uint32, includeBNodes bool) ([]uint32, error) { selectedNodes, selectedSet := selectedNodesFromIDs(idx, selectedIDs, includeBNodes) if len(selectedNodes) == 0 { return []uint32{}, nil } raw, err := q.Query(ctx, neighborsQuery(selectedNodes, includeBNodes)) if err != nil { return nil, err } return idsFromBindings(raw, "nbr", idx, selectedSet, includeBNodes) }