Exemple #1
0
func extractID(value interface{}) string {
	id := util.MaybeString(value)
	id = strings.Replace(id, " ", "", -1)
	id = strings.Replace(id, "{{", "", -1)
	id = strings.Replace(id, "}}", "", -1)
	return id
}
Exemple #2
0
func include(stmt *Stmt) (func(*Context) (interface{}, error), error) {

	source := util.MaybeString(stmt.RawData["include"])
	if !filepath.IsAbs(source) {
		currentSource := stmt.File
		source = filepath.Clean(filepath.Join(filepath.Dir(currentSource), source))
	}
	importedCode, err := LoadYAMLFile(source)
	if err != nil {
		return nil, stmt.Errorf("yaml parse error: %s", err)
	}
	stmt.Args = map[string]Value{}
	for key, value := range stmt.RawData {
		stmt.Args[key], err = NewValue(value)
		if err != nil {
			return nil, stmt.Errorf("yaml parse error: %s", err)
		}
	}
	stmt.File = source
	stmts, err := MakeStmts(stmt.File, importedCode)
	if err != nil {
		return nil, stmt.Errorf("import code parse error: %s", err)
	}
	stmt.Vars, err = MapToValue(util.MaybeMap(stmt.RawData["vars"]))
	if err != nil {
		return nil, stmt.Errorf("yaml parse error: %s", err)
	}
	return StmtsToFunc(stmt.funcName, stmts)
}
Exemple #3
0
// Extend clones context and extend it
func (context *Context) Extend(values map[string]interface{}) *Context {
	newContext := NewContext(context.VM.Clone())
	for key, value := range context.data {
		newContext.Set(key, value)
	}
	for key, value := range values {
		newContext.Set(util.MaybeString(key), value)
	}
	return newContext
}
Exemple #4
0
func command(stmt *gohanscript.Stmt) (func(*gohanscript.Context) (interface{}, error), error) {
	var err error
	stmt.Args, err = gohanscript.MapToValue(util.MaybeMap(stmt.RawData["args"]))
	if err != nil {
		return nil, err
	}
	stmt.Args["command"], err = gohanscript.NewValue(stmt.RawData["command"])
	if err != nil {
		return nil, err
	}
	return func(context *gohanscript.Context) (interface{}, error) {
		chdir := stmt.Arg("chdir", context)
		if chdir != nil {
			currentDir, _ := filepath.Abs(".")
			os.Chdir(util.MaybeString(chdir))
			defer os.Chdir(currentDir)
		}
		command := util.MaybeString(stmt.Arg("command", context))
		parts := strings.Fields(command)
		result, err := exec.Command(parts[0], parts[1:]...).CombinedOutput()
		return string(result), err
	}, nil
}
Exemple #5
0
func transactionFunc(stmt *gohanscript.Stmt) (func(*gohanscript.Context) (interface{}, error), error) {
	stmts, err := gohanscript.MakeStmts(stmt.File, stmt.RawNode["transaction"])
	if err != nil {
		return nil, err
	}
	runner, err := gohanscript.StmtsToFunc("transaction", stmts)
	if err != nil {
		return nil, err
	}
	return func(context *gohanscript.Context) (interface{}, error) {
		dbVar := util.MaybeString(stmt.RawData["db"])
		if dbVar == "" {
			dbVar = "db"
		}
		rawDB, err := context.Get(dbVar)
		if err != nil {
			return nil, err
		}
		connection := rawDB.(db.DB)
		tx, err := connection.Begin()
		if err != nil {
			return nil, err
		}
		transactionVar := util.MaybeString(stmt.RawData["transaction_var"])
		if transactionVar == "" {
			transactionVar = "transaction"
		}
		context.Set(transactionVar, tx)
		value, err := runner(context)
		if err == nil {
			tx.Commit()
		}
		tx.Close()
		return value, err
	}, nil
}
Exemple #6
0
func define(stmt *Stmt) (func(*Context) (interface{}, error), error) {
	var err error
	funcName := util.MaybeString(stmt.Args["name"].Value(nil))
	defineNode := MappingNodeToMap(stmt.RawNode["define"])
	funcArgs := util.MaybeMap(stmt.Args["args"].Value(nil))
	stmts, err := MakeStmts(stmt.File, defineNode["body"])
	if err != nil {
		return nil, stmt.Errorf("error in define body: %s", err)
	}
	var body func(*Context) (interface{}, error)
	RegisterStmtParser(
		funcName,
		func(aStmt *Stmt) (func(*Context) (interface{}, error), error) {
			for key := range funcArgs {
				_, ok := aStmt.Args[key]
				if !ok {
					return nil, fmt.Errorf("missing augument %s", key)
				}
			}
			return func(context *Context) (value interface{}, err error) {
				vm := context.VM
				newContext := NewContext(vm)
				for key := range funcArgs {
					newContext.Set(key, aStmt.Arg(key, context))
				}
				value, err = body(newContext)

				if vm.debugReturn {
					vm.debugReturn = false
					vm.debug = true
				}
				return
			}, nil
		})
	body, err = StmtsToFunc("funcName", stmts)
	if err != nil {
		return nil, err
	}
	return func(context *Context) (interface{}, error) {
		return nil, nil
	}, nil
}
Exemple #7
0
//NewSchemaFromObj is a constructor for a schema by obj
func NewSchemaFromObj(rawTypeData interface{}) (*Schema, error) {
	typeData := rawTypeData.(map[string]interface{})

	metaschema, ok := GetManager().Schema("schema")
	if ok {
		err := metaschema.Validate(metaschema.JSONSchema, typeData)
		if err != nil {
			return nil, err
		}
	}

	id := util.MaybeString(typeData["id"])
	if id == "" {
		return nil, &typeAssertionError{"id"}
	}
	plural := util.MaybeString(typeData["plural"])
	if plural == "" {
		return nil, &typeAssertionError{"plural"}
	}
	title := util.MaybeString(typeData["title"])
	if title == "" {
		return nil, &typeAssertionError{"title"}
	}
	description := util.MaybeString(typeData["description"])
	if description == "" {
		return nil, &typeAssertionError{"description"}
	}
	singular := util.MaybeString(typeData["singular"])
	if singular == "" {
		return nil, &typeAssertionError{"singular"}
	}

	schema := NewSchema(id, plural, title, description, singular)

	schema.Prefix = util.MaybeString(typeData["prefix"])
	schema.URL = util.MaybeString(typeData["url"])
	schema.Type = util.MaybeString(typeData["type"])
	schema.Parent = util.MaybeString(typeData["parent"])
	schema.OnParentDeleteCascade, _ = typeData["on_parent_delete_cascade"].(bool)
	schema.NamespaceID = util.MaybeString(typeData["namespace"])
	schema.IsolationLevel = util.MaybeMap(typeData["isolation_level"])
	jsonSchema, ok := typeData["schema"].(map[string]interface{})
	if !ok {
		return nil, &typeAssertionError{"schema"}
	}
	schema.JSONSchema = jsonSchema

	schema.Metadata = util.MaybeMap(typeData["metadata"])
	schema.Extends = util.MaybeStringList(typeData["extends"])

	actions := util.MaybeMap(typeData["actions"])
	schema.Actions = []Action{}
	for actionID, actionBody := range actions {
		action, err := NewActionFromObject(actionID, actionBody)
		if err != nil {
			return nil, err
		}
		schema.Actions = append(schema.Actions, action)
	}

	if err := schema.Init(); err != nil {
		return nil, err
	}
	return schema, nil
}
Exemple #8
0
func httpServer(stmt *gohanscript.Stmt) (func(*gohanscript.Context) (interface{}, error), error) {
	return func(globalContext *gohanscript.Context) (interface{}, error) {
		m := martini.Classic()
		var mutex = &sync.Mutex{}
		history := []interface{}{}
		server := map[string]interface{}{
			"history": history,
		}
		m.Handlers()
		m.Use(middleware.Logging())
		m.Use(martini.Recovery())
		rawBody := util.MaybeMap(stmt.RawData["http_server"])
		paths := util.MaybeMap(rawBody["paths"])
		middlewareCode := util.MaybeString(rawBody["middleware"])
		if middlewareCode != "" {
			vm := gohanscript.NewVM()
			err := vm.LoadString(stmt.File, middlewareCode)

			if err != nil {
				return nil, err
			}
			m.Use(func(w http.ResponseWriter, r *http.Request) {
				context := globalContext.Extend(nil)
				fillInContext(context.Data(), r, w, nil)

				reqData, _ := ioutil.ReadAll(r.Body)
				buff := ioutil.NopCloser(bytes.NewBuffer(reqData))
				r.Body = buff
				var data interface{}
				if reqData != nil {
					json.Unmarshal(reqData, &data)
				}

				context.Set("request", data)
				vm.Run(context.Data())
			})
		}
		m.Use(func(w http.ResponseWriter, r *http.Request) {
			reqData, _ := ioutil.ReadAll(r.Body)
			buff := ioutil.NopCloser(bytes.NewBuffer(reqData))
			r.Body = buff
			var data interface{}
			if reqData != nil {
				json.Unmarshal(reqData, &data)
			}
			mutex.Lock()
			server["history"] = append(server["history"].([]interface{}),
				map[string]interface{}{
					"method": r.Method,
					"path":   r.URL.String(),
					"data":   data,
				})
			mutex.Unlock()
		})
		for path, body := range paths {
			methods, ok := body.(map[string]interface{})
			if !ok {
				continue
			}
			for method, rawRouteBody := range methods {
				routeBody, ok := rawRouteBody.(map[string]interface{})
				if !ok {
					continue
				}
				code := util.MaybeString(routeBody["code"])
				vm := gohanscript.NewVM()
				err := vm.LoadString(stmt.File, code)
				if err != nil {
					return nil, err
				}
				switch method {
				case "get":
					m.Get(path, func(w http.ResponseWriter, r *http.Request, p martini.Params) {
						context := globalContext.Extend(nil)
						fillInContext(context.Data(), r, w, p)
						vm.Run(context.Data())
						serveResponse(w, context.Data())
					})
				case "post":
					m.Post(path, func(w http.ResponseWriter, r *http.Request, p martini.Params) {
						context := globalContext.Extend(nil)
						fillInContext(context.Data(), r, w, p)
						requestData, _ := middleware.ReadJSON(r)
						context.Set("request", requestData)
						vm.Run(context.Data())
						serveResponse(w, context.Data())
					})
				case "put":
					m.Put(path, func(w http.ResponseWriter, r *http.Request, p martini.Params) {
						context := globalContext.Extend(nil)
						fillInContext(context.Data(), r, w, p)
						requestData, _ := middleware.ReadJSON(r)
						context.Set("request", requestData)
						vm.Run(context.Data())
						serveResponse(w, context.Data())
					})
				case "delete":
					m.Delete(path, func(w http.ResponseWriter, r *http.Request, p martini.Params) {
						context := globalContext.Extend(nil)
						fillInContext(context.Data(), r, w, p)
						vm.Run(context.Data())
						serveResponse(w, context.Data())
					})
				}
			}
		}
		testMode := stmt.Args["test"].Value(globalContext).(bool)
		if testMode {
			ts := httptest.NewServer(m)
			server["server"] = ts
			return server, nil
		}
		m.RunOnAddr(stmt.Args["address"].Value(globalContext).(string))
		return nil, nil
	}, nil
}
Exemple #9
0
//NewStmt makes gohan statement from yaml node
func NewStmt(FileName string, node *yaml.Node) (stmt *Stmt, err error) {
	if node == nil {
		return nil, nil
	}
	stmt = &Stmt{}
	stmt.RawNode = MappingNodeToMap(node)
	stmt.Line = node.Line + 1
	stmt.Column = node.Column
	var rawData interface{}
	yaml.UnmarshalNode(node, &rawData)
	stmt.RawData = util.MaybeMap(convertMapformat(rawData))
	stmt.Name = util.MaybeString(stmt.RawData["name"])
	stmt.File, _ = filepath.Abs(FileName)
	stmt.Dir = filepath.Dir(stmt.File)
	stmt.Always, err = MakeStmts(FileName, stmt.RawNode["always"])
	if err != nil {
		return nil, stmt.Error(err)
	}
	stmt.Rescue, err = MakeStmts(FileName, stmt.RawNode["rescue"])
	if err != nil {
		return nil, stmt.Error(err)
	}
	stmt.ElseStmt, err = MakeStmts(FileName, stmt.RawNode["else"])
	if err != nil {
		return nil, stmt.Error(err)
	}
	stmt.Retry = util.MaybeInt(stmt.RawData["retries"])
	stmt.Worker = util.MaybeInt(stmt.RawData["worker"])
	stmt.LoopVar = util.MaybeString(stmt.RawData["loop_var"])
	if stmt.LoopVar == "" {
		stmt.LoopVar = "item"
	}
	if stmt.Retry == 0 {
		stmt.Retry = 1
	}
	stmt.Delay = util.MaybeInt(stmt.RawData["delay"])
	stmt.WithItems, err = NewValue(stmt.RawData["with_items"])
	if err != nil {
		return nil, stmt.Error(err)
	}
	stmt.WithDict, err = NewValue(stmt.RawData["with_dict"])
	if err != nil {
		return nil, stmt.Error(err)
	}
	if stmt.RawData["when"] != nil {
		stmt.When, err = CompileExpr(util.MaybeString(stmt.RawData["when"]))
		if err != nil {
			return nil, stmt.Error(err)
		}
	}
	if stmt.RawData["until"] != nil {
		stmt.Until, err = CompileExpr(util.MaybeString(stmt.RawData["until"]))
		if err != nil {
			return nil, stmt.Error(err)
		}
	}
	stmt.Register = util.MaybeString(stmt.RawData["register"])
	stmt.Vars, err = MapToValue(util.MaybeMap(stmt.RawData["vars"]))
	if err != nil {
		return nil, stmt.Error(err)
	}
	return stmt, nil
}
Exemple #10
0
// MaybeString returns a string
func (context *Context) MaybeString(key string) string {
	return util.MaybeString(context.MayGet(key))
}