github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/gen_method/template.go (about)

     1  package gen_method
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	//"os"
     7  	"strings"
     8  	"text/template"
     9  )
    10  
    11  var golangKeyword = map[string]bool{
    12  	"break":       true,
    13  	"default":     true,
    14  	"func":        true,
    15  	"interface":   true,
    16  	"select":      true,
    17  	"case ":       true,
    18  	"defer":       true,
    19  	"go":          true,
    20  	"map":         true,
    21  	"struct":      true,
    22  	"chan":        true,
    23  	"else":        true,
    24  	"goto":        true,
    25  	"package":     true,
    26  	"switch":      true,
    27  	"const":       true,
    28  	"fallthrough": true,
    29  	"if":          true,
    30  	"range":       true,
    31  	"type":        true,
    32  	"continue":    true,
    33  	"for":         true,
    34  	"import":      true,
    35  	"return":      true,
    36  	"var":         true,
    37  	"nil":         true,
    38  }
    39  
    40  var fileReserveWord = map[string]bool{
    41  	"time": true,
    42  	"git.chinawayltd.com/golib": true,
    43  	"error":                     true,
    44  	"dberr":                     true,
    45  	"logging":                   true,
    46  	"mysql":                     true,
    47  	"gorm":                      true,
    48  	"timelib":                   true,
    49  	"httplib":                   true,
    50  	"db":                        true,
    51  	"id":                        true,
    52  	"err":                       true,
    53  	"int32":                     true,
    54  	"count":                     true,
    55  	"updateMap":                 true,
    56  	"ok":                        true,
    57  }
    58  
    59  var golangSpecialShortUpperWord = map[string]bool{
    60  	"ACL":   true,
    61  	"API":   true,
    62  	"ASCII": true,
    63  	"CPU":   true,
    64  	"CSS":   true,
    65  	"DNS":   true,
    66  	"EOF":   true,
    67  	"GUID":  true,
    68  	"HTML":  true,
    69  	"HTTP":  true,
    70  	"HTTPS": true,
    71  	"ID":    true,
    72  	"IP":    true,
    73  	"JSON":  true,
    74  	"LHS":   true,
    75  	"QPS":   true,
    76  	"RAM":   true,
    77  	"RHS":   true,
    78  	"RPC":   true,
    79  	"SLA":   true,
    80  	"SMTP":  true,
    81  	"SQL":   true,
    82  	"SSH":   true,
    83  	"TCP":   true,
    84  	"TLS":   true,
    85  	"TTL":   true,
    86  	"UDP":   true,
    87  	"UI":    true,
    88  	"UID":   true,
    89  	"UUID":  true,
    90  	"URI":   true,
    91  	"URL":   true,
    92  	"UTF8":  true,
    93  	"VM":    true,
    94  	"XML":   true,
    95  	"XMPP":  true,
    96  	"XSRF":  true,
    97  	"XSS":   true,
    98  }
    99  
   100  func isKeyword(word string) bool {
   101  	return golangKeyword[word] || fileReserveWord[word]
   102  }
   103  
   104  func isShortUpperWord(word string) bool {
   105  	return golangSpecialShortUpperWord[word]
   106  }
   107  
   108  func isUpperLetterString(dstString string) bool {
   109  	for _, letter := range dstString {
   110  		if !isUpperLetter(letter) {
   111  			return false
   112  		}
   113  	}
   114  
   115  	return true
   116  }
   117  
   118  func isUpperLetter(letter rune) bool {
   119  	if letter >= 'A' && letter <= 'Z' {
   120  		return true
   121  	} else {
   122  		return false
   123  	}
   124  }
   125  
   126  func fetchUpLetter(src string) string {
   127  	var dst string
   128  	for _, character := range src {
   129  		if isUpperLetter(character) {
   130  			dst = fmt.Sprintf("%s%c", dst, character)
   131  		}
   132  	}
   133  
   134  	shortLetter := strings.ToLower(dst)
   135  	if isKeyword(shortLetter) {
   136  		shortLetter += "Allen"
   137  	}
   138  
   139  	return shortLetter
   140  }
   141  
   142  func convertFirstLetterToLower(dst string) string {
   143  	if len(dst) > 0 {
   144  		return strings.ToLower(fmt.Sprintf("%c", dst[0])) + dst[1:]
   145  	} else {
   146  		return dst
   147  	}
   148  }
   149  
   150  // HelloGirl -> hello_girl
   151  // niceCar -> nice_car
   152  // TestIDCard->test_id-card
   153  func convertUpLetterToUnderscorePlusLowLetter(src string) string {
   154  	var wordList []string
   155  	var currentWord, tmpWord string
   156  	for i := 0; i < len(src); i++ {
   157  		if isUpperLetter(rune(src[i])) {
   158  			tmpWord = currentWord + fmt.Sprintf("%c", src[i])
   159  			if isUpperLetterString(tmpWord) {
   160  				if isShortUpperWord(tmpWord) {
   161  					wordList = append(wordList, strings.ToLower(tmpWord))
   162  					currentWord = currentWord[len(currentWord):]
   163  				} else {
   164  					currentWord += fmt.Sprintf("%c", src[i])
   165  				}
   166  			} else {
   167  				wordList = append(wordList, strings.ToLower(currentWord))
   168  				currentWord = fmt.Sprintf("%c", src[i])
   169  			}
   170  		} else {
   171  			currentWord += fmt.Sprintf("%c", src[i])
   172  		}
   173  	}
   174  
   175  	if len(currentWord) > 0 {
   176  		wordList = append(wordList, strings.ToLower(currentWord))
   177  	}
   178  
   179  	return strings.Join(wordList, "_")
   180  }
   181  
   182  func genDataAndStore(model *Model, data interface{}, text, tmplName string) error {
   183  	tmpl := template.Must(template.New(tmplName).Parse(text))
   184  
   185  	var tmpBuf []byte
   186  	buf := bytes.NewBuffer(tmpBuf)
   187  	if err := tmpl.Execute(buf, data); err != nil {
   188  		return err
   189  	} else {
   190  		if _, ok := model.FuncMapContent[tmplName]; ok {
   191  			// do nothing
   192  		} else {
   193  			model.FuncMapContent[tmplName] = string(buf.Bytes())
   194  		}
   195  		return nil
   196  	}
   197  }
   198  
   199  type BaseInfoOfGenCode struct {
   200  	PartFuncName   string
   201  	FuncInputParam string
   202  	OrmQueryFormat string
   203  	OrmQueryParam  string
   204  }
   205  
   206  type TableNameTemplateParam struct {
   207  	BaseInfoOfGenCode
   208  	StructName              string
   209  	ReceiverName            string
   210  	PackageName             string
   211  	HasCreateTimeField      bool
   212  	HasUpdateTimeField      bool
   213  	HasEnabledField         bool
   214  	EnabledFieldType        string
   215  	CreateTimeFieldType     string
   216  	UpdateTimeFieldType     string
   217  	DbEnabledField          string
   218  	DbCreateTimeField       string
   219  	DbUpdateTimeField       string
   220  	NeedCreateTableNameFunc bool
   221  	TableNameStr            string
   222  	GlobalPkgPath           string
   223  }
   224  
   225  func genTableNameFunc(model *Model, pkgName, httplibPkgPath string, ignoreCreateTableNameFunc bool) error {
   226  	if strings.Contains(httplibPkgPath, "git.chinawayltd.com/golib") {
   227  		httplibPkgPath = ""
   228  	}
   229  
   230  	data := TableNameTemplateParam{
   231  		StructName:              model.Name,
   232  		ReceiverName:            fetchUpLetter(model.Name),
   233  		PackageName:             pkgName,
   234  		HasEnabledField:         model.HasEnabledField,
   235  		HasCreateTimeField:      model.HasCreateTimeField,
   236  		HasUpdateTimeField:      model.HasUpdateTimeField,
   237  		CreateTimeFieldType:     model.CreateTimeFieldType,
   238  		UpdateTimeFieldType:     model.UpdateTimeFieldType,
   239  		NeedCreateTableNameFunc: ignoreCreateTableNameFunc == false,
   240  		TableNameStr:            "t_" + convertUpLetterToUnderscorePlusLowLetter(model.Name),
   241  		GlobalPkgPath:           httplibPkgPath,
   242  	}
   243  
   244  	return genDataAndStore(model, data, TableNameTemplate, "tableName")
   245  }
   246  
   247  var TableNameTemplate = `package {{.PackageName}} 
   248  import (
   249      {{if .HasCreateTimeField}} 
   250      "time"{{else if .HasUpdateTimeField}}
   251      "time"{{end}}
   252      "reflect"
   253      "strings"
   254  
   255      {{if eq .UpdateTimeFieldType "timelib.MySQLTimestamp"}}
   256      "github.com/artisanhe/tools/timelib"{{else if eq .CreateTimeFieldType "timelib.MySQLTimestamp"}}
   257      "github.com/artisanhe/tools/timelib"{{end}}
   258      "github.com/artisanhe/tools/mysql/dberr"
   259      "github.com/artisanhe/gorm"
   260      "github.com/go-sql-driver/mysql"
   261      "github.com/sirupsen/logrus"
   262      "github.com/artisanhe/tools/courier/enumeration"
   263      "github.com/artisanhe/tools/httplib"
   264      "github.com/artisanhe/tools/duration"
   265  ) 
   266  
   267  type {{.StructName}}List []{{.StructName}}
   268  func init() {
   269      DBTable.Register(&{{.StructName}}{})
   270  }
   271  
   272  {{if .NeedCreateTableNameFunc}} 
   273  func ({{.ReceiverName}} {{.StructName}}) TableName() string {
   274      table_name := "{{.TableNameStr}}"
   275  	if DBTable.Name == "" {
   276  		return table_name
   277  	}
   278  	return DBTable.Name + "." + table_name
   279  }{{end}}
   280  `
   281  
   282  type DbFieldTempalteParam struct {
   283  	StructName            string
   284  	ReceiverName          string
   285  	NewStructFields       []string
   286  	NewStructValue        []string
   287  	NoUniqueIndexFields   []string
   288  	StructFieldAndDBField []string
   289  	DBFieldAndStructField []string
   290  	EnabledFieldType      string
   291  	UpdateTimeFieldType   string
   292  	CreateTimeFieldType   string
   293  	HasEnabledField       bool
   294  	HasUpdateTimeField    bool
   295  	HasCreateTimeField    bool
   296  }
   297  
   298  var DbFiledTemplate = `
   299  type {{.StructName}}DBFieldData struct {
   300      {{range .NewStructFields}} {{.}} 
   301      {{end}}
   302  }
   303  
   304  // FetchNoneUniqueIndexFields without Enabled and CreateTime field.
   305  func ({{.ReceiverName}}dbfd *{{.StructName}}DBFieldData) FetchNoneUniqueIndexFields() []string {
   306      return []string{
   307          {{range .NoUniqueIndexFields}} {{.}}, {{end}}
   308      }
   309  }
   310  
   311  func ({{.ReceiverName}} {{.StructName}}) DBField() *{{.StructName}}DBFieldData {
   312      return &{{.StructName}}DBFieldData {
   313          {{range .NewStructValue}} {{.}},
   314          {{end}}
   315      }
   316  }
   317  
   318  var {{.StructName}}StructFieldAndDBFieldRelate = map[string]string{
   319      {{range .StructFieldAndDBField}} {{.}} 
   320      {{end}}
   321  }
   322  
   323  var {{.StructName}}DBFieldAndStructFieldRelate = map[string]string{
   324      {{range .DBFieldAndStructField}} {{.}} 
   325      {{end}}
   326  }
   327  
   328  // CreateOnDuplicateWithUpdateFields only update the no unique index field, it return error if updateFields contain unique index field.
   329  // It doesn't update the Enabled and CreateTime field.
   330  func ({{.ReceiverName}} *{{.StructName}}) CreateOnDuplicateWithUpdateFields(db *gorm.DB, updateFields []string) error {
   331  	defer duration.PrintDuration(map[string]interface{}{
   332          "request" : "[DB]{{.StructName}}.CreateOnDuplicateWithUpdateFields",
   333  	})()
   334  	if len(updateFields) == 0 {
   335  	    return fmt.Errorf("Must have update fields.")
   336  	}
   337  
   338      noUniqueIndexFields := (&{{.StructName}}DBFieldData{}).FetchNoneUniqueIndexFields()
   339      if len(noUniqueIndexFields) == 0 {
   340          return fmt.Errorf("There are no unique fields.")
   341      }
   342  
   343      var noUniqueIndexFieldsMap = make(map[string]string)
   344      for _, field := range noUniqueIndexFields {
   345          noUniqueIndexFieldsMap[field] = ""
   346      }
   347  
   348      var updateFieldsMap = make(map[string]string)
   349      for _, field := range updateFields {
   350          // have unique field in updateFields
   351          if _, ok := noUniqueIndexFieldsMap[field]; !ok {
   352              return fmt.Errorf("Field[%s] is unique index or wrong field or Enable field", {{.StructName}}DBFieldAndStructFieldRelate[field])
   353          }
   354          updateFieldsMap[field] = ""
   355      }
   356  
   357      {{if .HasCreateTimeField}}
   358      {{if eq .CreateTimeFieldType "int32" "int64" "uint32" "uint64"}}if {{.ReceiverName}}.CreateTime == 0 { 
   359          {{.ReceiverName}}.CreateTime = time.Now().Unix() 
   360      }{{else if eq .CreateTimeFieldType "time.Time"}}if {{.ReceiverName}}.CreateTime.IsZero() {
   361          {{.ReceiverName}}.CreateTime = time.Now()
   362      }{{else if eq .CreateTimeFieldType "timelib.MySQLTimestamp"}} if time.Time({{.ReceiverName}}.CreateTime).IsZero() {
   363          {{.ReceiverName}}.CreateTime = timelib.MySQLTimestamp(time.Now()) 
   364      }{{end}}
   365      {{end}}
   366      {{if .HasUpdateTimeField}} 
   367      {{if eq .UpdateTimeFieldType "int32" "int64" "uint32" "uint64"}}if {{.ReceiverName}}.UpdateTime == 0 { 
   368          {{.ReceiverName}}.UpdateTime = time.Now().Unix() 
   369      }{{else if eq .UpdateTimeFieldType "time.Time"}}if {{.ReceiverName}}.UpdateTime.IsZero() {
   370          {{.ReceiverName}}.UpdateTime = time.Now()
   371      }{{else if eq .UpdateTimeFieldType "timelib.MySQLTimestamp"}} if time.Time({{.ReceiverName}}.UpdateTime).IsZero() {
   372          {{.ReceiverName}}.UpdateTime = timelib.MySQLTimestamp(time.Now()) 
   373      }{{end}}
   374      {{end}}
   375      {{if .HasEnabledField}} 
   376      {{.ReceiverName}}.Enabled = {{.EnabledFieldType}}(enumeration.BOOL__TRUE){{end}}
   377  
   378      structType := reflect.TypeOf({{.ReceiverName}}).Elem()
   379  	if structType.Kind() != reflect.Struct {
   380  	    return fmt.Errorf("Instance not struct type.")
   381  	}
   382      structVal := reflect.ValueOf({{.ReceiverName}}).Elem()
   383  
   384  	var param_list []interface{}
   385  	var str_list = []string{"insert into"}
   386  	var insertFieldsStr = {{.ReceiverName}}.TableName() + "("
   387  	var placeHolder = "values("
   388  	for i := 0; i < structType.NumField(); i++ {
   389  		if i == 0 {
   390  		    insertFieldsStr += {{.StructName}}StructFieldAndDBFieldRelate[structType.Field(i).Name]
   391  			placeHolder += fmt.Sprintf("%s", "?")
   392  		} else {
   393  		    insertFieldsStr += fmt.Sprintf(",%s", {{.StructName}}StructFieldAndDBFieldRelate[structType.Field(i).Name])
   394  			placeHolder += fmt.Sprintf("%s", ", ?")
   395  		}
   396  		param_list = append(param_list, structVal.Field(i).Interface())
   397  	}
   398  	insertFieldsStr += ")"
   399  	placeHolder += ")"
   400  	str_list = append(str_list, []string{insertFieldsStr, placeHolder, "on duplicate key update"}...)
   401  
   402  	var updateStr []string
   403      for i := 0; i < structType.NumField(); i++ {
   404          if dbField, ok := {{.StructName}}StructFieldAndDBFieldRelate[structType.Field(i).Name]; !ok {
   405              return fmt.Errorf("Wrong field of struct, may be changed field but not regenerate code.")
   406          } else {
   407              if _, ok := updateFieldsMap[dbField]; ok {
   408                  updateStr = append(updateStr, fmt.Sprintf("%s = ?", dbField))
   409                  param_list = append(param_list, structVal.Field(i).Interface())
   410              }
   411          }
   412      }
   413      str_list = append(str_list, strings.Join(updateStr, ","))
   414  	sql := strings.Join(str_list, " ")
   415  	err := db.Exec(sql, param_list...).Error
   416  	if err != nil {
   417          logrus.Errorf("%s", err.Error())
   418          return dberr.RecordCreateFailedError
   419  	}
   420  
   421  	return nil
   422  }
   423  `
   424  
   425  func genDBFiledFunc(model *Model, newStructFields, newStructValue, noUniqueIndexFields, dBFieldAndStructField, structFieldAndDBField []string) error {
   426  	data := DbFieldTempalteParam{
   427  		StructName:            model.Name,
   428  		ReceiverName:          fetchUpLetter(model.Name),
   429  		NewStructFields:       newStructFields,
   430  		NewStructValue:        newStructValue,
   431  		NoUniqueIndexFields:   noUniqueIndexFields,
   432  		DBFieldAndStructField: dBFieldAndStructField,
   433  		StructFieldAndDBField: structFieldAndDBField,
   434  		HasEnabledField:       model.HasEnabledField,
   435  		HasUpdateTimeField:    model.HasUpdateTimeField,
   436  		HasCreateTimeField:    model.HasCreateTimeField,
   437  		EnabledFieldType:      model.EnabledFieldType,
   438  		UpdateTimeFieldType:   model.UpdateTimeFieldType,
   439  		CreateTimeFieldType:   model.CreateTimeFieldType,
   440  	}
   441  
   442  	return genDataAndStore(model, data, DbFiledTemplate, "DbFiled")
   443  }
   444  
   445  var CreateTemplate = `
   446  func ({{.ReceiverName}} *{{.StructName}}) Create(db *gorm.DB) error {
   447      defer duration.PrintDuration(map[string]interface{}{
   448              "request" :  "[DB]{{.StructName}}.Create",
   449          })()
   450  
   451      {{if .HasCreateTimeField}}
   452      {{if eq .CreateTimeFieldType "int32" "int64" "uint32" "uint64"}}if {{.ReceiverName}}.CreateTime == 0 { 
   453          {{.ReceiverName}}.CreateTime = time.Now().Unix() 
   454      }{{else if eq .CreateTimeFieldType "time.Time"}}if {{.ReceiverName}}.CreateTime.IsZero() {
   455          {{.ReceiverName}}.CreateTime = time.Now()
   456      }{{else if eq .CreateTimeFieldType "timelib.MySQLTimestamp"}} if time.Time({{.ReceiverName}}.CreateTime).IsZero() {
   457          {{.ReceiverName}}.CreateTime = timelib.MySQLTimestamp(time.Now()) 
   458      }{{end}}
   459      {{end}}
   460      {{if .HasUpdateTimeField}} 
   461      {{if eq .UpdateTimeFieldType "int32" "int64" "uint32" "uint64"}}if {{.ReceiverName}}.UpdateTime == 0 { 
   462          {{.ReceiverName}}.UpdateTime = time.Now().Unix() 
   463      }{{else if eq .UpdateTimeFieldType "time.Time"}}if {{.ReceiverName}}.UpdateTime.IsZero() {
   464          {{.ReceiverName}}.UpdateTime = time.Now()
   465      }{{else if eq .UpdateTimeFieldType "timelib.MySQLTimestamp"}} if time.Time({{.ReceiverName}}.UpdateTime).IsZero() {
   466          {{.ReceiverName}}.UpdateTime = timelib.MySQLTimestamp(time.Now()) 
   467      }{{end}}
   468      {{end}}
   469      {{if .HasEnabledField}} 
   470      {{.ReceiverName}}.Enabled = {{.EnabledFieldType}}(enumeration.BOOL__TRUE){{end}}
   471      err := db.Table({{.ReceiverName}}.TableName()).Create({{.ReceiverName}}).Error
   472      if err != nil {
   473          if mysql_err, ok := err.(*mysql.MySQLError); !ok {
   474              logrus.Errorf("%s", err.Error())
   475              return dberr.RecordCreateFailedError
   476          } else if mysql_err.Number != dberr.DuplicateEntryErrNumber {
   477              logrus.Errorf("%s", err.Error())
   478              return dberr.RecordCreateFailedError
   479          } else {
   480              return dberr.RecordConflictError
   481          }
   482      } else {
   483          return nil
   484      }
   485  }
   486  `
   487  
   488  func genCreateFunc(model *Model) error {
   489  	data := TableNameTemplateParam{
   490  		StructName:          model.Name,
   491  		ReceiverName:        fetchUpLetter(model.Name),
   492  		HasEnabledField:     model.HasEnabledField,
   493  		HasUpdateTimeField:  model.HasUpdateTimeField,
   494  		HasCreateTimeField:  model.HasCreateTimeField,
   495  		EnabledFieldType:    model.EnabledFieldType,
   496  		UpdateTimeFieldType: model.UpdateTimeFieldType,
   497  		CreateTimeFieldType: model.CreateTimeFieldType,
   498  	}
   499  
   500  	return genDataAndStore(model, data, CreateTemplate, "Create")
   501  }
   502  
   503  type FetchTemplateParam struct {
   504  	TableNameTemplateParam
   505  	Field            string
   506  	DbField          string
   507  	ReceiverListName string
   508  	StructListName   string
   509  }
   510  
   511  func genFetchFuncByNormalIndex(model *Model, baseInfoGenCode *BaseInfoOfGenCode) error {
   512  	data := new(FetchTemplateParam)
   513  	data.StructName = model.Name
   514  	data.ReceiverName = fetchUpLetter(model.Name)
   515  	data.HasEnabledField = model.HasEnabledField
   516  	data.DbEnabledField = model.DbEnabledField
   517  	data.ReceiverListName = fetchUpLetter(model.Name) + "l"
   518  	data.StructListName = model.Name + "List"
   519  	data.PartFuncName = baseInfoGenCode.PartFuncName
   520  	data.FuncInputParam = baseInfoGenCode.FuncInputParam
   521  	data.OrmQueryFormat = baseInfoGenCode.OrmQueryFormat
   522  	data.OrmQueryParam = baseInfoGenCode.OrmQueryParam
   523  
   524  	return genDataAndStore(model, data, FetchTemplate, "FetchBy"+data.PartFuncName)
   525  }
   526  
   527  var FetchTemplate = `
   528  func ({{.ReceiverListName}} *{{.StructListName}}) FetchBy{{.PartFuncName}}({{.FuncInputParam}}) error {
   529      defer duration.PrintDuration(map[string]interface{}{
   530              "request" :  "[DB]{{.StructName}}.FetchBy{{.PartFuncName}}",
   531          })()
   532  
   533      {{if .HasEnabledField}}err := db.Table({{.StructName}}{}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Find({{.ReceiverListName}}).Error{{else}} 
   534      err := db.Table({{.StructName}}{}.TableName()).Where("{{.OrmQueryFormat}}", {{.OrmQueryParam}}).Find({{.ReceiverListName}}).Error{{end}}
   535      if err == nil {
   536          return nil
   537      } else {
   538          logrus.Errorf("%s", err.Error())
   539          return dberr.RecordFetchFailedError
   540      } 
   541  }
   542  `
   543  
   544  type BatchFetchTemplateParam struct {
   545  	FetchTemplateParam
   546  	FieldType        string
   547  	ParamField       string
   548  	ReceiverListName string
   549  	StructListName   string
   550  }
   551  
   552  func genBatchFetchFunc(model *Model, field, dbField, fieldType string) error {
   553  	data := new(BatchFetchTemplateParam)
   554  	data.StructName = model.Name
   555  	data.ReceiverName = fetchUpLetter(model.Name)
   556  	data.Field = field
   557  	data.ParamField = convertFirstLetterToLower(field)
   558  	data.ReceiverListName = fetchUpLetter(model.Name) + "l"
   559  	data.StructListName = model.Name + "List"
   560  	data.DbField = dbField
   561  	data.FieldType = fieldType
   562  	data.HasEnabledField = model.HasEnabledField
   563  	data.DbEnabledField = model.DbEnabledField
   564  
   565  	return genDataAndStore(model, data, BatchFetchTemplate, "BatchFetchBy"+data.Field)
   566  }
   567  
   568  var BatchFetchTemplate = `
   569  func ({{.ReceiverListName}} *{{.StructListName}}) BatchFetchBy{{.Field}}List(db *gorm.DB, {{.ParamField}}List []{{.FieldType}}) error {
   570      defer duration.PrintDuration(map[string]interface{}{
   571              "request" :  "[DB]{{.StructName}}.BatchFetchBy{{.Field}}List",
   572          })()
   573  
   574      if len({{.ParamField}}List) == 0 {
   575          return nil
   576      }
   577  
   578      {{if .HasEnabledField}}err := db.Table({{.StructName}}{}.TableName()).Where("{{.DbField}} in (?) and {{.DbEnabledField}} = ?", {{.ParamField}}List, enumeration.BOOL__TRUE).Find({{.ReceiverListName}}).Error{{else}}
   579      err := db.Table({{.StructName}}{}.TableName()).Where("{{.DbField}} in (?)", {{.ParamField}}List).Find({{.ReceiverListName}}).Error{{end}}
   580      if err != nil {
   581          logrus.Errorf("%s", err.Error())
   582          return dberr.RecordFetchFailedError
   583      } else {
   584          return nil
   585      }
   586  }
   587  `
   588  
   589  type FetchListTemplateParam struct {
   590  	ReceiverListName   string
   591  	StructListName     string
   592  	StructName         string
   593  	HasEnabledField    bool
   594  	HasCreateTimeField bool
   595  	DbCreateTimeField  string
   596  	DbEnabledField     string
   597  }
   598  
   599  func genFetchListFunc(model *Model) error {
   600  	data := new(FetchListTemplateParam)
   601  	data.StructName = model.Name
   602  	data.ReceiverListName = fetchUpLetter(model.Name) + "l"
   603  	data.StructListName = model.Name + "List"
   604  	data.HasEnabledField = model.HasEnabledField
   605  	data.HasCreateTimeField = model.HasCreateTimeField
   606  	data.DbCreateTimeField = model.DbCreateTimeField
   607  	data.DbEnabledField = model.DbEnabledField
   608  
   609  	return genDataAndStore(model, data, FetchListTemplate, "FetchList")
   610  	//tmpl := template.Must(template.New("fetchList").Parse(FetchListTemplate))
   611  	//return tmpl.Execute(file, data)
   612  }
   613  
   614  var FetchListTemplate = `
   615  func ({{.ReceiverListName}} *{{.StructListName}}) FetchList(db *gorm.DB, size, offset int32, query ...map[string]interface{}) (int32, error) {
   616      defer duration.PrintDuration(map[string]interface{}{
   617              "request" :  "[DB]{{.StructName}}.FetchList",
   618          })()
   619  
   620      var count int32{{if .HasEnabledField}} 
   621      if len(query) == 0 {
   622          query = append(query, map[string]interface{}{"{{.DbEnabledField}}": enumeration.BOOL__TRUE})
   623      } else {
   624          if _, ok := query[0]["{{.DbEnabledField}}"]; !ok { 
   625              query[0]["{{.DbEnabledField}}"] = enumeration.BOOL__TRUE 
   626          }
   627      }
   628  
   629      if size <= 0 {
   630          size = -1
   631          offset = -1
   632      }
   633      var err error
   634  
   635      {{if .HasCreateTimeField}}err = db.Table({{.StructName}}{}.TableName()).Where(query[0]).Count(&count).Limit(size).Offset(offset).Order("{{.DbCreateTimeField}} desc").Find({{.ReceiverListName}}).Error{{else}}err = db.Table({{.StructName}}{}.TableName()).Where(query[0]).Count(&count).Limit(size).Offset(offset).Find({{.ReceiverListName}}).Error{{end}}
   636      {{else}}
   637      if size <= 0 {
   638          size = -1
   639          offset = -1
   640      }
   641  
   642      var err error
   643      if len(query) == 0 {
   644          {{if .HasCreateTimeField}}err = db.Table({{.StructName}}{}.TableName()).Count(&count).Limit(size).Offset(offset).Order("{{.DbCreateTimeField}} desc").Find({{.ReceiverListName}}).Error{{else}}err = db.Table({{.StructName}}{}.TableName()).Count(&count).Limit(size).Offset(offset).Find({{.ReceiverListName}}).Error{{end}}
   645      } else {
   646          {{if .HasCreateTimeField}}err = db.Table({{.StructName}}{}.TableName()).Where(query[0]).Count(&count).Limit(size).Offset(offset).Order("{{.DbCreateTimeField}} desc").Find({{.ReceiverListName}}).Error{{else}}err = db.Table({{.StructName}}{}.TableName()).Where(query[0]).Count(&count).Limit(size).Offset(offset).Find({{.ReceiverListName}}).Error{{end}}
   647      }{{end}} 
   648      if err != nil {
   649          logrus.Errorf("%s", err.Error())
   650          return 0, dberr.RecordFetchFailedError
   651      } else {
   652          return int32(count), nil
   653      }
   654  }
   655  `
   656  
   657  type UniqueFetchTemplateParam struct {
   658  	TableNameTemplateParam
   659  	UnionField string
   660  }
   661  
   662  func genFetchForUpdateFuncByUniqueIndex(model *Model, baseInfoGenCode *BaseInfoOfGenCode) error {
   663  	data := new(UniqueFetchTemplateParam)
   664  	data.StructName = model.Name
   665  	data.ReceiverName = fetchUpLetter(model.Name)
   666  	//data.UnionField = unionField
   667  	data.DbEnabledField = model.DbEnabledField
   668  	data.HasEnabledField = model.HasEnabledField
   669  	data.PartFuncName = baseInfoGenCode.PartFuncName
   670  	data.FuncInputParam = baseInfoGenCode.FuncInputParam
   671  	data.OrmQueryFormat = baseInfoGenCode.OrmQueryFormat
   672  	data.OrmQueryParam = baseInfoGenCode.OrmQueryParam
   673  
   674  	return genDataAndStore(model, data, genFetchForUpdateFuncByUniqueIndeTemplate,
   675  		"FetchBy"+data.PartFuncName+"ForUpdate")
   676  }
   677  
   678  var genFetchForUpdateFuncByUniqueIndeTemplate = `
   679  func ({{.ReceiverName}} *{{.StructName}}) FetchBy{{.PartFuncName}}ForUpdate({{.FuncInputParam}}) error {
   680      defer duration.PrintDuration(map[string]interface{}{
   681              "request" :  "[DB]{{.StructName}}.FetchBy{{.PartFuncName}}ForUpdate",
   682          })()
   683  
   684      {{if .HasEnabledField}}err := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Set("gorm:query_option", "FOR UPDATE").Find({{.ReceiverName}}).Error{{else}} 
   685      err := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}}", {{.OrmQueryParam}}).Set("gorm:query_option", "FOR UPDATE").Find({{.ReceiverName}}).Error{{end}}
   686      if err == nil {
   687          return nil
   688      } else {
   689          if err == gorm.RecordNotFound {
   690              return dberr.RecordNotFoundError
   691          } else {
   692              logrus.Errorf("%s", err.Error())
   693              return dberr.RecordFetchFailedError
   694          }
   695      } 
   696  }
   697  `
   698  
   699  func genFetchFuncByUniqueIndex(model *Model, baseInfoGenCode *BaseInfoOfGenCode) error {
   700  	data := new(UniqueFetchTemplateParam)
   701  	data.StructName = model.Name
   702  	data.ReceiverName = fetchUpLetter(model.Name)
   703  	data.HasEnabledField = model.HasEnabledField
   704  	//data.UnionField = unionField
   705  	data.DbEnabledField = model.DbEnabledField
   706  	data.PartFuncName = baseInfoGenCode.PartFuncName
   707  	data.FuncInputParam = baseInfoGenCode.FuncInputParam
   708  	data.OrmQueryFormat = baseInfoGenCode.OrmQueryFormat
   709  	data.OrmQueryParam = baseInfoGenCode.OrmQueryParam
   710  
   711  	return genDataAndStore(model, data, FetchByUniqueInexTemplate, "FetchBy"+data.PartFuncName)
   712  }
   713  
   714  var FetchByUniqueInexTemplate = `
   715  func ({{.ReceiverName}} *{{.StructName}}) FetchBy{{.PartFuncName}}({{.FuncInputParam}}) error {
   716      defer duration.PrintDuration(map[string]interface{}{
   717              "request" :  "[DB]{{.StructName}}.FetchBy{{.PartFuncName}}",
   718          })()
   719  
   720      {{if .HasEnabledField}}err := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Find({{.ReceiverName}}).Error{{else}} 
   721      err := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}}", {{.OrmQueryParam}}).Find({{.ReceiverName}}).Error{{end}}
   722      if err == nil {
   723          return nil
   724      } else {
   725          if err == gorm.RecordNotFound {
   726              return dberr.RecordNotFoundError
   727          } else {
   728              logrus.Errorf("%s", err.Error())
   729              return dberr.RecordFetchFailedError
   730          }
   731      } 
   732  }
   733  `
   734  
   735  type UniqueUpdateWithStructTemplateParam struct {
   736  	TableNameTemplateParam
   737  	UnionField string
   738  }
   739  
   740  func genUpdateWithStructFuncByUniqueIndex(model *Model, baseInfoGenCode *BaseInfoOfGenCode) error {
   741  	data := new(UniqueUpdateWithStructTemplateParam)
   742  	data.StructName = model.Name
   743  	data.ReceiverName = fetchUpLetter(model.Name)
   744  	//data.UnionField = uniqueField
   745  	data.HasUpdateTimeField = model.HasUpdateTimeField
   746  	data.UpdateTimeFieldType = model.UpdateTimeFieldType
   747  	data.HasEnabledField = model.HasEnabledField
   748  	data.DbEnabledField = model.DbEnabledField
   749  	data.PartFuncName = baseInfoGenCode.PartFuncName
   750  	data.FuncInputParam = baseInfoGenCode.FuncInputParam
   751  	data.OrmQueryFormat = baseInfoGenCode.OrmQueryFormat
   752  	data.OrmQueryParam = baseInfoGenCode.OrmQueryParam
   753  
   754  	return genDataAndStore(model, data, genUpdateWithStructFuncByUniqueIndexTemplate,
   755  		"UpdateBy"+data.PartFuncName+"WithStruct")
   756  }
   757  
   758  var genUpdateWithStructFuncByUniqueIndexTemplate = `
   759  func ({{.ReceiverName}} *{{.StructName}}) UpdateBy{{.PartFuncName}}WithStruct({{.FuncInputParam}}) error {
   760      defer duration.PrintDuration(map[string]interface{}{
   761              "request" :  "[DB]{{.StructName}}.UpdateBy{{.PartFuncName}}WithStruct",
   762          })()
   763  
   764      {{if .HasUpdateTimeField}}
   765      {{if eq .UpdateTimeFieldType "int32" "int64" "uint32" "uint64"}}if {{.ReceiverName}}.UpdateTime == 0 { 
   766          {{.ReceiverName}}.UpdateTime = time.Now().Unix() 
   767      }{{else if eq .UpdateTimeFieldType "time.Time"}}if {{.ReceiverName}}.UpdateTime.IsZero() {
   768          {{.ReceiverName}}.UpdateTime = time.Now()
   769      }{{else if eq .UpdateTimeFieldType "timelib.MySQLTimestamp"}} if time.Time({{.ReceiverName}}.UpdateTime).IsZero() {
   770          {{.ReceiverName}}.UpdateTime = timelib.MySQLTimestamp(time.Now()) 
   771      }{{end}}
   772      {{end}}
   773      {{if .HasEnabledField}}dbRet := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Updates({{.ReceiverName}}){{else}} 
   774      dbRet := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}}", {{.OrmQueryParam}}).Updates({{.ReceiverName}}){{end}}
   775      err := dbRet.Error
   776      if err != nil {
   777          if mysql_err, ok := err.(*mysql.MySQLError); !ok {
   778              logrus.Errorf("%s", err.Error())
   779              return dberr.RecordUpdateFailedError 
   780          } else if mysql_err.Number != dberr.DuplicateEntryErrNumber {
   781              logrus.Errorf("%s", err.Error())
   782              return dberr.RecordUpdateFailedError
   783          } else {
   784              return dberr.RecordConflictError
   785          }
   786      } else {
   787          if dbRet.RowsAffected == 0 {
   788              {{if .HasEnabledField}}findErr := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Find(&{{.StructName}}{}).Error{{else}}
   789              findErr := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}}", {{.OrmQueryParam}}).Find(&{{.StructName}}{}).Error{{end}}
   790              if findErr == gorm.RecordNotFound {
   791                  return dberr.RecordNotFoundError
   792              } else if findErr != nil {
   793                  return dberr.RecordUpdateFailedError
   794              }
   795              //存在有效数据记录,返回成功
   796              return nil
   797  	    } else {
   798  		    return nil
   799  	    }
   800      }
   801  }
   802  `
   803  
   804  type UniqueUpdateWithMapTemplateParam struct {
   805  	TableNameTemplateParam
   806  	UnionField string
   807  }
   808  
   809  func genUpdateWithMapFuncByUniqueIndex(model *Model, baseInfoGenCode *BaseInfoOfGenCode) error {
   810  	data := new(UniqueUpdateWithMapTemplateParam)
   811  	data.StructName = model.Name
   812  	data.ReceiverName = fetchUpLetter(model.Name)
   813  	data.HasUpdateTimeField = model.HasUpdateTimeField
   814  	data.UpdateTimeFieldType = model.UpdateTimeFieldType
   815  	data.DbUpdateTimeField = model.DbUpdateTimeField
   816  	data.HasEnabledField = model.HasEnabledField
   817  	data.DbEnabledField = model.DbEnabledField
   818  	data.PartFuncName = baseInfoGenCode.PartFuncName
   819  	data.FuncInputParam = baseInfoGenCode.FuncInputParam
   820  	data.OrmQueryFormat = baseInfoGenCode.OrmQueryFormat
   821  	data.OrmQueryParam = baseInfoGenCode.OrmQueryParam
   822  
   823  	return genDataAndStore(model, data, genUpdateWithMapFuncByUniqueIndexTemplate,
   824  		"UpdateBy"+data.PartFuncName+"WithMap")
   825  }
   826  
   827  var genUpdateWithMapFuncByUniqueIndexTemplate = `
   828  func ({{.ReceiverName}} *{{.StructName}}) UpdateBy{{.PartFuncName}}WithMap({{.FuncInputParam}}, updateMap map[string]interface{}) error {
   829      defer duration.PrintDuration(map[string]interface{}{
   830              "request" :  "[DB]{{.StructName}}.UpdateBy{{.PartFuncName}}WithMap",
   831          })()
   832  
   833      {{if .HasUpdateTimeField}}if _, ok := updateMap["{{.DbUpdateTimeField}}"]; !ok { 
   834          {{if eq .UpdateTimeFieldType "int32" "int64" "uint32" "uint64"}}updateMap["{{.DbUpdateTimeField}}"] = time.Now().Unix()
   835          {{else if eq .UpdateTimeFieldType "time.Time"}}updateMap["{{.DbUpdateTimeField}}"] = time.Now()
   836          {{else if eq .UpdateTimeFieldType "timelib.MySQLTimestamp"}}updateMap["{{.DbUpdateTimeField}}"] = timelib.MySQLTimestamp(time.Now())
   837          {{end}}
   838      }{{end}}
   839      {{if .HasEnabledField}}dbRet := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Updates(updateMap){{else}} 
   840      dbRet := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}}", {{.OrmQueryParam}}).Updates(updateMap){{end}}
   841      err := dbRet.Error
   842      if err != nil {
   843          if mysql_err, ok := err.(*mysql.MySQLError); !ok {
   844              logrus.Errorf("%s", err.Error())
   845              return dberr.RecordUpdateFailedError 
   846          } else if mysql_err.Number != dberr.DuplicateEntryErrNumber {
   847              logrus.Errorf("%s", err.Error())
   848              return dberr.RecordUpdateFailedError
   849          } else {
   850              return dberr.RecordConflictError
   851          }
   852      } else {
   853          if dbRet.RowsAffected == 0 {
   854              {{if .HasEnabledField}}findErr := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Find(&{{.StructName}}{}).Error{{else}}
   855              findErr := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}}", {{.OrmQueryParam}}).Find(&{{.StructName}}{}).Error{{end}}
   856              if findErr == gorm.RecordNotFound {
   857                  return dberr.RecordNotFoundError
   858              } else if findErr != nil {
   859                  return dberr.RecordUpdateFailedError
   860              }
   861              //存在有效数据记录,返回成功
   862              return nil
   863  	    } else {
   864  		    return nil
   865  	    }
   866      }
   867  }
   868  `
   869  
   870  type UniqueDeleteTemplateParam struct {
   871  	TableNameTemplateParam
   872  	UnionField string
   873  }
   874  
   875  func genSoftDeleteFuncByUniqueIndex(model *Model, baseInfoGenCode *BaseInfoOfGenCode) error {
   876  	data := new(UniqueDeleteTemplateParam)
   877  	data.StructName = model.Name
   878  	data.ReceiverName = fetchUpLetter(model.Name)
   879  	//data.UnionField = unionField
   880  	data.HasUpdateTimeField = model.HasUpdateTimeField
   881  	data.HasEnabledField = model.HasEnabledField
   882  	data.UpdateTimeFieldType = model.UpdateTimeFieldType
   883  	data.DbEnabledField = model.DbEnabledField
   884  	data.PartFuncName = baseInfoGenCode.PartFuncName
   885  	data.FuncInputParam = baseInfoGenCode.FuncInputParam
   886  	data.OrmQueryFormat = baseInfoGenCode.OrmQueryFormat
   887  	data.OrmQueryParam = baseInfoGenCode.OrmQueryParam
   888  
   889  	return genDataAndStore(model, data, genSoftDeleteFuncByUniqueIndexTemplate,
   890  		"SoftDeleteBy"+data.PartFuncName)
   891  }
   892  
   893  var genSoftDeleteFuncByUniqueIndexTemplate = `
   894  func ({{.ReceiverName}} *{{.StructName}}) SoftDeleteBy{{.PartFuncName}}({{.FuncInputParam}}) error {
   895      defer duration.PrintDuration(map[string]interface{}{
   896              "request" :  "[DB]{{.StructName}}.SoftDeleteBy{{.PartFuncName}}",
   897          })()
   898  
   899      {{if .HasEnabledField}}var updateMap = map[string]interface{}{}
   900      updateMap["{{.DbEnabledField}}"] = enumeration.BOOL__FALSE
   901      {{if .HasUpdateTimeField}}
   902      {{if eq .UpdateTimeFieldType "int32" "int64" "uint32" "uint64"}}if {{.ReceiverName}}.UpdateTime == 0 { 
   903          {{.ReceiverName}}.UpdateTime = time.Now().Unix() 
   904      }{{else if eq .UpdateTimeFieldType "time.Time"}}if {{.ReceiverName}}.UpdateTime.IsZero() {
   905          {{.ReceiverName}}.UpdateTime = time.Now()
   906      }{{else if eq .UpdateTimeFieldType "timelib.MySQLTimestamp"}} if time.Time({{.ReceiverName}}.UpdateTime).IsZero() {
   907          {{.ReceiverName}}.UpdateTime = timelib.MySQLTimestamp(time.Now()) 
   908      }{{end}}
   909      {{end}}
   910      err := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Updates(updateMap).Error
   911      if err != nil {
   912          if mysql_err, ok := err.(*mysql.MySQLError); !ok {
   913              logrus.Errorf("%s", err.Error())
   914              return dberr.RecordDeleteFailedError
   915          } else if mysql_err.Number != dberr.DuplicateEntryErrNumber {
   916              logrus.Errorf("%s", err.Error())
   917              return dberr.RecordDeleteFailedError
   918          } else {
   919              logrus.Warningf("%s", err.Error())
   920              // 物理删除被软删除的数据
   921              delErr := db.Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Delete(&{{.StructName}}{}).Error
   922              if delErr != nil {
   923                  logrus.Errorf("%s", delErr.Error())
   924                  return dberr.RecordDeleteFailedError
   925              } 
   926  
   927              return nil
   928          }
   929      } else {
   930          return nil
   931      }{{else}}
   932      return nil{{end}}
   933  }
   934  `
   935  
   936  type UniquePhysicsDeleteTemplateParam struct {
   937  	TableNameTemplateParam
   938  	UnionField string
   939  }
   940  
   941  func genPhysicsDeleteFuncByUniqueIndex(model *Model, baseInfoGenCode *BaseInfoOfGenCode) error {
   942  	data := new(UniqueDeleteTemplateParam)
   943  	data.StructName = model.Name
   944  	data.ReceiverName = fetchUpLetter(model.Name)
   945  	data.DbEnabledField = model.DbEnabledField
   946  	data.HasEnabledField = model.HasEnabledField
   947  	data.PartFuncName = baseInfoGenCode.PartFuncName
   948  	data.FuncInputParam = baseInfoGenCode.FuncInputParam
   949  	data.OrmQueryFormat = baseInfoGenCode.OrmQueryFormat
   950  	data.OrmQueryParam = baseInfoGenCode.OrmQueryParam
   951  
   952  	return genDataAndStore(model, data, genPhysicsDeleteFuncByUniqueIndexTemplate,
   953  		"DeleteBy"+data.PartFuncName)
   954  }
   955  
   956  var genPhysicsDeleteFuncByUniqueIndexTemplate = `
   957  func ({{.ReceiverName}} *{{.StructName}}) DeleteBy{{.PartFuncName}}({{.FuncInputParam}}) error {
   958      defer duration.PrintDuration(map[string]interface{}{
   959              "request" :  "[DB]{{.StructName}}.DeleteBy{{.PartFuncName}}",
   960          })()
   961  
   962      {{if .HasEnabledField}}err := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}} and {{.DbEnabledField}} = ?", {{.OrmQueryParam}}, enumeration.BOOL__TRUE).Delete({{.ReceiverName}}).Error{{else}}
   963      err := db.Table({{.ReceiverName}}.TableName()).Where("{{.OrmQueryFormat}}", {{.OrmQueryParam}}).Delete({{.ReceiverName}}).Error{{end}}
   964      if err != nil {
   965          logrus.Errorf("%s", err.Error())
   966          return dberr.RecordDeleteFailedError
   967      } else {
   968          return nil
   969      }
   970  }
   971  `