Quellcode durchsuchen

阶段性工作

Jollia Dai vor 2 Monaten
Ursprung
Commit
86fb7caa66
8 geänderte Dateien mit 278 neuen und 88 gelöschten Zeilen
  1. 1 0
      .gitignore
  2. 9 0
      build_linux64.bat
  3. 9 0
      build_win64.bat
  4. 17 5
      go.mod
  5. 47 14
      go.sum
  6. 13 69
      main.go
  7. 77 0
      services/config.go
  8. 105 0
      services/gen_service.go

+ 1 - 0
.gitignore

@@ -8,3 +8,4 @@
 /db2code
 
 /*.log
+

+ 9 - 0
build_linux64.bat

@@ -0,0 +1,9 @@
+go mod tidy
+
+@ECHO OFF
+SET CGO_ENABLED=0
+SET GOOS=linux
+SET GOARCH=amd64
+@ECHO ON
+go build -o out/activity ./main.go
+@ECHO OFF

+ 9 - 0
build_win64.bat

@@ -0,0 +1,9 @@
+go mod tidy
+
+@ECHO OFF
+SET CGO_ENABLED=0
+SET GOOS=windows
+SET GOARCH=amd64
+@ECHO ON
+go build -o out/db2code.exe ./main.go
+@ECHO OFF

+ 17 - 5
go.mod

@@ -1,19 +1,31 @@
 module db2code
 
-go 1.22.3
+go 1.23.4
 
 require (
-	gorm.io/driver/mysql v1.5.6
+	github.com/pkg/errors v0.9.1
+	gorm.io/driver/mysql v1.5.7
 	gorm.io/gen v0.3.26
-	gorm.io/gorm v1.25.9
+	gorm.io/gorm v1.25.12
+	jollia.cn/jolib/jokode v0.8.8
 )
 
 require (
+	github.com/bwmarrin/snowflake v0.3.0 // indirect
 	github.com/go-sql-driver/mysql v1.7.0 // indirect
+	github.com/google/uuid v1.6.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
-	golang.org/x/mod v0.14.0 // indirect
-	golang.org/x/tools v0.17.0 // indirect
+	github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
+	go.uber.org/multierr v1.10.0 // indirect
+	go.uber.org/zap v1.27.0 // indirect
+	golang.org/x/crypto v0.33.0 // indirect
+	golang.org/x/mod v0.17.0 // indirect
+	golang.org/x/sync v0.11.0 // indirect
+	golang.org/x/sys v0.30.0 // indirect
+	golang.org/x/text v0.22.0 // indirect
+	golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c // indirect
 	gorm.io/hints v1.1.0 // indirect
 	gorm.io/plugin/dbresolver v1.5.0 // indirect

+ 47 - 14
go.sum

@@ -1,4 +1,9 @@
+github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
+github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
+github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
+github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
@@ -7,6 +12,8 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt
 github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
 github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
 github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
 github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
 github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
@@ -34,26 +41,50 @@ github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOj
 github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
 github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
 github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
+github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
+github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
-golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
-golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
-golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
+go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
+go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
+golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
+golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
+golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
+golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c h1:jWdr7cHgl8c/ua5vYbR2WhSp+NQmzhsj0xoY3foTzW8=
 gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c/go.mod h1:SH2K9R+2RMjuX1CkCONrPwoe9JzVv2hkQvEu4bXGojE=
 gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
-gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
-gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
+gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
+gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
 gorm.io/driver/postgres v1.4.5 h1:mTeXTTtHAgnS9PgmhN2YeUbazYpLhUI1doLnw42XUZc=
 gorm.io/driver/postgres v1.4.5/go.mod h1:GKNQYSJ14qvWkvPwXljMGehpKrhlDNsqYRr5HnYGncg=
 gorm.io/driver/sqlite v1.1.6/go.mod h1:W8LmC/6UvVbHKah0+QOC7Ja66EaZXHwUTjgXY8YNWX8=
@@ -68,9 +99,11 @@ gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
 gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
 gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
 gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
-gorm.io/gorm v1.25.9 h1:wct0gxZIELDk8+ZqF/MVnHLkA1rvYlBWUMv2EdsK1g8=
-gorm.io/gorm v1.25.9/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
+gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
 gorm.io/hints v1.1.0 h1:Lp4z3rxREufSdxn4qmkK3TLDltrM10FLTHiuqwDPvXw=
 gorm.io/hints v1.1.0/go.mod h1:lKQ0JjySsPBj3uslFzY3JhYDtqEwzm+G1hv8rWujB6Y=
 gorm.io/plugin/dbresolver v1.5.0 h1:XVHLxh775eP0CqVh3vcfJtYqja3uFl5Wr3cKlY8jgDY=
 gorm.io/plugin/dbresolver v1.5.0/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
+jollia.cn/jolib/jokode v0.8.8 h1:ff86eQb3r25kAjPAO36SPuGLnuLb7Tufzv5rNPcX8fM=
+jollia.cn/jolib/jokode v0.8.8/go.mod h1:uihUtfL4MHHyIss+gLtS1m/k+VC5K/WzIKRPCqZGovM=

+ 13 - 69
main.go

@@ -1,83 +1,27 @@
 package main
 
 import (
-	"fmt"
-	"gorm.io/driver/mysql"
-	"gorm.io/gen"
-	"gorm.io/gorm"
-	"gorm.io/gorm/logger"
-	"strings"
+	"db2code/services"
+	"jollia.cn/jolib/jokode"
+	"jollia.cn/jolib/jokode/log"
 )
 
-type Config struct {
-	DbAddr   string `json:"dbAddr,omitempty"`
-	DbSchema string `json:"dbSchema,omitempty"`
-	DbUser   string `json:"dbUser,omitempty"`
-	DbPwd    string `json:"dbPwd,omitempty"`
-}
-
 func main() {
-	fmt.Println("db2code started ....")
-	defer fmt.Println("db2code stopped ....")
-
-	cfg := &Config{
-		DbAddr:   "158.8.12.102:3308",
-		DbSchema: "ticket-cloud",
-		DbUser:   "root",
-		DbPwd:    "ticket@2025",
+	svr := &services.GenService{}
+	if err := log.InitLogger("log/gen.log"); err != nil {
+		panic(err)
 	}
 
-	db := initDb(cfg)
-	genStructs(db)
-}
+	log.Warnf("service %s starting", svr.GetName())
+	defer log.Warnf("service %s stopped", svr.GetName())
 
-func initDb(cfg *Config) *gorm.DB {
-	if cfg == nil {
-		panic("can not init db wih nil config")
+	if err := jokode.RegService(svr); err != nil {
+		panic(err)
 	}
 
-	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
-		cfg.DbUser,
-		cfg.DbPwd,
-		cfg.DbAddr,
-		cfg.DbSchema)
-
-	if db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
-		Logger: logger.Default.LogMode(logger.Info),
-	}); err != nil {
-		panic(fmt.Sprintf("try connect to db fail, dsn: '%s', error info: %v",
-			dsn, err))
-	} else {
-		return db
+	if err := jokode.RunServices(); err != nil {
+		panic(err)
 	}
-}
-
-func genStructs(db *gorm.DB) {
-	g := gen.NewGenerator(gen.Config{
-		OutPath:           "po",
-		WithUnitTest:      false,
-		FieldNullable:     true,
-		FieldCoverable:    true,
-		FieldSignable:     false,
-		FieldWithIndexTag: true,
-		FieldWithTypeTag:  true,
-		Mode:              gen.WithDefaultQuery | gen.WithQueryInterface,
-	})
-
-	g.WithDataTypeMap(map[string]func(columnType gorm.ColumnType) (dataType string){
-		"tinyint": func(filedType gorm.ColumnType) string {
-			if ct, ok := filedType.ColumnType(); ok {
-				if strings.HasPrefix(strings.ToLower(ct), "tinyint(1)") {
-					return "int8"
-				}
-				return "int16"
-			} else {
-				return "int32"
-			}
-		},
-	})
 
-	g.UseDB(db)
-	g.GenerateAllTable()
-	g.Execute()
+	jokode.WaitServices()
 }

+ 77 - 0
services/config.go

@@ -0,0 +1,77 @@
+package services
+
+import (
+	"errors"
+	"flag"
+)
+
+type DbConfig struct {
+	Host   string `json:"host,omitempty" yaml:"host,omitempty"`
+	Port   int    `json:"port,omitempty" yaml:"port,omitempty"`
+	Schema string `json:"schema,omitempty" yaml:"schema,omitempty"`
+	User   string `json:"user,omitempty" yaml:"user,omitempty"`
+	Pwd    string `json:"pwd,omitempty" yaml:"pwd,omitempty"`
+}
+
+const (
+	defCfgFilePath = "conf/db.yaml"
+)
+
+var (
+	dbConfigInstance *DbConfig
+	cfgFilePath      string
+)
+
+func init() {
+	dbConfigInstance = &DbConfig{}
+	flag.StringVar(&dbConfigInstance.Host, "h", "", "database host")
+	flag.IntVar(&dbConfigInstance.Port, "p", 0, "database port")
+	flag.StringVar(&dbConfigInstance.Schema, "s", "", "database schema")
+	flag.StringVar(&dbConfigInstance.User, "u", "", "database user")
+	flag.StringVar(&dbConfigInstance.Pwd, "P", "", "database password")
+	flag.StringVar(&cfgFilePath, "c", "", "database config file path")
+}
+
+func (cfg *DbConfig) IsZero() bool {
+	if cfg == nil {
+		return true
+	}
+
+	if cfg.Host != "" ||
+		cfg.Port != 0 ||
+		cfg.Schema != "" ||
+		cfg.User != "" ||
+		cfg.Pwd != "" {
+		return false
+	}
+
+	return true
+}
+
+func (cfg *DbConfig) FixDefaultValues() error {
+	if cfg == nil {
+		return errors.New("can not fix values of nil object")
+	}
+
+	if cfg.Schema == "" {
+		return errors.New("can not fix default values with empty database schema")
+	}
+
+	if cfg.Pwd == "" {
+		return errors.New("can not fix default values with empty database password")
+	}
+
+	if cfg.Host == "" {
+		cfg.Host = "localhost"
+	}
+
+	if cfg.Port == 0 {
+		cfg.Port = 3306
+	}
+
+	if cfg.User == "" {
+		cfg.User = "root"
+	}
+
+	return nil
+}

+ 105 - 0
services/gen_service.go

@@ -0,0 +1,105 @@
+package services
+
+import (
+	"flag"
+	"fmt"
+	"github.com/pkg/errors"
+	"gorm.io/driver/mysql"
+	"gorm.io/gen"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+	"strings"
+)
+
+type GenService struct {
+	dbInstance *gorm.DB
+}
+
+func (s *GenService) Init() error {
+	if !flag.Parsed() {
+		flag.Parse()
+	}
+
+	if dbConfigInstance.IsZero() {
+
+	}
+
+	return nil
+}
+
+func (s *GenService) Start() error {
+	if s.dbInstance == nil {
+		return errors.New("try start gen service with nil database instance")
+	}
+
+	g := gen.NewGenerator(gen.Config{
+		OutPath:           "po",
+		OutFile:           "po",
+		ModelPkgPath:      "po",
+		WithUnitTest:      false,
+		FieldNullable:     true,
+		FieldCoverable:    true,
+		FieldSignable:     true,
+		FieldWithIndexTag: true,
+		FieldWithTypeTag:  true,
+		Mode:              gen.WithDefaultQuery | gen.WithQueryInterface,
+	})
+
+	g.WithDataTypeMap(map[string]func(columnType gorm.ColumnType) (dataType string){
+		"tinyint": func(filedType gorm.ColumnType) string {
+			if ct, ok := filedType.ColumnType(); ok {
+				if strings.HasPrefix(strings.ToLower(ct), "tinyint(1)") {
+					return "int8"
+				}
+				return "int16"
+			} else {
+				return "int32"
+			}
+		},
+	})
+
+	g.UseDB(s.dbInstance)
+	g.GenerateAllTable()
+	g.Execute()
+
+	return nil
+}
+
+func (s *GenService) Stop() {
+	// do nothing
+}
+
+func (s *GenService) GetName() string {
+	return "GenService"
+}
+
+func (s *GenService) GetInitOrder() int {
+	return 0
+}
+
+func (s *GenService) initDatabase(dbCfg *DbConfig) error {
+	if dbCfg == nil {
+		return errors.New("can not init database with nil db config")
+	}
+
+	if err := dbCfg.FixDefaultValues(); err != nil {
+		return errors.Wrap(err, "try fix default values of database config fail")
+	}
+
+	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
+		dbCfg.User,
+		dbCfg.Pwd,
+		dbCfg.Host,
+		dbCfg.Port,
+		dbCfg.Schema)
+
+	if db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
+		Logger: logger.Default.LogMode(logger.Info),
+	}); err != nil {
+		return errors.Wrapf(err, "try open database with dsn '%s' fail", dsn)
+	} else {
+		s.dbInstance = db
+	}
+
+	return nil
+}