Merge pull request #995 from trheyi/main

Refactor DSL list retrieval to support conditional data source selection
This commit is contained in:
Max 2025-07-15 16:59:10 +08:00 committed by GitHub
commit 5019c33f35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 103 additions and 32 deletions

View file

@ -127,16 +127,25 @@ func (dsl *DSL) Source(ctx context.Context, id string) (string, error) {
// List DSLs // List DSLs
func (dsl *DSL) List(ctx context.Context, opts *types.ListOptions) ([]*types.Info, error) { func (dsl *DSL) List(ctx context.Context, opts *types.ListOptions) ([]*types.Info, error) {
// Get the list from the db // Get the list from the db
dbList, err := dsl.db.List(opts) var dbList []*types.Info
var fileList []*types.Info
var err error
// If StoreType is not specified or is DB, get from db
if opts.Store == "" || opts.Store == types.StoreTypeDB {
dbList, err = dsl.db.List(opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
// Get the list from the file // If StoreType is not specified or is File, get from file
fileList, err := dsl.fs.List(opts) if opts.Store == "" || opts.Store == types.StoreTypeFile {
fileList, err = dsl.fs.List(opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
// Merge the list and unique // Merge the list and unique
list := []*types.Info{} list := []*types.Info{}

View file

@ -118,10 +118,16 @@ func (db *DB) List(options *types.ListOptions) ([]*types.Info, error) {
wheres = append(wheres, model.QueryWhere{Wheres: orwheres}) wheres = append(wheres, model.QueryWhere{Wheres: orwheres})
} }
// Select fields
fields := []interface{}{"dsl_id", "label", "path", "sort", "tags", "description", "status", "store", "mtime", "ctime"}
if options.Source {
fields = append(fields, "source")
}
// Get the list // Get the list
rows, err := m.Get(model.QueryParam{ rows, err := m.Get(model.QueryParam{
Wheres: []model.QueryWhere{{Column: "type", Value: db.Type}}, Wheres: wheres,
Select: []interface{}{"dsl_id", "label", "path", "sort", "tags", "description", "status", "store", "mtime", "ctime"}, Select: fields,
Orders: orders, Orders: orders,
}) })
if err != nil { if err != nil {

View file

@ -101,6 +101,14 @@ func (fs *FS) List(options *types.ListOptions) ([]*types.Info, error) {
for _, tag := range options.Tags { for _, tag := range options.Tags {
for _, t := range info.Tags { for _, t := range info.Tags {
if t == tag { if t == tag {
if options.Source {
source, _, err := fs.Source(id)
if err != nil {
errs = append(errs, err)
return nil
}
info.Source = source
}
infos = append(infos, info) infos = append(infos, info)
return nil return nil
} }
@ -109,6 +117,14 @@ func (fs *FS) List(options *types.ListOptions) ([]*types.Info, error) {
} }
// Add to the list // Add to the list
if options.Source {
source, _, err := fs.Source(id)
if err != nil {
errs = append(errs, err)
return nil
}
info.Source = source
}
infos = append(infos, info) infos = append(infos, info)
return err return err
}, patterns...) }, patterns...)

View file

@ -78,29 +78,33 @@ const (
// Info for DSL // Info for DSL
type Info struct { type Info struct {
ID string ID string `json:"id" yaml:"id"` // Unique identifier for the DSL instance
Type Type Type Type `json:"type" yaml:"type"` // DSL type (model, api, table, form, list, chart, dashboard, etc.)
Label string Label string `json:"label,omitempty" yaml:"label,omitempty"` // Display name for the DSL
Description string Description string `json:"description,omitempty" yaml:"description,omitempty"` // Detailed description of the DSL
Tags []string Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"` // Tags for categorization and filtering
Sort int Sort int `json:"sort,omitempty" yaml:"sort,omitempty"` // Sort order for display, default is 0
Path string Path string `json:"path" yaml:"path"` // File system path or identifier
Store StoreType Store StoreType `json:"store" yaml:"store"` // Storage type (file or database)
Readable bool Readable bool `json:"readable,omitempty" yaml:"readable,omitempty"` // Whether the DSL is readable
Builtin bool Builtin bool `json:"built_in,omitempty" yaml:"built_in,omitempty"` // Whether this is a built-in DSL
Status Status Status Status `json:"status,omitempty" yaml:"status,omitempty"` // Current status (loading, loaded, error)
Mtime time.Time Mtime time.Time `json:"mtime" yaml:"mtime"` // Last modification timestamp
Ctime time.Time Ctime time.Time `json:"ctime" yaml:"ctime"` // Creation timestamp
Source string `json:"source,omitempty" yaml:"source,omitempty"` // Source content, only available when explicitly requested
} }
// ListOptions for DSL list // ListOptions for DSL list
type ListOptions struct { type ListOptions struct {
Sort string Sort string
Order string Order string
Store StoreType
Source bool
Tags []string Tags []string
} }

View file

@ -1,9 +1,11 @@
package model package model
import ( import (
"context"
"fmt" "fmt"
"path/filepath" "path/filepath"
"strings" "strings"
"time"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
"github.com/yaoapp/gou/application" "github.com/yaoapp/gou/application"
@ -11,6 +13,8 @@ import (
"github.com/yaoapp/kun/log" "github.com/yaoapp/kun/log"
"github.com/yaoapp/yao/config" "github.com/yaoapp/yao/config"
"github.com/yaoapp/yao/data" "github.com/yaoapp/yao/data"
"github.com/yaoapp/yao/dsl"
"github.com/yaoapp/yao/dsl/types"
"github.com/yaoapp/yao/share" "github.com/yaoapp/yao/share"
) )
@ -54,18 +58,23 @@ func Load(cfg config.Config) error {
}, exts...) }, exts...)
if len(messages) > 0 { if len(messages) > 0 {
for _, message := range messages {
log.Error("Load filesystem models error: %s", message)
}
return fmt.Errorf(strings.Join(messages, ";\n")) return fmt.Errorf(strings.Join(messages, ";\n"))
} }
// Load database models ( ignore error) // Load database models ( ignore error)
err = loadDatabaseModels() errs := loadDatabaseModels()
if err != nil { if len(errs) > 0 {
log.Error("load database models error: %s", err.Error()) for _, err := range errs {
log.Error("Load database models error: %s", err.Error())
}
} }
return err return err
} }
// LoadSystemModels load system models
func loadSystemModels() error { func loadSystemModels() error {
for id, path := range systemModels { for id, path := range systemModels {
content, err := data.Read(path) content, err := data.Read(path)
@ -100,7 +109,7 @@ func loadSystemModels() error {
} }
// Auto migrate // Auto migrate
err = mod.Migrate(true, model.WithDonotInsertValues(true)) err = mod.Migrate(false, model.WithDonotInsertValues(true))
if err != nil { if err != nil {
log.Error("migrate system model %s error: %s", id, err.Error()) log.Error("migrate system model %s error: %s", id, err.Error())
return err return err
@ -110,6 +119,33 @@ func loadSystemModels() error {
return nil return nil
} }
func loadDatabaseModels() error { // LoadDatabaseModels load database models
return nil func loadDatabaseModels() []error {
var errs []error = []error{}
manager, err := dsl.New(types.TypeModel)
if err != nil {
errs = append(errs, err)
return errs
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
models, err := manager.List(ctx, &types.ListOptions{Store: types.StoreTypeDB, Source: true})
if err != nil {
errs = append(errs, err)
return errs
}
// Load models
for _, info := range models {
_, err := model.LoadSource([]byte(info.Source), info.ID, info.Path)
if err != nil {
errs = append(errs, err)
continue
}
}
return errs
} }