[add] Form widget processes: load, reload, unload, read and exists.
This commit is contained in:
parent
f422dd29c6
commit
5a719b6469
9 changed files with 230 additions and 22 deletions
|
|
@ -55,7 +55,7 @@ func (dsl *DSL) bindForm() error {
|
||||||
|
|
||||||
// Load form
|
// Load form
|
||||||
if _, has := Forms[id]; !has {
|
if _, has := Forms[id]; !has {
|
||||||
if err := LoadID(id, dsl.Root); err != nil {
|
if err := LoadID(id); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,11 @@ var Forms map[string]*DSL = map[string]*DSL{}
|
||||||
var lock sync.Mutex
|
var lock sync.Mutex
|
||||||
|
|
||||||
// New create a new DSL
|
// New create a new DSL
|
||||||
func New(id string) *DSL {
|
func New(id string, file string, source []byte) *DSL {
|
||||||
return &DSL{
|
return &DSL{
|
||||||
ID: id,
|
ID: id,
|
||||||
|
file: file,
|
||||||
|
source: source,
|
||||||
Fields: &FieldsDSL{Form: field.Columns{}},
|
Fields: &FieldsDSL{Form: field.Columns{}},
|
||||||
Layout: &LayoutDSL{},
|
Layout: &LayoutDSL{},
|
||||||
CProps: field.CloudProps{},
|
CProps: field.CloudProps{},
|
||||||
|
|
@ -96,6 +98,11 @@ func Load(cfg config.Config) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unload unload the form
|
||||||
|
func Unload(id string) {
|
||||||
|
delete(Forms, id)
|
||||||
|
}
|
||||||
|
|
||||||
// LoadFileSync load form dsl by file
|
// LoadFileSync load form dsl by file
|
||||||
func LoadFileSync(root string, file string) error {
|
func LoadFileSync(root string, file string) error {
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
|
|
@ -112,23 +119,15 @@ func LoadFile(root string, file string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dsl := New(id)
|
_, err = load(data, id, file)
|
||||||
err = application.Parse(file, data, dsl)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("[%s] %s", id, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = dsl.parse(id, root)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
Forms[id] = dsl
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadID load via id
|
// LoadID load via id
|
||||||
func LoadID(id string, root string) error {
|
func LoadID(id string) error {
|
||||||
|
|
||||||
file := filepath.Join("forms", share.File(id, ".form.yao"))
|
file := filepath.Join("forms", share.File(id, ".form.yao"))
|
||||||
if exists, _ := application.App.Exists(file); exists {
|
if exists, _ := application.App.Exists(file); exists {
|
||||||
|
|
@ -148,10 +147,39 @@ func LoadID(id string, root string) error {
|
||||||
return fmt.Errorf("form %s not found", id)
|
return fmt.Errorf("form %s not found", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadData load via data
|
// LoadSourceSync load form dsl by source
|
||||||
func (dsl *DSL) parse(id string, root string) error {
|
func LoadSourceSync(source []byte, id string) (*DSL, error) {
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
return LoadSource(source, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadSource load form dsl by source
|
||||||
|
func LoadSource(source []byte, id string) (*DSL, error) {
|
||||||
|
file := filepath.Join("forms", share.File(id, ".form.yao"))
|
||||||
|
return load(source, id, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadSource load form dsl by source
|
||||||
|
func load(source []byte, id string, file string) (*DSL, error) {
|
||||||
|
dsl := New(id, file, source)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
Forms[id] = dsl
|
||||||
|
return dsl, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadData load via data
|
||||||
|
func (dsl *DSL) parse(id string) error {
|
||||||
|
|
||||||
dsl.Root = root
|
|
||||||
if dsl.Action == nil {
|
if dsl.Action == nil {
|
||||||
dsl.Action = &ActionDSL{}
|
dsl.Action = &ActionDSL{}
|
||||||
}
|
}
|
||||||
|
|
@ -312,3 +340,19 @@ func (dsl *DSL) Actions() []component.ActionsExport {
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reload reload the form
|
||||||
|
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 form exists
|
||||||
|
func Exists(id string) bool {
|
||||||
|
_, has := Forms[id]
|
||||||
|
return has
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package form
|
package form
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
@ -32,12 +31,66 @@ func TestLoadID(t *testing.T) {
|
||||||
defer test.Clean()
|
defer test.Clean()
|
||||||
prepare(t)
|
prepare(t)
|
||||||
|
|
||||||
err := LoadID("pet", filepath.Join(config.Conf.Root))
|
err := LoadID("pet")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadSourceSync(t *testing.T) {
|
||||||
|
test.Prepare(t, config.Conf)
|
||||||
|
defer test.Clean()
|
||||||
|
prepare(t)
|
||||||
|
source := []byte(`{
|
||||||
|
"name": "Pet Admin Form Bind Model",
|
||||||
|
"action": {
|
||||||
|
"bind": { "model": "pet" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
form, err := LoadSourceSync(source, `dynamic.pet`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, "Pet Admin Form Bind Model", form.Name)
|
||||||
|
assert.Equal(t, "pet", form.Action.Bind.Model)
|
||||||
|
assert.True(t, Exists("dynamic.pet"))
|
||||||
|
|
||||||
|
// Reload
|
||||||
|
form, err = form.Reload()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, "Pet Admin Form Bind Model", form.Name)
|
||||||
|
assert.Equal(t, "pet", form.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)
|
||||||
|
form := MustGet("pet")
|
||||||
|
assert.NotNil(t, form)
|
||||||
|
|
||||||
|
// Read
|
||||||
|
source := form.Read()
|
||||||
|
if source == nil {
|
||||||
|
t.Fatal("Read Error")
|
||||||
|
}
|
||||||
|
|
||||||
|
form, err := LoadSourceSync(source, `dynamic.pet`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, "::Pet Admin", form.Name)
|
||||||
|
}
|
||||||
|
|
||||||
func prepare(t *testing.T) {
|
func prepare(t *testing.T) {
|
||||||
|
|
||||||
// load flows
|
// load flows
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/yaoapp/gou/application"
|
||||||
"github.com/yaoapp/gou/fs"
|
"github.com/yaoapp/gou/fs"
|
||||||
gouProcess "github.com/yaoapp/gou/process"
|
gouProcess "github.com/yaoapp/gou/process"
|
||||||
"github.com/yaoapp/gou/types"
|
"github.com/yaoapp/gou/types"
|
||||||
|
|
@ -28,6 +29,10 @@ func exportProcess() {
|
||||||
gouProcess.Register("yao.form.update", processUpdate)
|
gouProcess.Register("yao.form.update", processUpdate)
|
||||||
gouProcess.Register("yao.form.delete", processDelete)
|
gouProcess.Register("yao.form.delete", processDelete)
|
||||||
gouProcess.Register("yao.form.load", processLoad)
|
gouProcess.Register("yao.form.load", processLoad)
|
||||||
|
gouProcess.Register("yao.form.reload", processReload)
|
||||||
|
gouProcess.Register("yao.form.unload", processUnload)
|
||||||
|
gouProcess.Register("yao.form.read", processRead)
|
||||||
|
gouProcess.Register("yao.form.exists", processExists)
|
||||||
}
|
}
|
||||||
|
|
||||||
func processXgen(process *gouProcess.Process) interface{} {
|
func processXgen(process *gouProcess.Process) interface{} {
|
||||||
|
|
@ -182,9 +187,22 @@ func processDelete(process *gouProcess.Process) interface{} {
|
||||||
return form.Action.Delete.MustExec(process)
|
return form.Action.Delete.MustExec(process)
|
||||||
}
|
}
|
||||||
|
|
||||||
// processLoad yao.table.Load (:file)
|
// processLoad yao.form.Load form_name file <source>
|
||||||
func processLoad(process *gouProcess.Process) interface{} {
|
func processLoad(process *gouProcess.Process) interface{} {
|
||||||
process.ValidateArgNums(1)
|
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)
|
file := process.ArgsString(0)
|
||||||
if file == "" {
|
if file == "" {
|
||||||
exception.New("file is required", 400).Throw()
|
exception.New("file is required", 400).Throw()
|
||||||
|
|
@ -193,3 +211,39 @@ func processLoad(process *gouProcess.Process) interface{} {
|
||||||
file = strings.TrimPrefix(file, string(os.PathSeparator))
|
file = strings.TrimPrefix(file, string(os.PathSeparator))
|
||||||
return LoadFileSync("forms", file)
|
return LoadFileSync("forms", file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// processReload yao.form.Reload form_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
|
||||||
|
}
|
||||||
|
|
||||||
|
// processUnload yao.form.Unload form_name
|
||||||
|
func processUnload(process *gouProcess.Process) interface{} {
|
||||||
|
process.ValidateArgNums(1)
|
||||||
|
Unload(process.ArgsString(0))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// processRead yao.form.Read form_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.form.Exists form_name
|
||||||
|
func processExists(process *gouProcess.Process) interface{} {
|
||||||
|
process.ValidateArgNums(1)
|
||||||
|
return Exists(process.ArgsString(0))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -342,6 +342,59 @@ func TestProcessXgenWithPermissions(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProcessLoad(t *testing.T) {
|
||||||
|
test.Prepare(t, config.Conf)
|
||||||
|
defer test.Clean()
|
||||||
|
prepare(t)
|
||||||
|
|
||||||
|
source := `{
|
||||||
|
"name": "Pet Admin Form Bind Model",
|
||||||
|
"action": {
|
||||||
|
"bind": { "model": "pet" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
args := []interface{}{"dynamic.pet", "/forms/dynamic/pet.form.yao", source}
|
||||||
|
|
||||||
|
// Load
|
||||||
|
assert.NotPanics(t, func() {
|
||||||
|
process.New("yao.form.Load", args...).Run()
|
||||||
|
})
|
||||||
|
form := MustGet("dynamic.pet")
|
||||||
|
assert.Equal(t, "Pet Admin Form Bind Model", form.Name)
|
||||||
|
assert.Equal(t, "pet", form.Action.Bind.Model)
|
||||||
|
|
||||||
|
// Exist
|
||||||
|
res := process.New("yao.form.Exists", "dynamic.pet").Run()
|
||||||
|
assert.True(t, res.(bool))
|
||||||
|
|
||||||
|
// Reload
|
||||||
|
assert.NotPanics(t, func() {
|
||||||
|
process.New("yao.form.Reload", "dynamic.pet").Run()
|
||||||
|
})
|
||||||
|
form = MustGet("dynamic.pet")
|
||||||
|
assert.Equal(t, "Pet Admin Form Bind Model", form.Name)
|
||||||
|
assert.Equal(t, "pet", form.Action.Bind.Model)
|
||||||
|
|
||||||
|
// Unload
|
||||||
|
assert.NotPanics(t, func() {
|
||||||
|
process.New("yao.form.Unload", "dynamic.pet").Run()
|
||||||
|
})
|
||||||
|
res = process.New("yao.form.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.form.Read", "pet").Run()
|
||||||
|
assert.NotNil(t, res)
|
||||||
|
assert.Equal(t, "::Pet Admin", res.(map[string]interface{})["name"])
|
||||||
|
}
|
||||||
|
|
||||||
func testData(t *testing.T) {
|
func testData(t *testing.T) {
|
||||||
pet := model.Select("pet")
|
pet := model.Select("pet")
|
||||||
err := pet.Insert(
|
err := pet.Insert(
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,14 @@ import (
|
||||||
// DSL the form DSL
|
// DSL the form DSL
|
||||||
type DSL struct {
|
type DSL struct {
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Root string `json:"-"`
|
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Action *ActionDSL `json:"action"`
|
Action *ActionDSL `json:"action"`
|
||||||
Layout *LayoutDSL `json:"layout"`
|
Layout *LayoutDSL `json:"layout"`
|
||||||
Fields *FieldsDSL `json:"fields"`
|
Fields *FieldsDSL `json:"fields"`
|
||||||
Config map[string]interface{} `json:"config,omitempty"`
|
Config map[string]interface{} `json:"config,omitempty"`
|
||||||
CProps field.CloudProps `json:"-"`
|
CProps field.CloudProps `json:"-"`
|
||||||
|
file string `json:"-"`
|
||||||
|
source []byte `json:"-"`
|
||||||
compute.Computable
|
compute.Computable
|
||||||
*mapping.Mapping
|
*mapping.Mapping
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func TestFiledsBindModel(t *testing.T) {
|
||||||
testData(t)
|
testData(t)
|
||||||
|
|
||||||
m := model.Select("pet")
|
m := model.Select("pet")
|
||||||
tab := New("unit-test")
|
tab := New("unit-test", "unit-test.tab.yao", nil)
|
||||||
err := tab.Fields.BindModel(m)
|
err := tab.Fields.BindModel(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,7 @@ func processReload(process *gouProcess.Process) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// processUnload yao.table.Unload table_name
|
||||||
func processUnload(process *gouProcess.Process) interface{} {
|
func processUnload(process *gouProcess.Process) interface{} {
|
||||||
process.ValidateArgNums(1)
|
process.ValidateArgNums(1)
|
||||||
Unload(process.ArgsString(0))
|
Unload(process.ArgsString(0))
|
||||||
|
|
|
||||||
|
|
@ -85,9 +85,11 @@ var Tables map[string]*DSL = map[string]*DSL{}
|
||||||
var lock sync.Mutex
|
var lock sync.Mutex
|
||||||
|
|
||||||
// New create a new DSL
|
// New create a new DSL
|
||||||
func New(id string) *DSL {
|
func New(id string, file string, source []byte) *DSL {
|
||||||
return &DSL{
|
return &DSL{
|
||||||
ID: id,
|
ID: id,
|
||||||
|
file: file,
|
||||||
|
source: source,
|
||||||
Fields: &FieldsDSL{Filter: field.Filters{}, Table: field.Columns{}},
|
Fields: &FieldsDSL{Filter: field.Filters{}, Table: field.Columns{}},
|
||||||
CProps: field.CloudProps{},
|
CProps: field.CloudProps{},
|
||||||
Config: map[string]interface{}{},
|
Config: map[string]interface{}{},
|
||||||
|
|
@ -189,7 +191,7 @@ func LoadSource(source []byte, id string) (*DSL, error) {
|
||||||
|
|
||||||
// LoadSource load table dsl by source
|
// LoadSource load table dsl by source
|
||||||
func load(source []byte, id string, file string) (*DSL, error) {
|
func load(source []byte, id string, file string) (*DSL, error) {
|
||||||
dsl := &DSL{ID: id, source: source, file: file}
|
dsl := New(id, file, source)
|
||||||
err := application.Parse(file, source, dsl)
|
err := application.Parse(file, source, dsl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("[%s] %s", id, err.Error())
|
return nil, fmt.Errorf("[%s] %s", id, err.Error())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue