Skip to content

Commit

Permalink
query: expose query results as json-ld, if supported
Browse files Browse the repository at this point in the history
  • Loading branch information
dennwc committed Sep 25, 2019
1 parent 5287e85 commit 74330c2
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 33 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.12

require (
github.com/badgerodon/peg v0.0.0-20130729175151-9e5f7f4d07ca
github.com/cayleygraph/quad v1.0.0
github.com/cayleygraph/quad v1.1.0
github.com/cockroachdb/apd v1.1.0 // indirect
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
github.com/coreos/bbolt v1.3.3 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/cayleygraph/quad v1.0.0 h1:RhKzgiWK3I0ekgxVlwpwdM9Q/Rq3QA9bc9Mtw7x4pRs=
github.com/cayleygraph/quad v1.0.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4=
github.com/cayleygraph/quad v1.1.0 h1:w1nXAmn+nz07+qlw89dke9LwWkYpeX+OcvfTvGQRBpM=
github.com/cayleygraph/quad v1.1.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4=
github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
Expand Down
11 changes: 0 additions & 11 deletions query/gizmo/finals.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,3 @@ func quadValueToString(v quad.Value) string {
}
return quad.StringOf(v)
}

func quadValueToNative(v quad.Value) interface{} {
if v == nil {
return nil
}
out := v.Native()
if nv, ok := out.(quad.Value); ok && v == nv {
return quad.StringOf(v)
}
return out
}
38 changes: 23 additions & 15 deletions query/gizmo/gizmo.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ type Session struct {
vm *goja.Runtime
ns voc.Namespaces
sch *schema.Config
col query.Collation

last string
p *goja.Program
Expand Down Expand Up @@ -127,10 +128,24 @@ func (s *Session) buildEnv() error {
return nil
}

func (s *Session) quadValueToNative(v quad.Value) interface{} {
if v == nil {
return nil
}
if s.col == query.JSONLD {
return jsonld.FromValue(v)
}
out := v.Native()
if nv, ok := out.(quad.Value); ok && v == nv {
return quad.StringOf(v)
}
return out
}

func (s *Session) tagsToValueMap(m map[string]graph.Ref) map[string]interface{} {
outputMap := make(map[string]interface{})
for k, v := range m {
if o := jsonld.FromValue(s.qs.NameOf(v)); o != nil {
if o := s.quadValueToNative(s.qs.NameOf(v)); o != nil {
outputMap[k] = o
}
}
Expand Down Expand Up @@ -161,7 +176,7 @@ func (s *Session) runIteratorToArrayNoTags(it graph.Iterator, limit int) ([]inte

output := make([]interface{}, 0)
err := graph.Iterate(ctx, it).Paths(false).Limit(limit).EachValue(s.qs, func(v quad.Value) {
if o := jsonld.FromValue(v); o != nil {
if o := s.quadValueToNative(v); o != nil {
output = append(output, o)
}
})
Expand Down Expand Up @@ -282,7 +297,7 @@ func (s *Session) run() (goja.Value, error) {
}
func (s *Session) Execute(ctx context.Context, qu string, opt query.Options) (query.Iterator, error) {
switch opt.Collation {
case query.Raw, query.JSON, query.REPL:
case query.Raw, query.JSON, query.JSONLD, query.REPL:
default:
return nil, &query.ErrUnsupportedCollation{Collation: opt.Collation}
}
Expand All @@ -293,6 +308,7 @@ func (s *Session) Execute(ctx context.Context, qu string, opt query.Options) (qu
s.count = 0
ctx, cancel := context.WithCancel(context.Background())
s.ctx = ctx
s.col = opt.Collation
return &results{
col: opt.Collation,
s: s,
Expand Down Expand Up @@ -362,17 +378,15 @@ func (it *results) Result() interface{} {
switch it.col {
case query.Raw:
return it.cur
case query.JSON:
return it.jsonResult(false)
case query.JSONLD:
return it.jsonResult(true)
case query.JSON, query.JSONLD:
return it.jsonResult()
case query.REPL:
return it.replResult()
}
return nil
}

func (it *results) jsonResult(ld bool) interface{} {
func (it *results) jsonResult() interface{} {
data := it.cur
if data.Meta {
return nil
Expand All @@ -389,13 +403,7 @@ func (it *results) jsonResult(ld bool) interface{} {
sort.Strings(tagKeys)
for _, k := range tagKeys {
if name := it.s.qs.NameOf(tags[k]); name != nil {
var v interface{}
if ld {
v = jsonld.FromValue(v)
} else {
v = quadValueToNative(name)
}
obj[k] = v
obj[k] = it.s.quadValueToNative(name)
} else {
delete(obj, k)
}
Expand Down
2 changes: 2 additions & 0 deletions query/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ const (
REPL = Collation(iota)
// JSON collates results as maps, arrays and values, that can be encoded to JSON.
JSON
// JSONLD collates results as maps, arrays and values compatible with JSON-LD spec.
JSONLD
)

// Options for the query execution.
Expand Down
30 changes: 24 additions & 6 deletions server/http/api_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const (
hdrAccept = "Accept"
hdrAcceptEncoding = "Accept-Encoding"
contentTypeJSON = "application/json"
contentTypeJSONLD = "application/ld+json"
)

func getFormat(r *http.Request, formKey string, acceptName string) *quad.Format {
Expand Down Expand Up @@ -415,9 +416,11 @@ func defaultErrorFunc(w query.ResponseWriter, err error) {
}

func writeResults(w io.Writer, r interface{}) {
w.Write([]byte(`{"result": `))
json.NewEncoder(w).Encode(r)
w.Write([]byte("}\n"))
enc := json.NewEncoder(w)
enc.SetEscapeHTML(false)
enc.Encode(map[string]interface{}{
"result": r,
})
}

const maxQuerySize = 1024 * 1024 // 1 MB
Expand Down Expand Up @@ -488,10 +491,20 @@ func (api *APIv2) ServeQuery(w http.ResponseWriter, r *http.Request) {
clog.Infof("query: %s: %q", lang, qu)
}

it, err := ses.Execute(ctx, qu, query.Options{
Collation: query.JSON,
opt := query.Options{
Collation: query.JSON, // TODO: switch to JSON-LD by default when the time comes
Limit: api.limit,
})
}
if specs := ParseAccept(r.Header, hdrAccept); len(specs) != 0 {
// TODO: sort by Q
switch specs[0].Value {
case contentTypeJSON:
opt.Collation = query.JSON
case contentTypeJSONLD:
opt.Collation = query.JSONLD
}
}
it, err := ses.Execute(ctx, qu, opt)
if err != nil {
errFunc(w, err)
return
Expand All @@ -506,5 +519,10 @@ func (api *APIv2) ServeQuery(w http.ResponseWriter, r *http.Request) {
errFunc(w, err)
return
}
if opt.Collation == query.JSONLD {
w.Header().Set(hdrContentType, contentTypeJSONLD)
} else {
w.Header().Set(hdrContentType, contentTypeJSON)
}
writeResults(w, out)
}

0 comments on commit 74330c2

Please sign in to comment.