123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package sqlmodel
- import (
- "bytes"
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
- "strings"
- "text/template"
- "zero/core/stringx"
- "zero/tools/goctl/api/spec"
- "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
- }
|