You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
7.9 KiB
Go
248 lines
7.9 KiB
Go
4 years ago
|
package modelgen
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
"text/template"
|
||
|
|
||
|
"zero/tools/modelctl/model"
|
||
|
"zero/tools/modelctl/util"
|
||
|
)
|
||
|
|
||
|
type (
|
||
|
Query struct {
|
||
|
Rows string
|
||
|
Args string
|
||
|
Values string
|
||
|
}
|
||
|
Update struct {
|
||
|
Rows string
|
||
|
Values string
|
||
|
}
|
||
|
Template struct {
|
||
|
Package string
|
||
|
PrimaryKeyField string
|
||
|
PrimaryKeyFieldCamel string
|
||
|
PrimaryKeyType string
|
||
|
ModelCamelWithLowerStart string
|
||
|
ModelLowerSplitByPound string
|
||
|
ModelCamelWithUpperStart string
|
||
|
Fields string
|
||
|
Abbr string
|
||
|
WithCache bool
|
||
|
Insert Query
|
||
|
// 包含where语句
|
||
|
Update Update
|
||
|
}
|
||
|
|
||
|
StructField struct {
|
||
|
// 字段名称,下划线
|
||
|
NameWithUnderline string
|
||
|
// 字段名称,驼峰式,大写开头
|
||
|
NameCamelWithUpperStart string
|
||
|
// 字段数据类型
|
||
|
DataType string
|
||
|
// 字段注释
|
||
|
Comment string
|
||
|
// 是否为主键
|
||
|
PrimaryKey bool
|
||
|
}
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
fieldTemplateText = "{{.NameCamelWithUpperStart}} {{.DataType}} `db:\"{{.NameWithUnderline}}\" json:\"{{.NameWithUnderline}},omitempty\"` {{.Comment}}"
|
||
|
modelTemplateText = `package {{.Package}}
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"zero/core/stores/redis"
|
||
|
"zero/core/stores/sqlx"
|
||
|
"zero/service/shared/builderx"
|
||
|
"zero/service/shared/cache"
|
||
|
|
||
|
)
|
||
|
var (
|
||
|
{{.ModelCamelWithLowerStart}}QueryRows = strings.Join(builderx.FieldNames(&{{.ModelCamelWithUpperStart}}{}), ",")
|
||
|
{{if .WithCache}}{{.ModelCamelWithLowerStart}}CachePrefix = "xjy#{{.ModelLowerSplitByPound}}#"
|
||
|
{{.ModelCamelWithLowerStart}}Expire = 7 * 24 * 3600{{end}}
|
||
|
)
|
||
|
|
||
|
type (
|
||
|
{{.ModelCamelWithUpperStart}}Model struct {
|
||
|
{{if .WithCache}} *CachedModel{{else}}
|
||
|
table string
|
||
|
conn sqlx.SqlConn{{end}}
|
||
|
}
|
||
|
{{.ModelCamelWithUpperStart}} struct {
|
||
|
{{.Fields}}
|
||
|
}
|
||
|
)
|
||
|
|
||
|
func New{{.ModelCamelWithUpperStart}}Model(table string, conn sqlx.SqlConn{{if .WithCache}}, rds *redis.Redis{{end}}) *{{.ModelCamelWithUpperStart}}Model {
|
||
|
{{if .WithCache}} return &{{.ModelCamelWithUpperStart}}Model{NewCachedModel(conn, table, rds)}
|
||
|
{{else}}return &{{.ModelCamelWithUpperStart}}Model{table:table,conn:conn}{{end}}
|
||
|
}
|
||
|
|
||
|
func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) Insert(data *{{.ModelCamelWithUpperStart}}) error {
|
||
|
querySql:="insert into "+{{.Abbr}}.table+" ({{.Insert.Rows}}) value ({{.Insert.Args}})"
|
||
|
_, err := {{.Abbr}}.conn.Exec(querySql, {{.Insert.Values}})
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) Update(data *{{.ModelCamelWithUpperStart}}) error {
|
||
|
{{if .WithCache}}err := {{.Abbr}}.cleanCache(data.{{.PrimaryKeyField}})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
querySql := "update " + {{.Abbr}}.table + " set {{.Update.Rows}}"
|
||
|
_, err = {{.Abbr}}.conn.Exec(querySql,{{.Update.Values}} )
|
||
|
return err
|
||
|
{{else}}querySql := "update " + {{.Abbr}}.table + " set {{.Update.Rows}}"
|
||
|
_, err := {{.Abbr}}.conn.Exec(querySql,{{.Update.Values}} )
|
||
|
return err{{end}}
|
||
|
}
|
||
|
|
||
|
func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) FindOne({{.PrimaryKeyFieldCamel}} {{.PrimaryKeyType}})(*{{.ModelCamelWithUpperStart}},error){
|
||
|
querySql:="select "+{{.ModelCamelWithLowerStart}}QueryRows+" from "+{{.Abbr}}.table+" where {{.PrimaryKeyFieldCamel}} = ? limit 1"
|
||
|
var resp {{.ModelCamelWithUpperStart}}
|
||
|
{{if .WithCache}}key := cache.FormatKey({{.ModelCamelWithLowerStart}}CachePrefix,{{.PrimaryKeyFieldCamel}})
|
||
|
err := {{.Abbr}}.QueryRow(&resp, key, {{.ModelCamelWithLowerStart}}Expire, func(conn sqlx.Session, v interface{}) error {
|
||
|
return conn.QueryRow(v, querySql, {{.PrimaryKeyFieldCamel}})
|
||
|
})
|
||
|
if err != nil {
|
||
|
if err == sqlx.ErrNotFound {
|
||
|
return nil, ErrNotFound
|
||
|
}
|
||
|
return nil, err
|
||
|
}
|
||
|
{{else}}err := {{.Abbr}}.conn.QueryRow(&resp, querySql, {{.PrimaryKeyFieldCamel}})
|
||
|
if err != nil {
|
||
|
if err == sqlx.ErrNotFound {
|
||
|
return nil, ErrNotFound
|
||
|
}
|
||
|
return nil, err
|
||
|
}{{end}}
|
||
|
return &resp, nil
|
||
|
}
|
||
|
|
||
|
func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) DeleteById({{.PrimaryKeyFieldCamel}} {{.PrimaryKeyType}}) error {
|
||
|
{{if .WithCache}}err := {{.Abbr}}.cleanCache({{.PrimaryKeyFieldCamel}})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
querySql := "delete from " + {{.Abbr}}.table + " where {{.PrimaryKeyFieldCamel}} = ? "
|
||
|
_, err = {{.Abbr}}.conn.Exec(querySql, {{.PrimaryKeyFieldCamel}})
|
||
|
return err
|
||
|
{{else}}querySql := "delete from " + {{.Abbr}}.table + " where {{.PrimaryKeyFieldCamel}} = ? "
|
||
|
_, err := {{.Abbr}}.conn.Exec(querySql, {{.PrimaryKeyFieldCamel}})
|
||
|
return err{{end}}
|
||
|
}
|
||
|
|
||
|
{{if .WithCache}}
|
||
|
func ({{.Abbr}} *{{.ModelCamelWithUpperStart}}Model) cleanCache({{.PrimaryKeyFieldCamel}} {{.PrimaryKeyType}}) error {
|
||
|
key := cache.FormatKey({{.ModelCamelWithLowerStart}}CachePrefix,{{.PrimaryKeyFieldCamel}})
|
||
|
_, err := {{.Abbr}}.rds.Del(key)
|
||
|
return err
|
||
|
}
|
||
|
{{end}}
|
||
|
|
||
|
`
|
||
|
)
|
||
|
|
||
|
func generateModelTemplate(packageName, table string, fileds []*Field) (*Template, error) {
|
||
|
list := make([]*StructField, 0)
|
||
|
var containsPrimaryKey bool
|
||
|
for _, item := range fileds {
|
||
|
goType, ok := model.CommonMysqlDataTypeMap[item.Type]
|
||
|
if !ok {
|
||
|
return nil, errors.New(fmt.Sprintf("table:%v,the data type %v of mysql does not match", table, item.Type))
|
||
|
}
|
||
|
if !containsPrimaryKey {
|
||
|
containsPrimaryKey = item.Primary == "PRI"
|
||
|
}
|
||
|
list = append(list, &StructField{
|
||
|
NameWithUnderline: item.Name,
|
||
|
NameCamelWithUpperStart: util.FmtUnderLine2Camel(item.Name, true),
|
||
|
DataType: goType,
|
||
|
Comment: item.Comment,
|
||
|
PrimaryKey: item.Primary == "PRI",
|
||
|
})
|
||
|
}
|
||
|
if !containsPrimaryKey {
|
||
|
return nil, errors.New(fmt.Sprintf("table:%v,primary key does not exist", table))
|
||
|
}
|
||
|
var structBuffer, insertRowsBuffer, insertArgBuffer, insertValuesBuffer, updateRowsBuffer, updateValuesBuffer bytes.Buffer
|
||
|
var primaryField *StructField
|
||
|
for index, item := range list {
|
||
|
out, err := convertField(item)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
structBuffer.WriteString(out + "\n")
|
||
|
if !item.PrimaryKey {
|
||
|
insertRowsBuffer.WriteString(item.NameWithUnderline)
|
||
|
insertArgBuffer.WriteString("?")
|
||
|
insertValuesBuffer.WriteString("data." + item.NameCamelWithUpperStart)
|
||
|
|
||
|
updateRowsBuffer.WriteString(item.NameWithUnderline + "=?")
|
||
|
updateValuesBuffer.WriteString("data." + item.NameCamelWithUpperStart)
|
||
|
|
||
|
if index < len(list)-1 {
|
||
|
insertRowsBuffer.WriteString(",")
|
||
|
insertArgBuffer.WriteString(",")
|
||
|
insertValuesBuffer.WriteString(",")
|
||
|
|
||
|
updateRowsBuffer.WriteString(",")
|
||
|
}
|
||
|
updateValuesBuffer.WriteString(",")
|
||
|
} else {
|
||
|
primaryField = item
|
||
|
}
|
||
|
}
|
||
|
|
||
|
updateRowsBuffer.WriteString(" where " + primaryField.NameWithUnderline + "=?")
|
||
|
updateValuesBuffer.WriteString(" data." + primaryField.NameCamelWithUpperStart)
|
||
|
modelSplitByPoundArr := strings.Replace(table, "_", "#", -1)
|
||
|
templateStruct := Template{
|
||
|
Package: packageName,
|
||
|
PrimaryKeyField: primaryField.NameCamelWithUpperStart,
|
||
|
PrimaryKeyFieldCamel: primaryField.NameWithUnderline,
|
||
|
PrimaryKeyType: primaryField.DataType,
|
||
|
ModelCamelWithLowerStart: util.FmtUnderLine2Camel(table, false),
|
||
|
ModelLowerSplitByPound: modelSplitByPoundArr,
|
||
|
ModelCamelWithUpperStart: util.FmtUnderLine2Camel(table, true),
|
||
|
Fields: structBuffer.String(),
|
||
|
Abbr: util.Abbr(table) + "m",
|
||
|
Insert: Query{
|
||
|
Rows: insertRowsBuffer.String(),
|
||
|
Args: insertArgBuffer.String(),
|
||
|
Values: insertValuesBuffer.String(),
|
||
|
},
|
||
|
Update: Update{
|
||
|
Rows: updateRowsBuffer.String(),
|
||
|
Values: updateValuesBuffer.String(),
|
||
|
},
|
||
|
}
|
||
|
return &templateStruct, nil
|
||
|
}
|
||
|
|
||
|
func convertField(field *StructField) (string, error) {
|
||
|
if strings.TrimSpace(field.Comment) != "" {
|
||
|
field.Comment = "// " + field.Comment
|
||
|
}
|
||
|
tl, err := template.New("").Parse(fieldTemplateText)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
buf := bytes.NewBufferString("")
|
||
|
err = tl.Execute(buf, field)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
return buf.String(), nil
|
||
|
}
|