233 lines
4.2 KiB
Go
233 lines
4.2 KiB
Go
|
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)
|
||
|
}
|
||
|
}
|