func (api *Api) ServeV1Shape(w http.ResponseWriter, r *http.Request, params httprouter.Params) int { var ses graph.HttpSession switch params.ByName("query_lang") { case "gremlin": ses = gremlin.NewSession(api.ts, api.config.GremlinTimeout, false) case "mql": ses = mql.NewSession(api.ts) default: return FormatJson400(w, "Need a query language.") } var err error bodyBytes, err := ioutil.ReadAll(r.Body) if err != nil { return FormatJson400(w, err) } code := string(bodyBytes) result, err := ses.InputParses(code) switch result { case graph.Parsed: var output []byte var err error output, err = GetQueryShape(code, ses) if err != nil { return FormatJson400(w, err) } fmt.Fprint(w, string(output)) return 200 case graph.ParseFail: return FormatJson400(w, err) default: return FormatJsonError(w, 500, "Incomplete data?") } http.Error(w, "", http.StatusNotFound) return http.StatusNotFound }
func (api *API) ServeV1Shape(w http.ResponseWriter, r *http.Request, params httprouter.Params) int { var ses query.HTTP switch params.ByName("query_lang") { case "gremlin": ses = gremlin.NewSession(api.handle.QuadStore, api.config.Timeout, false) case "mql": ses = mql.NewSession(api.handle.QuadStore) default: return jsonResponse(w, 400, "Need a query language.") } bodyBytes, err := ioutil.ReadAll(r.Body) if err != nil { return jsonResponse(w, 400, err) } code := string(bodyBytes) result, err := ses.InputParses(code) switch result { case query.Parsed: var output []byte var err error output, err = GetQueryShape(code, ses) if err != nil { return jsonResponse(w, 400, err) } fmt.Fprint(w, string(output)) return 200 case query.ParseFail: return jsonResponse(w, 400, err) default: return jsonResponse(w, 500, "Incomplete data?") } }
func runQuery(queryLang, code string) (interface{}, error) { qs := &QuadStore{} var ses query.HTTP switch queryLang { case "gremlin": ses = gremlin.NewSession(qs, 100*time.Second, false) case "mql": ses = mql.NewSession(qs) default: } result, err := ses.Parse(code) switch result { case query.Parsed: output, err := Run(code, ses) if err != nil { return nil, err } return output, nil case query.ParseFail: ses = nil return nil, err default: ses = nil return nil, fmt.Errorf("Incomplete data?") } }
func checkQueries(t *testing.T) { for _, test := range benchmarkQueries { if testing.Short() && test.long { continue } if test.skip { continue } tInit := time.Now() t.Logf("Now testing %s ", test.message) ses := gremlin.NewSession(handle.QuadStore, cfg.Timeout, true) _, err := ses.Parse(test.query) if err != nil { t.Fatalf("Failed to parse benchmark gremlin %s: %v", test.message, err) } c := make(chan interface{}, 5) go ses.Execute(test.query, c, 100) var ( got []interface{} timedOut bool ) for r := range c { ses.Collate(r) j, err := ses.Results() if j == nil && err == nil { continue } if err == gremlin.ErrKillTimeout { timedOut = true continue } got = append(got, j.([]interface{})...) } if timedOut { t.Error("Query timed out: skipping validation.") continue } t.Logf("(%v)\n", time.Since(tInit)) if len(got) != len(test.expect) { t.Errorf("Unexpected number of results, got:%d expect:%d on %s.", len(got), len(test.expect), test.message) continue } if unsortedEqual(got, test.expect) { continue } t.Errorf("Unexpected results for %s:\n", test.message) for i := range got { t.Errorf("\n\tgot:%#v\n\texpect:%#v\n", got[i], test.expect[i]) } } }
// TODO(barakmich): Turn this into proper middleware. func (api *Api) ServeV1Query(w http.ResponseWriter, r *http.Request, params httprouter.Params) int { var ses query.HttpSession switch params.ByName("query_lang") { case "gremlin": ses = gremlin.NewSession(api.ts, api.config.GremlinTimeout, false) case "mql": ses = mql.NewSession(api.ts) default: return FormatJson400(w, "Need a query language.") } bodyBytes, err := ioutil.ReadAll(r.Body) if err != nil { return FormatJson400(w, err) } code := string(bodyBytes) result, err := ses.InputParses(code) switch result { case query.Parsed: var output interface{} var bytes []byte var err error output, err = RunJsonQuery(code, ses) if err != nil { bytes, err = WrapErrResult(err) http.Error(w, string(bytes), 400) ses = nil return 400 } bytes, err = WrapResult(output) if err != nil { ses = nil return FormatJson400(w, err) } fmt.Fprint(w, string(bytes)) ses = nil return 200 case query.ParseFail: ses = nil return FormatJson400(w, err) default: ses = nil return FormatJsonError(w, 500, "Incomplete data?") } http.Error(w, "", http.StatusNotFound) ses = nil return http.StatusNotFound }
// TODO(barakmich): Turn this into proper middleware. func (api *API) ServeV1Query(w http.ResponseWriter, r *http.Request, params httprouter.Params) int { h, err := api.GetHandleForRequest(r) var ses query.HTTP switch params.ByName("query_lang") { case "gremlin": ses = gremlin.NewSession(h.QuadStore, api.config.Timeout, false) case "mql": ses = mql.NewSession(h.QuadStore) default: return jsonResponse(w, 400, "Need a query language.") } bodyBytes, err := ioutil.ReadAll(r.Body) if err != nil { return jsonResponse(w, 400, err) } code := string(bodyBytes) result, err := ses.Parse(code) switch result { case query.Parsed: var output interface{} var bytes []byte var err error output, err = Run(code, ses) if err != nil { bytes, err = WrapErrResult(err) http.Error(w, string(bytes), 400) ses = nil return 400 } bytes, err = WrapResult(output) if err != nil { ses = nil return jsonResponse(w, 400, err) } fmt.Fprint(w, string(bytes)) ses = nil return 200 case query.ParseFail: ses = nil return jsonResponse(w, 400, err) default: ses = nil return jsonResponse(w, 500, "Incomplete data?") } }
func runBench(n int, b *testing.B) { if testing.Short() && benchmarkQueries[n].long { b.Skip() } prepare(b) ses := gremlin.NewSession(ts, cfg.GremlinTimeout, true) _, err := ses.InputParses(benchmarkQueries[n].query) if err != nil { b.Fatalf("Failed to parse benchmark gremlin %s: %v", benchmarkQueries[n].message, err) } b.ResetTimer() for i := 0; i < b.N; i++ { c := make(chan interface{}, 5) go ses.ExecInput(benchmarkQueries[n].query, c, 100) for _ = range c { } } }
func runBench(n int, b *testing.B) { if testing.Short() && benchmarkQueries[n].long { b.Skip() } prepare(b) b.StopTimer() b.ResetTimer() for i := 0; i < b.N; i++ { c := make(chan interface{}, 5) ses := gremlin.NewSession(handle.QuadStore, cfg.Timeout, true) // Do the parsing we know works. ses.Parse(benchmarkQueries[n].query) b.StartTimer() go ses.Execute(benchmarkQueries[n].query, c, 100) for _ = range c { } b.StopTimer() } }
func TestQueries(t *testing.T) { prepare(t) for _, test := range benchmarkQueries { if testing.Short() && test.long { continue } ses := gremlin.NewSession(ts, cfg.Timeout, true) _, err := ses.InputParses(test.query) if err != nil { t.Fatalf("Failed to parse benchmark gremlin %s: %v", test.message, err) } c := make(chan interface{}, 5) go ses.ExecInput(test.query, c, 100) var ( got [][]interface{} timedOut bool ) for r := range c { ses.BuildJson(r) j, err := ses.GetJson() if j == nil && err == nil { continue } if err == gremlin.ErrKillTimeout { timedOut = true continue } got = append(got, j) } if timedOut { t.Error("Query timed out: skipping validation.") continue } // TODO(kortschak) Be more rigorous in this result validation. if len(got) != len(test.expect) { t.Errorf("Unexpected number of results, got:%d expect:%d on %s.", len(got), len(test.expect), test.message) } } }
func findProperty(graph *cayleyGraph.Handle, rsp http.ResponseWriter, req *http.Request) int { result := make(map[string]interface{}) retcode := 200 pathVars := mux.Vars(req) result["request"] = pathVars session := cayleyGremlin.NewSession(graph.QuadStore, time.Duration(10*time.Second), false) gremlinQuery := fmt.Sprintf(`g.V("/properties/%s").All()`, pathVars["id"]) queryResult, err := session.Parse(gremlinQuery) switch queryResult { case cayleyQuery.Parsed: output, err := runGremlinQuery(gremlinQuery, session) if err != nil { result["success"] = false result["error"] = err retcode = 400 break } result["success"] = true result["output"] = output case cayleyQuery.ParseFail: result["success"] = false result["error"] = fmt.Sprintf("Failed to parse query: %s", err) retcode = 400 default: result["success"] = false result["error"] = "Possibly incomplete data or query?" retcode = 500 } bytes, _ := json.MarshalIndent(result, "", " ") fmt.Fprintln(rsp, string(bytes)) return retcode }
func Repl(ts graph.TripleStore, queryLanguage string, cfg *config.Config) error { var ses query.Session switch queryLanguage { case "sexp": ses = sexp.NewSession(ts) case "mql": ses = mql.NewSession(ts) case "gremlin": fallthrough default: ses = gremlin.NewSession(ts, cfg.Timeout, true) } buf := bufio.NewReader(os.Stdin) var line []byte for { if len(line) == 0 { fmt.Print("cayley> ") } else { fmt.Print("... ") } l, prefix, err := buf.ReadLine() if err == io.EOF { if len(line) != 0 { line = line[:0] } else { return nil } } if err != nil { line = line[:0] } if prefix { return errors.New("line too long") } line = append(line, l...) if len(line) == 0 { continue } line = bytes.TrimSpace(line) if len(line) == 0 || line[0] == '#' { line = line[:0] continue } if bytes.HasPrefix(line, []byte(":debug")) { ses.ToggleDebug() fmt.Println("Debug Toggled") line = line[:0] continue } if bytes.HasPrefix(line, []byte(":a")) { var tripleStmt = line[3:] triple, err := cquads.Parse(string(tripleStmt)) if !triple.IsValid() { if err != nil { fmt.Printf("not a valid triple: %v\n", err) } line = line[:0] continue } ts.AddTriple(triple) line = line[:0] continue } if bytes.HasPrefix(line, []byte(":d")) { var tripleStmt = line[3:] triple, err := cquads.Parse(string(tripleStmt)) if !triple.IsValid() { if err != nil { fmt.Printf("not a valid triple: %v\n", err) } line = line[:0] continue } ts.RemoveTriple(triple) line = line[:0] continue } result, err := ses.InputParses(string(line)) switch result { case query.Parsed: Run(string(line), ses) line = line[:0] case query.ParseFail: fmt.Println("Error: ", err) line = line[:0] case query.ParseMore: } } }
func Repl(h *graph.Handle, queryLanguage string, cfg *config.Config) error { var ses query.Session switch queryLanguage { case "sexp": ses = sexp.NewSession(h.QuadStore) case "mql": ses = mql.NewSession(h.QuadStore) case "gremlin": fallthrough default: ses = gremlin.NewSession(h.QuadStore, cfg.Timeout, true) } term, err := terminal(history) if os.IsNotExist(err) { fmt.Printf("creating new history file: %q\n", history) } defer persist(term, history) var ( prompt = ps1 code string ) for { if len(code) == 0 { prompt = ps1 } else { prompt = ps2 } line, err := term.Prompt(prompt) if err != nil { if err == io.EOF { fmt.Println() return nil } return err } term.AppendHistory(line) line = strings.TrimSpace(line) if len(line) == 0 || line[0] == '#' { continue } if code == "" { cmd, args := splitLine(line) switch cmd { case ":debug": args = strings.TrimSpace(args) var debug bool switch args { case "t": debug = true case "f": // Do nothing. default: debug, err = strconv.ParseBool(args) if err != nil { fmt.Printf("Error: cannot parse %q as a valid boolean - acceptable values: 't'|'true' or 'f'|'false'\n", args) continue } } ses.Debug(debug) fmt.Printf("Debug set to %t\n", debug) continue case ":a": quad, err := cquads.Parse(args) if err != nil { fmt.Printf("Error: not a valid quad: %v\n", err) continue } h.QuadWriter.WriteQuad(quad) continue case ":d": quad, err := cquads.Parse(args) if err != nil { fmt.Printf("Error: not a valid quad: %v\n", err) continue } err = h.QuadWriter.RemoveQuad(quad) if err != nil { fmt.Printf("error deleting: %v\n", err) } continue case "exit": term.Close() os.Exit(0) default: if cmd[0] == ':' { fmt.Printf("Unknown command: %q\n", cmd) continue } } } code += line result, err := ses.Parse(code) switch result { case query.Parsed: Run(code, ses) code = "" case query.ParseFail: fmt.Println("Error: ", err) code = "" case query.ParseMore: } } }
func Repl(ts graph.TripleStore, queryLanguage string, cfg *config.Config) { var ses graph.Session switch queryLanguage { case "sexp": ses = sexp.NewSession(ts) case "mql": ses = mql.NewSession(ts) case "gremlin": fallthrough default: ses = gremlin.NewSession(ts, cfg.GremlinTimeout, true) } inputBf := bufio.NewReader(os.Stdin) line := "" for { if line == "" { fmt.Print("cayley> ") } else { fmt.Print("... ") } l, pre, err := inputBf.ReadLine() if err == io.EOF { if line != "" { line = "" } else { break } } if err != nil { line = "" } if pre { panic("Line too long") } line += string(l) if line == "" { continue } if strings.HasPrefix(line, ":debug") { ses.ToggleDebug() fmt.Println("Debug Toggled") line = "" continue } if strings.HasPrefix(line, ":a") { var tripleStmt = line[3:] triple := nquads.Parse(tripleStmt) if triple == nil { fmt.Println("Not a valid triple.") line = "" continue } ts.AddTriple(triple) line = "" continue } if strings.HasPrefix(line, ":d") { var tripleStmt = line[3:] triple := nquads.Parse(tripleStmt) if triple == nil { fmt.Println("Not a valid triple.") line = "" continue } ts.RemoveTriple(triple) line = "" continue } result, err := ses.InputParses(line) switch result { case graph.Parsed: Run(line, ses) line = "" case graph.ParseFail: fmt.Println("Error: ", err) line = "" case graph.ParseMore: default: } } }
func Repl(h *graph.Handle, queryLanguage string, cfg *config.Config) error { var ses query.Session switch queryLanguage { case "sexp": ses = sexp.NewSession(h.QuadStore) case "mql": ses = mql.NewSession(h.QuadStore) case "gremlin": fallthrough default: ses = gremlin.NewSession(h.QuadStore, cfg.Timeout, true) } term, err := terminal(history) if os.IsNotExist(err) { fmt.Printf("creating new history file: %q\n", history) } defer persist(term, history) var ( prompt = ps1 code string ) for { if len(code) == 0 { prompt = ps1 } else { prompt = ps2 } line, err := term.Prompt(prompt) if err != nil { if err == io.EOF { fmt.Println() return nil } return err } term.AppendHistory(line) line = strings.TrimSpace(line) if len(line) == 0 || line[0] == '#' { continue } if code == "" { switch { case strings.HasPrefix(line, ":debug"): ses.ToggleDebug() fmt.Println("Debug Toggled") continue case strings.HasPrefix(line, ":a"): quad, err := cquads.Parse(line[3:]) if !quad.IsValid() { if err != nil { fmt.Printf("not a valid quad: %v\n", err) } continue } h.QuadWriter.AddQuad(quad) continue case strings.HasPrefix(line, ":d"): quad, err := cquads.Parse(line[3:]) if !quad.IsValid() { if err != nil { fmt.Printf("not a valid quad: %v\n", err) } continue } h.QuadWriter.RemoveQuad(quad) continue } } code += line result, err := ses.InputParses(code) switch result { case query.Parsed: Run(code, ses) code = "" case query.ParseFail: fmt.Println("Error: ", err) code = "" case query.ParseMore: } } }