| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 | 
							- package ii
 
- import (
 
- 	"encoding/xml"
 
- 	"errors"
 
- 	"fmt"
 
- 	"log"
 
- 	"os"
 
- 	"path/filepath"
 
- 	"strings"
 
- 	
 
- 	"golib/features/mlib/mo"
 
- )
 
- type itemInfo struct {
 
- 	Name     Name        `xml:"Name,attr"` // main.user
 
- 	Label    string      `xml:"Label,attr"`
 
- 	Fields   []fieldInfo `xml:"Fields>Field"`
 
- 	fieldMap map[string]fieldInfo
 
- }
 
- func (c *itemInfo) Init() {
 
- 	lstFields := make([]fieldInfo, len(c.Fields))
 
- 	for idx, field := range c.Fields {
 
- 		if err := field.init(); err != nil {
 
- 			log.Panicf("LoadItemInfo.Init: %s -> %s", c.Name, err)
 
- 		}
 
- 		lstFields[idx] = field
 
- 	}
 
- 	c.Fields = lstFields
 
- 	fieldMap := make(map[string]fieldInfo, len(c.Fields))
 
- 	for _, field := range c.Fields {
 
- 		fieldMap[field.Name] = field
 
- 	}
 
- 	c.fieldMap = fieldMap
 
- }
 
- func (c itemInfo) GetName() Name {
 
- 	return c.Name
 
- }
 
- func (c itemInfo) GetLabel() string {
 
- 	return c.Label
 
- }
 
- func (c itemInfo) GetField(name string) (Field, error) {
 
- 	v, ok := c.fieldMap[name]
 
- 	if !ok {
 
- 		return nil, fmt.Errorf("unknown_field: %s", name)
 
- 	}
 
- 	return v, nil
 
- }
 
- func (c itemInfo) GetFields() []Field {
 
- 	field := make([]Field, len(c.Fields))
 
- 	for i := 0; i < len(c.Fields); i++ {
 
- 		field[i] = Field(c.Fields[i])
 
- 	}
 
- 	return field
 
- }
 
- func (c itemInfo) GetFieldMap() map[string]Field {
 
- 	im := make(map[string]Field, len(c.fieldMap))
 
- 	for k, v := range c.fieldMap {
 
- 		im[k] = v
 
- 	}
 
- 	return im
 
- }
 
- func (c itemInfo) GetFieldsName() []string {
 
- 	name := make([]string, 0, len(c.Fields))
 
- 	for _, f := range c.Fields {
 
- 		if f.Ignore {
 
- 			continue
 
- 		}
 
- 		name = append(name, f.Name)
 
- 	}
 
- 	return name
 
- }
 
- type fieldInfo struct {
 
- 	Name    string      `xml:"Name,attr"`
 
- 	Label   string      `xml:"Label"`
 
- 	Type    mo.Type     `xml:"Type,attr"`  // Data type
 
- 	Model   Model       `xml:"Model,attr"` // Format type
 
- 	Default string      `xml:"Default"`
 
- 	Ignore  bool        `xml:"Ignore,attr"` // 忽略此字段
 
- 	Enums   []string    `xml:"Enums>Enum"`
 
- 	Number  NumberValue `xml:"Number"`
 
- 	Lookup  Lookup      `xml:"Lookup"`
 
- }
 
- type NumberValue struct {
 
- 	Minimum int64 `xml:"Minimum,attr"`
 
- 	Maximum int64 `xml:"Maximum,attr"`
 
- }
 
- type Lookup struct {
 
- 	From      string `xml:"From,attr"`      // 需要关联的表: ums.user
 
- 	Condition string `xml:"Condition,attr"` // 字段条件: _id
 
- 	Need      string `xml:"Need,attr"`      // 获取结果中的字段: name
 
- 	AS        string `xml:"As,attr"`        // 需要生成的字段: _id_name
 
- }
 
- func (c fieldInfo) GetName() string {
 
- 	return c.Name
 
- }
 
- func (c fieldInfo) GetLabel() string {
 
- 	return c.Label
 
- }
 
- func (c fieldInfo) GetType() mo.Type {
 
- 	return c.Type
 
- }
 
- func (c fieldInfo) GetModel() Model {
 
- 	return c.Model
 
- }
 
- func (c fieldInfo) IsIgnore() bool {
 
- 	return c.Ignore
 
- }
 
- func (c fieldInfo) GetLookup() (Lookup, bool) {
 
- 	if c.Lookup.From == "" {
 
- 		return Lookup{}, false
 
- 	}
 
- 	// lookup := mo.D{{
 
- 	// 	Key: mo.PLookup, Value: mo.D{
 
- 	// 		{Key: "from", Value: c.Lookup.From},
 
- 	// 		{Key: "localField", Value: c.Lookup.Need},
 
- 	// 		{Key: "foreignField", Value: c.Lookup.Condition},
 
- 	// 		{Key: "as", Value: c.Lookup.AS}},
 
- 	// }}
 
- 	return c.Lookup, true
 
- }
 
