首页 > 其他分享 >go gorm 通用微服务反射实现通用增删改查功能

go gorm 通用微服务反射实现通用增删改查功能

时间:2024-10-15 21:21:35浏览次数:14  
标签:通用 err self 改查 entity reflect var go return

package pagedb

import (
    "errors"
    "fmt"
    "git.ichub.com/general/webcli120/goconfig/base/basedto"
    "git.ichub.com/general/webcli120/goconfig/base/baseutils"
    "git.ichub.com/general/webcli120/goconfig/base/jsonutils"
    "git.ichub.com/general/webcli120/goconfig/base/stringutils"
    "git.ichub.com/general/webcli120/goconfig/ichublog/golog"
    dbpkgdto "git.ichub.com/general/webcli120/goweb/meta/db/pkg/dto"
    "git.ichub.com/general/webcli120/goweb/meta/db/pkg/service"
    "git.ichub.com/general/webcli120/goweb/page"
    "github.com/huandu/go-clone"
    "github.com/sirupsen/logrus"
    "reflect"
    "strings"
    "time"
)

type PagedbGroup struct {
    *PageDbRequest
    StatFieldTemplate string
}

func DefaultDbGroup() *PagedbGroup {
    var dbgroup = NewPagedbGroup()
    dbgroup.Init()
    return dbgroup
}
func NewPagedbGroup() *PagedbGroup {
    return &PagedbGroup{
       StatFieldTemplate: `
       sum(statField) statFieldSum,
       max(statField) statFieldMax,
       count(statField) statFieldCount,
       min(statField) statFieldMin,
       avg(statField) statFieldAvg    `,
    }
}

func (self *PagedbGroup) Init() {
    self.PageDbRequest = Default()
}

// var sql = `select groupFields, sum(statField)  ,max(statField),count(statField) ,
//
//  min(statField),count(statField) ,avg(statField)    from ` + self.TableName
func (self *PagedbGroup) Stat(statfield ...string) (map[string]any, error) {
    if self.PageDbRequest == nil {
       //return nil, errors.New("PageDbRequest is nil")
    }
    var result, err = self.GroupStat("", statfield[0])
    if err != nil {
       return nil, err
    }

    return result[0], nil
}
func (self *PagedbGroup) GroupStat(groupFields string, statfields ...string) ([]map[string]any, error) {
    var statfield = statfields[0]
    var fields = `groupFields, 
             sum(statField) sum,
             max(statField) max,
             count(statField) count,
             min(statField) min,
             avg(statField) avg `
    if groupFields == "" {
       fields = strings.ReplaceAll(fields, "groupFields,", "")
    } else {
       fields = strings.ReplaceAll(fields, "groupFields", groupFields)
    }
    fields = strings.ReplaceAll(fields, "statField", statfield)

    var dbc = self.GetDB().Table(self.TableName).Select(fields)
    if groupFields != "" {
       dbc = dbc.Group(groupFields)
    }
    dbc = dbc.Offset(self.Start()).Limit(self.PageSize)

    dbc = self.BuildWhere(dbc)
    if self.IfOrderBys() {
       dbc = self.Order(dbc)
    }
    var rows, err = dbc.Rows()
    if err != nil {
       golog.Error(err)
       return nil, err
    }
    defer func() {
       rows.Close()
    }()
    var records = make([]map[string]any, 0)

    var record = self.CreateStatStru(groupFields)
    for rows.Next() {
       record = clone.Clone(record)
       dbc.ScanRows(rows, record)
       records = append(records, jsonutils.Stru2Map(record))
    }

    golog.Info(records)
    return records, nil

}
func (self *PagedbGroup) CreateStatStru(groupFields string, statField ...string) any {

    var statFields = "Avg,Max,Min,Sum"
    dbFields := []reflect.StructField{}
    if groupFields != "" {
       for _, field := range strings.Split(groupFields, ",") {
          var colField = reflect.StructField{
             Name: stringutils.Capitalize(field),
             Type: reflect.TypeOf(""),
             Tag:  reflect.StructTag(`json:"` + stringutils.Lcfirst(field) + `"`),
          }
          dbFields = append(dbFields, colField)
       }

    }
    for _, field := range strings.Split(statFields, ",") {
       var colField = reflect.StructField{
          Name: stringutils.Capitalize(field),
          Type: reflect.TypeOf(""),
          Tag:  reflect.StructTag(`json:"` + stringutils.Lcfirst(field) + `"`),
       }
       dbFields = append(dbFields, colField)
    }

    var colField = reflect.StructField{
       Name: "Count",
       Type: reflect.TypeOf(int(0)),
       Tag:  `json:"count"`,
    }
    dbFields = append(dbFields, colField)

    colField = reflect.StructField{
       Name: "BaseEntity",
       Type: reflect.TypeOf(basedto.BaseEntity{}),
       Tag:  `json:"-"`,
    }
    dbFields = append(dbFields, colField)

    dbtableType := reflect.StructOf(dbFields)
    //初始化一个动态结构体实例
    var stru = reflect.New(dbtableType).Elem().Addr().Interface()
    //初始化baseentity some成员
    baseutils.IfProxy(stru)
    return stru

}
func (self *PagedbGroup) Insert(entity any) (map[string]any, error) {

    var err = self.GetDB().Table(self.TableName).Model(entity).Create(entity).Error
    if err != nil {
       logrus.Error(err.Error())
       return nil, err
    }
    var result = jsonutils.Stru2Map(entity)
    return result, err

}
func (self *PagedbGroup) FindPkName() string {
    var metadataFactroy = service.FindMetadataFactroy(self.DbClientDto)
    var metadata = metadataFactroy.FindMetaTable(self.TableName)
    var pk = metadata.PkInfo.PkName
    return pk
}
func (self *PagedbGroup) Update(entity any, v any) (any, error) {
    var pk = self.FindPkName()
    var err = self.GetDB().Table(self.TableName).Model(entity).Where(pk+"=?", v).Update(entity).Error
    if err != nil {
       golog.Error(err)
       return entity, err
    }
    return jsonutils.Stru2Map(entity), err
}

