github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/gormgen/internal/template/method.go (about)

     1  package template
     2  
     3  // DIYMethod DIY method
     4  const DIYMethod = `
     5  
     6  // {{.DocComment }}
     7  func ({{.S}} {{.TargetStruct}}Do){{.FuncSign}}{
     8  	{{if .HasSQLData}}var params []interface{}
     9  
    10  	{{end}}var generateSQL strings.Builder
    11  	{{range $line:=.Section.Tmpls}}{{$line}}
    12  	{{end}}
    13  
    14  	{{if .HasNeedNewResult}}result ={{if .ResultData.IsMap}}make{{else}}new{{end}}({{if ne .ResultData.Package ""}}{{.ResultData.Package}}.{{end}}{{.ResultData.Type}}){{end}}
    15  	{{if .ReturnSQLResult}}stmt := {{.S}}.UnderlyingDB().Statement
    16  	result,{{if .ReturnError}}err{{else}}_{{end}} = stmt.ConnPool.ExecContext(stmt.Context,generateSQL.String(){{if .HasSQLData}},params...{{end}}) // ignore_security_alert
    17  	{{else if .ReturnSQLRow}}row = {{.S}}.UnderlyingDB().Raw(generateSQL.String(){{if .HasSQLData}},params...{{end}}).Row() // ignore_security_alert
    18  	{{else if .ReturnSQLRows}}rows,{{if .ReturnError}}err{{else}}_{{end}} = {{.S}}.UnderlyingDB().Raw(generateSQL.String(){{if .HasSQLData}},params...{{end}}).Rows() // ignore_security_alert
    19  	{{else}}var executeSQL *gorm.DB
    20  	executeSQL = {{.S}}.UnderlyingDB().{{.GormOption}}(generateSQL.String(){{if .HasSQLData}},params...{{end}}){{if not .ResultData.IsNull}}.{{.GormRunMethodName}}({{if .HasGotPoint}}&{{end}}{{.ResultData.Name}}){{end}}  // ignore_security_alert
    21  	{{if .ReturnRowsAffected}}rowsAffected = executeSQL.RowsAffected
    22  	{{end}}{{if .ReturnError}}err = executeSQL.Error
    23  	{{end}}{{if .ReturnNothing}}_ = executeSQL
    24  	{{end}}{{end}}
    25  	return
    26  }
    27  
    28  `
    29  
    30  // CRUDMethod CRUD method
    31  const CRUDMethod = `
    32  func ({{.S}} {{.QueryStructName}}Do) Debug() {{.ReturnObject}} {
    33  	return {{.S}}.withDO({{.S}}.DO.Debug())
    34  }
    35  
    36  func ({{.S}} {{.QueryStructName}}Do) WithContext(ctx context.Context) {{.ReturnObject}} {
    37  	return {{.S}}.withDO({{.S}}.DO.WithContext(ctx))
    38  }
    39  
    40  func ({{.S}} {{.QueryStructName}}Do) ReadDB() {{.ReturnObject}} {
    41  	return {{.S}}.Clauses(dbresolver.Read)
    42  }
    43  
    44  func ({{.S}} {{.QueryStructName}}Do) WriteDB() {{.ReturnObject}} {
    45  	return {{.S}}.Clauses(dbresolver.Write)
    46  }
    47  
    48  func ({{.S}} {{.QueryStructName}}Do) Session(config *gorm.Session) {{.ReturnObject}} {
    49  	return {{.S}}.withDO({{.S}}.DO.Session(config))
    50  }
    51  
    52  func ({{.S}} {{.QueryStructName}}Do) Clauses(conds ...clause.Expression) {{.ReturnObject}} {
    53  	return {{.S}}.withDO({{.S}}.DO.Clauses(conds...))
    54  }
    55  
    56  func ({{.S}} {{.QueryStructName}}Do) Returning(value interface{}, columns ...string) {{.ReturnObject}} {
    57  	return {{.S}}.withDO({{.S}}.DO.Returning(value, columns...))
    58  }
    59  
    60  func ({{.S}} {{.QueryStructName}}Do) Not(conds ...gormgen.Condition) {{.ReturnObject}} {
    61  	return {{.S}}.withDO({{.S}}.DO.Not(conds...))
    62  }
    63  
    64  func ({{.S}} {{.QueryStructName}}Do) Or(conds ...gormgen.Condition) {{.ReturnObject}} {
    65  	return {{.S}}.withDO({{.S}}.DO.Or(conds...))
    66  }
    67  
    68  func ({{.S}} {{.QueryStructName}}Do) Select(conds ...field.Expr) {{.ReturnObject}} {
    69  	return {{.S}}.withDO({{.S}}.DO.Select(conds...))
    70  }
    71  
    72  func ({{.S}} {{.QueryStructName}}Do) Where(conds ...gormgen.Condition) {{.ReturnObject}} {
    73  	return {{.S}}.withDO({{.S}}.DO.Where(conds...))
    74  }
    75  
    76  func ({{.S}} {{.QueryStructName}}Do) Exists(subquery interface{UnderlyingDB() *gorm.DB}) {{.ReturnObject}} {
    77  	return {{.S}}.Where(field.CompareSubQuery(field.ExistsOp, nil, subquery.UnderlyingDB()))
    78  }
    79  
    80  func ({{.S}} {{.QueryStructName}}Do) Order(conds ...field.Expr) {{.ReturnObject}} {
    81  	return {{.S}}.withDO({{.S}}.DO.Order(conds...))
    82  }
    83  
    84  func ({{.S}} {{.QueryStructName}}Do) Distinct(cols ...field.Expr) {{.ReturnObject}} {
    85  	return {{.S}}.withDO({{.S}}.DO.Distinct(cols...))
    86  }
    87  
    88  func ({{.S}} {{.QueryStructName}}Do) Omit(cols ...field.Expr) {{.ReturnObject}} {
    89  	return {{.S}}.withDO({{.S}}.DO.Omit(cols...))
    90  }
    91  
    92  func ({{.S}} {{.QueryStructName}}Do) Join(table schema.Tabler, on ...field.Expr) {{.ReturnObject}} {
    93  	return {{.S}}.withDO({{.S}}.DO.Join(table, on...))
    94  }
    95  
    96  func ({{.S}} {{.QueryStructName}}Do) LeftJoin(table schema.Tabler, on ...field.Expr) {{.ReturnObject}} {
    97  	return {{.S}}.withDO({{.S}}.DO.LeftJoin(table, on...))
    98  }
    99  
   100  func ({{.S}} {{.QueryStructName}}Do) RightJoin(table schema.Tabler, on ...field.Expr) {{.ReturnObject}} {
   101  	return {{.S}}.withDO({{.S}}.DO.RightJoin(table, on...))
   102  }
   103  
   104  func ({{.S}} {{.QueryStructName}}Do) Group(cols ...field.Expr) {{.ReturnObject}} {
   105  	return {{.S}}.withDO({{.S}}.DO.Group(cols...))
   106  }
   107  
   108  func ({{.S}} {{.QueryStructName}}Do) Having(conds ...gormgen.Condition) {{.ReturnObject}} {
   109  	return {{.S}}.withDO({{.S}}.DO.Having(conds...))
   110  }
   111  
   112  func ({{.S}} {{.QueryStructName}}Do) Limit(limit int) {{.ReturnObject}} {
   113  	return {{.S}}.withDO({{.S}}.DO.Limit(limit))
   114  }
   115  
   116  func ({{.S}} {{.QueryStructName}}Do) Offset(offset int) {{.ReturnObject}} {
   117  	return {{.S}}.withDO({{.S}}.DO.Offset(offset))
   118  }
   119  
   120  func ({{.S}} {{.QueryStructName}}Do) Scopes(funcs ...func(gormgen.Dao) gormgen.Dao) {{.ReturnObject}} {
   121  	return {{.S}}.withDO({{.S}}.DO.Scopes(funcs...))
   122  }
   123  
   124  func ({{.S}} {{.QueryStructName}}Do) Unscoped() {{.ReturnObject}} {
   125  	return {{.S}}.withDO({{.S}}.DO.Unscoped())
   126  }
   127  
   128  func ({{.S}} {{.QueryStructName}}Do) Create(values ...*{{.StructInfo.Package}}.{{.StructInfo.Type}}) error {
   129  	if len(values) == 0 {
   130  		return nil
   131  	}
   132  	return {{.S}}.DO.Create(values)
   133  }
   134  
   135  func ({{.S}} {{.QueryStructName}}Do) CreateInBatches(values []*{{.StructInfo.Package}}.{{.StructInfo.Type}}, batchSize int) error {
   136  	return {{.S}}.DO.CreateInBatches(values, batchSize)
   137  }
   138  
   139  // Save : !!! underlying implementation is different with GORM
   140  // The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
   141  func ({{.S}} {{.QueryStructName}}Do) Save(values ...*{{.StructInfo.Package}}.{{.StructInfo.Type}}) error {
   142  	if len(values) == 0 {
   143  		return nil
   144  	}
   145  	return {{.S}}.DO.Save(values)
   146  }
   147  
   148  func ({{.S}} {{.QueryStructName}}Do) First() (*{{.StructInfo.Package}}.{{.StructInfo.Type}}, error) {
   149  	if result, err := {{.S}}.DO.First(); err != nil {
   150  		return nil, err
   151  	} else {
   152  		return result.(*{{.StructInfo.Package}}.{{.StructInfo.Type}}), nil
   153  	}
   154  }
   155  
   156  func ({{.S}} {{.QueryStructName}}Do) Take() (*{{.StructInfo.Package}}.{{.StructInfo.Type}}, error) {
   157  	if result, err := {{.S}}.DO.Take(); err != nil {
   158  		return nil, err
   159  	} else {
   160  		return result.(*{{.StructInfo.Package}}.{{.StructInfo.Type}}), nil
   161  	}
   162  }
   163  
   164  func ({{.S}} {{.QueryStructName}}Do) Last() (*{{.StructInfo.Package}}.{{.StructInfo.Type}}, error) {
   165  	if result, err := {{.S}}.DO.Last(); err != nil {
   166  		return nil, err
   167  	} else {
   168  		return result.(*{{.StructInfo.Package}}.{{.StructInfo.Type}}), nil
   169  	}
   170  }
   171  
   172  func ({{.S}} {{.QueryStructName}}Do) Find() ([]*{{.StructInfo.Package}}.{{.StructInfo.Type}}, error) {
   173  	result, err := {{.S}}.DO.Find()
   174  	return result.([]*{{.StructInfo.Package}}.{{.StructInfo.Type}}), err
   175  }
   176  
   177  func ({{.S}} {{.QueryStructName}}Do) FindInBatch(batchSize int, fc func(tx gormgen.Dao, batch int) error) (results []*{{.StructInfo.Package}}.{{.StructInfo.Type}}, err error) {
   178  	buf := make([]*{{.StructInfo.Package}}.{{.StructInfo.Type}}, 0, batchSize)
   179  	err = {{.S}}.DO.FindInBatches(&buf, batchSize, func(tx gormgen.Dao, batch int) error {
   180  		defer func() { results = append(results, buf...) }()
   181  		return fc(tx, batch)
   182  	})
   183  	return results, err
   184  }
   185  
   186  func ({{.S}} {{.QueryStructName}}Do) FindInBatches(result *[]*{{.StructInfo.Package}}.{{.StructInfo.Type}}, batchSize int, fc func(tx gormgen.Dao, batch int) error) error {
   187  	return {{.S}}.DO.FindInBatches(result, batchSize, fc)
   188  }
   189  
   190  func ({{.S}} {{.QueryStructName}}Do) Attrs(attrs ...field.AssignExpr) {{.ReturnObject}} {
   191  	return {{.S}}.withDO({{.S}}.DO.Attrs(attrs...))
   192  }
   193  
   194  func ({{.S}} {{.QueryStructName}}Do) Assign(attrs ...field.AssignExpr) {{.ReturnObject}} {
   195  	return {{.S}}.withDO({{.S}}.DO.Assign(attrs...))
   196  }
   197  
   198  func ({{.S}} {{.QueryStructName}}Do) Joins(fields ...field.RelationField) {{.ReturnObject}} {
   199  	for _, _f := range fields {
   200          {{.S}} = *{{.S}}.withDO({{.S}}.DO.Joins(_f))
   201      }
   202  	return &{{.S}}
   203  }
   204  
   205  func ({{.S}} {{.QueryStructName}}Do) Preload(fields ...field.RelationField) {{.ReturnObject}} {
   206      for _, _f := range fields {
   207          {{.S}} = *{{.S}}.withDO({{.S}}.DO.Preload(_f))
   208      }
   209  	return &{{.S}}
   210  }
   211  
   212  func ({{.S}} {{.QueryStructName}}Do) FirstOrInit() (*{{.StructInfo.Package}}.{{.StructInfo.Type}}, error) {
   213  	if result, err := {{.S}}.DO.FirstOrInit(); err != nil {
   214  		return nil, err
   215  	} else {
   216  		return result.(*{{.StructInfo.Package}}.{{.StructInfo.Type}}), nil
   217  	}
   218  }
   219  
   220  func ({{.S}} {{.QueryStructName}}Do) FirstOrCreate() (*{{.StructInfo.Package}}.{{.StructInfo.Type}}, error) {
   221  	if result, err := {{.S}}.DO.FirstOrCreate(); err != nil {
   222  		return nil, err
   223  	} else {
   224  		return result.(*{{.StructInfo.Package}}.{{.StructInfo.Type}}), nil
   225  	}
   226  }
   227  
   228  func ({{.S}} {{.QueryStructName}}Do) FindByPage(offset int, limit int) (result []*{{.StructInfo.Package}}.{{.StructInfo.Type}}, count int64, err error) {
   229  	result, err = {{.S}}.Offset(offset).Limit(limit).Find()
   230  	if err != nil{
   231  		return
   232  	}
   233  
   234  	if size := len(result); 0 < limit && 0 < size && size < limit {
   235  		count = int64(size+offset)
   236  		return
   237  	}
   238  
   239  	count, err = {{.S}}.Offset(-1).Limit(-1).Count()
   240  	return
   241  }
   242  
   243  func ({{.S}} {{.QueryStructName}}Do) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
   244  	count, err = {{.S}}.Count()
   245  	if err != nil {
   246  		return
   247  	}
   248  
   249  	err = {{.S}}.Offset(offset).Limit(limit).Scan(result)
   250  	return
   251  }
   252  
   253  func ({{.S}} {{.QueryStructName}}Do) Scan(result interface{}) (err error) {
   254  	return {{.S}}.DO.Scan(result)
   255  }
   256  
   257  func ({{.S}} {{.QueryStructName}}Do) Fetch(result interface{}) (err error) {
   258  	return {{.S}}.DO.Fetch(result)
   259  }
   260  
   261  func ({{.S}} {{.QueryStructName}}Do) Delete(models ...*{{.StructInfo.Package}}.{{.StructInfo.Type}}) (result gormgen.ResultInfo, err error) {
   262  	return {{.S}}.DO.Delete(models)
   263  }
   264  
   265  func ({{.S}} *{{.QueryStructName}}Do) withDO(do gormgen.Dao) (*{{.QueryStructName}}Do) {
   266  	{{.S}}.DO = *do.(*gormgen.DO)
   267  	return {{.S}}
   268  }
   269  
   270  `
   271  
   272  // CRUDMethodTest CRUD method test
   273  const CRUDMethodTest = `
   274  func init() {
   275  	InitializeDB()
   276  	err := db.AutoMigrate(&{{.StructInfo.Package}}.{{.ModelStructName}}{})
   277  	if err != nil{
   278  		fmt.Printf("Error: AutoMigrate(&{{.StructInfo.Package}}.{{.ModelStructName}}{}) fail: %s", err)
   279  	}
   280  }
   281  
   282  func Test_{{.QueryStructName}}Query(t *testing.T) {
   283  	{{.QueryStructName}} := new{{.ModelStructName}}(db)
   284  	{{.QueryStructName}} = *{{.QueryStructName}}.As({{.QueryStructName}}.TableName())
   285  	_do := {{.QueryStructName}}.WithContext(context.Background()).Debug()
   286  
   287  	primaryKey := field.NewString({{.QueryStructName}}.TableName(), clause.PrimaryKey)
   288  	_, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete()
   289  	if err != nil {
   290  		t.Error("clean table <{{.TableName}}> fail:", err)
   291  		return
   292  	}
   293  	
   294  	_, ok := {{.QueryStructName}}.GetFieldByName("")
   295  	if ok {
   296  		t.Error("GetFieldByName(\"\") from {{.QueryStructName}} success")
   297  	}
   298  
   299  	err = _do.Create(&{{.StructInfo.Package}}.{{.ModelStructName}}{})
   300  	if err != nil {
   301  		t.Error("create item in table <{{.TableName}}> fail:", err)
   302  	}
   303  
   304  	err = _do.Save(&{{.StructInfo.Package}}.{{.ModelStructName}}{})
   305  	if err != nil {
   306  		t.Error("create item in table <{{.TableName}}> fail:", err)
   307  	}
   308  
   309  	err = _do.CreateInBatches([]*{{.StructInfo.Package}}.{{.ModelStructName}}{ {}, {} }, 10)
   310  	if err != nil {
   311  		t.Error("create item in table <{{.TableName}}> fail:", err)
   312  	}
   313  
   314  	_, err = _do.Select({{.QueryStructName}}.ALL).Take()
   315  	if err != nil {
   316  		t.Error("Take() on table <{{.TableName}}> fail:", err)
   317  	}
   318  
   319  	_, err = _do.First()
   320  	if err != nil {
   321  		t.Error("First() on table <{{.TableName}}> fail:", err)
   322  	}
   323  
   324  	_, err = _do.Last()
   325  	if err != nil {
   326  		t.Error("First() on table <{{.TableName}}> fail:", err)
   327  	}
   328  
   329  	_, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gormgen.Dao, batch int) error { return nil })
   330  	if err != nil {
   331  		t.Error("FindInBatch() on table <{{.TableName}}> fail:", err)
   332  	}
   333  
   334  	err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*{{.StructInfo.Package}}.{{.ModelStructName}}{}, 10, func(tx gormgen.Dao, batch int) error { return nil })
   335  	if err != nil {
   336  		t.Error("FindInBatches() on table <{{.TableName}}> fail:", err)
   337  	}
   338  
   339  	_, err = _do.Select({{.QueryStructName}}.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find()
   340  	if err != nil {
   341  		t.Error("Find() on table <{{.TableName}}> fail:", err)
   342  	}
   343  
   344  	_, err = _do.Distinct(primaryKey).Take()
   345  	if err != nil {
   346  		t.Error("select Distinct() on table <{{.TableName}}> fail:", err)
   347  	}
   348  
   349  	_, err = _do.Select({{.QueryStructName}}.ALL).Omit(primaryKey).Take()
   350  	if err != nil {
   351  		t.Error("Omit() on table <{{.TableName}}> fail:", err)
   352  	}
   353  
   354  	_, err = _do.Group(primaryKey).Find()
   355  	if err != nil {
   356  		t.Error("Group() on table <{{.TableName}}> fail:", err)
   357  	}
   358  
   359  	_, err = _do.Scopes(func(dao gormgen.Dao) gormgen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find()
   360  	if err != nil {
   361  		t.Error("Scopes() on table <{{.TableName}}> fail:", err)
   362  	}
   363  
   364  	_, _, err = _do.FindByPage(0, 1)
   365  	if err != nil {
   366  		t.Error("FindByPage() on table <{{.TableName}}> fail:", err)
   367  	}
   368  	
   369  	_, err = _do.ScanByPage(&{{.StructInfo.Package}}.{{.ModelStructName}}{}, 0, 1)
   370  	if err != nil {
   371  		t.Error("ScanByPage() on table <{{.TableName}}> fail:", err)
   372  	}
   373  
   374  	_, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit()
   375  	if err != nil {
   376  		t.Error("FirstOrInit() on table <{{.TableName}}> fail:", err)
   377  	}
   378  
   379  	_, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate()
   380  	if err != nil {
   381  		t.Error("FirstOrCreate() on table <{{.TableName}}> fail:", err)
   382  	}
   383  	
   384  	var _a _another
   385  	var _aPK = field.NewString(_a.TableName(), clause.PrimaryKey)
   386  
   387  	err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{})
   388  	if err != nil {
   389  		t.Error("Join() on table <{{.TableName}}> fail:", err)
   390  	}
   391  
   392  	err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{})
   393  	if err != nil {
   394  		t.Error("LeftJoin() on table <{{.TableName}}> fail:", err)
   395  	}
   396  	
   397  	_, err = _do.Not().Or().Clauses().Take()
   398  	if err != nil {
   399  		t.Error("Not/Or/Clauses on table <{{.TableName}}> fail:", err)
   400  	}
   401  }
   402  `
   403  
   404  // DIYMethodTestBasic DIY method test basic
   405  const DIYMethodTestBasic = `
   406  type Input struct {
   407  	Args []interface{}
   408  }
   409  
   410  type Expectation struct {
   411  	Ret []interface{}
   412  }
   413  
   414  type TestCase struct {
   415  	Input
   416  	Expectation
   417  }
   418  
   419  `
   420  
   421  // DIYMethodTest DIY method test
   422  const DIYMethodTest = `
   423  
   424  var {{.OriginStruct.Type}}{{.MethodName}}TestCase = []TestCase{}
   425  
   426  func Test_{{.TargetStruct}}_{{.MethodName}}(t *testing.T) {
   427  	{{.TargetStruct}} := new{{.OriginStruct.Type}}(db)
   428  	do := {{.TargetStruct}}.WithContext(context.Background()).Debug()
   429  
   430  	for i, tt := range {{.OriginStruct.Type}}{{.MethodName}}TestCase {
   431  		t.Run("{{.MethodName}}_"+strconv.Itoa(i), func(t *testing.T) {
   432  			{{.GetTestResultParamInTmpl}} := do.{{.MethodName}}({{.GetTestParamInTmpl}})
   433  			{{.GetAssertInTmpl}}
   434  		})
   435  	}
   436  }
   437  
   438  `