484 lines
10 KiB
Go
484 lines
10 KiB
Go
package engine
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/yaoapp/gou/application"
|
|
"github.com/yaoapp/kun/exception"
|
|
"github.com/yaoapp/yao/api"
|
|
"github.com/yaoapp/yao/cert"
|
|
"github.com/yaoapp/yao/config"
|
|
"github.com/yaoapp/yao/connector"
|
|
"github.com/yaoapp/yao/flow"
|
|
"github.com/yaoapp/yao/fs"
|
|
"github.com/yaoapp/yao/i18n"
|
|
"github.com/yaoapp/yao/importer"
|
|
"github.com/yaoapp/yao/model"
|
|
"github.com/yaoapp/yao/plugin"
|
|
"github.com/yaoapp/yao/query"
|
|
"github.com/yaoapp/yao/runtime"
|
|
"github.com/yaoapp/yao/schedule"
|
|
"github.com/yaoapp/yao/script"
|
|
"github.com/yaoapp/yao/share"
|
|
"github.com/yaoapp/yao/socket"
|
|
"github.com/yaoapp/yao/store"
|
|
"github.com/yaoapp/yao/task"
|
|
"github.com/yaoapp/yao/websocket"
|
|
"github.com/yaoapp/yao/widget"
|
|
"github.com/yaoapp/yao/widgets"
|
|
)
|
|
|
|
// Load application engine
|
|
func Load(cfg config.Config) (err error) {
|
|
defer func() { err = exception.Catch(recover()) }()
|
|
|
|
// SET XGEN_BASE
|
|
adminRoot := "yao"
|
|
if share.App.Optional != nil {
|
|
if root, has := share.App.Optional["adminRoot"]; has {
|
|
adminRoot = fmt.Sprintf("%v", root)
|
|
}
|
|
}
|
|
os.Setenv("XGEN_BASE", adminRoot)
|
|
|
|
// load the application
|
|
err = loadApp(cfg.Root)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Load Application", err)
|
|
panic(err)
|
|
}
|
|
|
|
// Load Certs
|
|
err = cert.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Cert", err)
|
|
}
|
|
|
|
// Load Connectors
|
|
err = connector.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Connector", err)
|
|
}
|
|
|
|
// Load FileSystem
|
|
err = fs.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "FileSystem", err)
|
|
}
|
|
|
|
// Load i18n
|
|
err = i18n.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "i18n", err)
|
|
}
|
|
|
|
// start v8 runtime
|
|
err = runtime.Start(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Runtime", err)
|
|
}
|
|
|
|
// Make Database connections
|
|
err = share.DBConnect(cfg.DB)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "DB", err)
|
|
}
|
|
|
|
// Load Query Engine
|
|
err = query.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Query Engine", err)
|
|
}
|
|
|
|
// Load Scripts
|
|
err = script.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Script", err)
|
|
}
|
|
|
|
// Load Models
|
|
err = model.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Model", err)
|
|
}
|
|
|
|
// Load Data flows
|
|
err = flow.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Flow", err)
|
|
}
|
|
|
|
// Load Stores
|
|
err = store.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Store", err)
|
|
}
|
|
|
|
// Load Plugins
|
|
err = plugin.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Plugin", err)
|
|
}
|
|
|
|
// Load WASM Application (experimental)
|
|
|
|
// Load build-in widgets (table / form / chart / ...)
|
|
err = widgets.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Widgets", err)
|
|
}
|
|
|
|
// Load Importers
|
|
err = importer.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Plugin", err)
|
|
}
|
|
|
|
// Load Apis
|
|
err = api.Load(cfg) // 加载业务接口 API
|
|
if err != nil {
|
|
printErr(cfg.Mode, "API", err)
|
|
}
|
|
|
|
// Load Sockets
|
|
err = socket.Load(cfg) // Load sockets
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Socket", err)
|
|
}
|
|
|
|
// Load websockets (client mode)
|
|
err = websocket.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "WebSocket", err)
|
|
}
|
|
|
|
// Load tasks
|
|
err = task.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Task", err)
|
|
}
|
|
|
|
// Load schedules
|
|
err = schedule.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Schedule", err)
|
|
}
|
|
|
|
// Load Custom Widget
|
|
err = widget.Load(cfg)
|
|
if err != nil {
|
|
printErr(cfg.Mode, "Widget", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Unload application engine
|
|
func Unload() (err error) {
|
|
defer func() { err = exception.Catch(recover()) }()
|
|
|
|
// Close DB
|
|
err = share.DBClose()
|
|
|
|
// Stop Runtime
|
|
err = runtime.Stop()
|
|
|
|
// Recycle
|
|
// api
|
|
// models
|
|
// flows
|
|
// stores
|
|
// scripts
|
|
// connectors
|
|
// filesystem
|
|
// i18n
|
|
// certs
|
|
// plugins
|
|
// importers
|
|
// tasks
|
|
// schedules
|
|
// sockets
|
|
// websockets
|
|
// widgets
|
|
// custom widget
|
|
|
|
return err
|
|
}
|
|
|
|
// Reload the application engine
|
|
func Reload(cfg config.Config) error {
|
|
err := Unload()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return Load(cfg)
|
|
}
|
|
|
|
// loadApp load the application from bindata / pkg / disk
|
|
func loadApp(root string) error {
|
|
|
|
var err error
|
|
var app application.Application
|
|
|
|
if root == "bin:application.pkg" {
|
|
app, err = application.OpenFromBin(root, &share.Pack{}) // Load app from Bin
|
|
if err != nil {
|
|
return err
|
|
}
|
|
application.Load(app)
|
|
|
|
} else if strings.HasSuffix(root, ".pkg") {
|
|
|
|
app, err = application.OpenFromPkg(root, &share.Pack{}) // Load app from .pkg file
|
|
if err != nil {
|
|
return err
|
|
}
|
|
application.Load(app)
|
|
}
|
|
|
|
app, err = application.OpenFromDisk(root) // Load app from Disk
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
application.Load(app)
|
|
return nil
|
|
}
|
|
|
|
func printErr(mode, widget string, err error) {
|
|
message := fmt.Sprintf("[%s] %s", widget, err.Error())
|
|
if !strings.Contains(message, "does not exists") && mode == "development" {
|
|
color.Red(message)
|
|
}
|
|
}
|
|
|
|
// // LoadDeprecated 根据配置加载 API, FLow, Model, Plugin
|
|
// func LoadDeprecated(cfg config.Config) (err error) {
|
|
// defer func() { err = exception.Catch(recover()) }()
|
|
|
|
// // // Load Runtime
|
|
// // err = runtime.Load(cfg)
|
|
// // if err != nil {
|
|
// // printErr(cfg.Mode, "Runtime", err)
|
|
// // }
|
|
|
|
// // // 加载应用信息
|
|
// // // 第一步: 加载应用信息
|
|
// // app.Load(cfg)
|
|
|
|
// // 加密密钥函数
|
|
// // model.LoadCrypt(fmt.Sprintf(`{"key":"%s"}`, cfg.DB.AESKey), "AES")
|
|
// // gou.LoadCrypt(`{}`, "PASSWORD")
|
|
|
|
// // Load Certs
|
|
// err = cert.Load(cfg)
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Cert", err)
|
|
// }
|
|
|
|
// // Load connectors
|
|
// err = connector.Load(cfg)
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Connector", err)
|
|
// }
|
|
|
|
// // Load FileSystem
|
|
// err = fs.Load(cfg)
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "FileSystem", err)
|
|
// }
|
|
|
|
// // Load i18n
|
|
// err = i18n.Load(cfg)
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "i18n", err)
|
|
// }
|
|
|
|
// // Load Studio development mode only
|
|
// if cfg.Mode == "development" {
|
|
// err = studio.Load(cfg)
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Studio", err)
|
|
// }
|
|
// }
|
|
|
|
// // 第二步: 建立数据库 & 会话连接
|
|
// err = share.DBConnect(cfg.DB) // 创建数据库连接
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "DB", err)
|
|
// }
|
|
|
|
// // share.SessionConnect(cfg.Session) // 创建会话服务器链接
|
|
|
|
// // 加载应用引擎
|
|
// if os.Getenv("YAO_DEV") != "" {
|
|
// LoadEngine(filepath.Join(os.Getenv("YAO_DEV"), "/yao"))
|
|
// } else {
|
|
// LoadEngine()
|
|
// }
|
|
|
|
// // 第三步: 加载数据分析引擎
|
|
// query.Load(cfg) // 加载数据分析引擎
|
|
|
|
// // 第四步: 加载共享库 & JS 处理器
|
|
// err = share.Load(cfg) // 加载共享库 lib
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Lib", err)
|
|
// }
|
|
|
|
// err = script.Load(cfg) // 加载JS处理器 script
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Script", err)
|
|
// }
|
|
|
|
// // 第五步: 加载数据模型等
|
|
// err = model.Load(cfg) // 加载数据模型 model
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Model", err)
|
|
// }
|
|
|
|
// err = flow.Load(cfg) // 加载业务逻辑 Flow
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Flow", err)
|
|
// }
|
|
|
|
// err = store.Load(cfg) // Load stores
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Store", err)
|
|
// }
|
|
|
|
// err = plugin.Load(cfg) // 加载业务插件 plugin
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Plugin", err)
|
|
// }
|
|
|
|
// // // XGEN 1.0
|
|
// // if share.App.XGen == "1.0" {
|
|
|
|
// // // SET XGEN_BASE
|
|
// // // adminRoot := "yao"
|
|
// // // if share.App.Optional != nil {
|
|
// // // if root, has := share.App.Optional["adminRoot"]; has {
|
|
// // // adminRoot = fmt.Sprintf("%v", root)
|
|
// // // }
|
|
// // // }
|
|
// // // os.Setenv("XGEN_BASE", adminRoot)
|
|
|
|
// // // Load build-in widgets
|
|
// // err = widgets.Load(cfg)
|
|
// // if err != nil {
|
|
// // printErr(cfg.Mode, "Widgets", err)
|
|
// // }
|
|
|
|
// // delete(gou.APIs, "xiang.table")
|
|
// // delete(gou.APIs, "xiang.page")
|
|
// // delete(gou.APIs, "xiang.chart")
|
|
// // delete(gou.APIs, "xiang.xiang")
|
|
// // delete(gou.APIs, "xiang.user")
|
|
// // delete(gou.APIs, "xiang.storage")
|
|
|
|
// // } else { // old version
|
|
// // err = table.Load(cfg) // 加载数据表格 table
|
|
// // if err != nil {
|
|
// // printErr(cfg.Mode, "Table", err)
|
|
// // }
|
|
|
|
// // err = chart.Load(cfg) // 加载分析图表 chart
|
|
// // if err != nil {
|
|
// // printErr(cfg.Mode, "Chart", err)
|
|
// // }
|
|
|
|
// // err = page.Load(cfg) // 加载页面 page 忽略错误
|
|
// // if err != nil {
|
|
// // printErr(cfg.Mode, "Page", err)
|
|
// // }
|
|
// // }
|
|
|
|
// importer.Load(cfg) // 加载数据导入 imports
|
|
|
|
// err = api.Load(cfg) // 加载业务接口 API
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "API", err)
|
|
// }
|
|
|
|
// err = socket.Load(cfg) // Load sockets
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Socket", err)
|
|
// }
|
|
|
|
// err = websocket.Load(cfg) // Load websockets (client)
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "WebSocket", err)
|
|
// }
|
|
|
|
// err = task.Load(cfg) // Load tasks
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Task", err)
|
|
// }
|
|
|
|
// err = schedule.Load(cfg) // Load schedules
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Schedule", err)
|
|
// }
|
|
|
|
// err = widget.Load(cfg) // Load widgets
|
|
// if err != nil {
|
|
// printErr(cfg.Mode, "Widget", err)
|
|
// }
|
|
|
|
// return nil
|
|
// }
|
|
|
|
// Reload 根据配置重新加载 API, FLow, Model, Plugin
|
|
// func Reload(cfg config.Config) {
|
|
// gou.APIs = map[string]*gou.API{}
|
|
// gou.Models = map[string]*gou.Model{}
|
|
// gou.Flows = map[string]*gou.Flow{}
|
|
// gou.Plugins = map[string]*gou.Plugin{}
|
|
// Load(cfg)
|
|
// }
|
|
|
|
// LoadEngine 加载引擎的 API, Flow, Model 配置
|
|
// func LoadEngine(from ...string) {
|
|
// var scripts []share.Script
|
|
// if len(from) > 0 {
|
|
// scripts = share.GetFilesFS(from[0], ".json")
|
|
// } else {
|
|
// scripts = share.GetFilesBin("yao", ".json")
|
|
// }
|
|
|
|
// if scripts == nil {
|
|
// exception.New("读取文件失败", 500, from).Throw()
|
|
// }
|
|
|
|
// if len(scripts) == 0 {
|
|
// exception.New("读取文件失败, 未找到任何可执行脚本", 500, from).Throw()
|
|
// }
|
|
|
|
// // 加载 API, Flow, Models, Table, Chart, Screens
|
|
// for _, script := range scripts {
|
|
// switch script.Type {
|
|
// case "models":
|
|
// gou.LoadModel(string(script.Content), "xiang."+script.Name)
|
|
// break
|
|
// case "flows":
|
|
// gou.LoadFlow(string(script.Content), "xiang."+script.Name)
|
|
// break
|
|
// case "apis":
|
|
// gou.LoadAPI(string(script.Content), "xiang."+script.Name)
|
|
// break
|
|
// }
|
|
// }
|
|
|
|
// // 加载数据应用
|
|
// for _, script := range scripts {
|
|
// switch script.Type {
|
|
// case "tables":
|
|
// table.LoadTable(string(script.Content), "xiang."+script.Name)
|
|
// break
|
|
// }
|
|
// }
|
|
// }
|