- Enhanced the List method in the DSL struct to conditionally retrieve data from either the database or file system based on the StoreType specified in ListOptions. - Updated the Info struct to include a new Source field for optional source content retrieval. - Modified the List methods in both DB and FS to include source information when requested, improving data accessibility and flexibility.
151 lines
3.5 KiB
Go
151 lines
3.5 KiB
Go
package model
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
jsoniter "github.com/json-iterator/go"
|
|
"github.com/yaoapp/gou/application"
|
|
"github.com/yaoapp/gou/model"
|
|
"github.com/yaoapp/kun/log"
|
|
"github.com/yaoapp/yao/config"
|
|
"github.com/yaoapp/yao/data"
|
|
"github.com/yaoapp/yao/dsl"
|
|
"github.com/yaoapp/yao/dsl/types"
|
|
"github.com/yaoapp/yao/share"
|
|
)
|
|
|
|
// SystemModels system models
|
|
var systemModels = map[string]string{
|
|
"__yao.assistant": "yao/models/assistant.mod.yao",
|
|
"__yao.attachment": "yao/models/attachment.mod.yao",
|
|
"__yao.audit": "yao/models/audit.mod.yao",
|
|
"__yao.chat": "yao/models/chat.mod.yao",
|
|
"__yao.config": "yao/models/config.mod.yao",
|
|
"__yao.dsl": "yao/models/dsl.mod.yao",
|
|
"__yao.history": "yao/models/history.mod.yao",
|
|
"__yao.kb": "yao/models/kb.mod.yao",
|
|
}
|
|
|
|
// Load load models
|
|
func Load(cfg config.Config) error {
|
|
|
|
messages := []string{}
|
|
|
|
model.WithCrypt([]byte(fmt.Sprintf(`{"key":"%s"}`, cfg.DB.AESKey)), "AES")
|
|
model.WithCrypt([]byte(`{}`), "PASSWORD")
|
|
|
|
// Load system models
|
|
err := loadSystemModels()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Load filesystem models
|
|
exts := []string{"*.mod.yao", "*.mod.json", "*.mod.jsonc"}
|
|
err = application.App.Walk("models", func(root, file string, isdir bool) error {
|
|
if isdir {
|
|
return nil
|
|
}
|
|
_, err := model.Load(file, share.ID(root, file))
|
|
if err != nil {
|
|
messages = append(messages, err.Error())
|
|
}
|
|
return err
|
|
}, exts...)
|
|
|
|
if len(messages) > 0 {
|
|
for _, message := range messages {
|
|
log.Error("Load filesystem models error: %s", message)
|
|
}
|
|
return fmt.Errorf(strings.Join(messages, ";\n"))
|
|
}
|
|
|
|
// Load database models ( ignore error)
|
|
errs := loadDatabaseModels()
|
|
if len(errs) > 0 {
|
|
for _, err := range errs {
|
|
log.Error("Load database models error: %s", err.Error())
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
// LoadSystemModels load system models
|
|
func loadSystemModels() error {
|
|
for id, path := range systemModels {
|
|
content, err := data.Read(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Parse model
|
|
var data map[string]interface{}
|
|
err = application.Parse(path, content, &data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Set prefix
|
|
if table, ok := data["table"].(map[string]interface{}); ok {
|
|
if name, ok := table["name"].(string); ok {
|
|
table["name"] = share.App.Prefix + name
|
|
content, err = jsoniter.Marshal(data)
|
|
if err != nil {
|
|
log.Error("failed to marshal model data: %v", err)
|
|
return fmt.Errorf("failed to marshal model data: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Load Model
|
|
mod, err := model.LoadSource(content, id, filepath.Join("__system", path))
|
|
if err != nil {
|
|
log.Error("load system model %s error: %s", id, err.Error())
|
|
return err
|
|
}
|
|
|
|
// Auto migrate
|
|
err = mod.Migrate(false, model.WithDonotInsertValues(true))
|
|
if err != nil {
|
|
log.Error("migrate system model %s error: %s", id, err.Error())
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// LoadDatabaseModels load database models
|
|
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
|
|
}
|