diff --git a/tools/goctl/model/mongomodel/gen/genmethod.go b/tools/goctl/model/mongomodel/gen/genmethod.go deleted file mode 100644 index 219bc7ce..00000000 --- a/tools/goctl/model/mongomodel/gen/genmethod.go +++ /dev/null @@ -1,33 +0,0 @@ -package gen - -import ( - "strings" - - "github.com/tal-tech/go-zero/tools/goctl/model/mongomodel/utils" -) - -func genMethodTemplate(funcDesc FunctionDesc, needCache bool) (template string) { - var tmp string - switch funcDesc.Type { - case functionTypeGet: - if needCache { - tmp = getTemplate - } else { - tmp = noCacheGetTemplate - } - case functionTypeFind: - tmp = findTemplate - case functionTypeSet: - if needCache { - tmp = "" - } else { - tmp = noCacheSetFieldtemplate - } - default: - return "" - } - tmp = strings.ReplaceAll(tmp, "{{.Name}}", funcDesc.FieldName) - tmp = strings.ReplaceAll(tmp, "{{.name}}", utils.UpperCamelToLower(funcDesc.FieldName)) - tmp = strings.ReplaceAll(tmp, "{{.type}}", funcDesc.FieldType) - return tmp -} diff --git a/tools/goctl/model/mongomodel/gen/genmongomodel.go b/tools/goctl/model/mongomodel/gen/genmongomodel.go deleted file mode 100644 index e7de5f37..00000000 --- a/tools/goctl/model/mongomodel/gen/genmongomodel.go +++ /dev/null @@ -1,156 +0,0 @@ -package gen - -import ( - "fmt" - "strings" - "text/template" - - "github.com/tal-tech/go-zero/tools/goctl/api/spec" - "github.com/tal-tech/go-zero/tools/goctl/api/util" - "github.com/tal-tech/go-zero/tools/goctl/model/mongomodel/utils" -) - -const ( - functionTypeGet = "get" //GetByField return single model - functionTypeFind = "find" // findByField return many model - functionTypeSet = "set" // SetField only set specified field - - TagOperate = "o" //字段函数的tag - TagComment = "c" //字段注释的tag -) - -type ( - FunctionDesc struct { - Type string // get,find,set - FieldName string // 字段名字 eg:Age - FieldType string // 字段类型 eg: string,int64 等 - } -) - -func GenMongoModel(goFilePath string, needCache bool) error { - structs, imports, err := utils.ParseGoFile(goFilePath) - if err != nil { - return err - } - if len(structs) != 1 { - return fmt.Errorf("only 1 struct should be provided") - } - structStr, err := genStructs(structs) - if err != nil { - return err - } - - fp, err := util.ClearAndOpenFile(goFilePath) - if err != nil { - return err - } - defer fp.Close() - - var myTemplate string - if needCache { - myTemplate = cacheTemplate - } else { - myTemplate = noCacheTemplate - } - structName := getStructName(structs) - functionList := getFunctionList(structs) - - for _, fun := range functionList { - funTmp := genMethodTemplate(fun, needCache) - if funTmp == "" { - continue - } - myTemplate += "\n" - myTemplate += funTmp - myTemplate += "\n" - } - - t := template.Must(template.New("mongoTemplate").Parse(myTemplate)) - return t.Execute(fp, map[string]string{ - "modelName": structName, - "importArray": getImports(imports, needCache), - "modelFields": structStr, - }) -} - -func getFunctionList(structs []utils.Struct) []FunctionDesc { - var list []FunctionDesc - for _, field := range structs[0].Fields { - tagMap := parseTag(field.Tag) - if fun, ok := tagMap[TagOperate]; ok { - funList := strings.Split(fun, ",") - for _, o := range funList { - var f FunctionDesc - f.FieldType = field.Type - f.FieldName = field.Name - f.Type = o - list = append(list, f) - } - } - } - return list -} - -func getStructName(structs []utils.Struct) string { - for _, structItem := range structs { - return structItem.Name - } - return "" -} - -func genStructs(structs []utils.Struct) (string, error) { - if len(structs) > 1 { - return "", fmt.Errorf("input .go file must only one struct") - } - - modelFields := `Id bson.ObjectId ` + quotationMark + `bson:"_id" json:"id,omitempty"` + quotationMark + "\n\t" - for _, structItem := range structs { - for _, field := range structItem.Fields { - modelFields += getFieldLine(field) - } - } - modelFields += "\t" + `CreateTime time.Time ` + quotationMark + `json:"createTime,omitempty" bson:"createTime"` + quotationMark + "\n\t" - modelFields += "\t" + `UpdateTime time.Time ` + quotationMark + `json:"updateTime,omitempty" bson:"updateTime"` + quotationMark - return modelFields, nil -} - -func getFieldLine(member spec.Member) string { - if member.Name == "CreateTime" || member.Name == "UpdateTime" || member.Name == "Id" { - return "" - } - jsonName := utils.UpperCamelToLower(member.Name) - result := "\t" + member.Name + ` ` + member.Type + ` ` + quotationMark + `json:"` + jsonName + `,omitempty"` + ` bson:"` + jsonName + `"` + quotationMark - tagMap := parseTag(member.Tag) - if comment, ok := tagMap[TagComment]; ok { - result += ` //` + comment + "\n\t" - } else { - result += "\n\t" - } - return result -} - -// tag like `o:"find,get,update" c:"姓名"` -func parseTag(tag string) map[string]string { - var result = make(map[string]string, 0) - tags := strings.Split(tag, " ") - for _, kv := range tags { - temp := strings.Split(kv, ":") - if len(temp) > 1 { - key := strings.ReplaceAll(strings.ReplaceAll(temp[0], "\"", ""), "`", "") - value := strings.ReplaceAll(strings.ReplaceAll(temp[1], "\"", ""), "`", "") - result[key] = value - } - } - return result -} - -func getImports(imports []string, needCache bool) string { - - importStr := strings.Join(imports, "\n\t") - importStr += "\"errors\"\n\t" - importStr += "\"time\"\n\t" - importStr += "\n\t\"github.com/tal-tech/go-zero/core/stores/cache\"\n\t" - importStr += "\"github.com/tal-tech/go-zero/core/stores/mongoc\"\n\t" - importStr += "\n\t\"github.com/globalsign/mgo/bson\"" - return importStr -} diff --git a/tools/goctl/model/mongomodel/gen/genmongomodelbynetwork.go b/tools/goctl/model/mongomodel/gen/genmongomodelbynetwork.go deleted file mode 100644 index af64fb5c..00000000 --- a/tools/goctl/model/mongomodel/gen/genmongomodelbynetwork.go +++ /dev/null @@ -1,67 +0,0 @@ -package gen - -import ( - "bytes" - "errors" - "fmt" - "strings" - "text/template" - - "github.com/tal-tech/go-zero/tools/goctl/model/mongomodel/utils" -) - -func GenMongoModelByNetwork(input string, needCache bool) (string, error) { - if strings.TrimSpace(input) == "" { - return "", errors.New("struct不能为空") - } - if strings.Index(strings.TrimSpace(input), "type") != 0 { - input = "type " + input - } - - if strings.Index(strings.TrimSpace(input), "package") != 0 { - input = "package model\r\n" + input - } - - structs, imports, err := utils.ParseGoFileByNetwork(input) - if err != nil { - return "", err - } - if len(structs) != 1 { - return "", fmt.Errorf("only 1 struct should be provided") - } - structStr, err := genStructs(structs) - if err != nil { - return "", err - } - - var myTemplate string - if needCache { - myTemplate = cacheTemplate - } else { - myTemplate = noCacheTemplate - } - structName := getStructName(structs) - functionList := getFunctionList(structs) - - for _, fun := range functionList { - funTmp := genMethodTemplate(fun, needCache) - if funTmp == "" { - continue - } - myTemplate += "\n" - myTemplate += funTmp - myTemplate += "\n" - } - - t := template.Must(template.New("mongoTemplate").Parse(myTemplate)) - var result bytes.Buffer - err = t.Execute(&result, map[string]string{ - "modelName": structName, - "importArray": getImports(imports, needCache), - "modelFields": structStr, - }) - if err != nil { - return "", err - } - return result.String(), nil -} diff --git a/tools/goctl/model/mongomodel/gen/templatemodel.go b/tools/goctl/model/mongomodel/gen/templatemodel.go deleted file mode 100644 index 3b597baa..00000000 --- a/tools/goctl/model/mongomodel/gen/templatemodel.go +++ /dev/null @@ -1,238 +0,0 @@ -package gen - -const ( - quotationMark = "`" - // templates that do not use caching - noCacheTemplate = `package model - -import ( - {{.importArray}} -) - -var ErrNotFound = mongoc.ErrNotFound - -type ( - {{.modelName}}Model struct { - *mongoc.Model - } - - {{.modelName}} struct { - {{.modelFields}} - } -) - -func New{{.modelName}}Model(url, database, collection string, c cache.CacheConf, opts ...cache.Option) *{{.modelName}}Model { - return &{{.modelName}}Model{mongoc.MustNewModel(url, database, collection, c, opts...)} -} - -func (m *{{.modelName}}Model) FindOne(id string) (*{{.modelName}}, error) { - session, err := m.Model.TakeSession() - if err != nil { - return nil, err - } - defer m.Model.PutSession(session) - - var result {{.modelName}} - err = m.GetCollection(session).FindOneIdNoCache(&result,bson.ObjectIdHex(id)) - if err != nil { - return nil, err - } - return &result, nil -} - -func (m *{{.modelName}}Model) Delete(id string) error { - session, err := m.TakeSession() - if err != nil { - return err - } - defer m.PutSession(session) - return m.GetCollection(session).RemoveIdNoCache(bson.ObjectIdHex(id)) -} - -func (m *{{.modelName}}Model) Insert(data *{{.modelName}}) error { - session, err := m.TakeSession() - if err != nil { - return err - } - defer m.PutSession(session) - - return m.GetCollection(session).Insert(data) -} - -func (m *{{.modelName}}Model) Update(data *{{.modelName}}) error { - session, err := m.TakeSession() - if err != nil { - return err - } - defer m.PutSession(session) - - data.UpdateTime = time.Now() - return m.GetCollection(session).UpdateIdNoCache(data.Id, data) -} -` - - //use cache template - cacheTemplate = `package model - -import ( - {{.importArray}} -) - -var ErrNotFound = errors.New("not found") - -const ( - Prefix{{.modelName}}CacheKey = "#{{.modelName}}#cache" //todo please modify this prefix -) - -type ( - {{.modelName}}Model struct { - *mongoc.Model - } - - {{.modelName}} struct { - {{.modelFields}} - } -) - -func New{{.modelName}}Model(url, database, collection string, c cache.CacheConf, opts ...cache.Option) *{{.modelName}}Model { - return &{{.modelName}}Model{mongoc.MustNewModel(url, database, collection, c, opts...)} -} - -func (m *{{.modelName}}Model) FindOne(id string) (*{{.modelName}}, error) { - key := Prefix{{.modelName}}CacheKey + id - session, err := m.Model.TakeSession() - if err != nil { - return nil, err - } - defer m.Model.PutSession(session) - - var result {{.modelName}} - err = m.GetCollection(session).FindOneId(&result, key, bson.ObjectIdHex(id)) - switch err { - case nil: - return &result, nil - case mongoc.ErrNotFound: - return nil, ErrNotFound - default: - return nil, err - } -} - -func (m *{{.modelName}}Model) Delete(id string) error { - session, err := m.TakeSession() - if err != nil { - return err - } - defer m.PutSession(session) - - key := Prefix{{.modelName}}CacheKey + id - return m.GetCollection(session).RemoveId(bson.ObjectIdHex(id), key) -} - -func (m *{{.modelName}}Model) Insert(data *{{.modelName}}) error { - session, err := m.TakeSession() - if err != nil { - return err - } - defer m.PutSession(session) - - return m.GetCollection(session).Insert(data) -} - -func (m *{{.modelName}}Model) Update(data *{{.modelName}}) error { - session, err := m.TakeSession() - if err != nil { - return err - } - defer m.PutSession(session) - - data.UpdateTime = time.Now() - key := Prefix{{.modelName}}CacheKey + data.Id.Hex() - return m.GetCollection(session).UpdateId(data.Id, data, key) -} -` - cacheSetFieldtemplate = `func (m *{{.modelName}}Model) Set{{.Name}}(id string, {{.name}} {{.type}}) error { - _, err := m.cache.Del(Prefix{{.modelName}}CacheKey + id) - if err != nil { - return err - } - - session, err := m.TakeSession() - if err != nil { - return err - } - defer m.PutSession(session) - - update := bson.M{"$set": bson.M{"{{.name}}": {{.name}}, "updateTime": time.Now()}} - return m.GetCollection(session).UpdateId(bson.ObjectIdHex(id), update) -}` - - noCacheSetFieldtemplate = `func (m *{{.modelName}}Model) Set{{.Name}}(id string, {{.name}} {{.type}}) error { - session, err := m.TakeSession() - if err != nil { - return err - } - defer m.PutSession(session) - - update := bson.M{"$set": bson.M{"{{.name}}": {{.name}}, "updateTime": time.Now()}} - return m.GetCollection(session).UpdateId(bson.ObjectIdHex(id), update) -}` - - noCacheGetTemplate = `func (m *{{.modelName}}Model) GetBy{{.Name}}({{.name}} {{.type}}) (*{{.modelName}},error) { - session, err := m.TakeSession() - if err != nil { - return nil,err - } - defer m.PutSession(session) - var result {{.modelName}} - query := bson.M{"{{.name}}":{{.name}}} - err = m.GetCollection(session).FindOneNoCache(&result, query) - if err != nil { - if err == mgo.ErrNotFound { - return nil,ErrNotFound - } - return nil,err - } - return &result,nil -}` - // GetByField return single model - getTemplate = `func (m *{{.modelName}}Model) GetBy{{.Name}}({{.name}} {{.type}}) (*{{.modelName}},error) { - session, err := m.TakeSession() - if err != nil { - return nil,err - } - defer m.PutSession(session) - var result {{.modelName}} - query := bson.M{"{{.name}}":{{.name}}} - key := getCachePrimaryKeyBy{{.Name}}({{.name}}) - err = m.GetCollection(session).FindOne(&result,key,query) - if err != nil { - if err == mgo.ErrNotFound { - return nil,ErrNotFound - } - return nil,err - } - return &result,nil -} - -func getCachePrimaryKeyBy{{.Name}}({{.name}} {{.type}}) string { - return "" //todo 请补全这里 -} -` - - findTemplate = `func (m *{{.modelName}}Model) FindBy{{.Name}}({{.name}} string) ([]{{.modelName}},error) { - session, err := m.TakeSession() - if err != nil { - return nil,err - } - defer m.PutSession(session) - - query := bson.M{"{{.name}}":{{.name}}} - var result []{{.modelName}} - err = m.GetCollection(session).FindAllNoCache(&result,query) - if err != nil { - return nil,err - } - return result,nil -}` -) diff --git a/tools/goctl/model/mongomodel/genmongocmd.go b/tools/goctl/model/mongomodel/genmongocmd.go deleted file mode 100644 index 2d15eeec..00000000 --- a/tools/goctl/model/mongomodel/genmongocmd.go +++ /dev/null @@ -1,29 +0,0 @@ -package mongomodel - -import ( - "errors" - "fmt" - - "github.com/logrusorgru/aurora" - "github.com/tal-tech/go-zero/core/lang" - "github.com/tal-tech/go-zero/tools/goctl/model/mongomodel/gen" - "github.com/urfave/cli" -) - -func ModelCommond(c *cli.Context) error { - src := c.String("src") - cache := c.String("cache") - - if len(src) == 0 { - return errors.New("missing -src") - } - var needCache bool - if cache == "yes" { - needCache = true - } - - lang.Must(gen.GenMongoModel(src, needCache)) - - fmt.Println(aurora.Green("Done.")) - return nil -} diff --git a/tools/goctl/model/mongomodel/utils/parsesimplegofile.go b/tools/goctl/model/mongomodel/utils/parsesimplegofile.go deleted file mode 100644 index 8b1a73d8..00000000 --- a/tools/goctl/model/mongomodel/utils/parsesimplegofile.go +++ /dev/null @@ -1,167 +0,0 @@ -package utils - -import ( - "fmt" - "go/ast" - "go/parser" - "go/token" - "io/ioutil" - "strings" - - "github.com/tal-tech/go-zero/tools/goctl/api/spec" -) - -const ( - StructArr = "struct" - ImportArr = "import" - Unknown = "unknown" -) - -type Struct struct { - Name string - Fields []spec.Member -} - -func readFile(filePath string) (string, error) { - b, err := ioutil.ReadFile(filePath) - if err != nil { - return "", err - } - return string(b), nil -} - -func ParseNetworkGoFile(io string) ([]Struct, []string, error) { - fset := token.NewFileSet() // 位置是相对于节点 - - f, err := parser.ParseFile(fset, "", io, 0) - if err != nil { - return nil, nil, err - } - return parse(f) -} - -func ParseGoFile(pathOrStr string) ([]Struct, []string, error) { - var goFileStr string - var err error - goFileStr, err = readFile(pathOrStr) - if err != nil { - return nil, nil, err - } - - fset := token.NewFileSet() // 位置是相对于节点 - - f, err := parser.ParseFile(fset, "", goFileStr, 0) - if err != nil { - return nil, nil, err - } - return parse(f) -} - -func ParseGoFileByNetwork(io string) ([]Struct, []string, error) { - fset := token.NewFileSet() // 位置是相对于节点 - - f, err := parser.ParseFile(fset, "", io, 0) - if err != nil { - return nil, nil, err - } - return parse(f) -} - -//使用ast包解析golang文件 -func parse(f *ast.File) ([]Struct, []string, error) { - if len(f.Decls) == 0 { - return nil, nil, fmt.Errorf("you should provide as least 1 struct") - } - var structList []Struct - var importList []string - for _, decl := range f.Decls { - structs, imports, err := getStructAndImportInfo(decl) - if err != nil { - return nil, nil, err - } - structList = append(structList, structs...) - importList = append(importList, imports...) - } - return structList, importList, nil -} - -func getStructAndImportInfo(decl ast.Decl) (structs []Struct, imports []string, err error) { - var structList []Struct - var importList []string - genDecl, ok := decl.(*ast.GenDecl) - if !ok { - return nil, nil, fmt.Errorf("please input right file") - } - for _, tpyObj := range genDecl.Specs { - switch tpyObj.(type) { - case *ast.ImportSpec: // import - importSpec := tpyObj.(*ast.ImportSpec) - s := importSpec.Path.Value - importList = append(importList, s) - case *ast.TypeSpec: //type - typeSpec := tpyObj.(*ast.TypeSpec) - switch typeSpec.Type.(type) { - case *ast.StructType: // struct - struct1, err := parseStruct(typeSpec) - if err != nil { - return nil, nil, err - } - structList = append(structList, *struct1) - } - default: - - } - } - return structList, importList, nil -} - -func parseStruct(typeSpec *ast.TypeSpec) (*Struct, error) { - var result Struct - structName := typeSpec.Name.Name - result.Name = structName - structType, ok := typeSpec.Type.(*ast.StructType) - if !ok { - return nil, fmt.Errorf("not struct") - } - - for _, item := range structType.Fields.List { - var member spec.Member - var err error - member.Name = parseFiledName(item.Names) - member.Type, err = parseFiledType(item.Type) - if err != nil { - return nil, err - } - if item.Tag != nil { - member.Tag = item.Tag.Value - } - result.Fields = append(result.Fields, member) - } - return &result, nil -} - -func parseFiledType(expr ast.Expr) (string, error) { - switch expr.(type) { - case *ast.Ident: - return expr.(*ast.Ident).Name, nil - case *ast.SelectorExpr: - selectorExpr := expr.(*ast.SelectorExpr) - return selectorExpr.X.(*ast.Ident).Name + "." + selectorExpr.Sel.Name, nil - default: - return "", fmt.Errorf("can't parse type") - } -} - -func parseFiledName(idents []*ast.Ident) string { - for _, name := range idents { - return name.Name - } - return "" -} - -func UpperCamelToLower(name string) string { - if len(name) == 0 { - return "" - } - return strings.ToLower(name[:1]) + name[1:] -} diff --git a/tools/goctl/model/sqlmodel/deletesql.go b/tools/goctl/model/sqlmodel/deletesql.go deleted file mode 100644 index 087e6799..00000000 --- a/tools/goctl/model/sqlmodel/deletesql.go +++ /dev/null @@ -1,37 +0,0 @@ -package sqlmodel - -import ( - "bytes" - "strings" - "text/template" -) - -var deleteTemplate = ` -func ({{.pointer}} *{{.model}}Model) Delete({{.conditions}}) error { - sql := ` + "`" + `delete from` + " ` + " + `{{.pointer}}.table ` + "+ `" + ` where {{.valueConditions}}` + "`\n" + - ` _, err := {{.pointer}}.conn.Exec(sql, {{.values}}) - return err -} -` - -func (s *structExp) genDelete() (string, error) { - idType := "string" - if s.idAutoIncrement { - idType = "int64" - } - conditionExp, valueConditions := s.buildCondition() - t := template.Must(template.New("deleteTemplate").Parse(deleteTemplate)) - var tmplBytes bytes.Buffer - err := t.Execute(&tmplBytes, map[string]string{ - "pointer": "m", - "model": s.name, - "idType": idType, - "valueConditions": valueConditions, - "conditions": conditionExp, - "values": strings.Join(s.conditionNames(), ", "), - }) - if err != nil { - return "", err - } - return tmplBytes.String(), nil -} diff --git a/tools/goctl/model/sqlmodel/errors.go b/tools/goctl/model/sqlmodel/errors.go deleted file mode 100644 index 80930d66..00000000 --- a/tools/goctl/model/sqlmodel/errors.go +++ /dev/null @@ -1,7 +0,0 @@ -package sqlmodel - -import "errors" - -func sqlError(str string) error { - return errors.New("sql error: " + str) -} diff --git a/tools/goctl/model/sqlmodel/gen.go b/tools/goctl/model/sqlmodel/gen.go deleted file mode 100644 index 8beb9094..00000000 --- a/tools/goctl/model/sqlmodel/gen.go +++ /dev/null @@ -1,46 +0,0 @@ -package sqlmodel - -import ( - "go/format" - - "github.com/tal-tech/go-zero/core/logx" -) - -type ( - Column struct { - DataType string `json:"dataType"` - Name string `json:"name"` - Comment string `json:"comment"` - } - - Table struct { - Name string `json:"table"` - PrimaryKey string `json:"primaryKey"` - Columns []*Column `json:"columns"` - } -) - -func GenMysqlGoModel(req *Table, conditions []string) (string, error) { - resp, err := generateTypeModel(req.Name, req.Columns) - if err != nil { - return "", err - } - resp.PrimaryKey = req.PrimaryKey - s, err := NewStructExp(*resp) - if len(conditions) == 0 { - s.conditions = []string{resp.PrimaryKey} - } else { - s.conditions = conditions - } - if err != nil { - return "", err - } - result, err := s.genMysqlCRUD() - // code format - bts, err := format.Source([]byte(result)) - if err != nil { - logx.Errorf("%+v", err) - return "", err - } - return string(bts), err -} diff --git a/tools/goctl/model/sqlmodel/genmodel.go b/tools/goctl/model/sqlmodel/genmodel.go deleted file mode 100644 index 77eea68b..00000000 --- a/tools/goctl/model/sqlmodel/genmodel.go +++ /dev/null @@ -1,185 +0,0 @@ -package sqlmodel - -import ( - "bytes" - "fmt" - "go/ast" - "go/parser" - "go/token" - "strings" - "text/template" - - "github.com/tal-tech/go-zero/core/stringx" - "github.com/tal-tech/go-zero/tools/goctl/api/spec" - "github.com/tal-tech/go-zero/tools/goctl/util" -) - -var ( - commonTemplate = ` -var ( - {{.modelWithLowerStart}}FieldNames = builderx.FieldNames(&{{.model}}{}) - {{.modelWithLowerStart}}Rows = strings.Join({{.modelWithLowerStart}}FieldNames, ",") - {{.modelWithLowerStart}}RowsExpectAutoSet = strings.Join(stringx.Remove({{.modelWithLowerStart}}FieldNames, {{.expected}}), ",") - {{.modelWithLowerStart}}RowsWithPlaceHolder = strings.Join(stringx.Remove({{.modelWithLowerStart}}FieldNames, {{.expected}}), "=?,") + "=?" -) -` -) - -type ( - fieldExp struct { - name string - tag string - ty string - } - structExp struct { - genStruct GenStruct - name string - idAutoIncrement bool - Fields []fieldExp - primaryKey string - conditions []string - ignoreFields []string - } -) - -func NewStructExp(s GenStruct) (*structExp, error) { - src := s.TableStruct - fset := token.NewFileSet() - file, err := parser.ParseFile(fset, "", src, 0) - - if err != nil { - return nil, err - } - if len(file.Decls) == 0 { - return nil, sqlError("no struct inspect") - } - typeDecl := file.Decls[0].(*ast.GenDecl) - - if len(typeDecl.Specs) == 0 { - return nil, sqlError("no type specs") - } - typeSpec := typeDecl.Specs[0].(*ast.TypeSpec) - structDecl := typeSpec.Type.(*ast.StructType) - - var strExp structExp - strExp.genStruct = s - strExp.primaryKey = s.PrimaryKey - strExp.name = typeSpec.Name.Name - fields := structDecl.Fields.List - for _, field := range fields { - typeExpr := field.Type - - start := typeExpr.Pos() - 1 - end := typeExpr.End() - 1 - - typeInSource := src[start:end] - if len(field.Names) == 0 { - return nil, sqlError("field name empty") - } - var name = field.Names[0].Name - var tag = util.Untitle(name) - if field.Tag != nil { - tag = src[field.Tag.Pos():field.Tag.End()] - } - dbTag := getDBColumnName(tag, name) - strExp.Fields = append(strExp.Fields, fieldExp{ - name: name, - ty: typeInSource, - tag: dbTag, - }) - if dbTag == strExp.primaryKey && typeInSource == "int64" { - strExp.ignoreFields = append(strExp.ignoreFields, dbTag) - strExp.idAutoIncrement = true - } - if name == "UpdateTime" || name == "CreateTime" { - strExp.ignoreFields = append(strExp.ignoreFields, dbTag) - } - } - return &strExp, nil -} - -func (s *structExp) genMysqlCRUD() (string, error) { - commonStr, err := s.genCommon() - if err != nil { - return "", err - } - insertStr, err := s.genInsert() - if err != nil { - return "", err - } - updateStr, err := s.genUpdate() - if err != nil { - return "", err - } - - deleteStr, err := s.genDelete() - if err != nil { - return "", err - } - - queryOneStr, err := s.genQueryOne() - if err != nil { - return "", err - } - - queryListStr, err := s.genQueryList() - if err != nil { - return "", err - } - return strings.Join([]string{"package model \n", commonStr, s.genStruct.TableModel, queryOneStr, queryListStr, deleteStr, insertStr, updateStr}, "\n"), nil -} - -func getDBColumnName(tag, name string) string { - matches := spec.TagRe.FindStringSubmatch(tag) - for i := range matches { - name := spec.TagSubNames[i] - if name == "name" { - return matches[i] - } - } - - return util.Untitle(name) -} - -func (s *structExp) genCommon() (string, error) { - templateName := commonTemplate - t := template.Must(template.New("commonTemplate").Parse(templateName)) - var tmplBytes bytes.Buffer - var ignoreFieldsQuota []string - for _, item := range s.ignoreFields { - ignoreFieldsQuota = append(ignoreFieldsQuota, fmt.Sprintf("\"%s\"", item)) - } - err := t.Execute(&tmplBytes, map[string]string{ - "model": s.name, - "expected": strings.Join(ignoreFieldsQuota, ", "), - "modelWithLowerStart": fmtUnderLine2Camel(s.name, false), - }) - if err != nil { - return "", err - } - return tmplBytes.String(), nil -} - -func (s *structExp) buildCondition() (string, string) { - var conditionExp []string - var valueConditions []string - for _, field := range s.Fields { - if stringx.Contains(s.conditions, strings.ToLower(field.tag)) || - stringx.Contains(s.conditions, strings.ToLower(field.name)) { - conditionExp = append(conditionExp, fmt.Sprintf("%s %s", util.Untitle(field.name), field.ty)) - valueConditions = append(valueConditions, fmt.Sprintf("%s = ?", field.tag)) - } - } - return strings.Join(conditionExp, ", "), strings.Join(valueConditions, " and ") -} - -func (s *structExp) conditionNames() []string { - var conditionExp []string - for _, field := range s.Fields { - if stringx.Contains(s.conditions, strings.ToLower(field.tag)) || - stringx.Contains(s.conditions, strings.ToLower(field.name)) { - conditionExp = append(conditionExp, util.Untitle(field.name)) - } - } - return conditionExp -} diff --git a/tools/goctl/model/sqlmodel/insertsql.go b/tools/goctl/model/sqlmodel/insertsql.go deleted file mode 100644 index 4fcd266e..00000000 --- a/tools/goctl/model/sqlmodel/insertsql.go +++ /dev/null @@ -1,46 +0,0 @@ -package sqlmodel - -import ( - "bytes" - "fmt" - "strings" - "text/template" - - "github.com/tal-tech/go-zero/core/stringx" -) - -var insertTemplate = ` -func ({{.pointer}} *{{.model}}Model) Insert(data {{.model}}) error { - sql := ` + "`" + `insert into` + " ` + " + `{{.pointer}}.table ` + " + `(` + " + "{{.modelWithLowerStart}}RowsExpectAutoSet" + " + `" + `) value ({{.valueHolder}})` + "`\n" + - ` _, err := {{.pointer}}.conn.Exec(sql, {{.values}}) - return err -} -` - -func (s *structExp) genInsert() (string, error) { - var valueHolder []string - var values []string - for _, field := range s.Fields { - if stringx.Contains(s.ignoreFields, field.name) || stringx.Contains(s.ignoreFields, field.tag) { - continue - } - valueHolder = append(valueHolder, "?") - values = append(values, fmt.Sprintf("data.%s", field.name)) - } - - t := template.Must(template.New("insertTemplate").Parse(insertTemplate)) - var tmplBytes bytes.Buffer - var columns = "rowsExpectAutoSet" - err := t.Execute(&tmplBytes, map[string]string{ - "pointer": "m", - "model": s.name, - "columns": columns, - "valueHolder": strings.Join(valueHolder, ","), - "values": strings.Join(values, ", "), - "modelWithLowerStart": fmtUnderLine2Camel(s.name, false), - }) - if err != nil { - return "", err - } - return tmplBytes.String(), nil -} diff --git a/tools/goctl/model/sqlmodel/querysql.go b/tools/goctl/model/sqlmodel/querysql.go deleted file mode 100644 index 1a56d5a0..00000000 --- a/tools/goctl/model/sqlmodel/querysql.go +++ /dev/null @@ -1,75 +0,0 @@ -package sqlmodel - -import ( - "bytes" - "strings" - "text/template" -) - -var queryOneTemplate = ` -func ({{.pointer}} *{{.model}}Model) FindOne({{.conditions}}) (*{{.model}}, error) { - sql :=` + " `" + "select " + "` +" + ` {{.modelWithLowerStart}}Rows + ` + "`" + ` from ` + "` + " + `{{.pointer}}.table +` + " ` " + `where {{.valueConditions}} limit 1` + "`" + ` - var resp {{.model}} - err := {{.pointer}}.conn.QueryRow(&resp, sql, {{.values}}) - if err != nil { - if err == sqlx.ErrNotFound { - return nil, ErrNotFound - } - return nil, err - } - return &resp, nil -} -` - -var queryListTemplate = ` -func ({{.pointer}} *{{.model}}Model) Find({{.conditions}}) ([]{{.model}}, error) { - sql :=` + " `" + "select " + "` +" + ` {{.modelWithLowerStart}}Rows + ` + "`" + ` from ` + "` + " + `{{.pointer}}.table +` + " ` " + `where {{.valueConditions}}` + "`" + ` - var resp []{{.model}} - err := {{.pointer}}.conn.QueryRows(&resp, sql, {{.values}}) - if err != nil { - return nil, err - } - return resp, nil -} -` - -func (s *structExp) genQueryOne() (string, error) { - conditionExp, valueConditions := s.buildCondition() - - t := template.Must(template.New("queryOneTemplate").Parse(queryOneTemplate)) - var tmplBytes bytes.Buffer - err := t.Execute(&tmplBytes, map[string]string{ - "pointer": "m", - "model": s.name, - "conditions": conditionExp, - "valueConditions": valueConditions, - "values": strings.Join(s.conditionNames(), ", "), - "modelWithLowerStart": fmtUnderLine2Camel(s.name, false), - }) - if err != nil { - return "", err - } - return tmplBytes.String(), nil -} - -func (s *structExp) genQueryList() (string, error) { - if len(s.conditions) == 1 && s.conditions[0] == s.primaryKey { - return "", nil - } - conditionExp, valueConditions := s.buildCondition() - - t := template.Must(template.New("queryListTemplate").Parse(queryListTemplate)) - var tmplBytes bytes.Buffer - err := t.Execute(&tmplBytes, map[string]string{ - "pointer": "m", - "model": s.name, - "conditions": conditionExp, - "valueConditions": valueConditions, - "values": strings.Join(s.conditionNames(), ", "), - "modelWithLowerStart": fmtUnderLine2Camel(s.name, false), - }) - if err != nil { - return "", err - } - return tmplBytes.String(), nil -} diff --git a/tools/goctl/model/sqlmodel/table2struct.go b/tools/goctl/model/sqlmodel/table2struct.go deleted file mode 100644 index 89321960..00000000 --- a/tools/goctl/model/sqlmodel/table2struct.go +++ /dev/null @@ -1,208 +0,0 @@ -package sqlmodel - -import ( - "bytes" - "errors" - "fmt" - "strings" - "text/template" - - util2 "github.com/tal-tech/go-zero/tools/modelctl/util" -) - -var ( - commonMysqlDataTypeMap = map[string]string{ - "tinyint": "int64", - "smallint": "int64", - "mediumint": "int64", - "int": "int64", - "integer": "int64", - "bigint": "int64", - "float": "float64", - "double": "float64", - "decimal": "float64", - "date": "time.Time", - "time": "string", - "year": "int64", - "datetime": "time.Time", - "timestamp": "time.Time", - "char": "string", - "varchar": "string", - "tinyblob": "string", - "tinytext": "string", - "blob": "string", - "text": "string", - "mediumblob": "string", - "mediumtext": "string", - "longblob": "string", - "longtext": "string", - } -) - -var modelTemplate = ` -type ( - - {{.ModelCamelWithUpperStart}}Model struct { - table string - conn sqlx.SqlConn - } - - {{.ModelCamelWithUpperStart}} struct { - {{.Fields}} - } -) - -func New{{.ModelCamelWithUpperStart}}Model(table string, conn sqlx.SqlConn) *{{.ModelCamelWithUpperStart}}Model { - return &{{.ModelCamelWithUpperStart}}Model{table: table, conn: conn} -} -` - -const ( - fieldTemplateText = "{{.NameCamelWithUpperStart}} {{.DataType}} `db:\"{{.NameWithUnderline}}\"` {{.Comment}}" -) - -type ( - Template struct { - ModelCamelWithUpperStart string - Fields string - } - - StructField struct { - // 字段名称,下划线 - NameWithUnderline string - // 字段名称,驼峰式,大写开头 - NameCamelWithUpperStart string - // 字段名称,驼峰式,小写开头 - NameCamelWithLowerStart string - // 字段数据类型 - DataType string - // 字段注释 - Comment string - } - - GenStruct struct { - // 表对应的struct - TableStruct string `json:"tableStruct"` - // 表对应生成的model信息,参考模板${modelTemplate} - TableModel string `json:"tableModel"` - // 主键 - PrimaryKey string `json:"primaryKey"` - } -) - -func generateTypeModel(table string, fields []*Column) (*GenStruct, error) { - var resp GenStruct - structString, fieldsString, err := convertStruct(table, fields) - if err != nil { - return nil, err - } - templateStruct := Template{ - ModelCamelWithUpperStart: util2.FmtUnderLine2Camel(table, true), - Fields: fieldsString, - } - tl, err := template.New("").Parse(modelTemplate) - if err != nil { - return nil, err - } - var resultBuffer = bytes.NewBufferString("") - err = tl.Execute(resultBuffer, templateStruct) - if err != nil { - return nil, err - } - resp.TableStruct = structString - resp.TableModel = resultBuffer.String() - return &resp, nil -} - -// returns struct、fields、error -func convertStruct(table string, columns []*Column) (string, string, error) { - var structBuffer, fieldsBuffer bytes.Buffer - structBuffer.WriteString("package model \n\n") - structBuffer.WriteString("type " + fmtUnderLine2Camel(table, true) + " struct {\n") - for index, item := range columns { - goType, ok := commonMysqlDataTypeMap[item.DataType] - if !ok { - return "", "", errors.New(fmt.Sprintf("table: %s,the data type %s of %s does not match", table, item.DataType, item.Name)) - } - out, err := convertField(&StructField{ - NameWithUnderline: item.Name, - NameCamelWithUpperStart: fmtUnderLine2Camel(item.Name, true), - NameCamelWithLowerStart: fmtUnderLine2Camel(item.Name, false), - DataType: goType, - Comment: item.Comment, - }) - if err != nil { - return "", "", err - } - structBuffer.WriteString("\t" + out) - structBuffer.WriteString("\n") - - if index == 0 { - fieldsBuffer.WriteString(out) - } else { - fieldsBuffer.WriteString("\t\t" + out) - } - if index < len(columns)-1 { - fieldsBuffer.WriteString("\n") - } - - } - structBuffer.WriteString("}") - return structBuffer.String(), fieldsBuffer.String(), nil -} - -// column转换成struct field -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 -} - -// 简单的下划线转驼峰格式 -func fmtUnderLine2Camel(in string, upperStart bool) string { - if strings.TrimSpace(in) == "" { - return "" - } - var words []string - if strings.Contains(in, "_") { - words = strings.Split(in, "_") - if len(words) == 0 { - return "" - } - } - if len(words) == 0 { - if !upperStart { - bts := []byte(in) - r := bytes.ToLower([]byte{bts[0]}) - bts[0] = r[0] - return string(bts) - } else { - return strings.Title(in) - } - } - var buffer bytes.Buffer - for index, word := range words { - if strings.TrimSpace(word) == "" { - continue - } - bts := []byte(word) - if index == 0 && !upperStart { - bts[0] = bytes.ToLower([]byte{bts[0]})[0] - buffer.Write(bts) - continue - } - bts = bytes.Title(bts) - buffer.Write(bts) - } - return buffer.String() -} diff --git a/tools/goctl/model/sqlmodel/updatesql.go b/tools/goctl/model/sqlmodel/updatesql.go deleted file mode 100644 index e26a5f44..00000000 --- a/tools/goctl/model/sqlmodel/updatesql.go +++ /dev/null @@ -1,53 +0,0 @@ -package sqlmodel - -import ( - "bytes" - "fmt" - "strings" - "text/template" - - "github.com/tal-tech/go-zero/core/stringx" -) - -var updateTemplate = ` -func ({{.pointer}} *{{.model}}Model) Update(data {{.model}}{{.conditions}}) error { - sql := ` + "`" + `update ` + "` + " + `{{.pointer}}.table` + " + `" + ` set ` + "` +" + ` {{.modelWithLowerStart}}RowsWithPlaceHolder + ` + "` where" + ` {{.valueConditions}}` + "`\n" + - ` _, err := {{.pointer}}.conn.Exec(sql, {{.values}}) - return err -} -` - -func (s *structExp) genUpdate() (string, error) { - var updateValues []string - var conditionsValues []string - for _, field := range s.Fields { - key := fmt.Sprintf("data.%s", field.name) - if stringx.Contains(s.conditions, field.tag) || - stringx.Contains(s.conditions, field.name) { - conditionsValues = append(conditionsValues, key) - } else if !stringx.Contains(s.ignoreFields, field.name) && !stringx.Contains(s.ignoreFields, field.tag) { - updateValues = append(updateValues, key) - } - } - conditionExp, valueConditions := s.buildCondition() - if len(s.conditions) == 1 && s.conditions[0] == s.primaryKey { - conditionExp = "" - } else { - conditionExp = ", " + conditionExp - } - t := template.Must(template.New("updateTemplate").Parse(updateTemplate)) - var tmplBytes bytes.Buffer - err := t.Execute(&tmplBytes, map[string]string{ - "pointer": "m", - "model": s.name, - "values": strings.Join(append(updateValues, conditionsValues...), ", "), - "primaryKey": s.primaryKey, - "valueConditions": valueConditions, - "conditions": conditionExp, - "modelWithLowerStart": fmtUnderLine2Camel(s.name, false), - }) - if err != nil { - return "", err - } - return tmplBytes.String(), nil -}