123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- /*
- * EliasDB
- *
- * Copyright 2016 Matthias Ladkau. All rights reserved.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
- package ecal
- import (
- "fmt"
- "io/ioutil"
- "path/filepath"
- "strings"
- "devt.de/krotik/common/fileutil"
- "devt.de/krotik/ecal/cli/tool"
- "devt.de/krotik/ecal/stdlib"
- "devt.de/krotik/ecal/util"
- "devt.de/krotik/eliasdb/config"
- "devt.de/krotik/eliasdb/ecal/dbfunc"
- "devt.de/krotik/eliasdb/graph"
- )
- /*
- ScriptingInterpreter models a ECAL script interpreter instance.
- */
- type ScriptingInterpreter struct {
- GM *graph.Manager // GraphManager for the interpreter
- Dir string // Root dir for interpreter
- EntryFile string // Entry file for the program
- LogLevel string // Log level string (Debug, Info, Error)
- LogFile string // Logfile (blank for stdout)
- RunDebugServer bool // Run a debug server
- DebugServerHost string // Debug server host
- DebugServerPort string // Debug server port
- }
- /*
- NewScriptingInterpreter returns a new ECAL scripting interpreter.
- */
- func NewScriptingInterpreter(scriptFolder string, gm *graph.Manager) *ScriptingInterpreter {
- return &ScriptingInterpreter{
- GM: gm,
- Dir: scriptFolder,
- EntryFile: filepath.Join(scriptFolder, config.Str(config.ECALEntryScript)),
- LogLevel: config.Str(config.ECALLogLevel),
- LogFile: config.Str(config.ECALLogFile),
- RunDebugServer: config.Bool(config.EnableECALDebugServer),
- DebugServerHost: config.Str(config.ECALDebugServerHost),
- DebugServerPort: config.Str(config.ECALDebugServerPort),
- }
- }
- /*
- dummyEntryFile is a small valid ECAL which does not do anything. It is used
- as the default entry file if no entry file exists.
- */
- const dummyEntryFile = `0 # Write your ECAL code here
- `
- /*
- Run runs the ECAL scripting interpreter.
- */
- func (si *ScriptingInterpreter) Run() error {
- var err error
- // Ensure we have a dummy entry point
- if ok, _ := fileutil.PathExists(si.EntryFile); !ok {
- err = ioutil.WriteFile(si.EntryFile, []byte(dummyEntryFile), 0600)
- }
- if err == nil {
- i := tool.NewCLIInterpreter()
- i.Dir = &si.Dir
- i.LogFile = &si.LogFile
- i.LogLevel = &si.LogLevel
- i.EntryFile = si.EntryFile
- i.LoadPlugins = true
- i.CreateRuntimeProvider("eliasdb-runtime")
- // Adding functions
- stdlib.AddStdlibPkg("db", "EliasDB related functions")
- stdlib.AddStdlibFunc("db", "storeNode", &dbfunc.StoreNodeFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "removeNode", &dbfunc.RemoveNodeFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "fetchNode", &dbfunc.FetchNodeFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "storeEdge", &dbfunc.StoreEdgeFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "removeEdge", &dbfunc.RemoveEdgeFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "fetchEdge", &dbfunc.FetchEdgeFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "traverse", &dbfunc.TraverseFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "newTrans", &dbfunc.NewTransFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "newRollingTrans", &dbfunc.NewRollingTransFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "commit", &dbfunc.CommitTransFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "query", &dbfunc.QueryFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "graphQL", &dbfunc.GraphQLFunc{GM: si.GM})
- stdlib.AddStdlibFunc("db", "raiseGraphEventHandled", &dbfunc.RaiseGraphEventHandledFunc{})
- if err == nil {
- if si.RunDebugServer {
- di := tool.NewCLIDebugInterpreter(i)
- addr := fmt.Sprintf("%v:%v", si.DebugServerHost, si.DebugServerPort)
- di.DebugServerAddr = &addr
- di.RunDebugServer = &si.RunDebugServer
- falseFlag := false
- di.EchoDebugServer = &falseFlag
- di.Interactive = &falseFlag
- di.BreakOnStart = &falseFlag
- trueFlag := true
- di.BreakOnError = &trueFlag
- err = di.Interpret()
- } else {
- err = i.Interpret(false)
- }
- // Rules for the GraphManager are loaded after the code has been
- // executed and all rules have been added. The ECA processor can now be started.
- i.RuntimeProvider.Processor.Start()
- // EliasDB graph events can not be forwarded to ECAL via the eventbridge.
- si.GM.SetGraphRule(&EventBridge{
- Processor: i.RuntimeProvider.Processor,
- Logger: i.RuntimeProvider.Logger,
- })
- }
- }
- // Include a traceback if possible
- if ss, ok := err.(util.TraceableRuntimeError); ok {
- err = fmt.Errorf("%v\n %v", err.Error(), strings.Join(ss.GetTraceString(), "\n "))
- }
- return err
- }
|