github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/gormgen/field/export_test.go (about)

     1  package field_test
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/unionj-cloud/go-doudou/v2/toolkit/gormgen/field"
    11  )
    12  
    13  var _ field.ScanValuer = new(password)
    14  
    15  type password string
    16  
    17  func (p *password) Scan(src interface{}) error {
    18  	*p = password(fmt.Sprintf("this is password {%q}", src))
    19  	return nil
    20  }
    21  func (p password) Value() (driver.Value, error) {
    22  	return strings.TrimPrefix(strings.TrimSuffix(string(p), "}"), "this is password {"), nil
    23  }
    24  
    25  func TestExpr_Build(t *testing.T) {
    26  	timeData, _ := time.Parse("2006-01-02 15:04:05", "2021-06-29 15:11:49")
    27  	const p = password("i am password")
    28  
    29  	testcases := []struct {
    30  		Expr         field.Expr
    31  		ExpectedVars []interface{}
    32  		Result       string
    33  	}{
    34  		// ======================== generic ========================
    35  		{
    36  			Expr:         field.NewField("user", "password").Eq(p),
    37  			ExpectedVars: []interface{}{p},
    38  			Result:       "`user`.`password` = ?",
    39  		},
    40  		{
    41  			Expr:   field.NewField("", "id").EqCol(field.NewField("", "new_id")),
    42  			Result: "`id` = `new_id`",
    43  		},
    44  		{
    45  			Expr:   field.NewField("", "id").NeqCol(field.NewField("", "new_id")),
    46  			Result: "`id` <> `new_id`",
    47  		},
    48  		{
    49  			Expr:   field.NewField("", "id").LtCol(field.NewField("", "new_id")),
    50  			Result: "`id` < `new_id`",
    51  		},
    52  		{
    53  			Expr:   field.NewField("", "id").LteCol(field.NewField("", "new_id")),
    54  			Result: "`id` <= `new_id`",
    55  		},
    56  		{
    57  			Expr:   field.NewField("", "id").GtCol(field.NewField("", "new_id")),
    58  			Result: "`id` > `new_id`",
    59  		},
    60  		{
    61  			Expr:   field.NewField("", "id").GteCol(field.NewField("", "new_id")),
    62  			Result: "`id` >= `new_id`",
    63  		},
    64  		{
    65  			Expr:   field.NewField("", "id").EqCol(field.NewField("", "new_id").Avg()),
    66  			Result: "`id` = AVG(`new_id`)",
    67  		},
    68  		{
    69  			Expr:   field.NewField("", "id").EqCol(field.NewField("", "new_id").WithTable("tableB")),
    70  			Result: "`id` = `tableB`.`new_id`",
    71  		},
    72  		{
    73  			Expr:   field.NewField("", "id").EqCol(field.NewField("", "new_id").WithTable("tableB")),
    74  			Result: "`id` = `tableB`.`new_id`",
    75  		},
    76  		{
    77  			Expr:   field.NewField("", "id").NeqCol(field.NewField("", "new_id").WithTable("tableB")),
    78  			Result: "`id` <> `tableB`.`new_id`",
    79  		},
    80  		{
    81  			Expr:   field.NewField("", "id").IsNull(),
    82  			Result: "`id` IS NULL",
    83  		},
    84  		{
    85  			Expr:   field.NewField("", "id").IsNotNull(),
    86  			Result: "`id` IS NOT NULL",
    87  		},
    88  		{
    89  			Expr:   field.NewField("", "id").GroupConcat(),
    90  			Result: "GROUP_CONCAT(`id`)",
    91  		},
    92  		{
    93  			Expr:   field.Func.UnixTimestamp(),
    94  			Result: "UNIX_TIMESTAMP()",
    95  		},
    96  		{
    97  			Expr:         field.Func.UnixTimestamp("2005-03-27 03:00:00").Mul(99),
    98  			Result:       "(UNIX_TIMESTAMP(?))*?",
    99  			ExpectedVars: []interface{}{"2005-03-27 03:00:00", uint64(99)},
   100  		},
   101  		{
   102  			Expr:   field.NewInt("t1", "id").AddCol(field.NewInt("t2", "num")),
   103  			Result: "`t1`.`id` + `t2`.`num`",
   104  		},
   105  		{
   106  			Expr:   field.NewInt("t1", "id").AddCol(field.NewInt("t1", "num")).SubCol(field.NewInt("t1", "age")),
   107  			Result: "`t1`.`id` + `t1`.`num` - `t1`.`age`",
   108  		},
   109  		{
   110  			Expr:   field.NewInt("t1", "id").AddCol(field.NewInt("t1", "num")).SubCol(field.NewInt("t1", "age")).MulCol(field.NewInt("t1", "age")).DivCol(field.NewInt("t1", "base")),
   111  			Result: "((`t1`.`id` + `t1`.`num` - `t1`.`age`) * (`t1`.`age`)) / (`t1`.`base`)",
   112  		},
   113  		{
   114  			Expr:         field.NewInt("t1", "id").AddCol(field.NewInt("t2", "num").Add(1)),
   115  			Result:       "`t1`.`id` + `t2`.`num`+?",
   116  			ExpectedVars: []interface{}{int(1)},
   117  		},
   118  		{
   119  			Expr:         field.NewInt("t1", "id").EqCol(field.NewInt("t1", "id").AddCol(field.NewInt("t2", "num").Add(1))),
   120  			Result:       "`t1`.`id` = `t1`.`id` + `t2`.`num`+?",
   121  			ExpectedVars: []interface{}{int(1)},
   122  		},
   123  		{
   124  			Expr:         field.NewInt("t1", "a").AddCol(field.NewInt("t2", "b").Add(1)).(field.Field).GtCol(field.NewInt("t", "c")),
   125  			Result:       "`t1`.`a` + `t2`.`b`+? > `t`.`c`",
   126  			ExpectedVars: []interface{}{int(1)},
   127  		},
   128  		{
   129  			Expr:   field.ALL.Count(),
   130  			Result: "COUNT(*)",
   131  		},
   132  		{
   133  			Expr:   field.ALL.Distinct().Count(),
   134  			Result: "COUNT(DISTINCT *)",
   135  		},
   136  		{
   137  			Expr:   field.NewAsterisk("user").Count(),
   138  			Result: "COUNT(`user`.*)",
   139  		},
   140  		{
   141  			Expr:   field.NewAsterisk("user").Distinct().Count(),
   142  			Result: "COUNT(DISTINCT `user`.*)",
   143  		},
   144  		// ======================== integer ========================
   145  		{
   146  			Expr:   field.NewUint("", "id"),
   147  			Result: "`id`",
   148  		},
   149  		{
   150  			Expr:         field.NewUint("user", "id").Sum().Gt(100),
   151  			ExpectedVars: []interface{}{uint(100)},
   152  			Result:       "SUM(`user`.`id`) > ?",
   153  		},
   154  		{
   155  			Expr:   field.NewUint("", "i`d"),
   156  			Result: "`i``d`",
   157  		},
   158  		{
   159  			Expr:   field.NewUint("", "id").Avg(),
   160  			Result: "AVG(`id`)",
   161  		},
   162  		{
   163  			Expr:   field.NewUint("", "id").Desc(),
   164  			Result: "`id` DESC",
   165  		},
   166  		{
   167  			Expr:   field.NewUint("", "id").As("number"),
   168  			Result: "`id` AS `number`",
   169  		},
   170  		{
   171  			Expr:   field.NewUint("", "id").Avg().As("number"),
   172  			Result: "AVG(`id`) AS `number`",
   173  		},
   174  		{
   175  			Expr:         field.NewUint("", "id").Eq(10),
   176  			ExpectedVars: []interface{}{uint(10)},
   177  			Result:       "`id` = ?",
   178  		},
   179  		{
   180  			Expr:         field.NewUint("", "id").Neq(10),
   181  			ExpectedVars: []interface{}{uint(10)},
   182  			Result:       "`id` <> ?",
   183  		},
   184  		{
   185  			Expr:         field.NewUint("", "id").Gt(1),
   186  			ExpectedVars: []interface{}{uint(1)},
   187  			Result:       "`id` > ?",
   188  		},
   189  		{
   190  			Expr:         field.NewUint("", "id").Gte(1),
   191  			ExpectedVars: []interface{}{uint(1)},
   192  			Result:       "`id` >= ?",
   193  		},
   194  		{
   195  			Expr:         field.NewUint("", "id").Lt(1),
   196  			ExpectedVars: []interface{}{uint(1)},
   197  			Result:       "`id` < ?",
   198  		},
   199  		{
   200  			Expr:         field.NewUint("", "id").Lte(1),
   201  			ExpectedVars: []interface{}{uint(1)},
   202  			Result:       "`id` <= ?",
   203  		},
   204  		{
   205  			Expr:         field.NewUint("", "id").Mod(7),
   206  			ExpectedVars: []interface{}{uint(7)},
   207  			Result:       "`id`%?",
   208  		},
   209  		{
   210  			Expr:         field.And(field.NewUint("", "id").Gt(1), field.NewUint("", "id").Lt(10)),
   211  			ExpectedVars: []interface{}{uint(1), uint(10)},
   212  			Result:       "(`id` > ? AND `id` < ?)",
   213  		},
   214  		{
   215  			Expr:         field.Or(field.NewUint("", "id").Lt(4), field.NewUint("", "id").Gt(6)),
   216  			ExpectedVars: []interface{}{uint(4), uint(6)},
   217  			Result:       "(`id` < ? OR `id` > ?)",
   218  		},
   219  		{
   220  			Expr:         field.NewUint("", "id").In(1, 2, 3),
   221  			ExpectedVars: []interface{}{uint(1), uint(2), uint(3)},
   222  			Result:       "`id` IN (?,?,?)",
   223  		},
   224  		{
   225  			Expr:         field.NewUint("", "id").NotIn(1, 2, 3),
   226  			ExpectedVars: []interface{}{uint(1), uint(2), uint(3)},
   227  			Result:       "`id` NOT IN (?,?,?)",
   228  		},
   229  		{
   230  			Expr:         field.NewUint("", "id").Between(1, 10),
   231  			ExpectedVars: []interface{}{uint(1), uint(10)},
   232  			Result:       "`id` BETWEEN ? AND ?",
   233  		},
   234  		{
   235  			Expr:   field.NewUint("", "id").Count(),
   236  			Result: "COUNT(`id`)",
   237  		},
   238  		{
   239  			Expr:   field.NewUint("", "id").Count().As("UserID"),
   240  			Result: "COUNT(`id`) AS `UserID`",
   241  		},
   242  		{
   243  			Expr:   field.NewUint("", "id").Distinct(),
   244  			Result: "DISTINCT `id`",
   245  		},
   246  		{
   247  			Expr:   field.NewUint("", "id").Distinct().Count(),
   248  			Result: "COUNT(DISTINCT `id`)",
   249  		},
   250  		{
   251  			Expr:   field.NewUint("", "id").Distinct().Count().As("UserID"),
   252  			Result: "COUNT(DISTINCT `id`) AS `UserID`",
   253  		},
   254  		{
   255  			Expr:         field.NewInt("", "age").RightShift(3),
   256  			ExpectedVars: []interface{}{3},
   257  			Result:       "`age`>>?",
   258  		},
   259  		{
   260  			Expr:         field.NewInt("", "age").LeftShift(3),
   261  			ExpectedVars: []interface{}{3},
   262  			Result:       "`age`<<?",
   263  		},
   264  		{
   265  			Expr:         field.NewInt("", "age").Add(1).Mul(2).Div(3),
   266  			ExpectedVars: []interface{}{1, 2, 3},
   267  			Result:       "((`age`+?)*?)/?",
   268  		},
   269  		// ======================== float ========================
   270  		{
   271  			Expr:         field.NewFloat64("", "score").Add(3.0),
   272  			ExpectedVars: []interface{}{float64(3.0)},
   273  			Result:       "`score`+?",
   274  		},
   275  		{
   276  			Expr:         field.NewFloat64("", "score").Sub(3.0),
   277  			ExpectedVars: []interface{}{float64(3.0)},
   278  			Result:       "`score`-?",
   279  		},
   280  		{
   281  			Expr:         field.NewFloat64("", "score").Mul(3.0),
   282  			ExpectedVars: []interface{}{float64(3.0)},
   283  			Result:       "`score`*?",
   284  		},
   285  		{
   286  			Expr:         field.NewFloat64("", "score").Div(3.0),
   287  			ExpectedVars: []interface{}{float64(3.0)},
   288  			Result:       "`score`/?",
   289  		},
   290  		{
   291  			Expr:         field.NewFloat64("", "score").FloorDiv(3.0),
   292  			ExpectedVars: []interface{}{float64(3.0)},
   293  			Result:       "`score` DIV ?",
   294  		},
   295  		// ======================== string ========================
   296  		{
   297  			Expr:         field.NewString("", "name").Eq("tom"),
   298  			ExpectedVars: []interface{}{"tom"},
   299  			Result:       "`name` = ?",
   300  		},
   301  		{
   302  			Expr:         field.NewString("", "name").Neq("tom"),
   303  			ExpectedVars: []interface{}{"tom"},
   304  			Result:       "`name` <> ?",
   305  		},
   306  		{
   307  			Expr:         field.NewString("", "name").Like("%%tom%%"),
   308  			ExpectedVars: []interface{}{"%%tom%%"},
   309  			Result:       "`name` LIKE ?",
   310  		},
   311  		{
   312  			Expr:         field.NewString("", "name").NotLike("%%tom%%"),
   313  			ExpectedVars: []interface{}{"%%tom%%"},
   314  			Result:       "`name` NOT LIKE ?",
   315  		},
   316  		{
   317  			Expr:         field.NewString("", "name").Regexp(".*"),
   318  			ExpectedVars: []interface{}{".*"},
   319  			Result:       "`name` REGEXP ?",
   320  		},
   321  		{
   322  			Expr:         field.NewString("", "name").NotRegxp(".*"),
   323  			ExpectedVars: []interface{}{".*"},
   324  			Result:       "NOT `name` REGEXP ?",
   325  		},
   326  		{
   327  			Expr:         field.NewString("", "address").FindInSetWith("sh"),
   328  			ExpectedVars: []interface{}{"sh"},
   329  			Result:       "FIND_IN_SET(?,`address`)",
   330  		},
   331  		{
   332  			Expr:         field.NewString("", "address").FindInSet("sh"),
   333  			ExpectedVars: []interface{}{"sh"},
   334  			Result:       "FIND_IN_SET(`address`,?)",
   335  		},
   336  		{
   337  			Expr:         field.NewString("", "address").Replace("address", "path"),
   338  			ExpectedVars: []interface{}{"address", "path"},
   339  			Result:       "REPLACE(`address`,?,?)",
   340  		},
   341  		{
   342  			Expr:         field.NewString("", "address").Concat("[", "]"),
   343  			ExpectedVars: []interface{}{"[", "]"},
   344  			Result:       "CONCAT(?,`address`,?)",
   345  		},
   346  		{
   347  			Expr:         field.NewString("", "address").Concat("", "_"),
   348  			ExpectedVars: []interface{}{"_"},
   349  			Result:       "CONCAT(`address`,?)",
   350  		},
   351  		{
   352  			Expr:         field.NewString("", "address").Replace("address", "path").Concat("[", "]"),
   353  			ExpectedVars: []interface{}{"[", "address", "path", "]"},
   354  			Result:       "CONCAT(?,REPLACE(`address`,?,?),?)",
   355  		},
   356  		// ======================== time ========================
   357  		{
   358  			Expr:         field.NewTime("", "creatAt").Eq(timeData),
   359  			ExpectedVars: []interface{}{timeData},
   360  			Result:       "`creatAt` = ?",
   361  		},
   362  		{
   363  			Expr:         field.NewTime("", "creatAt").Gt(timeData),
   364  			ExpectedVars: []interface{}{timeData},
   365  			Result:       "`creatAt` > ?",
   366  		},
   367  		{
   368  			Expr:         field.NewTime("", "creatAt").Gte(timeData),
   369  			ExpectedVars: []interface{}{timeData},
   370  			Result:       "`creatAt` >= ?",
   371  		},
   372  		{
   373  			Expr:         field.NewTime("", "creatAt").Lt(timeData),
   374  			ExpectedVars: []interface{}{timeData},
   375  			Result:       "`creatAt` < ?",
   376  		},
   377  		{
   378  			Expr:         field.NewTime("", "creatAt").Lte(timeData),
   379  			ExpectedVars: []interface{}{timeData},
   380  			Result:       "`creatAt` <= ?",
   381  		},
   382  		{
   383  			Expr:         field.NewTime("", "creatAt").Between(timeData, timeData.Add(24*time.Hour)),
   384  			ExpectedVars: []interface{}{timeData, timeData.Add(24 * time.Hour)},
   385  			Result:       "`creatAt` BETWEEN ? AND ?",
   386  		},
   387  		{
   388  			Expr:         field.NewTime("", "creatAt").Add(24 * time.Hour),
   389  			ExpectedVars: []interface{}{time.Duration(24 * time.Hour).Microseconds()},
   390  			Result:       "DATE_ADD(`creatAt`, INTERVAL ? MICROSECOND)",
   391  		},
   392  		{
   393  			Expr:         field.NewTime("", "creatAt").Sub(24 * time.Hour),
   394  			ExpectedVars: []interface{}{time.Duration(24 * time.Hour).Microseconds()},
   395  			Result:       "DATE_SUB(`creatAt`, INTERVAL ? MICROSECOND)",
   396  		},
   397  		{
   398  			Expr:         field.NewTime("", "updateAt").DateFormat("%W %M %Y"),
   399  			ExpectedVars: []interface{}{"%W %M %Y"},
   400  			Result:       "DATE_FORMAT(`updateAt`,?)",
   401  		},
   402  		// ======================== bool ========================
   403  		{
   404  			Expr:   field.NewBool("", "male").Not(),
   405  			Result: "NOT `male`",
   406  		},
   407  		{
   408  			Expr:         field.NewBool("", "male").Is(true),
   409  			ExpectedVars: []interface{}{true},
   410  			Result:       "`male` = ?",
   411  		},
   412  		{
   413  			Expr:         field.NewBool("", "male").And(true),
   414  			ExpectedVars: []interface{}{true},
   415  			Result:       "`male` AND ?",
   416  		},
   417  		{
   418  			Expr:         field.NewBool("", "male").Or(true),
   419  			ExpectedVars: []interface{}{true},
   420  			Result:       "`male` OR ?",
   421  		},
   422  	}
   423  
   424  	for _, testcase := range testcases {
   425  		field.CheckBuildExpr(t, testcase.Expr, testcase.Result, testcase.ExpectedVars)
   426  	}
   427  }
   428  
   429  func TestExpr_BuildColumn(t *testing.T) {
   430  	stmt := field.GetStatement()
   431  	id := field.NewUint("user", "id")
   432  	expectColumnStr := "`id`"
   433  	expectColumnStrWithTable := "`user`.`id`"
   434  	expectColumnStrWithoutQuote := "id"
   435  	expectColumnStrWithTableWithoutQuote := "user.id"
   436  
   437  	if colStr := id.BuildColumn(stmt).String(); colStr != expectColumnStr {
   438  		t.Errorf("id.BuildColumn(stmt).String() got: %q, except: %q", colStr, expectColumnStr)
   439  	}
   440  	if colStr := id.BuildColumn(stmt, field.WithTable).String(); colStr != expectColumnStrWithTable {
   441  		t.Errorf("id.BuildColumn(stmt, field.WithTable).String() got: %q, except: %q", colStr, expectColumnStrWithTable)
   442  	}
   443  	if colStr := id.BuildColumn(stmt, field.WithoutQuote).String(); colStr != expectColumnStrWithoutQuote {
   444  		t.Errorf("id.BuildColumn(stmt, field.WithoutQuote).String() got: %q, except: %q", colStr, expectColumnStrWithoutQuote)
   445  	}
   446  	if colStr := id.BuildColumn(stmt, field.WithTable, field.WithoutQuote).String(); colStr != expectColumnStrWithTableWithoutQuote {
   447  		t.Errorf("id.BuildColumn(stmt, field.WithTable, field.WithoutQuote).String() got: %q, except: %q", colStr, expectColumnStrWithTableWithoutQuote)
   448  	}
   449  
   450  	expectStarColumnStr := "*"
   451  	if colStr := field.Star.BuildColumn(stmt).String(); colStr != expectStarColumnStr {
   452  		t.Errorf("field.Star.BuildColumn(stmt).String() got: %q, except: %q", colStr, expectStarColumnStr)
   453  	}
   454  
   455  	allField := field.NewString("user", "*")
   456  	expectStarColumnStrWithTable := "`user`.*"
   457  	if colStr := allField.BuildColumn(stmt, field.WithTable).String(); colStr != expectStarColumnStrWithTable {
   458  		t.Errorf("allField.BuildColumn(stmt, field.WithTable).String() got: %q, except: %q", colStr, expectStarColumnStrWithTable)
   459  	}
   460  }
   461  
   462  func BenchmarkExpr_Count(b *testing.B) {
   463  	id := field.NewUint("", "id")
   464  	for i := 0; i < b.N; i++ {
   465  		n := id.Count()
   466  		_ = n
   467  	}
   468  }
   469  
   470  func TestRelation_StructField(t *testing.T) {
   471  	var testdatas = []struct {
   472  		relation      *field.Relation
   473  		expectedValue string
   474  	}{
   475  		{
   476  			relation: field.NewRelation(
   477  				"CreditCards", "model.CreditCard",
   478  				*field.NewRelation("Owner", "model.Owner"),
   479  				*field.NewRelation("Bank", "model.Bank",
   480  					*field.NewRelation("Manager", "model.Bank"),
   481  					*field.NewRelation("City", "model.City",
   482  						*field.NewRelation("State", "model.Bank"),
   483  					),
   484  				),
   485  			),
   486  			expectedValue: "Owner struct {\nfield.RelationField\n}\nBank struct {\nfield.RelationField\nManager struct {\nfield.RelationField\n}\nCity struct {\nfield.RelationField\nState struct {\nfield.RelationField\n}\n}\n}\n",
   487  		},
   488  	}
   489  
   490  	for _, testdata := range testdatas {
   491  		if result := testdata.relation.StructField(); result != testdata.expectedValue {
   492  			t.Errorf("StructField fail: except %q, got %q", testdata.expectedValue, result)
   493  		}
   494  	}
   495  }
   496  
   497  func TestRelation_StructFieldInit(t *testing.T) {
   498  	var testdatas = []struct {
   499  		relation      *field.Relation
   500  		expectedValue string
   501  	}{
   502  		{
   503  			relation: field.NewRelation(
   504  				"CreditCards", "model.CreditCard",
   505  				*field.NewRelation("Owner", "model.Owner"),
   506  				*field.NewRelation("Bank", "model.Bank",
   507  					*field.NewRelation("Manager", "model.Manager"),
   508  					*field.NewRelation("City", "model.City",
   509  						*field.NewRelation("State", "model.State"),
   510  					),
   511  				),
   512  			),
   513  			expectedValue: "RelationField: field.NewRelation(\"CreditCards\", \"model.CreditCard\"),\nOwner: struct {\nfield.RelationField\n}{\nRelationField: field.NewRelation(\"CreditCards.Owner\", \"model.Owner\"),\n},\nBank: struct {\nfield.RelationField\nManager struct {\nfield.RelationField\n}\nCity struct {\nfield.RelationField\nState struct {\nfield.RelationField\n}\n}}{\nRelationField: field.NewRelation(\"CreditCards.Bank\", \"model.Bank\"),\nManager: struct {\nfield.RelationField\n}{\nRelationField: field.NewRelation(\"CreditCards.Bank.Manager\", \"model.Manager\"),\n},\nCity: struct {\nfield.RelationField\nState struct {\nfield.RelationField\n}}{\nRelationField: field.NewRelation(\"CreditCards.Bank.City\", \"model.City\"),\nState: struct {\nfield.RelationField\n}{\nRelationField: field.NewRelation(\"CreditCards.Bank.City.State\", \"model.State\"),\n},\n},\n},\n",
   514  		},
   515  	}
   516  
   517  	for _, testdata := range testdatas {
   518  		if result := testdata.relation.StructFieldInit(); result != testdata.expectedValue {
   519  			t.Errorf("StructField fail: except %q, got %q", testdata.expectedValue, result)
   520  		}
   521  	}
   522  }
   523  
   524  func expectedStruct() { // nolint
   525  	_ = struct {
   526  		field.RelationField
   527  		Owner struct {
   528  			field.RelationField
   529  		}
   530  		Bank struct {
   531  			field.RelationField
   532  			Manager struct {
   533  				field.RelationField
   534  			}
   535  			City struct {
   536  				field.RelationField
   537  				State struct {
   538  					field.RelationField
   539  				}
   540  			}
   541  		}
   542  	}{
   543  		RelationField: field.NewRelation("CreditCards", "model.CreditCard"),
   544  		Owner: struct {
   545  			field.RelationField
   546  		}{
   547  			RelationField: field.NewRelation("CreditCards.Owner", "model.Owner"),
   548  		},
   549  		Bank: struct {
   550  			field.RelationField
   551  			Manager struct {
   552  				field.RelationField
   553  			}
   554  			City struct {
   555  				field.RelationField
   556  				State struct {
   557  					field.RelationField
   558  				}
   559  			}
   560  		}{
   561  			RelationField: field.NewRelation("CreditCards.Bank", "model.Bank"),
   562  			Manager: struct {
   563  				field.RelationField
   564  			}{
   565  				RelationField: field.NewRelation("CreditCards.Bank.Manager", "model.Manager"),
   566  			},
   567  			City: struct {
   568  				field.RelationField
   569  				State struct {
   570  					field.RelationField
   571  				}
   572  			}{
   573  				RelationField: field.NewRelation("CreditCards.Bank.City", "model.City"),
   574  				State: struct {
   575  					field.RelationField
   576  				}{
   577  					RelationField: field.NewRelation("CreditCards.Bank.City.State", "model.State"),
   578  				},
   579  			},
   580  		},
   581  	}
   582  }