fusenapi/generator/main.go

233 lines
4.2 KiB
Go
Raw Normal View History

2023-06-14 10:17:45 +00:00
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, "")
}
const (
_ int = iota
LongVarBinary
LongVarChar
GeometryCollection
GeomCollection
LineString
MultiLineString
MultiPoint
MultiPolygon
Point
Polygon
Json
Geometry
Enum
Set
Bit
Time
Timestamp
DateTime
Binary
VarBinary
Blob
Year
Decimal
Dec
Fixed
Numeric
Float
Float4
Float8
Double
Real
TinyInt
SmallInt
MediumInt
Int
Integer
BigInt
MiddleInt
Int1
Int2
Int3
Int4
Int8
Date
TinyBlob
MediumBlob
LongBlob
Bool
Boolean
Serial
NVarChar
NChar
Char
Character
VarChar
TinyText
Text
MediumText
LongText
)
var SQLTypeToGoTypeMap = map[int]string{
LongVarBinary: "[]byte",
Binary: "[]byte",
VarBinary: "[]byte",
Blob: "[]byte",
TinyBlob: "[]byte",
MediumBlob: "[]byte",
LongBlob: "[]byte",
LongVarChar: "*string",
NVarChar: "*string",
NChar: "*string",
Char: "*string",
Character: "*string",
VarChar: "*string",
TinyText: "*string",
Text: "*string",
MediumText: "*string",
LongText: "*string",
Time: "*time.Time",
Timestamp: "*time.Time",
DateTime: "*time.Time",
Date: "*time.Time",
Year: "*int64",
TinyInt: "*int64",
SmallInt: "*int64",
MediumInt: "*int64",
Int: "*int64",
Integer: "*int64",
BigInt: "*int64",
MiddleInt: "*int64",
Int1: "*int64",
Int2: "*int64",
Int3: "*int64",
Int4: "*int64",
Int8: "*int64",
Serial: "*int64",
Decimal: "*float64",
Dec: "*float64",
Fixed: "*float64",
Numeric: "*float64",
Float: "*float64",
Float4: "*float64",
Float8: "*float64",
Double: "*float64",
Real: "*float64",
Bool: "*bool",
Boolean: "*bool",
}
func main() {
var name string
flag.StringVar(&name, "name", "", "输入需要序列化的ddl文件名, 不需要后缀.ddl")
flag.Parse()
p, err := filepath.Abs(fmt.Sprintf("%s/%s.sql", targerDir, name))
if err != nil {
panic(err)
}
ddlf, err := os.Open(p)
if err != nil {
panic(err)
}
ddlfilestr, err := ioutil.ReadAll(ddlf)
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]
}
// 匹配到主键定义
parser.NewParser()
result, err := parser.NewParser().From(p)
if err != nil {
panic(err)
}
fcontent := "package model\nimport \"gorm.io/gorm\"\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()]
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 += 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)
}
}