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