diff --git a/table/table.go b/table/table.go index 7ff9817..24a3427 100644 --- a/table/table.go +++ b/table/table.go @@ -19,22 +19,23 @@ import ( var NotFound = errors.New("找不到记录") type Table struct { - Name string `json:"name,omitempty"` - Fields []*Field `json:"fields,omitempty"` + Name string + Fields []*Field //Json Schema - Schema string `json:"schema,omitempty"` - schema *jsonschema.Schema + Schema *jsonschema.Schema //脚本 - Scripts map[string]string `json:"scripts,omitempty"` - scripts map[string]*goja.Program + Scripts map[string]*goja.Program //累加器 - Accumulations []*accumulate.Accumulation `json:"accumulations,omitempty"` + Accumulations []*accumulate.Accumulation - TimeSeries *options.TimeSeriesOptions `json:"-"` //时间序列参数 - Hook *Hook `json:"-"` + //时间序列参数 + TimeSeries *options.TimeSeriesOptions + + //钩子处理 + Hook *Hook //快照 Snapshot *SnapshotOptions `json:"snapshot,omitempty"` @@ -43,24 +44,6 @@ type Table struct { } func (t *Table) init() (err error) { - - //JSONSchema - if t.Schema != "" { - t.schema, err = compiler.Compile(t.Schema) - if err != nil { - return err - } - } - - //编译脚本 - t.scripts = make(map[string]*goja.Program) - for hook, str := range t.Scripts { - t.scripts[hook], err = javascript.Compile(str) - if err != nil { - return err - } - } - //初始化累加器 for _, a := range t.Accumulations { err = a.Init() @@ -85,8 +68,8 @@ func (t *Table) AggregateDocument(pipeline any, results *[]mongodb.Document) err func (t *Table) Insert(doc any) (id string, err error) { //检查 - if t.schema != nil { - err = t.schema.Validate(doc) + if t.Schema != nil { + err = t.Schema.Validate(doc) if err != nil { return "", exception.Wrap(err) } @@ -99,7 +82,7 @@ func (t *Table) Insert(doc any) (id string, err error) { return "", exception.Wrap(err) } } - if hook, ok := t.scripts["before.insert"]; ok { + if hook, ok := t.Scripts["before.insert"]; ok { vm := javascript.Runtime() _ = vm.Set("object", doc) _, err = vm.RunProgram(hook) @@ -136,7 +119,7 @@ func (t *Table) Insert(doc any) (id string, err error) { return "", exception.Wrap(err) } } - if hook, ok := t.scripts["after.insert"]; ok { + if hook, ok := t.Scripts["after.insert"]; ok { vm := javascript.Runtime() _ = vm.Set("_id", ret) _ = vm.Set("object", doc) @@ -172,8 +155,8 @@ func (t *Table) Insert(doc any) (id string, err error) { func (t *Table) Import(docs []any) (ids []string, err error) { //没有hook,则直接InsertMany //if t.Hook == nil || t.Hook.BeforeInsert == nil && t.Hook.AfterInsert == nil { - // if _, ok := t.scripts["before.insert"]; !ok { - // if _, ok := t.scripts["after.insert"]; !ok { + // if _, ok := t.Scripts["before.insert"]; !ok { + // if _, ok := t.Scripts["after.insert"]; !ok { // oids, err := db.InsertMany(t.Name, docs) // if err != nil { // return nil, err @@ -200,8 +183,8 @@ func (t *Table) Import(docs []any) (ids []string, err error) { func (t *Table) ImportDocument(docs []mongodb.Document) (ids []string, err error) { //没有hook,则直接InsertMany //if t.Hook == nil || t.Hook.BeforeInsert == nil && t.Hook.AfterInsert == nil { - // if _, ok := t.scripts["before.insert"]; !ok { - // if _, ok := t.scripts["after.insert"]; !ok { + // if _, ok := t.Scripts["before.insert"]; !ok { + // if _, ok := t.Scripts["after.insert"]; !ok { // ds := make([]any, 0, len(docs)) // for _, doc := range docs { // ds = append(ds, doc) @@ -237,7 +220,7 @@ func (t *Table) Delete(id string) error { return exception.Wrap(err) } } - if hook, ok := t.scripts["before.delete"]; ok { + if hook, ok := t.Scripts["before.delete"]; ok { vm := javascript.Runtime() _ = vm.Set("_id", id) _, err := vm.RunProgram(hook) @@ -283,7 +266,7 @@ func (t *Table) Delete(id string) error { return exception.Wrap(err) } } - if hook, ok := t.scripts["after.delete"]; ok { + if hook, ok := t.Scripts["after.delete"]; ok { vm := javascript.Runtime() _ = vm.Set("_id", id) _ = vm.Set("object", result) @@ -324,7 +307,7 @@ func (t *Table) Update(id string, update any) error { return exception.Wrap(err) } } - if hook, ok := t.scripts["before.update"]; ok { + if hook, ok := t.Scripts["before.update"]; ok { vm := javascript.Runtime() _ = vm.Set("_id", id) _ = vm.Set("change", update) @@ -388,7 +371,7 @@ func (t *Table) Update(id string, update any) error { return exception.Wrap(err) } } - if hook, ok := t.scripts["after.update"]; ok { + if hook, ok := t.Scripts["after.update"]; ok { vm := javascript.Runtime() _ = vm.Set("_id", id) _ = vm.Set("change", update) diff --git a/table/tables.go b/table/tables.go index 5e2184b..ac6bd68 100644 --- a/table/tables.go +++ b/table/tables.go @@ -2,19 +2,31 @@ package table import ( "encoding/json" + "errors" + "github.com/dop251/goja" "github.com/god-jason/bucket/lib" "github.com/god-jason/bucket/log" "github.com/god-jason/bucket/mongodb" "github.com/god-jason/bucket/pkg/exception" + "github.com/god-jason/bucket/pkg/javascript" + "github.com/santhosh-tekuri/jsonschema/v6" "github.com/spf13/viper" "go.mongodb.org/mongo-driver/mongo/options" "os" "path/filepath" - "strings" ) const Path = "tables" +var scripts = []string{ + "before.insert", + "after.insert", + "before.delete", + "after.delete", + "before.update", + "after.update", +} + var tables lib.Map[Table] func Get(name string) (*Table, error) { @@ -29,25 +41,99 @@ func Register(table *Table) { tables.Store(table.Name, table) } -func Load(name string) error { - fn := filepath.Join(viper.GetString("data"), Path, name+".json") - buf, err := os.ReadFile(fn) +func loadText(filename string) (string, error) { + buf, err := os.ReadFile(filename) + if err != nil { + return "", err + } + return string(buf), nil +} + +func loadJson(filename string, value any) error { + buf, err := os.ReadFile(filename) if err != nil { return err } + return json.Unmarshal(buf, value) +} + +func loadJavaScript(filename string) (*goja.Program, error) { + buf, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + return javascript.Compile(string(buf)) +} + +func loadSchema(filename string) (*jsonschema.Schema, error) { + buf, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + return compiler.Compile(string(buf)) +} + +func Load(name string) error { + dir := filepath.Join(viper.GetString("data"), Path, name) var table Table - err = json.Unmarshal(buf, &table) + table.Name = name + + //直接注册表 + Register(&table) + + //加载字段 + err := loadJson(filepath.Join(dir, "fields.json"), &table.Fields) if err != nil { return err } + //加载模式 + table.Schema, err = loadSchema(filepath.Join(dir, "schema.json")) + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + return err + } + } + + //加载累加器 + err = loadJson(filepath.Join(dir, "accumulations.json"), &table.Accumulations) + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + return err + } + } err = table.init() if err != nil { return err } - Register(&table) + //加载时序配置 + err = loadJson(filepath.Join(dir, "time-serials.json"), &table.TimeSeries) + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + return err + } + } + + //加载快照配置 + err = loadJson(filepath.Join(dir, "snapshot.json"), &table.Snapshot) + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + return err + } + } + + //加载脚本 + for _, k := range scripts { + js, err := loadJavaScript(filepath.Join(dir, k+".js")) + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + return err + } + } + table.Scripts[k] = js + } return nil } @@ -63,13 +149,12 @@ func LoadAll() error { for _, e := range es { if e.IsDir() { - continue - } - if filepath.Ext(e.Name()) == ".json" { - err = Load(strings.TrimRight(e.Name(), ".json")) + err = Load(e.Name()) if err != nil { - return err + log.Error(err) + //return err } + continue } }