github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/queries/eager_load_test.go (about)

     1  package queries
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/volatiletech/sqlboiler/v4/boil"
     9  )
    10  
    11  var testEagerCounters struct {
    12  	ChildOne   int
    13  	ChildMany  int
    14  	NestedOne  int
    15  	NestedMany int
    16  }
    17  
    18  type testEager struct {
    19  	ID int
    20  	R  *testEagerR
    21  	L  testEagerL
    22  }
    23  
    24  type testEagerR struct {
    25  	ChildOne  *testEagerChild
    26  	ChildMany []*testEagerChild
    27  	ZeroOne   *testEagerZero
    28  	ZeroMany  []*testEagerZero
    29  }
    30  type testEagerL struct {
    31  }
    32  
    33  type testEagerChild struct {
    34  	ID int
    35  	R  *testEagerChildR
    36  	L  testEagerChildL
    37  }
    38  type testEagerChildR struct {
    39  	NestedOne  *testEagerNested
    40  	NestedMany []*testEagerNested
    41  }
    42  type testEagerChildL struct {
    43  }
    44  
    45  type testEagerNested struct {
    46  	ID int
    47  	R  *testEagerNestedR
    48  	L  testEagerNestedL
    49  }
    50  type testEagerNestedR struct {
    51  }
    52  type testEagerNestedL struct {
    53  }
    54  
    55  type testEagerZero struct {
    56  	ID int
    57  	R  *testEagerZeroR
    58  	L  testEagerZeroL
    59  }
    60  type testEagerZeroR struct {
    61  	NestedOne  *testEagerNested
    62  	NestedMany []*testEagerNested
    63  }
    64  type testEagerZeroL struct {
    65  }
    66  
    67  func (testEagerL) LoadChildOne(_ boil.Executor, singular bool, obj interface{}, mods Applicator) error {
    68  	var toSetOn []*testEager
    69  	if singular {
    70  		toSetOn = []*testEager{obj.(*testEager)}
    71  	} else {
    72  		toSetOn = *obj.(*[]*testEager)
    73  	}
    74  
    75  	for _, o := range toSetOn {
    76  		if o.R == nil {
    77  			o.R = &testEagerR{}
    78  		}
    79  		o.R.ChildOne = &testEagerChild{ID: 11}
    80  	}
    81  
    82  	testEagerCounters.ChildOne++
    83  
    84  	return nil
    85  }
    86  
    87  func (testEagerL) LoadChildMany(_ boil.Executor, singular bool, obj interface{}, mods Applicator) error {
    88  	var toSetOn []*testEager
    89  	if singular {
    90  		toSetOn = []*testEager{obj.(*testEager)}
    91  	} else {
    92  		toSetOn = *obj.(*[]*testEager)
    93  	}
    94  
    95  	for _, o := range toSetOn {
    96  		if o.R == nil {
    97  			o.R = &testEagerR{}
    98  		}
    99  		o.R.ChildMany = []*testEagerChild{
   100  			&testEagerChild{ID: 12},
   101  			&testEagerChild{ID: 13},
   102  		}
   103  	}
   104  
   105  	testEagerCounters.ChildMany++
   106  
   107  	return nil
   108  }
   109  
   110  func (testEagerChildL) LoadNestedOne(_ boil.Executor, singular bool, obj interface{}, mods Applicator) error {
   111  	var toSetOn []*testEagerChild
   112  	if singular {
   113  		toSetOn = []*testEagerChild{obj.(*testEagerChild)}
   114  	} else {
   115  		toSetOn = *obj.(*[]*testEagerChild)
   116  	}
   117  
   118  	for _, o := range toSetOn {
   119  		if o.R == nil {
   120  			o.R = &testEagerChildR{}
   121  		}
   122  		o.R.NestedOne = &testEagerNested{ID: 21}
   123  	}
   124  
   125  	testEagerCounters.NestedOne++
   126  
   127  	return nil
   128  }
   129  
   130  func (testEagerChildL) LoadNestedMany(_ boil.Executor, singular bool, obj interface{}, mods Applicator) error {
   131  	var toSetOn []*testEagerChild
   132  	if singular {
   133  		toSetOn = []*testEagerChild{obj.(*testEagerChild)}
   134  	} else {
   135  		toSetOn = *obj.(*[]*testEagerChild)
   136  	}
   137  
   138  	for _, o := range toSetOn {
   139  		if o.R == nil {
   140  			o.R = &testEagerChildR{}
   141  		}
   142  		o.R.NestedMany = []*testEagerNested{
   143  			&testEagerNested{ID: 22},
   144  			&testEagerNested{ID: 23},
   145  		}
   146  	}
   147  
   148  	testEagerCounters.NestedMany++
   149  
   150  	return nil
   151  }
   152  
   153  func (testEagerL) LoadZeroOne(_ boil.Executor, singular bool, obj interface{}, mods Applicator) error {
   154  	var toSetOn []*testEager
   155  	if singular {
   156  		toSetOn = []*testEager{obj.(*testEager)}
   157  	} else {
   158  		toSetOn = *obj.(*[]*testEager)
   159  	}
   160  
   161  	for _, o := range toSetOn {
   162  		if o.R == nil {
   163  			o.R = &testEagerR{}
   164  		}
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  func (testEagerL) LoadZeroMany(_ boil.Executor, singular bool, obj interface{}, mods Applicator) error {
   171  	var toSetOn []*testEager
   172  	if singular {
   173  		toSetOn = []*testEager{obj.(*testEager)}
   174  	} else {
   175  		toSetOn = *obj.(*[]*testEager)
   176  	}
   177  
   178  	for _, o := range toSetOn {
   179  		if o.R == nil {
   180  			o.R = &testEagerR{}
   181  		}
   182  		o.R.ZeroMany = []*testEagerZero{}
   183  	}
   184  	return nil
   185  }
   186  
   187  func (testEagerZeroL) LoadNestedOne(_ boil.Executor, singular bool, obj interface{}, mods Applicator) error {
   188  	return nil
   189  }
   190  
   191  func (testEagerZeroL) LoadNestedMany(_ boil.Executor, singular bool, obj interface{}, mods Applicator) error {
   192  	return nil
   193  }
   194  
   195  func TestEagerLoadFromOne(t *testing.T) {
   196  	testEagerCounters.ChildOne = 0
   197  	testEagerCounters.ChildMany = 0
   198  	testEagerCounters.NestedOne = 0
   199  	testEagerCounters.NestedMany = 0
   200  
   201  	obj := &testEager{}
   202  
   203  	toLoad := []string{"ChildOne.NestedMany", "ChildOne.NestedOne", "ChildMany.NestedMany", "ChildMany.NestedOne"}
   204  	err := eagerLoad(nil, nil, toLoad, nil, obj, kindStruct)
   205  	if err != nil {
   206  		t.Fatal(err)
   207  	}
   208  
   209  	if testEagerCounters.ChildMany != 1 {
   210  		t.Error(testEagerCounters.ChildMany)
   211  	}
   212  	if testEagerCounters.ChildOne != 1 {
   213  		t.Error(testEagerCounters.ChildOne)
   214  	}
   215  	if testEagerCounters.NestedMany != 2 {
   216  		t.Error(testEagerCounters.NestedMany)
   217  	}
   218  	if testEagerCounters.NestedOne != 2 {
   219  		t.Error(testEagerCounters.NestedOne)
   220  	}
   221  
   222  	checkChildOne(obj.R.ChildOne)
   223  	checkChildMany(obj.R.ChildMany)
   224  
   225  	checkNestedOne(obj.R.ChildOne.R.NestedOne)
   226  	checkNestedOne(obj.R.ChildMany[0].R.NestedOne)
   227  	checkNestedOne(obj.R.ChildMany[1].R.NestedOne)
   228  
   229  	checkNestedMany(obj.R.ChildOne.R.NestedMany)
   230  	checkNestedMany(obj.R.ChildMany[0].R.NestedMany)
   231  	checkNestedMany(obj.R.ChildMany[1].R.NestedMany)
   232  }
   233  
   234  func TestEagerLoadFromMany(t *testing.T) {
   235  	testEagerCounters.ChildOne = 0
   236  	testEagerCounters.ChildMany = 0
   237  	testEagerCounters.NestedOne = 0
   238  	testEagerCounters.NestedMany = 0
   239  
   240  	slice := []*testEager{
   241  		{ID: -1},
   242  		{ID: -2},
   243  	}
   244  
   245  	toLoad := []string{"ChildOne.NestedMany", "ChildOne.NestedOne", "ChildMany.NestedMany", "ChildMany.NestedOne"}
   246  	err := eagerLoad(nil, nil, toLoad, nil, &slice, kindPtrSliceStruct)
   247  	if err != nil {
   248  		t.Fatal(err)
   249  	}
   250  
   251  	if testEagerCounters.ChildMany != 1 {
   252  		t.Error(testEagerCounters.ChildMany)
   253  	}
   254  	if testEagerCounters.ChildOne != 1 {
   255  		t.Error(testEagerCounters.ChildOne)
   256  	}
   257  	if testEagerCounters.NestedMany != 2 {
   258  		t.Error(testEagerCounters.NestedMany)
   259  	}
   260  	if testEagerCounters.NestedOne != 2 {
   261  		t.Error(testEagerCounters.NestedOne)
   262  	}
   263  
   264  	checkChildOne(slice[0].R.ChildOne)
   265  	checkChildOne(slice[1].R.ChildOne)
   266  	checkChildMany(slice[0].R.ChildMany)
   267  	checkChildMany(slice[1].R.ChildMany)
   268  
   269  	checkNestedOne(slice[0].R.ChildOne.R.NestedOne)
   270  	checkNestedOne(slice[0].R.ChildMany[0].R.NestedOne)
   271  	checkNestedOne(slice[0].R.ChildMany[1].R.NestedOne)
   272  	checkNestedOne(slice[1].R.ChildOne.R.NestedOne)
   273  	checkNestedOne(slice[1].R.ChildMany[0].R.NestedOne)
   274  	checkNestedOne(slice[1].R.ChildMany[1].R.NestedOne)
   275  
   276  	checkNestedMany(slice[0].R.ChildOne.R.NestedMany)
   277  	checkNestedMany(slice[0].R.ChildMany[0].R.NestedMany)
   278  	checkNestedMany(slice[0].R.ChildMany[1].R.NestedMany)
   279  	checkNestedMany(slice[1].R.ChildOne.R.NestedMany)
   280  	checkNestedMany(slice[1].R.ChildMany[0].R.NestedMany)
   281  	checkNestedMany(slice[1].R.ChildMany[1].R.NestedMany)
   282  }
   283  
   284  func TestEagerLoadZeroParents(t *testing.T) {
   285  	t.Parallel()
   286  
   287  	obj := &testEager{}
   288  
   289  	toLoad := []string{"ZeroMany.NestedMany", "ZeroOne.NestedOne", "ZeroMany.NestedMany", "ZeroOne.NestedOne"}
   290  	err := eagerLoad(nil, nil, toLoad, nil, obj, kindStruct)
   291  	if err != nil {
   292  		t.Fatal(err)
   293  	}
   294  
   295  	if len(obj.R.ZeroMany) != 0 {
   296  		t.Error("should have loaded nothing")
   297  	}
   298  	if obj.R.ZeroOne != nil {
   299  		t.Error("should have loaded nothing")
   300  	}
   301  }
   302  
   303  func TestEagerLoadZeroParentsMany(t *testing.T) {
   304  	t.Parallel()
   305  
   306  	obj := []*testEager{
   307  		&testEager{},
   308  		&testEager{},
   309  	}
   310  
   311  	toLoad := []string{"ZeroMany.NestedMany", "ZeroOne.NestedOne", "ZeroMany.NestedMany", "ZeroOne.NestedOne"}
   312  	err := eagerLoad(nil, nil, toLoad, nil, &obj, kindPtrSliceStruct)
   313  	if err != nil {
   314  		t.Fatal(err)
   315  	}
   316  
   317  	if len(obj[0].R.ZeroMany) != 0 {
   318  		t.Error("should have loaded nothing")
   319  	}
   320  	if obj[0].R.ZeroOne != nil {
   321  		t.Error("should have loaded nothing")
   322  	}
   323  	if len(obj[1].R.ZeroMany) != 0 {
   324  		t.Error("should have loaded nothing")
   325  	}
   326  	if obj[1].R.ZeroOne != nil {
   327  		t.Error("should have loaded nothing")
   328  	}
   329  }
   330  
   331  func TestCollectLoadedNils(t *testing.T) {
   332  	t.Parallel()
   333  
   334  	obj := []*testEager{
   335  		&testEager{R: &testEagerR{}},
   336  		&testEager{R: &testEagerR{}},
   337  	}
   338  
   339  	loaded, _, err := collectLoaded("ChildMany", reflect.ValueOf(obj))
   340  	collected := loaded.Interface().([]*testEagerChild)
   341  	if err != nil {
   342  		t.Fatal(err)
   343  	}
   344  
   345  	for _, c := range collected {
   346  		if c == nil {
   347  			t.Error("it should not be possible to get a nil")
   348  		}
   349  	}
   350  
   351  	loaded, _, err = collectLoaded("ChildOne", reflect.ValueOf(obj))
   352  	collected = loaded.Interface().([]*testEagerChild)
   353  	if err != nil {
   354  		t.Fatal(err)
   355  	}
   356  
   357  	for _, c := range collected {
   358  		if c == nil {
   359  			t.Error("it should not be possible to get a nil")
   360  		}
   361  	}
   362  }
   363  
   364  func checkChildOne(c *testEagerChild) {
   365  	if c == nil {
   366  		panic("c was nil")
   367  	}
   368  
   369  	if c.ID != 11 {
   370  		panic(fmt.Sprintf("ChildOne id was not loaded correctly: %d", c.ID))
   371  	}
   372  }
   373  
   374  func checkChildMany(cs []*testEagerChild) {
   375  	if len(cs) != 2 {
   376  		panic("cs len was not 2")
   377  	}
   378  
   379  	if cs[0].ID != 12 {
   380  		panic(fmt.Sprintf("cs[0] had wrong id: %d", cs[0].ID))
   381  	}
   382  	if cs[1].ID != 13 {
   383  		panic(fmt.Sprintf("cs[1] had wrong id: %d", cs[1].ID))
   384  	}
   385  }
   386  
   387  func checkNestedOne(n *testEagerNested) {
   388  	if n == nil {
   389  		panic("n was nil")
   390  	}
   391  
   392  	if n.ID != 21 {
   393  		panic(fmt.Sprintf("NestedOne id was not loaded correctly: %d", n.ID))
   394  	}
   395  }
   396  
   397  func checkNestedMany(ns []*testEagerNested) {
   398  	if len(ns) != 2 {
   399  		panic("ns len was not 2")
   400  	}
   401  
   402  	if ns[0].ID != 22 {
   403  		panic(fmt.Sprintf("ns[0] had wrong id: %d", ns[0].ID))
   404  	}
   405  	if ns[1].ID != 23 {
   406  		panic(fmt.Sprintf("ns[1] had wrong id: %d", ns[1].ID))
   407  	}
   408  }