forked from cayleygraph/cayley
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsession.go
141 lines (119 loc) · 4.09 KB
/
session.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2014 The Cayley Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package query defines the graph session interface general to all query languages.
package query
import (
"context"
"errors"
"fmt"
"io"
"github.com/cayleygraph/cayley/graph"
)
var ErrParseMore = errors.New("query: more input required")
type ErrUnsupportedCollation struct {
Collation Collation
}
func (e *ErrUnsupportedCollation) Error() string {
return fmt.Sprintf("unsupported collation: %v", e.Collation)
}
// Iterator for query results.
type Iterator interface {
// Next advances the iterator to the next value, which will then be available through
// the Result method. It returns false if no further advancement is possible, or if an
// error was encountered during iteration. Err should be consulted to distinguish
// between the two cases.
Next(ctx context.Context) bool
// Results returns the current result. The type depends on the collation mode of the query.
Result() interface{}
// Err returns any error that was encountered by the Iterator.
Err() error
// Close the iterator and do internal cleanup.
Close() error
}
// Collation of results.
type Collation int
const (
// Raw collates results as maps or arrays of graph.Refs or any other query-native or graph-native data type.
Raw = Collation(iota)
// REPL collates results as strings which will be used in CLI.
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.
type Options struct {
Limit int
Collation Collation
}
type Session interface {
// Execute runs the query and returns an iterator over the results.
// Type of results depends on Collation. See Options for details.
Execute(ctx context.Context, query string, opt Options) (Iterator, error)
}
type REPLSession = Session
// ResponseWriter is a subset of http.ResponseWriter
type ResponseWriter interface {
Write([]byte) (int, error)
WriteHeader(int)
}
// Language is a description of query language.
type Language struct {
Name string
Session func(graph.QuadStore) Session
// Custom HTTP handlers
HTTPQuery func(ctx context.Context, qs graph.QuadStore, w ResponseWriter, r io.Reader)
HTTPError func(w ResponseWriter, err error)
}
var languages = make(map[string]Language)
// RegisterLanguage register a new query language.
func RegisterLanguage(lang Language) {
languages[lang.Name] = lang
}
// NewSession creates a new session for specified query language.
// It returns nil if language was not registered.
func NewSession(qs graph.QuadStore, lang string) Session {
if l := languages[lang]; l.Session != nil {
return l.Session(qs)
}
return nil
}
// GetLanguage returns a query language description.
// It returns nil if language was not registered.
func GetLanguage(lang string) *Language {
l, ok := languages[lang]
if ok {
return &l
}
return nil
}
// Languages returns names of registered query languages.
func Languages() []string {
out := make([]string, 0, len(languages))
for name := range languages {
out = append(out, name)
}
return out
}
// Execute runs the query in a given language and returns an iterator over the results.
// Type of results depends on Collation. See Options for details.
func Execute(ctx context.Context, qs graph.QuadStore, lang, query string, opt Options) (Iterator, error) {
l := GetLanguage(lang)
if l == nil {
return nil, fmt.Errorf("unsupported language: %q", lang)
}
sess := l.Session(qs)
return sess.Execute(ctx, query, opt)
}