finish: gorm序列化
This commit is contained in:
232
generator/main.go
Normal file
232
generator/main.go
Normal file
@@ -0,0 +1,232 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
15
generator/main_test.go
Normal file
15
generator/main_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
// args := []string{"-name", "fs_guest"}
|
||||
targerDir = "../" + targerDir
|
||||
genDir = "../" + genDir
|
||||
os.Args = []string{"cmd", "-name=fs_guest"}
|
||||
|
||||
main()
|
||||
}
|
||||
Reference in New Issue
Block a user