代码拉取完成,页面将自动刷新
/*
元数据注册中心
*/
package schema
import (
"gitee.com/mosache/YFrame/orm/internal/errs"
"gitee.com/mosache/YFrame/orm/until/strx"
"reflect"
"strings"
"sync"
)
const (
ormTagName = "orm"
ormTagSplitter = ","
ormTagAssignment = "="
tagCol = "col"
)
type SchemaOpt func(s *Schema) error
func SchemaWithTableName(tableName string) SchemaOpt {
return func(s *Schema) error {
s.TableName = tableName
return nil
}
}
func WithColumName(field, colName string) SchemaOpt {
return func(s *Schema) error {
f, ok := s.FieldMap[field]
if !ok {
return errs.NewErrUnknownField(field)
}
f.ColumnName = colName
return nil
}
}
type Registry interface {
Get(val any) (*Schema, error)
Register(val any, opts ...SchemaOpt) (*Schema, error)
}
type Register struct {
Schemas sync.Map
}
func NewRegister() *Register {
return &Register{}
}
func (r *Register) Get(val any) (*Schema, error) {
typ := reflect.TypeOf(val)
for typ.Kind() == reflect.Pointer {
typ = typ.Elem()
}
var (
m *Schema
err error
)
getVal, ok := r.Schemas.Load(typ)
if ok {
return getVal.(*Schema), nil
}
if m, err = r.Register(val); err != nil {
return nil, err
}
return m, nil
}
func (r *Register) Register(entity any, opts ...SchemaOpt) (*Schema, error) {
typ := reflect.TypeOf(entity)
//val := reflect.ValueOf(entity)
for typ.Kind() == reflect.Pointer {
typ = typ.Elem()
//val = val.Elem()
}
m := new(Schema)
m.FieldMap = make(map[string]*Field)
m.ColumnMap = make(map[string]*Field)
m.Fields = make([]*Field, 0)
tableName := strx.ToSnakeCase(typ.Name())
if tn, ok := entity.(TableName); ok {
name := tn.TableName()
if len(name) > 0 {
tableName = name
}
}
m.TableName = tableName
fieldNum := typ.NumField()
for i := 0; i < fieldNum; i++ {
f := typ.Field(i)
tags, err := r.parseTag(f.Tag)
if err != nil {
return nil, err
}
cName := strx.ToSnakeCase(f.Name)
if colName, ok := tags[tagCol]; ok {
cName = colName
}
field := &Field{
GoName: f.Name,
ColumnName: cName,
Typ: f.Type,
OffSet: f.Offset,
}
m.FieldMap[f.Name] = field
m.ColumnMap[cName] = field
m.Fields = append(m.Fields, field)
}
for _, opt := range opts {
if err := opt(m); err != nil {
return nil, err
}
}
r.Schemas.Store(typ, m)
return m, nil
}
/*
parseTag
col:"col=xxx,a=b"
*/
func (r *Register) parseTag(tag reflect.StructTag) (map[string]string, error) {
m := make(map[string]string)
var (
col string
ok bool
)
if col, ok = tag.Lookup(ormTagName); ok {
col = strings.TrimSpace(col)
segs := strings.Split(col, ormTagSplitter)
for _, seg := range segs {
seg = strings.TrimSpace(seg)
if len(seg) > 0 {
items := strings.Split(seg, ormTagAssignment)
if len(items) != 2 {
return nil, errs.NewErrTagFormatErr(seg)
}
if len(items[0]) > 0 && len(items[1]) > 0 {
m[items[0]] = items[1]
}
}
}
}
return m, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。