-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Khang Ha
committed
Oct 6, 2020
1 parent
eeca5c7
commit 7ab11d3
Showing
19 changed files
with
587 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package database | ||
|
||
import ( | ||
"database/sql" | ||
"time" | ||
|
||
"gorm.io/driver/mysql" | ||
"gorm.io/gorm" | ||
"gorm.io/plugin/dbresolver" | ||
) | ||
|
||
// Errs alias | ||
var ( | ||
ErrRecordNotFound = gorm.ErrRecordNotFound | ||
) | ||
|
||
// DBAdapter interface represent adapter connect to DB | ||
type DBAdapter interface { | ||
Open(string) error | ||
Close() | ||
Begin() DBAdapter | ||
RollbackUselessCommitted() | ||
Commit() | ||
Gormer() *gorm.DB | ||
DB() *sql.DB | ||
} | ||
|
||
type adapter struct { | ||
gormer *gorm.DB | ||
isCommitted bool | ||
} | ||
|
||
// NewDB returns a new instance of DB. | ||
func NewDB() DBAdapter { | ||
return &adapter{} | ||
} | ||
|
||
// Open opens a DB connection. | ||
func (db *adapter) Open(connectionString string) error { | ||
//newLogger := logger.New( | ||
// log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer | ||
// logger.Config{ | ||
// SlowThreshold: time.Second, // Slow SQL threshold | ||
// LogLevel: logger.Info, // Log level | ||
// Colorful: true, // Disable color | ||
// }, | ||
//) | ||
|
||
gormDB, err := gorm.Open(mysql.Open(connectionString), &gorm.Config{}) | ||
if err != nil { | ||
return err | ||
} | ||
db.gormer = gormDB | ||
|
||
gormDB.Use( | ||
dbresolver.Register(dbresolver.Config{ /* xxx */ }). | ||
SetConnMaxIdleTime(time.Hour). | ||
SetConnMaxLifetime(24 * time.Hour). | ||
SetMaxIdleConns(100). | ||
SetMaxOpenConns(200), | ||
) | ||
return nil | ||
} | ||
|
||
// Close closes DB connection. | ||
func (db *adapter) Close() { | ||
_ = db.DB().Close() | ||
} | ||
|
||
// Begin starts a DB transaction. | ||
func (db *adapter) Begin() DBAdapter { | ||
tx := db.gormer.Begin() | ||
return &adapter{ | ||
gormer: tx, | ||
isCommitted: false, | ||
} | ||
} | ||
|
||
// RollbackUselessCommitted rollbacks useless DB transaction committed. | ||
func (db *adapter) RollbackUselessCommitted() { | ||
if !db.isCommitted { | ||
db.gormer.Rollback() | ||
} | ||
} | ||
|
||
// Commit commits a DB transaction. | ||
func (db *adapter) Commit() { | ||
if !db.isCommitted { | ||
db.gormer.Commit() | ||
db.isCommitted = true | ||
} | ||
} | ||
|
||
// Gormer returns an instance of gorm.DB. | ||
func (db *adapter) Gormer() *gorm.DB { | ||
return db.gormer | ||
} | ||
|
||
// DB returns an instance of sql.DB. | ||
func (db *adapter) DB() *sql.DB { | ||
database, _ := db.gormer.DB() | ||
return database | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
database "github.com/khanghldk/gokit/adapters" | ||
"github.com/khanghldk/gokit/configs" | ||
"github.com/khanghldk/gokit/constants" | ||
"github.com/khanghldk/gokit/models" | ||
"github.com/khanghldk/gokit/repositories" | ||
"github.com/khanghldk/gokit/templates" | ||
"github.com/khanghldk/gokit/utils" | ||
"github.com/sirupsen/logrus" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// genModelCmd represents the new command | ||
var genModelsCmd = &cobra.Command{ | ||
Use: "models", | ||
Aliases: []string{"m"}, | ||
Short: "Generate models from database", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
fmt.Print(constants.ColorBlue, "Generate models...\n") | ||
|
||
dir := "models" | ||
|
||
os.Mkdir(dir, os.ModePerm) | ||
|
||
db := database.NewDB() | ||
if err := db.Open(configs.AppConfig.DB.ConnectionString()); err != nil { | ||
logrus.Fatalf("Creating connection to DB: %v", err) | ||
} | ||
|
||
schema := repositories.NewSchema(db) | ||
tables, err := schema.GetTables() | ||
if err != nil { | ||
logrus.Fatalf("error: %v", err) | ||
} | ||
|
||
for i := range tables { | ||
if tables[i] == "migrations" { | ||
continue | ||
} | ||
columns, err := schema.GetColumns(tables[i]) | ||
if err != nil { | ||
logrus.Errorf("Get columns of table %v got error %v", tables[i], err) | ||
} else { | ||
fmt.Println("Creating model", utils.Camel(tables[i], false), "...") | ||
createModel(columns, dir, tables[i]) | ||
} | ||
} | ||
|
||
utils.GoFmt(dir) | ||
fmt.Println("Finish generating models") | ||
}, | ||
} | ||
|
||
func createModel(columns []*models.MySQLColumn, dir, tableName string) { | ||
fileName := fmt.Sprintf("./models/%v.go", utils.Snake(tableName)) | ||
columnsRaw := "" | ||
|
||
for i := 0; i < len(columns); i++ { | ||
column := templates.ColumnTemplate | ||
columnNameCamel := utils.Camel(columns[i].ColumnName, false) | ||
dataType := getDataType(columns[i].ColumnType) | ||
|
||
column = standardizedColumn(column, columnNameCamel, dataType) | ||
columnsRaw += fmt.Sprintf("\n%v", column) | ||
} | ||
|
||
model := strings.ReplaceAll(templates.ModelTemplate, constants.ModelContent, columnsRaw) | ||
model = strings.ReplaceAll(model, constants.ModelNameLower, utils.Camel(tableName, false)) | ||
err := utils.CreateFile(fileName, []byte(model)) | ||
if err != nil { | ||
logrus.Fatal(err) | ||
} | ||
} | ||
|
||
func standardizedColumn(column, columnNameCamel, dataType string) string { | ||
column = strings.ReplaceAll(column, constants.ColumnName, columnNameCamel) | ||
column = strings.ReplaceAll(column, constants.ColumnType, dataType) | ||
return column | ||
} | ||
|
||
func getDataType(sqlType string) string { | ||
if strings.Contains(sqlType, constants.Tinyint) { | ||
return constants.Bool | ||
} | ||
|
||
if strings.Contains(sqlType, constants.Int) || | ||
strings.Contains(sqlType, constants.Bigint) || | ||
strings.Contains(sqlType, constants.Smallint) { | ||
return constants.Int64 | ||
} | ||
|
||
if strings.Contains(sqlType, constants.Varchar) || | ||
strings.Contains(sqlType, constants.Text) || | ||
strings.Contains(sqlType, constants.Longtext) { | ||
return constants.String | ||
} | ||
|
||
if strings.Contains(sqlType, constants.Double) { | ||
return constants.Float64 | ||
} | ||
|
||
if strings.Contains(sqlType, constants.DateTime) || | ||
strings.Contains(sqlType, constants.Timestamp) { | ||
return constants.Time | ||
} | ||
|
||
if strings.Contains(sqlType, constants.Json) { | ||
return constants.JSON | ||
} | ||
|
||
if strings.Contains(sqlType, constants.Enum) { | ||
return "enum" | ||
} | ||
|
||
return "undefined" | ||
} | ||
|
||
func init() { | ||
_, err := configs.New() | ||
if err != nil { | ||
os.Exit(99) | ||
} | ||
|
||
RootCmd.AddCommand(genModelsCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package configs | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/kelseyhightower/envconfig" | ||
) | ||
|
||
// Package constants definition. | ||
const ( | ||
Prefix = "" | ||
) | ||
|
||
// App represents all configuration of qr-service application. | ||
type App struct { | ||
DB MySQL | ||
} | ||
|
||
// MySQL represents configuration of MySQL database. | ||
type MySQL struct { | ||
Username string `default:"root" envconfig:"MYSQL_USER"` | ||
Password string `default:"root" envconfig:"MYSQL_PASS"` | ||
Host string `default:"127.0.0.1" envconfig:"MYSQL_HOST"` | ||
Port int `default:"3306" envconfig:"MYSQL_PORT"` | ||
Database string `default:"evoucher_service" envconfig:"MYSQL_DB"` | ||
} | ||
|
||
// ConnectionString returns connection string of MySQL database. | ||
func (c *MySQL) ConnectionString() string { | ||
format := "%v:%v@tcp(%v:%v)/%v?parseTime=true&charset=utf8" | ||
return fmt.Sprintf(format, c.Username, c.Password, c.Host, c.Port, c.Database) + "&loc=Asia%2FHo_Chi_Minh" | ||
} | ||
|
||
// AppConfig is addition config for gami-service | ||
var AppConfig App | ||
|
||
// New returns a new instance of playground configuration. | ||
func New() (*App, error) { | ||
if err := envconfig.Process(Prefix, &AppConfig); err != nil { | ||
return nil, err | ||
} | ||
return &AppConfig, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package constants | ||
|
||
// Version ... | ||
const Version = "v0.0.6" | ||
const Version = "v0.0.10" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.