Destutter filenames
This commit is contained in:
parent
be116d7ba8
commit
47c9752e5e
58 changed files with 4864 additions and 4864 deletions
266
query/gremlin/session.go
Normal file
266
query/gremlin/session.go
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
// 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 gremlin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/robertkrimen/otto"
|
||||
|
||||
"github.com/google/cayley/graph"
|
||||
)
|
||||
|
||||
type GremlinSession struct {
|
||||
ts graph.TripleStore
|
||||
currentChannel chan interface{}
|
||||
env *otto.Otto
|
||||
debug bool
|
||||
limit int
|
||||
count int
|
||||
dataOutput []interface{}
|
||||
lookingForQueryShape bool
|
||||
queryShape map[string]interface{}
|
||||
err error
|
||||
script *otto.Script
|
||||
doHalt bool
|
||||
timeoutSec time.Duration
|
||||
emptyEnv *otto.Otto
|
||||
}
|
||||
|
||||
func NewGremlinSession(inputTripleStore graph.TripleStore, timeoutSec int, persist bool) *GremlinSession {
|
||||
var g GremlinSession
|
||||
g.ts = inputTripleStore
|
||||
g.env = BuildGremlinEnv(&g)
|
||||
g.limit = -1
|
||||
g.count = 0
|
||||
g.lookingForQueryShape = false
|
||||
if persist {
|
||||
g.emptyEnv = g.env
|
||||
}
|
||||
if timeoutSec < 0 {
|
||||
g.timeoutSec = time.Duration(-1)
|
||||
} else {
|
||||
g.timeoutSec = time.Duration(timeoutSec)
|
||||
}
|
||||
g.ClearJson()
|
||||
return &g
|
||||
}
|
||||
|
||||
type GremlinResult struct {
|
||||
metaresult bool
|
||||
err string
|
||||
val *otto.Value
|
||||
actualResults *map[string]graph.TSVal
|
||||
}
|
||||
|
||||
func (g *GremlinSession) ToggleDebug() {
|
||||
g.debug = !g.debug
|
||||
}
|
||||
|
||||
func (g *GremlinSession) GetQuery(input string, output_struct chan map[string]interface{}) {
|
||||
defer close(output_struct)
|
||||
g.queryShape = make(map[string]interface{})
|
||||
g.lookingForQueryShape = true
|
||||
g.env.Run(input)
|
||||
output_struct <- g.queryShape
|
||||
g.queryShape = nil
|
||||
}
|
||||
|
||||
func (g *GremlinSession) InputParses(input string) (graph.ParseResult, error) {
|
||||
script, err := g.env.Compile("", input)
|
||||
if err != nil {
|
||||
return graph.ParseFail, err
|
||||
}
|
||||
g.script = script
|
||||
return graph.Parsed, nil
|
||||
}
|
||||
|
||||
func (g *GremlinSession) SendResult(result *GremlinResult) bool {
|
||||
if g.limit >= 0 && g.limit == g.count {
|
||||
return false
|
||||
}
|
||||
if g.doHalt {
|
||||
return false
|
||||
}
|
||||
if g.currentChannel != nil {
|
||||
g.currentChannel <- result
|
||||
g.count++
|
||||
if g.limit >= 0 && g.limit == g.count {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var halt = errors.New("Query Timeout")
|
||||
|
||||
func (g *GremlinSession) runUnsafe(input interface{}) (otto.Value, error) {
|
||||
g.doHalt = false
|
||||
defer func() {
|
||||
if caught := recover(); caught != nil {
|
||||
if caught == halt {
|
||||
g.err = halt
|
||||
return
|
||||
}
|
||||
panic(caught) // Something else happened, repanic!
|
||||
}
|
||||
}()
|
||||
|
||||
g.env.Interrupt = make(chan func(), 1) // The buffer prevents blocking
|
||||
|
||||
if g.timeoutSec != -1 {
|
||||
go func() {
|
||||
time.Sleep(g.timeoutSec * time.Second) // Stop after two seconds
|
||||
g.doHalt = true
|
||||
if g.env != nil {
|
||||
g.env.Interrupt <- func() {
|
||||
panic(halt)
|
||||
}
|
||||
g.env = g.emptyEnv
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return g.env.Run(input) // Here be dragons (risky code)
|
||||
}
|
||||
|
||||
func (g *GremlinSession) ExecInput(input string, out chan interface{}, limit int) {
|
||||
defer close(out)
|
||||
g.err = nil
|
||||
g.currentChannel = out
|
||||
var err error
|
||||
var value otto.Value
|
||||
if g.script == nil {
|
||||
value, err = g.runUnsafe(input)
|
||||
} else {
|
||||
value, err = g.runUnsafe(g.script)
|
||||
}
|
||||
if err != nil {
|
||||
out <- &GremlinResult{metaresult: true,
|
||||
err: err.Error(),
|
||||
val: &value,
|
||||
actualResults: nil}
|
||||
} else {
|
||||
out <- &GremlinResult{metaresult: true,
|
||||
err: "",
|
||||
val: &value,
|
||||
actualResults: nil}
|
||||
}
|
||||
g.currentChannel = nil
|
||||
g.script = nil
|
||||
g.env = g.emptyEnv
|
||||
return
|
||||
}
|
||||
|
||||
func (s *GremlinSession) ToText(result interface{}) string {
|
||||
data := result.(*GremlinResult)
|
||||
if data.metaresult {
|
||||
if data.err != "" {
|
||||
return fmt.Sprintln("Error: ", data.err)
|
||||
}
|
||||
if data.val != nil {
|
||||
s, _ := data.val.Export()
|
||||
if data.val.IsObject() {
|
||||
typeVal, _ := data.val.Object().Get("_gremlin_type")
|
||||
if !typeVal.IsUndefined() {
|
||||
s = "[internal Iterator]"
|
||||
}
|
||||
}
|
||||
return fmt.Sprintln("=>", s)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
var out string
|
||||
out = fmt.Sprintln("****")
|
||||
if data.val == nil {
|
||||
tags := data.actualResults
|
||||
tagKeys := make([]string, len(*tags))
|
||||
i := 0
|
||||
for k, _ := range *tags {
|
||||
tagKeys[i] = k
|
||||
i++
|
||||
}
|
||||
sort.Strings(tagKeys)
|
||||
for _, k := range tagKeys {
|
||||
if k == "$_" {
|
||||
continue
|
||||
}
|
||||
out += fmt.Sprintf("%s : %s\n", k, s.ts.GetNameFor((*tags)[k]))
|
||||
}
|
||||
} else {
|
||||
if data.val.IsObject() {
|
||||
export, _ := data.val.Export()
|
||||
mapExport := export.(map[string]string)
|
||||
for k, v := range mapExport {
|
||||
out += fmt.Sprintf("%s : %v\n", k, v)
|
||||
}
|
||||
} else {
|
||||
strVersion, _ := data.val.ToString()
|
||||
out += fmt.Sprintf("%s\n", strVersion)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Web stuff
|
||||
func (ses *GremlinSession) BuildJson(result interface{}) {
|
||||
data := result.(*GremlinResult)
|
||||
if !data.metaresult {
|
||||
if data.val == nil {
|
||||
obj := make(map[string]string)
|
||||
tags := data.actualResults
|
||||
tagKeys := make([]string, len(*tags))
|
||||
i := 0
|
||||
for k, _ := range *tags {
|
||||
tagKeys[i] = k
|
||||
i++
|
||||
}
|
||||
sort.Strings(tagKeys)
|
||||
for _, k := range tagKeys {
|
||||
obj[k] = ses.ts.GetNameFor((*tags)[k])
|
||||
}
|
||||
ses.dataOutput = append(ses.dataOutput, obj)
|
||||
} else {
|
||||
if data.val.IsObject() {
|
||||
export, _ := data.val.Export()
|
||||
ses.dataOutput = append(ses.dataOutput, export)
|
||||
} else {
|
||||
strVersion, _ := data.val.ToString()
|
||||
ses.dataOutput = append(ses.dataOutput, strVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (ses *GremlinSession) GetJson() (interface{}, error) {
|
||||
defer ses.ClearJson()
|
||||
if ses.err != nil {
|
||||
return nil, ses.err
|
||||
}
|
||||
if ses.doHalt {
|
||||
return nil, halt
|
||||
}
|
||||
return ses.dataOutput, nil
|
||||
}
|
||||
|
||||
func (ses *GremlinSession) ClearJson() {
|
||||
ses.dataOutput = nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue