2 Star 1 Fork 1

mosache / YFrame

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
gen.go 6.75 KB
一键复制 编辑 原始数据 按行查看 历史
ヤ沒脩袮兲︶ 提交于 2024-01-09 18:36 . temp
package gen
import (
"errors"
"fmt"
"gitee.com/mosache/YFrame/core/common/slicex"
"gitee.com/mosache/YFrame/tools/Y/model/conf"
"gitee.com/mosache/YFrame/tools/Y/vars"
"go/ast"
"go/parser"
"go/token"
"os"
"path"
"slices"
"sort"
"sync"
"text/template"
)
type Generator struct {
dataBaseName string
tables []string
tableRegex []string
tablePrefix string
}
func NewGenerator(opts ...Option) (*Generator, error) {
g := &Generator{
dataBaseName: conf.Config.DataBase,
tables: nil,
tablePrefix: "",
}
for _, o := range opts {
if err := o(g); err != nil {
return nil, err
}
}
return g, nil
}
type Option func(g *Generator) error
func WithDataBaseName(dataBaseName string) Option {
return func(g *Generator) error {
g.dataBaseName = dataBaseName
return nil
}
}
func WithTables(tables []string) Option {
return func(g *Generator) error {
g.tables = tables
return nil
}
}
func WithTablePrefix(tablePrefix string) Option {
return func(g *Generator) error {
fs := token.NewFileSet()
pwd, err := os.Getwd()
if err != nil {
return err
}
f, err := parser.ParseFile(fs, fmt.Sprintf("%s/internal/config/config.go", pwd), nil, parser.ParseComments)
if err != nil {
return err
}
hasConfigTablePrefix := false
for _, d := range f.Decls {
switch d.(type) {
case *ast.GenDecl:
g := d.(*ast.GenDecl)
if g.Tok == token.TYPE {
for _, s := range g.Specs {
switch s.(type) {
case *ast.TypeSpec:
t := s.(*ast.TypeSpec)
if t.Name.Name == "Config" {
if st, ok := t.Type.(*ast.StructType); ok {
for _, field := range st.Fields.List {
if slices.Contains(slicex.Map(field.Names, func(v *ast.Ident) string {
return v.Name
}), tablePrefix) {
hasConfigTablePrefix = true
}
}
}
}
}
}
}
}
}
if !hasConfigTablePrefix {
return errors.New("tablePrefix do not config in config.go")
}
g.tablePrefix = tablePrefix
return nil
}
}
func WithTableRegex(tableRegex []string) Option {
return func(g *Generator) error {
g.tableRegex = tableRegex
return nil
}
}
///====================================================================================
func (g *Generator) Generate(targetPath string, packageName string, isDoc bool, isNew bool) error {
/// 1 get column information
cInfo, err := getColumnInfo(g.dataBaseName, g.tables, g.tableRegex)
if err != nil {
return err
}
if len(cInfo) == 0 {
return fmt.Errorf("no table named [%s] found in database[%s]", g.tables, g.dataBaseName)
}
/// 2 get table vo
tables := make([]tableInfo, 0)
tableNameFilterMap := make(map[tableNameAndCommentFilterMapKey][]*ColumnInfoModel)
for _, e := range cInfo {
key := tableNameAndCommentFilterMapKey{
TableName: e.TableName,
TableComment: e.TableComment,
}
if _, ok := tableNameFilterMap[key]; ok {
tableNameFilterMap[key] = append(tableNameFilterMap[key], e)
} else {
tableNameFilterMap[key] = []*ColumnInfoModel{e}
}
}
for k, v := range tableNameFilterMap {
filedList := make([]tableColumnInfo, 0)
sort.Slice(v, func(i, j int) bool {
return v[i].Position < v[j].Position
})
for _, e := range v {
filedList = append(filedList, tableColumnInfo{
ColumnName: e.ColumnName,
DataType: _getGoDataType(e.DataType),
ColumType: e.ColumnType,
ColumnComment: _getFieldComment(e.ColumnComment),
IsPrimaryKey: _getIsPrimaryKey(e.IsPrimaryKey),
Tag: _getModelFieldTag(e.ColumnName, _getIsPrimaryKey(e.IsPrimaryKey)),
})
}
tables = append(tables, tableInfo{
TableName: k.TableName,
TableComment: k.TableComment,
Package: packageName,
TableNamePrefix: g.tablePrefix,
ModName: conf.Config.ModName,
IsNew: isNew,
Columns: filedList,
})
}
/// 3 gen file
if !isDoc {
/// gen model file
return _genModelFile(targetPath, tables)
}
/// is doc , gen doc markdown file
return _genDocMarkDown(targetPath, tables)
}
func _genDocMarkDown(targetPath string, tables []tableInfo) error {
t := template.New("doc-template")
t.Funcs(map[string]interface{}{
"GetFieldCommentStr": GetFieldCommentStr,
})
pt, err := t.Parse(DocTpl)
if err != nil {
return err
}
/// 判断targetPath是否存在,没有需要创建
if err := _checkTargetPath(targetPath); err != nil {
return err
}
fileName := "doc.md"
file, err := os.OpenFile(fmt.Sprintf("%s/%s", targetPath, fileName), os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm)
if err != nil {
return err
}
err = pt.Execute(file, map[string]interface{}{"tables": tables})
if err != nil {
return err
}
return nil
}
func _genModelFile(targetPath string, tables []tableInfo) error {
t := template.New("m-template")
t.Funcs(map[string]interface{}{
"GetGoStylePropertyName": GetGoStylePropertyName,
"FormatComment": FormatComment,
})
pt, err := t.Parse(modelTpl)
if err != nil {
return err
}
hasTargetPath := true
if len(targetPath) == 0 {
hasTargetPath = false
targetPath = fmt.Sprintf("./%s", vars.CodeModelsDir)
}
/// 判断targetPath是否存在,没有需要创建
if err = _checkTargetPath(targetPath); err != nil {
return err
}
var tableErr any
var wg sync.WaitGroup
for _, e := range tables {
tblInfo := e
wg.Add(1)
go func() {
defer func() {
wg.Done()
tableErr = recover()
}()
var (
modelDirPath string
pkName string
)
if hasTargetPath {
modelDirPath = targetPath
pkName = path.Base(targetPath)
} else {
/// 创建文件夹
pkName = fmt.Sprintf("%sDao", GetGoStyleTableDaoName(tblInfo.TableName))
modelDirPath = fmt.Sprintf("%s/%s", targetPath, pkName)
if err = _checkModelDir(modelDirPath); err != nil {
fmt.Println(err.Error())
}
}
fileName := fmt.Sprintf("%sModel.go", GetGoStylePropertyName(tblInfo.TableName))
file, err := os.OpenFile(fmt.Sprintf("%s/%s", modelDirPath, fileName), os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm)
if err != nil {
fmt.Println(err.Error())
}
tblInfo.Package = pkName
err = pt.Execute(file, tblInfo)
if err != nil {
fmt.Println(err.Error())
}
}()
}
wg.Wait()
if tableErr != nil {
return tableErr.(error)
}
return nil
}
func _checkModelDir(modelDirPath string) error {
_, err := os.Stat(modelDirPath)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
err := os.MkdirAll(modelDirPath, os.ModePerm)
if err != nil {
return err
}
} else {
return err
}
}
return nil
}
func _checkTargetPath(targetPath string) error {
_, err := os.Stat(targetPath)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
err := os.MkdirAll(targetPath, os.ModePerm)
if err != nil {
return err
}
} else {
return err
}
}
return nil
}
Go
1
https://gitee.com/mosache/YFrame.git
git@gitee.com:mosache/YFrame.git
mosache
YFrame
YFrame
v0.1.75

搜索帮助

53164aa7 5694891 3bd8fe86 5694891