// no primary key will insert
func (self *PagedbGroup) Save(entity any, pk string, v any) (any, error) {

    var err = self.GetDB().Table(self.TableName).Model(entity).Where(pk+"=?", v).Save(entity).Error
    if err != nil {
       golog.Error(err)
       return entity, err
    }
    return jsonutils.Stru2Map(entity), err
}

func (self *PagedbGroup) CreateTableRecord() (any, error) {

    var entity, err = self.CreateTableStru()
    if err != nil {
       return nil, err
    }
    return entity.Addr().Interface(), err
}
func (self *PagedbGroup) CreateTableStru() (reflect.Value, error) {
    var metadataFactroy = service.NewMetadataFactroy(self.DbClientDto)
    var metadata = metadataFactroy.FindMetaTable(self.TableName)
    if !metadata.TableExist {
       return reflect.ValueOf(nil), errors.New("table not exist")
    }
    return self.CreateDbTableStru(metadata), nil
}
func (self *PagedbGroup) CreateDbTableStru(meta *dbpkgdto.MetaTableDto) reflect.Value {
    // logrus.Info("CreateDbTableStru meta=", meta.ToPrettyString())
    var metaColService = service.FindMetadataFactroy(self.DbClientDto)
    dbFields := []reflect.StructField{}

    for _, col := range meta.Columns {
       //logrus.Info("CreateDbTableStru col=", col.ToPrettyString())
       var colType = metaColService.FindGoType(col.DataType)
       var ColTyp8 = reflect.TypeOf(int8(0))

       var ct = func(colType string) *reflect.Type {
          var ColTyp = reflect.TypeOf(int8(0))
          switch colType {
          case "float32":
             ColTyp = reflect.TypeOf(float32(0))
          case "float64":
             ColTyp = reflect.TypeOf(float64(0))
          case "int64":
             ColTyp = reflect.TypeOf(int64(0))
          case "int32":
             ColTyp = reflect.TypeOf(int32(0))
          case "int16":
             ColTyp = reflect.TypeOf(int16(0))
          case "uint64":
             ColTyp = reflect.TypeOf(uint64(0))
          case "uint32":
             ColTyp = reflect.TypeOf(uint32(0))
          case "uint16":
             ColTyp = reflect.TypeOf(uint16(0))
          case "string":
             ColTyp = reflect.TypeOf("")
          case "bool":
             ColTyp = reflect.TypeOf(true)
          case "byte":
             ColTyp = reflect.TypeOf(byte(0))
          case "[]byte":
             ColTyp = reflect.TypeOf([]byte{})

          case "time.Time":
             ColTyp = reflect.TypeOf(time.Now())
             if col.ColumnName == "deleted_at" {
                var t *time.Time
                ColTyp = reflect.TypeOf(t)

             }

          }
          return &ColTyp
       }(colType)
       if ColTyp8 != *ct {
          if self.IfExistField(col.ColumnName) {
             //colField.Tag = reflect.StructTag(fmt.Sprintf("json:\"%s\"", col.ColumnName))
             var name = stringutils.Case2Camel(col.ColumnName)
             name = strings.ReplaceAll(name, ",", "")
             var colField = reflect.StructField{
                Name: name,
                Type: *ct,
                Tag:  reflect.StructTag(fmt.Sprintf("json:\"%s\"", col.ColumnName)),
             }
             //or primary key
             if col.ColumnName == "id" {
                colField.Tag = reflect.StructTag(`gorm:"column:id;type:INT8;PRIMARY_KEY;default:unique_rowid()" json:"id"`)
             }
             dbFields = append(dbFields, colField)
          }
       }
    }

    dbtableType := reflect.StructOf(dbFields)
    return reflect.New(dbtableType).Elem()

}

func (self *PagedbGroup) UpdateNotNull(pkeyValue any, maps map[string]any) (any, error) {

    var entity, _ = self.CreateTableRecord()

    var pk = self.FindPkName()
    err := self.GetDB().Table(self.TableName).Model(entity).Where(pk+"=?", pkeyValue).Updates(maps).Error
    if err != nil {
       logrus.Error(err.Error())
       return entity, err
    }
    return err, err
}
func (self *PagedbGroup) DeleteById(pkey any) error {
    var entity, _ = self.CreateTableRecord()
    var pk = self.FindPkName()
    err := self.GetDB().Table(self.TableName).Where(pk+"=?", pkey).Delete(&entity).Error
    return err
}

func (self *PagedbGroup) FindById(pkey any) (any, bool, error) {
    var entity, _ = self.CreateTableRecord()
    var pk = self.FindPkName()
    db := self.GetDB().Table(self.TableName).First(entity, pk+"=?", pkey)

    return entity, db.RecordNotFound(), db.Error

}

func (self *PagedbGroup) GeneralScanTable() *page.PageResult {
    return self.PageDbRequest.GeneralScanTable()
}

标签:通用,err,self,改查,entity,reflect,var,go,return
From: https://blog.csdn.net/leijmdas/article/details/142964877

相关文章