diff --git a/tools/goctl/model/sql/example/generator.sh b/tools/goctl/model/sql/example/generator.sh new file mode 100644 index 000000000..52f37a1d9 --- /dev/null +++ b/tools/goctl/model/sql/example/generator.sh @@ -0,0 +1,2 @@ +#!/bin/bash +go run . \ No newline at end of file diff --git a/tools/goctl/model/sql/example/main.go b/tools/goctl/model/sql/example/main.go new file mode 100644 index 000000000..541e7b1bb --- /dev/null +++ b/tools/goctl/model/sql/example/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "github.com/tal-tech/go-zero/core/lang" + "github.com/tal-tech/go-zero/tools/goctl/model/sql/gen" +) + +// go run . +func main() { + // generating with cache + withCacheGenerator := gen.NewDefaultGenerator("./test.sql", "./withcachemodel") + lang.Must(withCacheGenerator.Start(true)) + + // generating without cache + withoutGenerator := gen.NewDefaultGenerator("./test.sql", "./withoutcachemodel") + lang.Must(withoutGenerator.Start(false)) +} diff --git a/tools/goctl/model/sql/test/test.sql b/tools/goctl/model/sql/example/test.sql similarity index 83% rename from tools/goctl/model/sql/test/test.sql rename to tools/goctl/model/sql/example/test.sql index 9b96bfee9..28027de4a 100644 --- a/tools/goctl/model/sql/test/test.sql +++ b/tools/goctl/model/sql/example/test.sql @@ -7,8 +7,8 @@ CREATE TABLE `user_snake` ( `mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机号', `gender` char(5) COLLATE utf8mb4_general_ci NOT NULL COMMENT '男|女|未公开', `nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户昵称', - `create_time` timestamp NULL DEFAULT NULL, - `update_time` timestamp NULL DEFAULT NULL, + `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `name_index` (`name`), KEY `mobile_index` (`mobile`) @@ -22,8 +22,8 @@ CREATE TABLE `userCamel` ( `mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机号', `gender` char(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '男|女|未公开', `nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户昵称', - `createTime` timestamp NULL DEFAULT NULL, - `updateTime` timestamp NULL DEFAULT NULL, + `createTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `updateTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `nameIndex` (`name`), KEY `mobile_index` (`mobile`) diff --git a/tools/goctl/model/sql/example/withcachemodel/error.go b/tools/goctl/model/sql/example/withcachemodel/error.go new file mode 100755 index 000000000..beec9969e --- /dev/null +++ b/tools/goctl/model/sql/example/withcachemodel/error.go @@ -0,0 +1,7 @@ +package model + +import "github.com/tal-tech/go-zero/core/stores/sqlx" + +var ( + ErrNotFound = sqlx.ErrNotFound +) diff --git a/tools/goctl/model/sql/test/modelwithcache/testmodel.go b/tools/goctl/model/sql/example/withcachemodel/usercamelmodel.go old mode 100644 new mode 100755 similarity index 84% rename from tools/goctl/model/sql/test/modelwithcache/testmodel.go rename to tools/goctl/model/sql/example/withcachemodel/usercamelmodel.go index 09f34df68..faff972e3 --- a/tools/goctl/model/sql/test/modelwithcache/testmodel.go +++ b/tools/goctl/model/sql/example/withcachemodel/usercamelmodel.go @@ -19,11 +19,9 @@ var ( userCamelRowsExpectAutoSet = strings.Join(stringx.Remove(userCamelFieldNames, "create_time", "update_time"), ",") userCamelRowsWithPlaceHolder = strings.Join(stringx.Remove(userCamelFieldNames, "id", "create_time", "update_time"), "=?,") + "=?" - cacheuserCamelIdPrefix = "cache#userCamel#id#" - cacheuserCamelNamePrefix = "cache#userCamel#name#" - cacheuserCamelMobilePrefix = "cache#userCamel#mobile#" - - ErrNotFound = sqlx.ErrNotFound + cacheUserCamelIdPrefix = "cache#UserCamel#id#" + cacheUserCamelNamePrefix = "cache#UserCamel#name#" + cacheUserCamelMobilePrefix = "cache#UserCamel#mobile#" ) type ( @@ -58,7 +56,7 @@ func (m *UserCamelModel) Insert(data UserCamel) error { } func (m *UserCamelModel) FindOne(id int64) (*UserCamel, error) { - userCamelIdKey := fmt.Sprintf("cache#userCamel#id#%v", id) + userCamelIdKey := fmt.Sprintf("%s%v", cacheUserCamelIdPrefix, id) var resp UserCamel err := m.QueryRow(&resp, userCamelIdKey, func(conn sqlx.SqlConn, v interface{}) error { query := `select ` + userCamelRows + ` from ` + m.table + ` where id = ? limit 1` @@ -75,10 +73,10 @@ func (m *UserCamelModel) FindOne(id int64) (*UserCamel, error) { } func (m *UserCamelModel) FindOneByName(name string) (*UserCamel, error) { - userCamelNameKey := fmt.Sprintf("cache#userCamel#name#%v", name) + userCamelNameKey := fmt.Sprintf("%s%v", cacheUserCamelNamePrefix, name) var resp UserCamel err := m.QueryRowIndex(&resp, userCamelNameKey, func(primary interface{}) string { - return fmt.Sprintf("%s%v", cacheuserCamelIdPrefix, primary) + return fmt.Sprintf("%s%v", cacheUserCamelIdPrefix, primary) }, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { query := `select ` + userCamelRows + ` from ` + m.table + ` where name = ? limit 1` if err := conn.QueryRow(&resp, query, name); err != nil { @@ -100,10 +98,10 @@ func (m *UserCamelModel) FindOneByName(name string) (*UserCamel, error) { } func (m *UserCamelModel) FindOneByMobile(mobile string) (*UserCamel, error) { - userCamelMobileKey := fmt.Sprintf("cache#userCamel#mobile#%v", mobile) + userCamelMobileKey := fmt.Sprintf("%s%v", cacheUserCamelMobilePrefix, mobile) var resp UserCamel err := m.QueryRowIndex(&resp, userCamelMobileKey, func(primary interface{}) string { - return fmt.Sprintf("%s%v", cacheuserCamelIdPrefix, primary) + return fmt.Sprintf("%s%v", cacheUserCamelIdPrefix, primary) }, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { query := `select ` + userCamelRows + ` from ` + m.table + ` where mobile = ? limit 1` if err := conn.QueryRow(&resp, query, mobile); err != nil { @@ -125,7 +123,7 @@ func (m *UserCamelModel) FindOneByMobile(mobile string) (*UserCamel, error) { } func (m *UserCamelModel) Update(data UserCamel) error { - userCamelIdKey := fmt.Sprintf("cache#userCamel#id#%v", data.Id) + userCamelIdKey := fmt.Sprintf("%s%v", cacheUserCamelIdPrefix, data.Id) _, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := `update ` + m.table + ` set ` + userCamelRowsWithPlaceHolder + ` where id = ?` return conn.Exec(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id) @@ -138,9 +136,9 @@ func (m *UserCamelModel) Delete(id int64) error { if err != nil { return err } - userCamelIdKey := fmt.Sprintf("cache#userCamel#id#%v", id) - userCamelNameKey := fmt.Sprintf("cache#userCamel#name#%v", data.Name) - userCamelMobileKey := fmt.Sprintf("cache#userCamel#mobile#%v", data.Mobile) + userCamelIdKey := fmt.Sprintf("%s%v", cacheUserCamelIdPrefix, id) + userCamelNameKey := fmt.Sprintf("%s%v", cacheUserCamelNamePrefix, data.Name) + userCamelMobileKey := fmt.Sprintf("%s%v", cacheUserCamelMobilePrefix, data.Mobile) _, err = m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := `delete from ` + m.table + ` where id = ?` return conn.Exec(query, id) diff --git a/tools/goctl/model/sql/example/withcachemodel/usersnakemodel.go b/tools/goctl/model/sql/example/withcachemodel/usersnakemodel.go new file mode 100755 index 000000000..e3ffca5d3 --- /dev/null +++ b/tools/goctl/model/sql/example/withcachemodel/usersnakemodel.go @@ -0,0 +1,147 @@ +package model + +import ( + "database/sql" + "fmt" + "strings" + "time" + + "github.com/tal-tech/go-zero/core/stores/cache" + "github.com/tal-tech/go-zero/core/stores/sqlc" + "github.com/tal-tech/go-zero/core/stores/sqlx" + "github.com/tal-tech/go-zero/core/stringx" + "github.com/tal-tech/go-zero/tools/goctl/model/sql/builderx" +) + +var ( + userSnakeFieldNames = builderx.FieldNames(&UserSnake{}) + userSnakeRows = strings.Join(userSnakeFieldNames, ",") + userSnakeRowsExpectAutoSet = strings.Join(stringx.Remove(userSnakeFieldNames, "id", "create_time", "update_time"), ",") + userSnakeRowsWithPlaceHolder = strings.Join(stringx.Remove(userSnakeFieldNames, "id", "create_time", "update_time"), "=?,") + "=?" + + cacheUserSnakeIdPrefix = "cache#UserSnake#id#" + cacheUserSnakeNamePrefix = "cache#UserSnake#name#" + cacheUserSnakeMobilePrefix = "cache#UserSnake#mobile#" +) + +type ( + UserSnakeModel struct { + sqlc.CachedConn + table string + } + + UserSnake struct { + Id int64 `db:"id"` + Name string `db:"name"` // 用户名称 + Password string `db:"password"` // 用户密码 + Mobile string `db:"mobile"` // 手机号 + Gender string `db:"gender"` // 男|女|未公开 + Nickname string `db:"nickname"` // 用户昵称 + CreateTime time.Time `db:"create_time"` + UpdateTime time.Time `db:"update_time"` + } +) + +func NewUserSnakeModel(conn sqlx.SqlConn, c cache.CacheConf, table string) *UserSnakeModel { + return &UserSnakeModel{ + CachedConn: sqlc.NewConn(conn, c), + table: table, + } +} + +func (m *UserSnakeModel) Insert(data UserSnake) error { + query := `insert into ` + m.table + `(` + userSnakeRowsExpectAutoSet + `) value (?, ?, ?, ?, ?)` + _, err := m.ExecNoCache(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname) + return err +} + +func (m *UserSnakeModel) FindOne(id int64) (*UserSnake, error) { + userSnakeIdKey := fmt.Sprintf("%s%v", cacheUserSnakeIdPrefix, id) + var resp UserSnake + err := m.QueryRow(&resp, userSnakeIdKey, func(conn sqlx.SqlConn, v interface{}) error { + query := `select ` + userSnakeRows + ` from ` + m.table + ` where id = ? limit 1` + return conn.QueryRow(v, query, id) + }) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserSnakeModel) FindOneByName(name string) (*UserSnake, error) { + userSnakeNameKey := fmt.Sprintf("%s%v", cacheUserSnakeNamePrefix, name) + var resp UserSnake + err := m.QueryRowIndex(&resp, userSnakeNameKey, func(primary interface{}) string { + return fmt.Sprintf("%s%v", cacheUserSnakeIdPrefix, primary) + }, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { + query := `select ` + userSnakeRows + ` from ` + m.table + ` where name = ? limit 1` + if err := conn.QueryRow(&resp, query, name); err != nil { + return nil, err + } + return resp.Id, nil + }, func(conn sqlx.SqlConn, v, primary interface{}) error { + query := `select ` + userSnakeRows + ` from ` + m.table + ` where id = ? limit 1` + return conn.QueryRow(v, query, primary) + }) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserSnakeModel) FindOneByMobile(mobile string) (*UserSnake, error) { + userSnakeMobileKey := fmt.Sprintf("%s%v", cacheUserSnakeMobilePrefix, mobile) + var resp UserSnake + err := m.QueryRowIndex(&resp, userSnakeMobileKey, func(primary interface{}) string { + return fmt.Sprintf("%s%v", cacheUserSnakeIdPrefix, primary) + }, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { + query := `select ` + userSnakeRows + ` from ` + m.table + ` where mobile = ? limit 1` + if err := conn.QueryRow(&resp, query, mobile); err != nil { + return nil, err + } + return resp.Id, nil + }, func(conn sqlx.SqlConn, v, primary interface{}) error { + query := `select ` + userSnakeRows + ` from ` + m.table + ` where id = ? limit 1` + return conn.QueryRow(v, query, primary) + }) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserSnakeModel) Update(data UserSnake) error { + userSnakeIdKey := fmt.Sprintf("%s%v", cacheUserSnakeIdPrefix, data.Id) + _, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { + query := `update ` + m.table + ` set ` + userSnakeRowsWithPlaceHolder + ` where id = ?` + return conn.Exec(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id) + }, userSnakeIdKey) + return err +} + +func (m *UserSnakeModel) Delete(id int64) error { + data, err := m.FindOne(id) + if err != nil { + return err + } + userSnakeIdKey := fmt.Sprintf("%s%v", cacheUserSnakeIdPrefix, id) + userSnakeNameKey := fmt.Sprintf("%s%v", cacheUserSnakeNamePrefix, data.Name) + userSnakeMobileKey := fmt.Sprintf("%s%v", cacheUserSnakeMobilePrefix, data.Mobile) + _, err = m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { + query := `delete from ` + m.table + ` where id = ?` + return conn.Exec(query, id) + }, userSnakeMobileKey, userSnakeIdKey, userSnakeNameKey) + return err +} diff --git a/tools/goctl/model/sql/example/withoutcachemodel/error.go b/tools/goctl/model/sql/example/withoutcachemodel/error.go new file mode 100755 index 000000000..beec9969e --- /dev/null +++ b/tools/goctl/model/sql/example/withoutcachemodel/error.go @@ -0,0 +1,7 @@ +package model + +import "github.com/tal-tech/go-zero/core/stores/sqlx" + +var ( + ErrNotFound = sqlx.ErrNotFound +) diff --git a/tools/goctl/model/sql/example/withoutcachemodel/usercamelmodel.go b/tools/goctl/model/sql/example/withoutcachemodel/usercamelmodel.go new file mode 100755 index 000000000..79c7ec450 --- /dev/null +++ b/tools/goctl/model/sql/example/withoutcachemodel/usercamelmodel.go @@ -0,0 +1,104 @@ +package model + +import ( + "strings" + "time" + + "github.com/tal-tech/go-zero/core/stores/cache" + "github.com/tal-tech/go-zero/core/stores/sqlc" + "github.com/tal-tech/go-zero/core/stores/sqlx" + "github.com/tal-tech/go-zero/core/stringx" + "github.com/tal-tech/go-zero/tools/goctl/model/sql/builderx" +) + +var ( + userCamelFieldNames = builderx.FieldNames(&UserCamel{}) + userCamelRows = strings.Join(userCamelFieldNames, ",") + userCamelRowsExpectAutoSet = strings.Join(stringx.Remove(userCamelFieldNames, "create_time", "update_time"), ",") + userCamelRowsWithPlaceHolder = strings.Join(stringx.Remove(userCamelFieldNames, "id", "create_time", "update_time"), "=?,") + "=?" +) + +type ( + UserCamelModel struct { + sqlc.CachedConn + table string + } + + UserCamel struct { + Id int64 `db:"id"` + Name string `db:"name"` // 用户名称 + Password string `db:"password"` // 用户密码 + Mobile string `db:"mobile"` // 手机号 + Gender string `db:"gender"` // 男|女|未公开 + Nickname string `db:"nickname"` // 用户昵称 + CreateTime time.Time `db:"createTime"` + UpdateTime time.Time `db:"updateTime"` + } +) + +func NewUserCamelModel(conn sqlx.SqlConn, c cache.CacheConf, table string) *UserCamelModel { + return &UserCamelModel{ + CachedConn: sqlc.NewConn(conn, c), + table: table, + } +} + +func (m *UserCamelModel) Insert(data UserCamel) error { + query := `insert into ` + m.table + `(` + userCamelRowsExpectAutoSet + `) value (?, ?, ?, ?, ?, ?)` + _, err := m.ExecNoCache(query, data.Id, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname) + return err +} + +func (m *UserCamelModel) FindOne(id int64) (*UserCamel, error) { + query := `select ` + userCamelRows + ` from ` + m.table + ` where id = ? limit 1` + var resp UserCamel + err := m.QueryRowNoCache(&resp, query, id) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserCamelModel) FindOneByName(name string) (*UserCamel, error) { + var resp UserCamel + query := `select ` + userCamelRows + ` from ` + m.table + ` where name limit 1` + err := m.QueryRowNoCache(&resp, query, name) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserCamelModel) FindOneByMobile(mobile string) (*UserCamel, error) { + var resp UserCamel + query := `select ` + userCamelRows + ` from ` + m.table + ` where mobile limit 1` + err := m.QueryRowNoCache(&resp, query, mobile) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserCamelModel) Update(data UserCamel) error { + query := `update ` + m.table + ` set ` + userCamelRowsWithPlaceHolder + ` where id = ?` + _, err := m.ExecNoCache(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id) + return err +} + +func (m *UserCamelModel) Delete(id int64) error { + query := `delete from ` + m.table + ` where id = ?` + _, err := m.ExecNoCache(query, id) + return err +} diff --git a/tools/goctl/model/sql/example/withoutcachemodel/usersnakemodel.go b/tools/goctl/model/sql/example/withoutcachemodel/usersnakemodel.go new file mode 100755 index 000000000..da764ef29 --- /dev/null +++ b/tools/goctl/model/sql/example/withoutcachemodel/usersnakemodel.go @@ -0,0 +1,104 @@ +package model + +import ( + "strings" + "time" + + "github.com/tal-tech/go-zero/core/stores/cache" + "github.com/tal-tech/go-zero/core/stores/sqlc" + "github.com/tal-tech/go-zero/core/stores/sqlx" + "github.com/tal-tech/go-zero/core/stringx" + "github.com/tal-tech/go-zero/tools/goctl/model/sql/builderx" +) + +var ( + userSnakeFieldNames = builderx.FieldNames(&UserSnake{}) + userSnakeRows = strings.Join(userSnakeFieldNames, ",") + userSnakeRowsExpectAutoSet = strings.Join(stringx.Remove(userSnakeFieldNames, "id", "create_time", "update_time"), ",") + userSnakeRowsWithPlaceHolder = strings.Join(stringx.Remove(userSnakeFieldNames, "id", "create_time", "update_time"), "=?,") + "=?" +) + +type ( + UserSnakeModel struct { + sqlc.CachedConn + table string + } + + UserSnake struct { + Id int64 `db:"id"` + Name string `db:"name"` // 用户名称 + Password string `db:"password"` // 用户密码 + Mobile string `db:"mobile"` // 手机号 + Gender string `db:"gender"` // 男|女|未公开 + Nickname string `db:"nickname"` // 用户昵称 + CreateTime time.Time `db:"create_time"` + UpdateTime time.Time `db:"update_time"` + } +) + +func NewUserSnakeModel(conn sqlx.SqlConn, c cache.CacheConf, table string) *UserSnakeModel { + return &UserSnakeModel{ + CachedConn: sqlc.NewConn(conn, c), + table: table, + } +} + +func (m *UserSnakeModel) Insert(data UserSnake) error { + query := `insert into ` + m.table + `(` + userSnakeRowsExpectAutoSet + `) value (?, ?, ?, ?, ?)` + _, err := m.ExecNoCache(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname) + return err +} + +func (m *UserSnakeModel) FindOne(id int64) (*UserSnake, error) { + query := `select ` + userSnakeRows + ` from ` + m.table + ` where id = ? limit 1` + var resp UserSnake + err := m.QueryRowNoCache(&resp, query, id) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserSnakeModel) FindOneByName(name string) (*UserSnake, error) { + var resp UserSnake + query := `select ` + userSnakeRows + ` from ` + m.table + ` where name limit 1` + err := m.QueryRowNoCache(&resp, query, name) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserSnakeModel) FindOneByMobile(mobile string) (*UserSnake, error) { + var resp UserSnake + query := `select ` + userSnakeRows + ` from ` + m.table + ` where mobile limit 1` + err := m.QueryRowNoCache(&resp, query, mobile) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *UserSnakeModel) Update(data UserSnake) error { + query := `update ` + m.table + ` set ` + userSnakeRowsWithPlaceHolder + ` where id = ?` + _, err := m.ExecNoCache(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id) + return err +} + +func (m *UserSnakeModel) Delete(id int64) error { + query := `delete from ` + m.table + ` where id = ?` + _, err := m.ExecNoCache(query, id) + return err +} diff --git a/tools/goctl/model/sql/gen/delete.go b/tools/goctl/model/sql/gen/delete.go index 84f60ef02..71abbd798 100644 --- a/tools/goctl/model/sql/gen/delete.go +++ b/tools/goctl/model/sql/gen/delete.go @@ -15,8 +15,7 @@ func genDelete(table Table, withCache bool) (string, error) { for fieldName, key := range table.CacheKey { if fieldName == table.PrimaryKey.Name.Source() { keySet.AddStr(key.KeyExpression) - } - if fieldName != table.PrimaryKey.Name.Source() { + } else { keySet.AddStr(key.DataKeyExpression) } keyVariableSet.AddStr(key.Variable) diff --git a/tools/goctl/model/sql/gen/gen.go b/tools/goctl/model/sql/gen/gen.go index c25631e77..13be8491d 100644 --- a/tools/goctl/model/sql/gen/gen.go +++ b/tools/goctl/model/sql/gen/gen.go @@ -8,8 +8,9 @@ import ( "strings" "github.com/tal-tech/go-zero/tools/goctl/model/sql/parser" - sqltemplate "github.com/tal-tech/go-zero/tools/goctl/model/sql/template" + "github.com/tal-tech/go-zero/tools/goctl/model/sql/template" "github.com/tal-tech/go-zero/tools/goctl/util" + "github.com/tal-tech/go-zero/tools/goctl/util/console" "github.com/tal-tech/go-zero/tools/goctl/util/stringx" "github.com/tal-tech/go-zero/tools/goctl/util/templatex" ) @@ -24,17 +25,40 @@ type ( source string src string dir string + console.Console } + Option func(generator *defaultGenerator) ) -func NewDefaultGenerator(src, dir string) *defaultGenerator { +func NewDefaultGenerator(src, dir string, opt ...Option) *defaultGenerator { if src == "" { src = pwd } if dir == "" { dir = pwd } - return &defaultGenerator{src: src, dir: dir} + generator := &defaultGenerator{src: src, dir: dir} + var optionList []Option + optionList = append(optionList, newDefaultOption()) + optionList = append(optionList, opt...) + for _, fn := range optionList { + fn(generator) + } + return generator +} + +func WithConsoleOption(idea bool) Option { + return func(generator *defaultGenerator) { + if idea { + generator.Console = console.NewIdeaConsole() + } + } +} + +func newDefaultOption() Option { + return func(generator *defaultGenerator) { + generator.Console = console.NewColorConsole() + } } func (g *defaultGenerator) Start(withCache bool) error { @@ -61,12 +85,28 @@ func (g *defaultGenerator) Start(withCache bool) error { } for tableName, code := range modelList { - filename := filepath.Join(dirAbs, fmt.Sprintf("%smodel.go", stringx.From(tableName).Lower())) + name := fmt.Sprintf("%smodel.go", strings.ToLower(stringx.From(tableName).Snake2Camel())) + filename := filepath.Join(dirAbs, name) + if util.FileExists(filename) { + g.Warning("%s already exists", name) + continue + } err = ioutil.WriteFile(filename, []byte(code), os.ModePerm) if err != nil { return err } } + // generate error file + filename := filepath.Join(dirAbs, "error.go") + if util.FileExists(filename) { + g.Warning("error.go already exists") + } else { + err = ioutil.WriteFile(filename, []byte(template.Error), os.ModePerm) + if err != nil { + return err + } + } + g.Success("Done.") return nil } @@ -97,7 +137,7 @@ type ( func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, error) { t := templatex.With("model"). - Parse(sqltemplate.Model). + Parse(template.Model). GoFmt(true) m, err := genCacheKeys(in) @@ -112,7 +152,7 @@ func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, er table.Table = in table.CacheKey = m - varsCode, err := genVars(table) + varsCode, err := genVars(table, withCache) if err != nil { return "", err } diff --git a/tools/goctl/model/sql/gen/keys.go b/tools/goctl/model/sql/gen/keys.go index bc5ba855d..3b058ce02 100644 --- a/tools/goctl/model/sql/gen/keys.go +++ b/tools/goctl/model/sql/gen/keys.go @@ -34,17 +34,17 @@ func genCacheKeys(table parser.Table) (map[string]Key, error) { } camelFieldName := field.Name.Snake2Camel() lowerStartCamelFieldName := stringx.From(camelFieldName).LowerStart() - left := fmt.Sprintf("cache%s%sPrefix", lowerStartCamelTableName, camelFieldName) - right := fmt.Sprintf("cache#%s#%s#", lowerStartCamelTableName, lowerStartCamelFieldName) + left := fmt.Sprintf("cache%s%sPrefix", camelTableName, camelFieldName) + right := fmt.Sprintf("cache#%s#%s#", camelTableName, lowerStartCamelFieldName) variable := fmt.Sprintf("%s%sKey", lowerStartCamelTableName, camelFieldName) m[field.Name.Source()] = Key{ VarExpression: fmt.Sprintf(`%s = "%s"`, left, right), Left: left, Right: right, Variable: variable, - KeyExpression: fmt.Sprintf(`%s := fmt.Sprintf("cache#%s#%s#%s", %s)`, variable, lowerStartCamelTableName, lowerStartCamelFieldName, "%v", lowerStartCamelFieldName), - DataKeyExpression: fmt.Sprintf(`%s := fmt.Sprintf("cache#%s#%s#%s", data.%s)`, variable, lowerStartCamelTableName, lowerStartCamelFieldName, "%v", camelFieldName), - RespKeyExpression: fmt.Sprintf(`%s := fmt.Sprintf("cache#%s#%s#%s", resp.%s)`, variable, lowerStartCamelTableName, lowerStartCamelFieldName, "%v", camelFieldName), + KeyExpression: fmt.Sprintf(`%s := fmt.Sprintf("%s%s", %s,%s)`, variable, "%s", "%v", left, lowerStartCamelFieldName), + DataKeyExpression: fmt.Sprintf(`%s := fmt.Sprintf("%s%s",%s, data.%s)`, variable, "%s", "%v", left, camelFieldName), + RespKeyExpression: fmt.Sprintf(`%s := fmt.Sprintf("%s%s", %s,resp.%s)`, variable, "%s", "%v", left, camelFieldName), } } return m, nil diff --git a/tools/goctl/model/sql/gen/vars.go b/tools/goctl/model/sql/gen/vars.go index df157c0cd..d2d009433 100644 --- a/tools/goctl/model/sql/gen/vars.go +++ b/tools/goctl/model/sql/gen/vars.go @@ -8,7 +8,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/util/templatex" ) -func genVars(table Table) (string, error) { +func genVars(table Table, withCache bool) (string, error) { keys := make([]string, 0) for _, v := range table.CacheKey { keys = append(keys, v.VarExpression) @@ -23,6 +23,7 @@ func genVars(table Table) (string, error) { "cacheKeys": strings.Join(keys, "\r\n"), "autoIncrement": table.PrimaryKey.AutoIncrement, "originalPrimaryKey": table.PrimaryKey.Name.Source(), + "withCache": withCache, }) if err != nil { return "", err diff --git a/tools/goctl/model/sql/template/find.go b/tools/goctl/model/sql/template/find.go index e67692055..0665502aa 100644 --- a/tools/goctl/model/sql/template/find.go +++ b/tools/goctl/model/sql/template/find.go @@ -65,5 +65,6 @@ func (m *{{.upperStartCamelObject}}Model) FindOneBy{{.upperField}}({{.in}}) (*{{ return nil, ErrNotFound default: return nil, err - }{{end}} + } +}{{end}} ` diff --git a/tools/goctl/model/sql/template/import.go b/tools/goctl/model/sql/template/import.go index 96491ad05..1559a3ca5 100644 --- a/tools/goctl/model/sql/template/import.go +++ b/tools/goctl/model/sql/template/import.go @@ -2,9 +2,9 @@ package template var Imports = ` import ( - "database/sql"{{if .withCache}} - "fmt" - {{end}}"strings" + {{if .withCache}}"database/sql" + "fmt"{{end}} + "strings" "time" "github.com/tal-tech/go-zero/core/stores/cache" diff --git a/tools/goctl/model/sql/template/vars.go b/tools/goctl/model/sql/template/vars.go index e2bfc9960..9d0da1b89 100644 --- a/tools/goctl/model/sql/template/vars.go +++ b/tools/goctl/model/sql/template/vars.go @@ -7,8 +7,6 @@ var ( {{.lowerStartCamelObject}}RowsExpectAutoSet = strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}",{{end}} "create_time", "update_time"), ",") {{.lowerStartCamelObject}}RowsWithPlaceHolder = strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", "create_time", "update_time"), "=?,") + "=?" - {{.cacheKeys}} - - ErrNotFound = sqlx.ErrNotFound + {{if .withCache}}{{.cacheKeys}}{{end}} ) ` diff --git a/tools/goctl/model/sql/test/sql_test.go b/tools/goctl/model/sql/test/sql_test.go deleted file mode 100644 index 4611003a1..000000000 --- a/tools/goctl/model/sql/test/sql_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/tal-tech/go-zero/tools/goctl/model/sql/gen" -) - -func TestGenSqlWithCache(t *testing.T) { - generator := gen.NewDefaultGenerator("./test.sql", "./modelwithcache") - err := generator.Start(true) - assert.Nil(t, err) -} - -func TestGenSqlWithoutCache(t *testing.T) { - generator := gen.NewDefaultGenerator("./test.sql", "./modelwithoutcache") - err := generator.Start(false) - assert.Nil(t, err) -} diff --git a/tools/goctl/util/console/console.go b/tools/goctl/util/console/console.go new file mode 100644 index 000000000..946c65743 --- /dev/null +++ b/tools/goctl/util/console/console.go @@ -0,0 +1,58 @@ +package console + +import ( + "fmt" + + "github.com/logrusorgru/aurora" +) + +type ( + Console interface { + Success(format string, a ...interface{}) + Warning(format string, a ...interface{}) + Error(format string, a ...interface{}) + } + colorConsole struct { + } + // for idea log + ideaConsole struct { + } +) + +func NewColorConsole() *colorConsole { + return &colorConsole{} +} + +func (c *colorConsole) Success(format string, a ...interface{}) { + msg := fmt.Sprintf(format, a...) + fmt.Println(aurora.Green(msg)) +} + +func (c *colorConsole) Warning(format string, a ...interface{}) { + msg := fmt.Sprintf(format, a...) + fmt.Println(aurora.Yellow(msg)) +} + +func (c *colorConsole) Error(format string, a ...interface{}) { + msg := fmt.Sprintf(format, a...) + fmt.Println(aurora.Red(msg)) +} + +func NewIdeaConsole() *ideaConsole { + return &ideaConsole{} +} + +func (i *ideaConsole) Success(format string, a ...interface{}) { + msg := fmt.Sprintf(format, a...) + fmt.Println("[SUCCESS]: ", msg) +} + +func (i *ideaConsole) Warning(format string, a ...interface{}) { + msg := fmt.Sprintf(format, a...) + fmt.Println("[WARNING]: ", msg) +} + +func (i *ideaConsole) Error(format string, a ...interface{}) { + msg := fmt.Sprintf(format, a...) + fmt.Println("[ERROR]: ", msg) +}