package main import ( "flag" "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "regexp" "strings" "github.com/zeromicro/ddl-parser/parser" "golang.org/x/text/cases" "golang.org/x/text/language" ) var targerDir = "ddl" var genDir = "model/gmodel_gen" func toPascalCase(s string) string { words := strings.Split(s, "_") for i, word := range words { words[i] = cases.Title(language.English).String(strings.ToLower(word)) } return strings.Join(words, "") } func main() { var name string flag.StringVar(&name, "name", "", "输入需要序列化的ddl文件名, 不需要后缀.ddl") flag.Parse() if name != "" { name = fmt.Sprintf("%s/%s.sql", targerDir, name) GenFromPath(name) } else { matches, err := filepath.Glob(fmt.Sprintf("%s/*.sql", targerDir)) if err != nil { panic(err) } for _, pth := range matches { GenFromPath(pth) } } } func GenFromPath(pth string) { p, err := filepath.Abs(pth) if err != nil { panic(err) } ddlfilestr, err := ioutil.ReadFile(pth) if err != nil { panic(err) } // PRIMARY KEY (`guest_id`) USING BTREE re := regexp.MustCompile("PRIMARY\\s+KEY\\s+\\(\\s*`([^`]+)`\\s*\\)|`([^`]+)` [^\n]+PRIMARY\\s+KEY\\s+") matches := re.FindStringSubmatch(string(ddlfilestr)) PrimaryStr := "" if len(matches) > 0 { PrimaryStr = matches[1] } var importstr = "import (\"gorm.io/gorm\"\n" // 匹配到主键定义 parser.NewParser() result, err := parser.NewParser().From(p) if err != nil { panic(err) } fcontent := "package model\n" for _, table := range result { structstr := "type %s struct {%s\n}\n" tableName := toPascalCase(table.Name) fieldstr := "" for _, col := range table.Columns { fieldName := toPascalCase(col.Name) typeName := SQLTypeToGoTypeMap[col.DataType.Type()] if typeName == "*time.Time" { importstr += "\"time\"\n" } tagstr := "`gorm:" if col.Name == PrimaryStr { tagstr += "\"primary_key\"" typeName = typeName[1:] } else { tagstr += "\"\"" } tagstr += fmt.Sprintf(" json:\"%s\"`", col.Name) fieldColStr := fmt.Sprintf("\n%s %s %s// %s", fieldName, typeName, tagstr, col.Constraint.Comment) fieldstr += fieldColStr } fcontent += importstr + ")\n" fcontent += fmt.Sprintf(structstr, tableName, fieldstr) modelstr := fmt.Sprintf(`type %sModel struct {db *gorm.DB}`, tableName) fcontent += modelstr fcontent += "\n" newfuncstr := fmt.Sprintf(`func New%sModel(db *gorm.DB) *%sModel {return &%sModel{db}}`, tableName, tableName, tableName) fcontent += newfuncstr fcontent += "\n" genGoFileName := fmt.Sprintf("%s/%s_gen.go", genDir, table.Name) f, err := os.OpenFile(genGoFileName, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) if err != nil { panic(err) } f.WriteString(fcontent) err = f.Close() if err != nil { panic(err) } err = exec.Command("gofmt", "-w", genGoFileName).Run() if err != nil { panic(err) } // log.Println(fcontent) } }