[add] Table widget processes: load, reload, unload, read and exists.
This commit is contained in:
parent
0703743e72
commit
f422dd29c6
8 changed files with 231 additions and 31 deletions
|
|
@ -91,7 +91,7 @@ func (dsl *DSL) bindTable() error {
|
|||
|
||||
// Load table
|
||||
if _, has := table.Tables[id]; !has {
|
||||
if err := table.LoadID(id, dsl.Root); err != nil {
|
||||
if err := table.LoadID(id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (dsl *DSL) bindTable() error {
|
|||
|
||||
// Load table
|
||||
if _, has := table.Tables[id]; !has {
|
||||
if err := table.LoadID(id, dsl.Root); err != nil {
|
||||
if err := table.LoadID(id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ func (dsl *DSL) bindTable() error {
|
|||
|
||||
// Load table
|
||||
if _, has := Tables[id]; !has {
|
||||
if err := LoadID(id, dsl.Root); err != nil {
|
||||
if err := LoadID(id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/yaoapp/gou/application"
|
||||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/gou/model"
|
||||
gouProcess "github.com/yaoapp/gou/process"
|
||||
|
|
@ -43,6 +44,10 @@ func exportProcess() {
|
|||
gouProcess.Register("yao.table.deletein", processDeleteIn)
|
||||
gouProcess.Register("yao.table.export", processExport)
|
||||
gouProcess.Register("yao.table.load", processLoad)
|
||||
gouProcess.Register("yao.table.reload", processReload)
|
||||
gouProcess.Register("yao.table.unload", processUnload)
|
||||
gouProcess.Register("yao.table.read", processRead)
|
||||
gouProcess.Register("yao.table.exists", processExists)
|
||||
}
|
||||
|
||||
func processXgen(process *gouProcess.Process) interface{} {
|
||||
|
|
@ -307,9 +312,21 @@ func processExport(process *gouProcess.Process) interface{} {
|
|||
return filename
|
||||
}
|
||||
|
||||
// processLoad yao.table.Load (:file)
|
||||
// processLoad yao.table.Load table_name file <source>
|
||||
func processLoad(process *gouProcess.Process) interface{} {
|
||||
process.ValidateArgNums(1)
|
||||
// Load from source
|
||||
if process.NumOfArgs() >= 3 {
|
||||
id := process.ArgsString(0)
|
||||
source := process.ArgsString(2)
|
||||
_, err := LoadSourceSync([]byte(source), id)
|
||||
if err != nil {
|
||||
exception.New(err.Error(), 500).Throw()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Load from file
|
||||
file := process.ArgsString(0)
|
||||
if file == "" {
|
||||
exception.New("file is required", 400).Throw()
|
||||
|
|
@ -318,3 +335,38 @@ func processLoad(process *gouProcess.Process) interface{} {
|
|||
file = strings.TrimPrefix(file, string(os.PathSeparator))
|
||||
return LoadFileSync("tables", file)
|
||||
}
|
||||
|
||||
// processReload yao.table.Reload table_name
|
||||
func processReload(process *gouProcess.Process) interface{} {
|
||||
process.ValidateArgNums(1)
|
||||
tab := MustGet(process) // 0
|
||||
_, err := tab.Reload()
|
||||
if err != nil {
|
||||
exception.New(err.Error(), 500).Throw()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processUnload(process *gouProcess.Process) interface{} {
|
||||
process.ValidateArgNums(1)
|
||||
Unload(process.ArgsString(0))
|
||||
return nil
|
||||
}
|
||||
|
||||
// processRead yao.table.Read table_name
|
||||
func processRead(process *gouProcess.Process) interface{} {
|
||||
process.ValidateArgNums(1)
|
||||
tab := MustGet(process) // 0
|
||||
source := map[string]interface{}{}
|
||||
err := application.Parse(tab.file, tab.Read(), &source)
|
||||
if err != nil {
|
||||
exception.New(err.Error(), 500).Throw()
|
||||
}
|
||||
return source
|
||||
}
|
||||
|
||||
// processExists yao.table.Exists table_name
|
||||
func processExists(process *gouProcess.Process) interface{} {
|
||||
process.ValidateArgNums(1)
|
||||
return Exists(process.ArgsString(0))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/yaoapp/kun/any"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/helper"
|
||||
q "github.com/yaoapp/yao/query"
|
||||
"github.com/yaoapp/yao/test"
|
||||
)
|
||||
|
||||
|
|
@ -578,13 +577,62 @@ func TestProcessExport(t *testing.T) {
|
|||
assert.Greater(t, size, 1000)
|
||||
}
|
||||
|
||||
func load(t *testing.T) {
|
||||
func TestProcessLoad(t *testing.T) {
|
||||
test.Prepare(t, config.Conf)
|
||||
defer test.Clean()
|
||||
prepare(t)
|
||||
err := Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
q.Load(config.Conf)
|
||||
|
||||
source := `{
|
||||
"name": "Pet Admin Bind Model And Form",
|
||||
"action": {
|
||||
"bind": { "model": "pet", "option": { "form": "pet" } },
|
||||
"search": {
|
||||
"guard": "-",
|
||||
"process": "scripts.pet.Search",
|
||||
"default": [null, 1, 5]
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
args := []interface{}{"dynamic.pet", "/tables/dynamic/pet.tab.yao", source}
|
||||
|
||||
// Load
|
||||
assert.NotPanics(t, func() {
|
||||
process.New("yao.table.Load", args...).Run()
|
||||
})
|
||||
tab := MustGet("dynamic.pet")
|
||||
assert.Equal(t, "Pet Admin Bind Model And Form", tab.Name)
|
||||
assert.Equal(t, "pet", tab.Action.Bind.Model)
|
||||
|
||||
// Exist
|
||||
res := process.New("yao.table.Exists", "dynamic.pet").Run()
|
||||
assert.True(t, res.(bool))
|
||||
|
||||
// Reload
|
||||
assert.NotPanics(t, func() {
|
||||
process.New("yao.table.Reload", "dynamic.pet").Run()
|
||||
})
|
||||
tab = MustGet("dynamic.pet")
|
||||
assert.Equal(t, "Pet Admin Bind Model And Form", tab.Name)
|
||||
assert.Equal(t, "pet", tab.Action.Bind.Model)
|
||||
|
||||
// Unload
|
||||
assert.NotPanics(t, func() {
|
||||
process.New("yao.table.Unload", "dynamic.pet").Run()
|
||||
})
|
||||
res = process.New("yao.table.Exists", "dynamic.pet").Run()
|
||||
assert.False(t, res.(bool))
|
||||
}
|
||||
|
||||
func TestProcessRead(t *testing.T) {
|
||||
|
||||
test.Prepare(t, config.Conf)
|
||||
defer test.Clean()
|
||||
prepare(t)
|
||||
|
||||
res := process.New("yao.table.Read", "pet").Run()
|
||||
assert.NotNil(t, res)
|
||||
assert.Equal(t, "::Pet Admin", res.(map[string]interface{})["name"])
|
||||
}
|
||||
|
||||
func testData(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -125,8 +125,13 @@ func Load(cfg config.Config) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Unload unload the table
|
||||
func Unload(id string) {
|
||||
delete(Tables, id)
|
||||
}
|
||||
|
||||
// LoadID load table dsl by id
|
||||
func LoadID(id string, root string) error {
|
||||
func LoadID(id string) error {
|
||||
|
||||
file := filepath.Join("tables", share.File(id, ".tab.yao"))
|
||||
if exists, _ := application.App.Exists(file); exists {
|
||||
|
|
@ -162,31 +167,51 @@ func LoadFile(root string, file string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
dsl := &DSL{ID: id}
|
||||
err = application.Parse(file, data, dsl)
|
||||
if err != nil {
|
||||
return fmt.Errorf("[%s] %s", id, err.Error())
|
||||
}
|
||||
|
||||
err = dsl.parse(id, root)
|
||||
_, err = load(data, id, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Tables[id] = dsl
|
||||
return nil
|
||||
}
|
||||
|
||||
// parse parse table dsl source
|
||||
func (dsl *DSL) parse(id string, root string) error {
|
||||
// LoadSourceSync load table dsl by source
|
||||
func LoadSourceSync(source []byte, id string) (*DSL, error) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
return LoadSource(source, id)
|
||||
}
|
||||
|
||||
// LoadSource load table dsl by source
|
||||
func LoadSource(source []byte, id string) (*DSL, error) {
|
||||
file := filepath.Join("tables", share.File(id, ".tab.yao"))
|
||||
return load(source, id, file)
|
||||
}
|
||||
|
||||
// LoadSource load table dsl by source
|
||||
func load(source []byte, id string, file string) (*DSL, error) {
|
||||
dsl := &DSL{ID: id, source: source, file: file}
|
||||
err := application.Parse(file, source, dsl)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[%s] %s", id, err.Error())
|
||||
}
|
||||
|
||||
err = dsl.parse(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Tables[id] = dsl
|
||||
return dsl, nil
|
||||
}
|
||||
|
||||
// parse parse table dsl source
|
||||
func (dsl *DSL) parse(id string) error {
|
||||
|
||||
dsl.Root = root // remove next version
|
||||
if dsl.Action == nil {
|
||||
dsl.Action = &ActionDSL{}
|
||||
}
|
||||
|
||||
dsl.Action.SetDefaultProcess()
|
||||
|
||||
if dsl.Layout == nil {
|
||||
dsl.Layout = &LayoutDSL{
|
||||
Header: &HeaderLayoutDSL{
|
||||
|
|
@ -382,3 +407,19 @@ func (dsl *DSL) Actions() []component.ActionsExport {
|
|||
|
||||
return res
|
||||
}
|
||||
|
||||
// Reload reload the table
|
||||
func (dsl *DSL) Reload() (*DSL, error) {
|
||||
return LoadSourceSync(dsl.source, dsl.ID)
|
||||
}
|
||||
|
||||
// Read read the source
|
||||
func (dsl *DSL) Read() []byte {
|
||||
return dsl.source
|
||||
}
|
||||
|
||||
// Exists check the table exists
|
||||
func Exists(id string) bool {
|
||||
_, has := Tables[id]
|
||||
return has
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package table
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -29,18 +28,76 @@ func TestLoad(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLoadID(t *testing.T) {
|
||||
|
||||
test.Prepare(t, config.Conf)
|
||||
defer test.Clean()
|
||||
prepare(t)
|
||||
|
||||
err := LoadID("pet", filepath.Join(config.Conf.Root))
|
||||
err := LoadID("pet")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func prepare(t *testing.T, language ...string) {
|
||||
func TestLoadSourceSync(t *testing.T) {
|
||||
test.Prepare(t, config.Conf)
|
||||
defer test.Clean()
|
||||
prepare(t)
|
||||
source := []byte(`{
|
||||
"name": "Pet Admin Bind Model And Form",
|
||||
"action": {
|
||||
"bind": { "model": "pet", "option": { "form": "pet" } },
|
||||
"search": {
|
||||
"guard": "-",
|
||||
"process": "scripts.pet.Search",
|
||||
"default": [null, 1, 5]
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
tab, err := LoadSourceSync(source, `dynamic.pet`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, "Pet Admin Bind Model And Form", tab.Name)
|
||||
assert.Equal(t, "pet", tab.Action.Bind.Model)
|
||||
assert.True(t, Exists("dynamic.pet"))
|
||||
|
||||
// Reload
|
||||
tab, err = tab.Reload()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, "Pet Admin Bind Model And Form", tab.Name)
|
||||
assert.Equal(t, "pet", tab.Action.Bind.Model)
|
||||
assert.True(t, Exists("dynamic.pet"))
|
||||
|
||||
// Unload
|
||||
Unload("dynamic.pet")
|
||||
assert.False(t, Exists("dynamic.pet"))
|
||||
}
|
||||
|
||||
func TestRead(t *testing.T) {
|
||||
test.Prepare(t, config.Conf)
|
||||
defer test.Clean()
|
||||
prepare(t)
|
||||
tab := MustGet("pet")
|
||||
assert.NotNil(t, tab)
|
||||
|
||||
// Read
|
||||
source := tab.Read()
|
||||
if source == nil {
|
||||
t.Fatal("Read Error")
|
||||
}
|
||||
|
||||
tab, err := LoadSourceSync(source, `dynamic.pet`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "::Pet Admin", tab.Name)
|
||||
}
|
||||
|
||||
func prepare(t *testing.T) {
|
||||
|
||||
// test.Prepare(t, config.Conf)
|
||||
// defer test.Clean()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
// DSL the table DSL
|
||||
type DSL struct {
|
||||
Root string `json:"-"`
|
||||
// Root string `json:"-"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Action *ActionDSL `json:"action"`
|
||||
|
|
@ -19,6 +19,8 @@ type DSL struct {
|
|||
Fields *FieldsDSL `json:"fields"`
|
||||
Config map[string]interface{} `json:"config,omitempty"`
|
||||
CProps field.CloudProps `json:"-"`
|
||||
file string `json:"-"`
|
||||
source []byte `json:"-"`
|
||||
compute.Computable
|
||||
*mapping.Mapping
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue