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 }