- func (c fieldInfo) GetEnums() ([]string, bool) {
 
- 	return c.Enums, len(c.Enums) == 0
 
- }
 
- func (c fieldInfo) GetNumber() (min int64, max int64, ok bool) {
 
- 	return c.Number.Minimum, c.Number.Maximum, c.Number.Minimum != 0 && c.Number.Maximum != 0
 
- }
 
- func (c fieldInfo) GetDefaultValue() string {
 
- 	return c.Default
 
- }
 
- func (c *fieldInfo) init() error {
 
- 	if c.Name == "" {
 
- 		return errors.New("Field.Name does not exist")
 
- 	}
 
- 	if c.Label == "" {
 
- 		return errors.New("Field.Label does not exist")
 
- 	}
 
- 	// 关联显示
 
- 	if c.Lookup.From != "" {
 
- 		// 如果未指定本地字段则使用 Name
 
- 		if c.Lookup.Need == "" {
 
- 			c.Lookup.Need = c.Name
 
- 		}
 
- 		// 如果未指定远程字段则使用 Name
 
- 		if c.Lookup.Condition == "" {
 
- 			c.Lookup.Condition = c.Name
 
- 		}
 
- 		if c.Lookup.AS == "" {
 
- 			c.Lookup.AS = c.Name
 
- 		}
 
- 	}
 
- 	return nil
 
- }
 
- var (
 
- 	itemMap = &itemBody{infoMap: map[Name]itemInfo{}}
 
- )
 
- type itemBody struct {
 
- 	infoMap  map[Name]itemInfo
 
- 	isLoaded bool
 
- }
 
- func (c *itemBody) Init(itemInfo map[Name]itemInfo) {
 
- 	c.infoMap = itemInfo
 
- 	c.isLoaded = true
 
- }
 
- func (c itemBody) GetItem(name Name) (Item, bool) {
 
- 	if info, ok := c.infoMap[name]; ok {
 
- 		return info, true
 
- 	}
 
- 	return itemInfo{}, false
 
- }
 
- func (c itemBody) IsLoaded() bool {
 
- 	return c.isLoaded
 
- }
 
- func GetItemByName(name string) (Item, bool) {
 
- 	return itemMap.GetItem(NewName(name))
 
- }
 
- type Name string
 
- func (c Name) DbName() string {
 
- 	if i := strings.Index(c.String(), "."); i != -1 {
 
- 		return c.String()[:i]
 
- 	}
 
- 	return mo.DefaultDbName
 
- }
 
- func (c Name) CollName() string {
 
- 	if i := strings.Index(c.String(), "."); i != -1 {
 
- 		return c.String()[i+1:]
 
- 	}
 
- 	return c.String()
 
- }
 
- func (c Name) String() string {
 
- 	return string(c)
 
- }
 
- func (c *Name) UnmarshalXMLAttr(attr xml.Attr) error {
 
- 	if attr.Value == "" {
 
- 		return fmt.Errorf("unknown name: %s", attr.Value)
 
- 	}
 
- 	*c = Name(attr.Value)
 
- 	return nil
 
- }
 
- // NewName 获取包含数据库的集合名称, 例如: main.user
 
- // 当不包含 . 时则会补充 MongoDB 默认的数据库 test
 
- func NewName(name string) Name {
 
- 	return Name(name)
 
- }
 
- // LoadItemInfo 初始化
 
- func LoadItemInfo(path string) {
 
- 	if itemMap.IsLoaded() {
 
- 		return
 
- 	}
 
- 	info := make(map[Name]itemInfo, 512)
 
- 	err := filepath.Walk(path, func(filePath string, f os.FileInfo, err error) error {
 
- 		if strings.HasSuffix(filePath, ".xml") {
 
- 			oItemInfo, err := readItemInfoFromXml(filePath)
 
- 			if err != nil {
 
- 				return err
 
- 			}
 
- 			oItemInfo.Init()
 
- 			info[oItemInfo.Name] = oItemInfo
 
- 		}
 
- 		return nil
 
- 	})
 
- 	if err != nil {
 
- 		panic(err)
 
- 	}
 
- 	itemMap.Init(info)
 
- }
 
- func readItemInfoFromXml(path string) (itemInfo, error) {
 
- 	content, err := os.ReadFile(path)
 
- 	if err != nil {
 
- 		return itemInfo{}, err
 
- 	}
 
- 	var oItemInfoCfg itemInfo
 
- 	return oItemInfoCfg, xml.Unmarshal(content, &oItemInfoCfg)
 
- }
 
 
  |