[add] widget table bind table support
This commit is contained in:
parent
5d32073ffc
commit
48d3ec8bfa
9 changed files with 270 additions and 63 deletions
|
|
@ -6,6 +6,20 @@ import (
|
|||
"github.com/yaoapp/gou"
|
||||
)
|
||||
|
||||
// CopyBefore copy a before hook
|
||||
func CopyBefore(hook *Before, new *Before) {
|
||||
if hook != nil {
|
||||
*hook = *new
|
||||
}
|
||||
}
|
||||
|
||||
// CopyAfter copy a after hook
|
||||
func CopyAfter(hook *After, new *After) {
|
||||
if hook != nil {
|
||||
*hook = *new
|
||||
}
|
||||
}
|
||||
|
||||
// Exec execute the hook
|
||||
func (hook *Before) Exec(args []interface{}, sid string, global map[string]interface{}) ([]interface{}, error) {
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/yaoapp/kun/log"
|
||||
"github.com/yaoapp/kun/maps"
|
||||
"github.com/yaoapp/yao/widgets/action"
|
||||
"github.com/yaoapp/yao/widgets/hook"
|
||||
)
|
||||
|
||||
var processActionDefaults = map[string]*action.Process{
|
||||
|
|
@ -159,7 +160,7 @@ func (act *ActionDSL) SetDefaultProcess() {
|
|||
}
|
||||
|
||||
// BindModel bind model
|
||||
func (act *ActionDSL) BindModel(m *gou.Model) {
|
||||
func (act *ActionDSL) BindModel(m *gou.Model) error {
|
||||
|
||||
name := m.ID
|
||||
act.Search.Bind(fmt.Sprintf("models.%s.Paginate", name))
|
||||
|
|
@ -181,6 +182,54 @@ func (act *ActionDSL) BindModel(m *gou.Model) {
|
|||
act.Get.DefaultMerge([]interface{}{act.Bind.Option})
|
||||
act.Find.DefaultMerge([]interface{}{nil, act.Bind.Option})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BindTable bind table
|
||||
func (act *ActionDSL) BindTable(tab *DSL) error {
|
||||
|
||||
// Copy Hooks
|
||||
hook.CopyBefore(act.BeforeSearch, tab.Action.BeforeSearch)
|
||||
hook.CopyBefore(act.BeforeGet, tab.Action.BeforeGet)
|
||||
hook.CopyBefore(act.BeforeFind, tab.Action.BeforeFind)
|
||||
hook.CopyBefore(act.BeforeSave, tab.Action.BeforeSave)
|
||||
hook.CopyBefore(act.BeforeCreate, tab.Action.BeforeCreate)
|
||||
hook.CopyBefore(act.BeforeInsert, tab.Action.BeforeInsert)
|
||||
hook.CopyBefore(act.BeforeUpdate, tab.Action.BeforeUpdate)
|
||||
hook.CopyBefore(act.BeforeUpdateWhere, tab.Action.BeforeUpdateWhere)
|
||||
hook.CopyBefore(act.BeforeUpdateIn, tab.Action.BeforeUpdateIn)
|
||||
hook.CopyBefore(act.BeforeDelete, tab.Action.BeforeDelete)
|
||||
hook.CopyBefore(act.BeforeDeleteWhere, tab.Action.BeforeDeleteWhere)
|
||||
hook.CopyBefore(act.BeforeDeleteIn, tab.Action.BeforeDeleteIn)
|
||||
hook.CopyAfter(act.AfterSearch, tab.Action.AfterSearch)
|
||||
hook.CopyAfter(act.AfterGet, tab.Action.AfterGet)
|
||||
hook.CopyAfter(act.AfterFind, tab.Action.AfterFind)
|
||||
hook.CopyAfter(act.AfterSave, tab.Action.AfterSave)
|
||||
hook.CopyAfter(act.AfterCreate, tab.Action.AfterCreate)
|
||||
hook.CopyAfter(act.AfterInsert, tab.Action.AfterInsert)
|
||||
hook.CopyAfter(act.AfterUpdate, tab.Action.AfterUpdate)
|
||||
hook.CopyAfter(act.AfterUpdateWhere, tab.Action.AfterUpdateWhere)
|
||||
hook.CopyAfter(act.AfterUpdateIn, tab.Action.AfterUpdateIn)
|
||||
hook.CopyAfter(act.AfterDelete, tab.Action.AfterDelete)
|
||||
hook.CopyAfter(act.AfterDeleteWhere, tab.Action.AfterDeleteWhere)
|
||||
hook.CopyAfter(act.AfterDeleteIn, tab.Action.AfterDeleteIn)
|
||||
|
||||
// Merge Actions
|
||||
act.Search.Merge(tab.Action.Search)
|
||||
act.Get.Merge(tab.Action.Get)
|
||||
act.Find.Merge(tab.Action.Find)
|
||||
act.Save.Merge(tab.Action.Save)
|
||||
act.Create.Merge(tab.Action.Create)
|
||||
act.Insert.Merge(tab.Action.Insert)
|
||||
act.Update.Merge(tab.Action.Update)
|
||||
act.UpdateWhere.Merge(tab.Action.UpdateWhere)
|
||||
act.UpdateIn.Merge(tab.Action.UpdateIn)
|
||||
act.Delete.Merge(tab.Action.Delete)
|
||||
act.DeleteWhere.Merge(tab.Action.DeleteWhere)
|
||||
act.DeleteIn.Merge(tab.Action.DeleteIn)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func processHandler(p *action.Process, process *gou.Process) (interface{}, error) {
|
||||
|
|
|
|||
|
|
@ -41,8 +41,57 @@ func (dsl *DSL) bindModel() error {
|
|||
return err
|
||||
}
|
||||
|
||||
dsl.Action.BindModel(m)
|
||||
dsl.Layout.BindModel(m, dsl.Fields)
|
||||
err = dsl.Action.BindModel(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = dsl.Layout.BindModel(m, dsl.Fields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dsl *DSL) bindTable() error {
|
||||
|
||||
// Bind ID
|
||||
id := dsl.Action.Bind.Table
|
||||
if id == dsl.ID {
|
||||
return fmt.Errorf("bind.table %s can't bind self table", id)
|
||||
}
|
||||
|
||||
// Load table
|
||||
if _, has := Tables[id]; !has {
|
||||
if err := LoadID(id, dsl.Root); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
tab, err := Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Bind Fields
|
||||
err = dsl.Fields.BindTable(tab)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Bind Actions
|
||||
err = dsl.Action.BindTable(tab)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Bind Layout
|
||||
err = dsl.Layout.BindTable(tab, dsl.Fields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -50,8 +99,3 @@ func (dsl *DSL) bindStore() error {
|
|||
id := dsl.Action.Bind.Store
|
||||
return fmt.Errorf("bind.store %s does not support yet", id)
|
||||
}
|
||||
|
||||
func (dsl *DSL) bindTable() error {
|
||||
id := dsl.Action.Bind.Table
|
||||
return fmt.Errorf("bind.table %s does not support yet", id)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,36 @@ func (fields *FieldsDSL) BindModel(m *gou.Model) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// BindTable bind table
|
||||
func (fields *FieldsDSL) BindTable(tab *DSL) error {
|
||||
|
||||
// Bind filter
|
||||
if fields.Filter == nil || len(fields.Filter) == 0 {
|
||||
fields.Filter = tab.Fields.Filter
|
||||
|
||||
} else if tab.Fields.Filter != nil {
|
||||
for key, filter := range tab.Fields.Filter {
|
||||
if _, has := fields.Filter[key]; !has {
|
||||
fields.Filter[key] = filter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bind Table
|
||||
if fields.Table == nil || len(fields.Table) == 0 {
|
||||
fields.Table = tab.Fields.Table
|
||||
|
||||
} else if tab.Fields.Table != nil {
|
||||
for key, table := range tab.Fields.Table {
|
||||
if _, has := fields.Table[key]; !has {
|
||||
fields.Table[key] = table
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Xgen trans to xgen setting
|
||||
func (fields *FieldsDSL) Xgen(layout *LayoutDSL) (map[string]interface{}, error) {
|
||||
res := map[string]interface{}{}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
// BindModel bind model
|
||||
func (layout *LayoutDSL) BindModel(m *gou.Model, fields *FieldsDSL) {
|
||||
func (layout *LayoutDSL) BindModel(m *gou.Model, fields *FieldsDSL) error {
|
||||
|
||||
if layout.Primary == "" {
|
||||
layout.Primary = m.PrimaryKey
|
||||
|
|
@ -50,6 +50,28 @@ func (layout *LayoutDSL) BindModel(m *gou.Model, fields *FieldsDSL) {
|
|||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// BindTable bind table
|
||||
func (layout *LayoutDSL) BindTable(tab *DSL, fields *FieldsDSL) error {
|
||||
|
||||
if layout.Primary == "" {
|
||||
layout.Primary = tab.Layout.Primary
|
||||
}
|
||||
|
||||
if layout.Filter == nil && tab.Layout.Filter != nil {
|
||||
layout.Filter = &FilterLayoutDSL{}
|
||||
*layout.Filter = *tab.Layout.Filter
|
||||
}
|
||||
|
||||
if layout.Table == nil && tab.Layout.Table != nil {
|
||||
layout.Table = &ViewLayoutDSL{}
|
||||
*layout.Table = *tab.Layout.Table
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Xgen trans to Xgen setting
|
||||
|
|
|
|||
|
|
@ -91,11 +91,11 @@ func New(id string) *DSL {
|
|||
|
||||
// LoadAndExport load table
|
||||
func LoadAndExport(cfg config.Config) error {
|
||||
err := Load(cfg)
|
||||
err := Export()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return Export()
|
||||
return Load(cfg)
|
||||
}
|
||||
|
||||
// Load load table
|
||||
|
|
@ -104,6 +104,21 @@ func Load(cfg config.Config) error {
|
|||
return LoadFrom(root, "")
|
||||
}
|
||||
|
||||
// LoadID load by id
|
||||
func LoadID(id string, root string) error {
|
||||
dirs := strings.Split(id, ".")
|
||||
name := fmt.Sprintf("%s.tab.json", dirs[len(dirs)-1])
|
||||
elems := []string{root}
|
||||
elems = append(elems, dirs[0:len(dirs)-1]...)
|
||||
elems = append(elems, name)
|
||||
filename := filepath.Join(elems...)
|
||||
data, err := environment.ReadFile(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("[%s] root=%s %s", id, root, err.Error())
|
||||
}
|
||||
return LoadData(data, id, root)
|
||||
}
|
||||
|
||||
// LoadFrom load from dir
|
||||
func LoadFrom(dir string, prefix string) error {
|
||||
|
||||
|
|
@ -115,58 +130,16 @@ func LoadFrom(dir string, prefix string) error {
|
|||
err := share.Walk(dir, ".json", func(root, filename string) {
|
||||
id := prefix + share.ID(root, filename)
|
||||
data, err := environment.ReadFile(filename)
|
||||
dsl := New(id)
|
||||
err = jsoniter.Unmarshal(data, dsl)
|
||||
if err != nil {
|
||||
messages = append(messages, fmt.Sprintf("[%s] %s", id, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if dsl.Action == nil {
|
||||
dsl.Action = &ActionDSL{}
|
||||
}
|
||||
dsl.Action.SetDefaultProcess()
|
||||
|
||||
if dsl.Layout == nil {
|
||||
dsl.Layout = &LayoutDSL{
|
||||
Header: &HeaderLayoutDSL{
|
||||
Preset: &PresetHeaderDSL{},
|
||||
Actions: []component.ActionDSL{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if dsl.Fields == nil {
|
||||
dsl.Fields = &FieldsDSL{}
|
||||
}
|
||||
|
||||
// Bind model / store / table / ...
|
||||
err = dsl.Bind()
|
||||
err = LoadData(data, id, root)
|
||||
if err != nil {
|
||||
messages = append(messages, fmt.Sprintf("[%s] %s", id, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// Parse
|
||||
err = dsl.Parse()
|
||||
if err != nil {
|
||||
messages = append(messages, fmt.Sprintf("[%s] %s", id, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// Validate
|
||||
err = dsl.Validate()
|
||||
if err != nil {
|
||||
messages = append(messages, fmt.Sprintf("[%s] %s", id, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// Apply a language pack
|
||||
if lang.Default != nil {
|
||||
lang.Default.Apply(dsl)
|
||||
}
|
||||
|
||||
Tables[id] = dsl
|
||||
})
|
||||
|
||||
if len(messages) > 0 {
|
||||
|
|
@ -176,6 +149,61 @@ func LoadFrom(dir string, prefix string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// LoadData load table from source
|
||||
func LoadData(data []byte, id string, root string) error {
|
||||
dsl := New(id)
|
||||
dsl.Root = root
|
||||
|
||||
err := jsoniter.Unmarshal(data, dsl)
|
||||
if err != nil {
|
||||
return fmt.Errorf("[%s] %s", id, err.Error())
|
||||
}
|
||||
|
||||
if dsl.Action == nil {
|
||||
dsl.Action = &ActionDSL{}
|
||||
}
|
||||
dsl.Action.SetDefaultProcess()
|
||||
|
||||
if dsl.Layout == nil {
|
||||
dsl.Layout = &LayoutDSL{
|
||||
Header: &HeaderLayoutDSL{
|
||||
Preset: &PresetHeaderDSL{},
|
||||
Actions: []component.ActionDSL{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if dsl.Fields == nil {
|
||||
dsl.Fields = &FieldsDSL{}
|
||||
}
|
||||
|
||||
// Bind model / store / table / ...
|
||||
err = dsl.Bind()
|
||||
if err != nil {
|
||||
return fmt.Errorf("[%s] %s", id, err.Error())
|
||||
}
|
||||
|
||||
// Parse
|
||||
err = dsl.Parse()
|
||||
if err != nil {
|
||||
return fmt.Errorf("[%s] %s", id, err.Error())
|
||||
}
|
||||
|
||||
// Validate
|
||||
err = dsl.Validate()
|
||||
if err != nil {
|
||||
return fmt.Errorf("[%s] %s", id, err.Error())
|
||||
}
|
||||
|
||||
// Apply a language pack
|
||||
if lang.Default != nil {
|
||||
lang.Default.Apply(dsl)
|
||||
}
|
||||
|
||||
Tables[id] = dsl
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get table via process or id
|
||||
func Get(table interface{}) (*DSL, error) {
|
||||
id := ""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package table
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -17,12 +18,19 @@ import (
|
|||
|
||||
func TestLoad(t *testing.T) {
|
||||
prepare(t)
|
||||
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, 4, len(Tables))
|
||||
assert.Equal(t, 5, len(Tables))
|
||||
}
|
||||
|
||||
func TestLoadID(t *testing.T) {
|
||||
prepare(t)
|
||||
err := LoadID("pet", filepath.Join(config.Conf.Root, "tables"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func prepare(t *testing.T, language ...string) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
// DSL the table DSL
|
||||
type DSL struct {
|
||||
Root string `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Action *ActionDSL `json:"action"`
|
||||
|
|
@ -67,6 +68,7 @@ type BindActionDSL struct {
|
|||
Model string `json:"model,omitempty"` // bind model
|
||||
Store string `json:"store,omitempty"` // bind store
|
||||
Table string `json:"table,omitempty"` // bind table
|
||||
Form string `json:"form,omitempty"` // bind form
|
||||
Option map[string]interface{} `json:"option,omitempty"` // bind option
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package widgets
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/widgets/app"
|
||||
"github.com/yaoapp/yao/widgets/chart"
|
||||
|
|
@ -15,51 +18,58 @@ import (
|
|||
// Load the widgets
|
||||
func Load(cfg config.Config) error {
|
||||
|
||||
messages := []string{}
|
||||
|
||||
// load expression
|
||||
err := expression.Export()
|
||||
if err != nil {
|
||||
return err
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
// load component
|
||||
err = component.Export()
|
||||
if err != nil {
|
||||
return err
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
// load field transform
|
||||
err = field.LoadAndExport(config.Conf)
|
||||
if err != nil {
|
||||
return err
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
// login widget
|
||||
err = login.LoadAndExport(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
// app widget
|
||||
err = app.LoadAndExport(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
// table widget
|
||||
err = table.LoadAndExport(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
// form widget
|
||||
err = form.LoadAndExport(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
// chart widget
|
||||
err = chart.LoadAndExport(cfg)
|
||||
if err != nil {
|
||||
messages = append(messages, err.Error())
|
||||
}
|
||||
|
||||
if len(messages) > 0 {
|
||||
err = fmt.Errorf(strings.Join(messages, ";\n"))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue