preload_test.go 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701
  1. package gorm_test
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "os"
  6. "reflect"
  7. "testing"
  8. "github.com/jinzhu/gorm"
  9. )
  10. func getPreloadUser(name string) *User {
  11. return getPreparedUser(name, "Preload")
  12. }
  13. func checkUserHasPreloadData(user User, t *testing.T) {
  14. u := getPreloadUser(user.Name)
  15. if user.BillingAddress.Address1 != u.BillingAddress.Address1 {
  16. t.Error("Failed to preload user's BillingAddress")
  17. }
  18. if user.ShippingAddress.Address1 != u.ShippingAddress.Address1 {
  19. t.Error("Failed to preload user's ShippingAddress")
  20. }
  21. if user.CreditCard.Number != u.CreditCard.Number {
  22. t.Error("Failed to preload user's CreditCard")
  23. }
  24. if user.Company.Name != u.Company.Name {
  25. t.Error("Failed to preload user's Company")
  26. }
  27. if len(user.Emails) != len(u.Emails) {
  28. t.Error("Failed to preload user's Emails")
  29. } else {
  30. var found int
  31. for _, e1 := range u.Emails {
  32. for _, e2 := range user.Emails {
  33. if e1.Email == e2.Email {
  34. found++
  35. break
  36. }
  37. }
  38. }
  39. if found != len(u.Emails) {
  40. t.Error("Failed to preload user's email details")
  41. }
  42. }
  43. }
  44. func TestPreload(t *testing.T) {
  45. user1 := getPreloadUser("user1")
  46. DB.Save(user1)
  47. preloadDB := DB.Where("role = ?", "Preload").Preload("BillingAddress").Preload("ShippingAddress").
  48. Preload("CreditCard").Preload("Emails").Preload("Company")
  49. var user User
  50. preloadDB.Find(&user)
  51. checkUserHasPreloadData(user, t)
  52. user2 := getPreloadUser("user2")
  53. DB.Save(user2)
  54. user3 := getPreloadUser("user3")
  55. DB.Save(user3)
  56. var users []User
  57. preloadDB.Find(&users)
  58. for _, user := range users {
  59. checkUserHasPreloadData(user, t)
  60. }
  61. var users2 []*User
  62. preloadDB.Find(&users2)
  63. for _, user := range users2 {
  64. checkUserHasPreloadData(*user, t)
  65. }
  66. var users3 []*User
  67. preloadDB.Preload("Emails", "email = ?", user3.Emails[0].Email).Find(&users3)
  68. for _, user := range users3 {
  69. if user.Name == user3.Name {
  70. if len(user.Emails) != 1 {
  71. t.Errorf("should only preload one emails for user3 when with condition")
  72. }
  73. } else if len(user.Emails) != 0 {
  74. t.Errorf("should not preload any emails for other users when with condition")
  75. } else if user.Emails == nil {
  76. t.Errorf("should return an empty slice to indicate zero results")
  77. }
  78. }
  79. }
  80. func TestAutoPreload(t *testing.T) {
  81. user1 := getPreloadUser("auto_user1")
  82. DB.Save(user1)
  83. preloadDB := DB.Set("gorm:auto_preload", true).Where("role = ?", "Preload")
  84. var user User
  85. preloadDB.Find(&user)
  86. checkUserHasPreloadData(user, t)
  87. user2 := getPreloadUser("auto_user2")
  88. DB.Save(user2)
  89. var users []User
  90. preloadDB.Find(&users)
  91. for _, user := range users {
  92. checkUserHasPreloadData(user, t)
  93. }
  94. var users2 []*User
  95. preloadDB.Find(&users2)
  96. for _, user := range users2 {
  97. checkUserHasPreloadData(*user, t)
  98. }
  99. }
  100. func TestAutoPreloadFalseDoesntPreload(t *testing.T) {
  101. user1 := getPreloadUser("auto_user1")
  102. DB.Save(user1)
  103. preloadDB := DB.Set("gorm:auto_preload", false).Where("role = ?", "Preload")
  104. var user User
  105. preloadDB.Find(&user)
  106. if user.BillingAddress.Address1 != "" {
  107. t.Error("AutoPreload was set to fasle, but still fetched data")
  108. }
  109. user2 := getPreloadUser("auto_user2")
  110. DB.Save(user2)
  111. var users []User
  112. preloadDB.Find(&users)
  113. for _, user := range users {
  114. if user.BillingAddress.Address1 != "" {
  115. t.Error("AutoPreload was set to fasle, but still fetched data")
  116. }
  117. }
  118. }
  119. func TestNestedPreload1(t *testing.T) {
  120. type (
  121. Level1 struct {
  122. ID uint
  123. Value string
  124. Level2ID uint
  125. }
  126. Level2 struct {
  127. ID uint
  128. Level1 Level1
  129. Level3ID uint
  130. }
  131. Level3 struct {
  132. ID uint
  133. Name string
  134. Level2 Level2
  135. }
  136. )
  137. DB.DropTableIfExists(&Level3{})
  138. DB.DropTableIfExists(&Level2{})
  139. DB.DropTableIfExists(&Level1{})
  140. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  141. t.Error(err)
  142. }
  143. want := Level3{Level2: Level2{Level1: Level1{Value: "value"}}}
  144. if err := DB.Create(&want).Error; err != nil {
  145. t.Error(err)
  146. }
  147. var got Level3
  148. if err := DB.Preload("Level2").Preload("Level2.Level1").Find(&got).Error; err != nil {
  149. t.Error(err)
  150. }
  151. if !reflect.DeepEqual(got, want) {
  152. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  153. }
  154. if err := DB.Preload("Level2").Preload("Level2.Level1").Find(&got, "name = ?", "not_found").Error; err != gorm.ErrRecordNotFound {
  155. t.Error(err)
  156. }
  157. }
  158. func TestNestedPreload2(t *testing.T) {
  159. type (
  160. Level1 struct {
  161. ID uint
  162. Value string
  163. Level2ID uint
  164. }
  165. Level2 struct {
  166. ID uint
  167. Level1s []*Level1
  168. Level3ID uint
  169. }
  170. Level3 struct {
  171. ID uint
  172. Name string
  173. Level2s []Level2
  174. }
  175. )
  176. DB.DropTableIfExists(&Level3{})
  177. DB.DropTableIfExists(&Level2{})
  178. DB.DropTableIfExists(&Level1{})
  179. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  180. t.Error(err)
  181. }
  182. want := Level3{
  183. Level2s: []Level2{
  184. {
  185. Level1s: []*Level1{
  186. {Value: "value1"},
  187. {Value: "value2"},
  188. },
  189. },
  190. {
  191. Level1s: []*Level1{
  192. {Value: "value3"},
  193. },
  194. },
  195. },
  196. }
  197. if err := DB.Create(&want).Error; err != nil {
  198. t.Error(err)
  199. }
  200. var got Level3
  201. if err := DB.Preload("Level2s.Level1s").Find(&got).Error; err != nil {
  202. t.Error(err)
  203. }
  204. if !reflect.DeepEqual(got, want) {
  205. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  206. }
  207. }
  208. func TestNestedPreload3(t *testing.T) {
  209. type (
  210. Level1 struct {
  211. ID uint
  212. Value string
  213. Level2ID uint
  214. }
  215. Level2 struct {
  216. ID uint
  217. Level1 Level1
  218. Level3ID uint
  219. }
  220. Level3 struct {
  221. Name string
  222. ID uint
  223. Level2s []Level2
  224. }
  225. )
  226. DB.DropTableIfExists(&Level3{})
  227. DB.DropTableIfExists(&Level2{})
  228. DB.DropTableIfExists(&Level1{})
  229. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  230. t.Error(err)
  231. }
  232. want := Level3{
  233. Level2s: []Level2{
  234. {Level1: Level1{Value: "value1"}},
  235. {Level1: Level1{Value: "value2"}},
  236. },
  237. }
  238. if err := DB.Create(&want).Error; err != nil {
  239. t.Error(err)
  240. }
  241. var got Level3
  242. if err := DB.Preload("Level2s.Level1").Find(&got).Error; err != nil {
  243. t.Error(err)
  244. }
  245. if !reflect.DeepEqual(got, want) {
  246. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  247. }
  248. }
  249. func TestNestedPreload4(t *testing.T) {
  250. type (
  251. Level1 struct {
  252. ID uint
  253. Value string
  254. Level2ID uint
  255. }
  256. Level2 struct {
  257. ID uint
  258. Level1s []Level1
  259. Level3ID uint
  260. }
  261. Level3 struct {
  262. ID uint
  263. Name string
  264. Level2 Level2
  265. }
  266. )
  267. DB.DropTableIfExists(&Level3{})
  268. DB.DropTableIfExists(&Level2{})
  269. DB.DropTableIfExists(&Level1{})
  270. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  271. t.Error(err)
  272. }
  273. want := Level3{
  274. Level2: Level2{
  275. Level1s: []Level1{
  276. {Value: "value1"},
  277. {Value: "value2"},
  278. },
  279. },
  280. }
  281. if err := DB.Create(&want).Error; err != nil {
  282. t.Error(err)
  283. }
  284. var got Level3
  285. if err := DB.Preload("Level2.Level1s").Find(&got).Error; err != nil {
  286. t.Error(err)
  287. }
  288. if !reflect.DeepEqual(got, want) {
  289. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  290. }
  291. }
  292. // Slice: []Level3
  293. func TestNestedPreload5(t *testing.T) {
  294. type (
  295. Level1 struct {
  296. ID uint
  297. Value string
  298. Level2ID uint
  299. }
  300. Level2 struct {
  301. ID uint
  302. Level1 Level1
  303. Level3ID uint
  304. }
  305. Level3 struct {
  306. ID uint
  307. Name string
  308. Level2 Level2
  309. }
  310. )
  311. DB.DropTableIfExists(&Level3{})
  312. DB.DropTableIfExists(&Level2{})
  313. DB.DropTableIfExists(&Level1{})
  314. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  315. t.Error(err)
  316. }
  317. want := make([]Level3, 2)
  318. want[0] = Level3{Level2: Level2{Level1: Level1{Value: "value"}}}
  319. if err := DB.Create(&want[0]).Error; err != nil {
  320. t.Error(err)
  321. }
  322. want[1] = Level3{Level2: Level2{Level1: Level1{Value: "value2"}}}
  323. if err := DB.Create(&want[1]).Error; err != nil {
  324. t.Error(err)
  325. }
  326. var got []Level3
  327. if err := DB.Preload("Level2").Preload("Level2.Level1").Find(&got).Error; err != nil {
  328. t.Error(err)
  329. }
  330. if !reflect.DeepEqual(got, want) {
  331. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  332. }
  333. }
  334. func TestNestedPreload6(t *testing.T) {
  335. type (
  336. Level1 struct {
  337. ID uint
  338. Value string
  339. Level2ID uint
  340. }
  341. Level2 struct {
  342. ID uint
  343. Level1s []Level1
  344. Level3ID uint
  345. }
  346. Level3 struct {
  347. ID uint
  348. Name string
  349. Level2s []Level2
  350. }
  351. )
  352. DB.DropTableIfExists(&Level3{})
  353. DB.DropTableIfExists(&Level2{})
  354. DB.DropTableIfExists(&Level1{})
  355. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  356. t.Error(err)
  357. }
  358. want := make([]Level3, 2)
  359. want[0] = Level3{
  360. Level2s: []Level2{
  361. {
  362. Level1s: []Level1{
  363. {Value: "value1"},
  364. {Value: "value2"},
  365. },
  366. },
  367. {
  368. Level1s: []Level1{
  369. {Value: "value3"},
  370. },
  371. },
  372. },
  373. }
  374. if err := DB.Create(&want[0]).Error; err != nil {
  375. t.Error(err)
  376. }
  377. want[1] = Level3{
  378. Level2s: []Level2{
  379. {
  380. Level1s: []Level1{
  381. {Value: "value3"},
  382. {Value: "value4"},
  383. },
  384. },
  385. {
  386. Level1s: []Level1{
  387. {Value: "value5"},
  388. },
  389. },
  390. },
  391. }
  392. if err := DB.Create(&want[1]).Error; err != nil {
  393. t.Error(err)
  394. }
  395. var got []Level3
  396. if err := DB.Preload("Level2s.Level1s").Find(&got).Error; err != nil {
  397. t.Error(err)
  398. }
  399. if !reflect.DeepEqual(got, want) {
  400. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  401. }
  402. }
  403. func TestNestedPreload7(t *testing.T) {
  404. type (
  405. Level1 struct {
  406. ID uint
  407. Value string
  408. Level2ID uint
  409. }
  410. Level2 struct {
  411. ID uint
  412. Level1 Level1
  413. Level3ID uint
  414. }
  415. Level3 struct {
  416. ID uint
  417. Name string
  418. Level2s []Level2
  419. }
  420. )
  421. DB.DropTableIfExists(&Level3{})
  422. DB.DropTableIfExists(&Level2{})
  423. DB.DropTableIfExists(&Level1{})
  424. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  425. t.Error(err)
  426. }
  427. want := make([]Level3, 2)
  428. want[0] = Level3{
  429. Level2s: []Level2{
  430. {Level1: Level1{Value: "value1"}},
  431. {Level1: Level1{Value: "value2"}},
  432. },
  433. }
  434. if err := DB.Create(&want[0]).Error; err != nil {
  435. t.Error(err)
  436. }
  437. want[1] = Level3{
  438. Level2s: []Level2{
  439. {Level1: Level1{Value: "value3"}},
  440. {Level1: Level1{Value: "value4"}},
  441. },
  442. }
  443. if err := DB.Create(&want[1]).Error; err != nil {
  444. t.Error(err)
  445. }
  446. var got []Level3
  447. if err := DB.Preload("Level2s.Level1").Find(&got).Error; err != nil {
  448. t.Error(err)
  449. }
  450. if !reflect.DeepEqual(got, want) {
  451. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  452. }
  453. }
  454. func TestNestedPreload8(t *testing.T) {
  455. type (
  456. Level1 struct {
  457. ID uint
  458. Value string
  459. Level2ID uint
  460. }
  461. Level2 struct {
  462. ID uint
  463. Level1s []Level1
  464. Level3ID uint
  465. }
  466. Level3 struct {
  467. ID uint
  468. Name string
  469. Level2 Level2
  470. }
  471. )
  472. DB.DropTableIfExists(&Level3{})
  473. DB.DropTableIfExists(&Level2{})
  474. DB.DropTableIfExists(&Level1{})
  475. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  476. t.Error(err)
  477. }
  478. want := make([]Level3, 2)
  479. want[0] = Level3{
  480. Level2: Level2{
  481. Level1s: []Level1{
  482. {Value: "value1"},
  483. {Value: "value2"},
  484. },
  485. },
  486. }
  487. if err := DB.Create(&want[0]).Error; err != nil {
  488. t.Error(err)
  489. }
  490. want[1] = Level3{
  491. Level2: Level2{
  492. Level1s: []Level1{
  493. {Value: "value3"},
  494. {Value: "value4"},
  495. },
  496. },
  497. }
  498. if err := DB.Create(&want[1]).Error; err != nil {
  499. t.Error(err)
  500. }
  501. var got []Level3
  502. if err := DB.Preload("Level2.Level1s").Find(&got).Error; err != nil {
  503. t.Error(err)
  504. }
  505. if !reflect.DeepEqual(got, want) {
  506. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  507. }
  508. }
  509. func TestNestedPreload9(t *testing.T) {
  510. type (
  511. Level0 struct {
  512. ID uint
  513. Value string
  514. Level1ID uint
  515. }
  516. Level1 struct {
  517. ID uint
  518. Value string
  519. Level2ID uint
  520. Level2_1ID uint
  521. Level0s []Level0
  522. }
  523. Level2 struct {
  524. ID uint
  525. Level1s []Level1
  526. Level3ID uint
  527. }
  528. Level2_1 struct {
  529. ID uint
  530. Level1s []Level1
  531. Level3ID uint
  532. }
  533. Level3 struct {
  534. ID uint
  535. Name string
  536. Level2 Level2
  537. Level2_1 Level2_1
  538. }
  539. )
  540. DB.DropTableIfExists(&Level3{})
  541. DB.DropTableIfExists(&Level2{})
  542. DB.DropTableIfExists(&Level2_1{})
  543. DB.DropTableIfExists(&Level1{})
  544. DB.DropTableIfExists(&Level0{})
  545. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}, &Level2_1{}, &Level0{}).Error; err != nil {
  546. t.Error(err)
  547. }
  548. want := make([]Level3, 2)
  549. want[0] = Level3{
  550. Level2: Level2{
  551. Level1s: []Level1{
  552. {Value: "value1"},
  553. {Value: "value2"},
  554. },
  555. },
  556. Level2_1: Level2_1{
  557. Level1s: []Level1{
  558. {
  559. Value: "value1-1",
  560. Level0s: []Level0{{Value: "Level0-1"}},
  561. },
  562. {
  563. Value: "value2-2",
  564. Level0s: []Level0{{Value: "Level0-2"}},
  565. },
  566. },
  567. },
  568. }
  569. if err := DB.Create(&want[0]).Error; err != nil {
  570. t.Error(err)
  571. }
  572. want[1] = Level3{
  573. Level2: Level2{
  574. Level1s: []Level1{
  575. {Value: "value3"},
  576. {Value: "value4"},
  577. },
  578. },
  579. Level2_1: Level2_1{
  580. Level1s: []Level1{
  581. {
  582. Value: "value3-3",
  583. Level0s: []Level0{},
  584. },
  585. {
  586. Value: "value4-4",
  587. Level0s: []Level0{},
  588. },
  589. },
  590. },
  591. }
  592. if err := DB.Create(&want[1]).Error; err != nil {
  593. t.Error(err)
  594. }
  595. var got []Level3
  596. if err := DB.Preload("Level2").Preload("Level2.Level1s").Preload("Level2_1").Preload("Level2_1.Level1s").Preload("Level2_1.Level1s.Level0s").Find(&got).Error; err != nil {
  597. t.Error(err)
  598. }
  599. if !reflect.DeepEqual(got, want) {
  600. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  601. }
  602. }
  603. type LevelA1 struct {
  604. ID uint
  605. Value string
  606. }
  607. type LevelA2 struct {
  608. ID uint
  609. Value string
  610. LevelA3s []*LevelA3
  611. }
  612. type LevelA3 struct {
  613. ID uint
  614. Value string
  615. LevelA1ID sql.NullInt64
  616. LevelA1 *LevelA1
  617. LevelA2ID sql.NullInt64
  618. LevelA2 *LevelA2
  619. }
  620. func TestNestedPreload10(t *testing.T) {
  621. DB.DropTableIfExists(&LevelA3{})
  622. DB.DropTableIfExists(&LevelA2{})
  623. DB.DropTableIfExists(&LevelA1{})
  624. if err := DB.AutoMigrate(&LevelA1{}, &LevelA2{}, &LevelA3{}).Error; err != nil {
  625. t.Error(err)
  626. }
  627. levelA1 := &LevelA1{Value: "foo"}
  628. if err := DB.Save(levelA1).Error; err != nil {
  629. t.Error(err)
  630. }
  631. want := []*LevelA2{
  632. {
  633. Value: "bar",
  634. LevelA3s: []*LevelA3{
  635. {
  636. Value: "qux",
  637. LevelA1: levelA1,
  638. },
  639. },
  640. },
  641. {
  642. Value: "bar 2",
  643. LevelA3s: []*LevelA3{},
  644. },
  645. }
  646. for _, levelA2 := range want {
  647. if err := DB.Save(levelA2).Error; err != nil {
  648. t.Error(err)
  649. }
  650. }
  651. var got []*LevelA2
  652. if err := DB.Preload("LevelA3s.LevelA1").Find(&got).Error; err != nil {
  653. t.Error(err)
  654. }
  655. if !reflect.DeepEqual(got, want) {
  656. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  657. }
  658. }
  659. type LevelB1 struct {
  660. ID uint
  661. Value string
  662. LevelB3s []*LevelB3
  663. }
  664. type LevelB2 struct {
  665. ID uint
  666. Value string
  667. }
  668. type LevelB3 struct {
  669. ID uint
  670. Value string
  671. LevelB1ID sql.NullInt64
  672. LevelB1 *LevelB1
  673. LevelB2s []*LevelB2 `gorm:"many2many:levelb1_levelb3_levelb2s"`
  674. }
  675. func TestNestedPreload11(t *testing.T) {
  676. DB.DropTableIfExists(&LevelB2{})
  677. DB.DropTableIfExists(&LevelB3{})
  678. DB.DropTableIfExists(&LevelB1{})
  679. if err := DB.AutoMigrate(&LevelB1{}, &LevelB2{}, &LevelB3{}).Error; err != nil {
  680. t.Error(err)
  681. }
  682. levelB1 := &LevelB1{Value: "foo"}
  683. if err := DB.Create(levelB1).Error; err != nil {
  684. t.Error(err)
  685. }
  686. levelB3 := &LevelB3{
  687. Value: "bar",
  688. LevelB1ID: sql.NullInt64{Valid: true, Int64: int64(levelB1.ID)},
  689. LevelB2s: []*LevelB2{},
  690. }
  691. if err := DB.Create(levelB3).Error; err != nil {
  692. t.Error(err)
  693. }
  694. levelB1.LevelB3s = []*LevelB3{levelB3}
  695. want := []*LevelB1{levelB1}
  696. var got []*LevelB1
  697. if err := DB.Preload("LevelB3s.LevelB2s").Find(&got).Error; err != nil {
  698. t.Error(err)
  699. }
  700. if !reflect.DeepEqual(got, want) {
  701. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  702. }
  703. }
  704. type LevelC1 struct {
  705. ID uint
  706. Value string
  707. LevelC2ID uint
  708. }
  709. type LevelC2 struct {
  710. ID uint
  711. Value string
  712. LevelC1 LevelC1
  713. }
  714. type LevelC3 struct {
  715. ID uint
  716. Value string
  717. LevelC2ID uint
  718. LevelC2 LevelC2
  719. }
  720. func TestNestedPreload12(t *testing.T) {
  721. DB.DropTableIfExists(&LevelC2{})
  722. DB.DropTableIfExists(&LevelC3{})
  723. DB.DropTableIfExists(&LevelC1{})
  724. if err := DB.AutoMigrate(&LevelC1{}, &LevelC2{}, &LevelC3{}).Error; err != nil {
  725. t.Error(err)
  726. }
  727. level2 := LevelC2{
  728. Value: "c2",
  729. LevelC1: LevelC1{
  730. Value: "c1",
  731. },
  732. }
  733. DB.Create(&level2)
  734. want := []LevelC3{
  735. {
  736. Value: "c3-1",
  737. LevelC2: level2,
  738. }, {
  739. Value: "c3-2",
  740. LevelC2: level2,
  741. },
  742. }
  743. for i := range want {
  744. if err := DB.Create(&want[i]).Error; err != nil {
  745. t.Error(err)
  746. }
  747. }
  748. var got []LevelC3
  749. if err := DB.Preload("LevelC2").Preload("LevelC2.LevelC1").Find(&got).Error; err != nil {
  750. t.Error(err)
  751. }
  752. if !reflect.DeepEqual(got, want) {
  753. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  754. }
  755. }
  756. func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) {
  757. if dialect := os.Getenv("GORM_DIALECT"); dialect == "" || dialect == "sqlite" || dialect == "mssql" {
  758. return
  759. }
  760. type (
  761. Level1 struct {
  762. ID uint `gorm:"primary_key;"`
  763. LanguageCode string `gorm:"primary_key"`
  764. Value string
  765. }
  766. Level2 struct {
  767. ID uint `gorm:"primary_key;"`
  768. LanguageCode string `gorm:"primary_key"`
  769. Value string
  770. Level1s []Level1 `gorm:"many2many:levels;"`
  771. }
  772. )
  773. DB.DropTableIfExists(&Level2{})
  774. DB.DropTableIfExists(&Level1{})
  775. DB.DropTableIfExists("levels")
  776. if err := DB.AutoMigrate(&Level2{}, &Level1{}).Error; err != nil {
  777. t.Error(err)
  778. }
  779. want := Level2{Value: "Bob", LanguageCode: "ru", Level1s: []Level1{
  780. {Value: "ru", LanguageCode: "ru"},
  781. {Value: "en", LanguageCode: "en"},
  782. }}
  783. if err := DB.Save(&want).Error; err != nil {
  784. t.Error(err)
  785. }
  786. want2 := Level2{Value: "Tom", LanguageCode: "zh", Level1s: []Level1{
  787. {Value: "zh", LanguageCode: "zh"},
  788. {Value: "de", LanguageCode: "de"},
  789. }}
  790. if err := DB.Save(&want2).Error; err != nil {
  791. t.Error(err)
  792. }
  793. var got Level2
  794. if err := DB.Preload("Level1s").Find(&got, "value = ?", "Bob").Error; err != nil {
  795. t.Error(err)
  796. }
  797. if !reflect.DeepEqual(got, want) {
  798. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  799. }
  800. var got2 Level2
  801. if err := DB.Preload("Level1s").Find(&got2, "value = ?", "Tom").Error; err != nil {
  802. t.Error(err)
  803. }
  804. if !reflect.DeepEqual(got2, want2) {
  805. t.Errorf("got %s; want %s", toJSONString(got2), toJSONString(want2))
  806. }
  807. var got3 []Level2
  808. if err := DB.Preload("Level1s").Find(&got3, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
  809. t.Error(err)
  810. }
  811. if !reflect.DeepEqual(got3, []Level2{got, got2}) {
  812. t.Errorf("got %s; want %s", toJSONString(got3), toJSONString([]Level2{got, got2}))
  813. }
  814. var got4 []Level2
  815. if err := DB.Preload("Level1s", "value IN (?)", []string{"zh", "ru"}).Find(&got4, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
  816. t.Error(err)
  817. }
  818. var ruLevel1 Level1
  819. var zhLevel1 Level1
  820. DB.First(&ruLevel1, "value = ?", "ru")
  821. DB.First(&zhLevel1, "value = ?", "zh")
  822. got.Level1s = []Level1{ruLevel1}
  823. got2.Level1s = []Level1{zhLevel1}
  824. if !reflect.DeepEqual(got4, []Level2{got, got2}) {
  825. t.Errorf("got %s; want %s", toJSONString(got4), toJSONString([]Level2{got, got2}))
  826. }
  827. if err := DB.Preload("Level1s").Find(&got4, "value IN (?)", []string{"non-existing"}).Error; err != nil {
  828. t.Error(err)
  829. }
  830. }
  831. func TestManyToManyPreloadForNestedPointer(t *testing.T) {
  832. type (
  833. Level1 struct {
  834. ID uint
  835. Value string
  836. }
  837. Level2 struct {
  838. ID uint
  839. Value string
  840. Level1s []*Level1 `gorm:"many2many:levels;"`
  841. }
  842. Level3 struct {
  843. ID uint
  844. Value string
  845. Level2ID sql.NullInt64
  846. Level2 *Level2
  847. }
  848. )
  849. DB.DropTableIfExists(&Level3{})
  850. DB.DropTableIfExists(&Level2{})
  851. DB.DropTableIfExists(&Level1{})
  852. DB.DropTableIfExists("levels")
  853. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  854. t.Error(err)
  855. }
  856. want := Level3{
  857. Value: "Bob",
  858. Level2: &Level2{
  859. Value: "Foo",
  860. Level1s: []*Level1{
  861. {Value: "ru"},
  862. {Value: "en"},
  863. },
  864. },
  865. }
  866. if err := DB.Save(&want).Error; err != nil {
  867. t.Error(err)
  868. }
  869. want2 := Level3{
  870. Value: "Tom",
  871. Level2: &Level2{
  872. Value: "Bar",
  873. Level1s: []*Level1{
  874. {Value: "zh"},
  875. {Value: "de"},
  876. },
  877. },
  878. }
  879. if err := DB.Save(&want2).Error; err != nil {
  880. t.Error(err)
  881. }
  882. var got Level3
  883. if err := DB.Preload("Level2.Level1s").Find(&got, "value = ?", "Bob").Error; err != nil {
  884. t.Error(err)
  885. }
  886. if !reflect.DeepEqual(got, want) {
  887. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  888. }
  889. var got2 Level3
  890. if err := DB.Preload("Level2.Level1s").Find(&got2, "value = ?", "Tom").Error; err != nil {
  891. t.Error(err)
  892. }
  893. if !reflect.DeepEqual(got2, want2) {
  894. t.Errorf("got %s; want %s", toJSONString(got2), toJSONString(want2))
  895. }
  896. var got3 []Level3
  897. if err := DB.Preload("Level2.Level1s").Find(&got3, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
  898. t.Error(err)
  899. }
  900. if !reflect.DeepEqual(got3, []Level3{got, got2}) {
  901. t.Errorf("got %s; want %s", toJSONString(got3), toJSONString([]Level3{got, got2}))
  902. }
  903. var got4 []Level3
  904. if err := DB.Preload("Level2.Level1s", "value IN (?)", []string{"zh", "ru"}).Find(&got4, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
  905. t.Error(err)
  906. }
  907. var got5 Level3
  908. DB.Preload("Level2.Level1s").Find(&got5, "value = ?", "bogus")
  909. var ruLevel1 Level1
  910. var zhLevel1 Level1
  911. DB.First(&ruLevel1, "value = ?", "ru")
  912. DB.First(&zhLevel1, "value = ?", "zh")
  913. got.Level2.Level1s = []*Level1{&ruLevel1}
  914. got2.Level2.Level1s = []*Level1{&zhLevel1}
  915. if !reflect.DeepEqual(got4, []Level3{got, got2}) {
  916. t.Errorf("got %s; want %s", toJSONString(got4), toJSONString([]Level3{got, got2}))
  917. }
  918. }
  919. func TestNestedManyToManyPreload(t *testing.T) {
  920. type (
  921. Level1 struct {
  922. ID uint
  923. Value string
  924. }
  925. Level2 struct {
  926. ID uint
  927. Value string
  928. Level1s []*Level1 `gorm:"many2many:level1_level2;"`
  929. }
  930. Level3 struct {
  931. ID uint
  932. Value string
  933. Level2s []Level2 `gorm:"many2many:level2_level3;"`
  934. }
  935. )
  936. DB.DropTableIfExists(&Level1{})
  937. DB.DropTableIfExists(&Level2{})
  938. DB.DropTableIfExists(&Level3{})
  939. DB.DropTableIfExists("level1_level2")
  940. DB.DropTableIfExists("level2_level3")
  941. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  942. t.Error(err)
  943. }
  944. want := Level3{
  945. Value: "Level3",
  946. Level2s: []Level2{
  947. {
  948. Value: "Bob",
  949. Level1s: []*Level1{
  950. {Value: "ru"},
  951. {Value: "en"},
  952. },
  953. }, {
  954. Value: "Tom",
  955. Level1s: []*Level1{
  956. {Value: "zh"},
  957. {Value: "de"},
  958. },
  959. },
  960. },
  961. }
  962. if err := DB.Save(&want).Error; err != nil {
  963. t.Error(err)
  964. }
  965. var got Level3
  966. if err := DB.Preload("Level2s").Preload("Level2s.Level1s").Find(&got, "value = ?", "Level3").Error; err != nil {
  967. t.Error(err)
  968. }
  969. if !reflect.DeepEqual(got, want) {
  970. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  971. }
  972. if err := DB.Preload("Level2s.Level1s").Find(&got, "value = ?", "not_found").Error; err != gorm.ErrRecordNotFound {
  973. t.Error(err)
  974. }
  975. }
  976. func TestNestedManyToManyPreload2(t *testing.T) {
  977. type (
  978. Level1 struct {
  979. ID uint
  980. Value string
  981. }
  982. Level2 struct {
  983. ID uint
  984. Value string
  985. Level1s []*Level1 `gorm:"many2many:level1_level2;"`
  986. }
  987. Level3 struct {
  988. ID uint
  989. Value string
  990. Level2ID sql.NullInt64
  991. Level2 *Level2
  992. }
  993. )
  994. DB.DropTableIfExists(&Level1{})
  995. DB.DropTableIfExists(&Level2{})
  996. DB.DropTableIfExists(&Level3{})
  997. DB.DropTableIfExists("level1_level2")
  998. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  999. t.Error(err)
  1000. }
  1001. want := Level3{
  1002. Value: "Level3",
  1003. Level2: &Level2{
  1004. Value: "Bob",
  1005. Level1s: []*Level1{
  1006. {Value: "ru"},
  1007. {Value: "en"},
  1008. },
  1009. },
  1010. }
  1011. if err := DB.Save(&want).Error; err != nil {
  1012. t.Error(err)
  1013. }
  1014. var got Level3
  1015. if err := DB.Preload("Level2.Level1s").Find(&got, "value = ?", "Level3").Error; err != nil {
  1016. t.Error(err)
  1017. }
  1018. if !reflect.DeepEqual(got, want) {
  1019. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  1020. }
  1021. if err := DB.Preload("Level2.Level1s").Find(&got, "value = ?", "not_found").Error; err != gorm.ErrRecordNotFound {
  1022. t.Error(err)
  1023. }
  1024. }
  1025. func TestNestedManyToManyPreload3(t *testing.T) {
  1026. type (
  1027. Level1 struct {
  1028. ID uint
  1029. Value string
  1030. }
  1031. Level2 struct {
  1032. ID uint
  1033. Value string
  1034. Level1s []*Level1 `gorm:"many2many:level1_level2;"`
  1035. }
  1036. Level3 struct {
  1037. ID uint
  1038. Value string
  1039. Level2ID sql.NullInt64
  1040. Level2 *Level2
  1041. }
  1042. )
  1043. DB.DropTableIfExists(&Level1{})
  1044. DB.DropTableIfExists(&Level2{})
  1045. DB.DropTableIfExists(&Level3{})
  1046. DB.DropTableIfExists("level1_level2")
  1047. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  1048. t.Error(err)
  1049. }
  1050. level1Zh := &Level1{Value: "zh"}
  1051. level1Ru := &Level1{Value: "ru"}
  1052. level1En := &Level1{Value: "en"}
  1053. level21 := &Level2{
  1054. Value: "Level2-1",
  1055. Level1s: []*Level1{level1Zh, level1Ru},
  1056. }
  1057. level22 := &Level2{
  1058. Value: "Level2-2",
  1059. Level1s: []*Level1{level1Zh, level1En},
  1060. }
  1061. wants := []*Level3{
  1062. {
  1063. Value: "Level3-1",
  1064. Level2: level21,
  1065. },
  1066. {
  1067. Value: "Level3-2",
  1068. Level2: level22,
  1069. },
  1070. {
  1071. Value: "Level3-3",
  1072. Level2: level21,
  1073. },
  1074. }
  1075. for _, want := range wants {
  1076. if err := DB.Save(&want).Error; err != nil {
  1077. t.Error(err)
  1078. }
  1079. }
  1080. var gots []*Level3
  1081. if err := DB.Preload("Level2.Level1s", func(db *gorm.DB) *gorm.DB {
  1082. return db.Order("level1.id ASC")
  1083. }).Find(&gots).Error; err != nil {
  1084. t.Error(err)
  1085. }
  1086. if !reflect.DeepEqual(gots, wants) {
  1087. t.Errorf("got %s; want %s", toJSONString(gots), toJSONString(wants))
  1088. }
  1089. }
  1090. func TestNestedManyToManyPreload3ForStruct(t *testing.T) {
  1091. type (
  1092. Level1 struct {
  1093. ID uint
  1094. Value string
  1095. }
  1096. Level2 struct {
  1097. ID uint
  1098. Value string
  1099. Level1s []Level1 `gorm:"many2many:level1_level2;"`
  1100. }
  1101. Level3 struct {
  1102. ID uint
  1103. Value string
  1104. Level2ID sql.NullInt64
  1105. Level2 Level2
  1106. }
  1107. )
  1108. DB.DropTableIfExists(&Level1{})
  1109. DB.DropTableIfExists(&Level2{})
  1110. DB.DropTableIfExists(&Level3{})
  1111. DB.DropTableIfExists("level1_level2")
  1112. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  1113. t.Error(err)
  1114. }
  1115. level1Zh := Level1{Value: "zh"}
  1116. level1Ru := Level1{Value: "ru"}
  1117. level1En := Level1{Value: "en"}
  1118. level21 := Level2{
  1119. Value: "Level2-1",
  1120. Level1s: []Level1{level1Zh, level1Ru},
  1121. }
  1122. level22 := Level2{
  1123. Value: "Level2-2",
  1124. Level1s: []Level1{level1Zh, level1En},
  1125. }
  1126. wants := []*Level3{
  1127. {
  1128. Value: "Level3-1",
  1129. Level2: level21,
  1130. },
  1131. {
  1132. Value: "Level3-2",
  1133. Level2: level22,
  1134. },
  1135. {
  1136. Value: "Level3-3",
  1137. Level2: level21,
  1138. },
  1139. }
  1140. for _, want := range wants {
  1141. if err := DB.Save(&want).Error; err != nil {
  1142. t.Error(err)
  1143. }
  1144. }
  1145. var gots []*Level3
  1146. if err := DB.Preload("Level2.Level1s", func(db *gorm.DB) *gorm.DB {
  1147. return db.Order("level1.id ASC")
  1148. }).Find(&gots).Error; err != nil {
  1149. t.Error(err)
  1150. }
  1151. if !reflect.DeepEqual(gots, wants) {
  1152. t.Errorf("got %s; want %s", toJSONString(gots), toJSONString(wants))
  1153. }
  1154. }
  1155. func TestNestedManyToManyPreload4(t *testing.T) {
  1156. type (
  1157. Level4 struct {
  1158. ID uint
  1159. Value string
  1160. Level3ID uint
  1161. }
  1162. Level3 struct {
  1163. ID uint
  1164. Value string
  1165. Level4s []*Level4
  1166. }
  1167. Level2 struct {
  1168. ID uint
  1169. Value string
  1170. Level3s []*Level3 `gorm:"many2many:level2_level3;"`
  1171. }
  1172. Level1 struct {
  1173. ID uint
  1174. Value string
  1175. Level2s []*Level2 `gorm:"many2many:level1_level2;"`
  1176. }
  1177. )
  1178. DB.DropTableIfExists(&Level1{})
  1179. DB.DropTableIfExists(&Level2{})
  1180. DB.DropTableIfExists(&Level3{})
  1181. DB.DropTableIfExists(&Level4{})
  1182. DB.DropTableIfExists("level1_level2")
  1183. DB.DropTableIfExists("level2_level3")
  1184. dummy := Level1{
  1185. Value: "Level1",
  1186. Level2s: []*Level2{{
  1187. Value: "Level2",
  1188. Level3s: []*Level3{{
  1189. Value: "Level3",
  1190. Level4s: []*Level4{{
  1191. Value: "Level4",
  1192. }},
  1193. }},
  1194. }},
  1195. }
  1196. if err := DB.AutoMigrate(&Level4{}, &Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  1197. t.Error(err)
  1198. }
  1199. if err := DB.Save(&dummy).Error; err != nil {
  1200. t.Error(err)
  1201. }
  1202. var level1 Level1
  1203. if err := DB.Preload("Level2s").Preload("Level2s.Level3s").Preload("Level2s.Level3s.Level4s").First(&level1).Error; err != nil {
  1204. t.Error(err)
  1205. }
  1206. }
  1207. func TestManyToManyPreloadForPointer(t *testing.T) {
  1208. type (
  1209. Level1 struct {
  1210. ID uint
  1211. Value string
  1212. }
  1213. Level2 struct {
  1214. ID uint
  1215. Value string
  1216. Level1s []*Level1 `gorm:"many2many:levels;"`
  1217. }
  1218. )
  1219. DB.DropTableIfExists(&Level2{})
  1220. DB.DropTableIfExists(&Level1{})
  1221. DB.DropTableIfExists("levels")
  1222. if err := DB.AutoMigrate(&Level2{}, &Level1{}).Error; err != nil {
  1223. t.Error(err)
  1224. }
  1225. want := Level2{Value: "Bob", Level1s: []*Level1{
  1226. {Value: "ru"},
  1227. {Value: "en"},
  1228. }}
  1229. if err := DB.Save(&want).Error; err != nil {
  1230. t.Error(err)
  1231. }
  1232. want2 := Level2{Value: "Tom", Level1s: []*Level1{
  1233. {Value: "zh"},
  1234. {Value: "de"},
  1235. }}
  1236. if err := DB.Save(&want2).Error; err != nil {
  1237. t.Error(err)
  1238. }
  1239. var got Level2
  1240. if err := DB.Preload("Level1s").Find(&got, "value = ?", "Bob").Error; err != nil {
  1241. t.Error(err)
  1242. }
  1243. if !reflect.DeepEqual(got, want) {
  1244. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  1245. }
  1246. var got2 Level2
  1247. if err := DB.Preload("Level1s").Find(&got2, "value = ?", "Tom").Error; err != nil {
  1248. t.Error(err)
  1249. }
  1250. if !reflect.DeepEqual(got2, want2) {
  1251. t.Errorf("got %s; want %s", toJSONString(got2), toJSONString(want2))
  1252. }
  1253. var got3 []Level2
  1254. if err := DB.Preload("Level1s").Find(&got3, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
  1255. t.Error(err)
  1256. }
  1257. if !reflect.DeepEqual(got3, []Level2{got, got2}) {
  1258. t.Errorf("got %s; want %s", toJSONString(got3), toJSONString([]Level2{got, got2}))
  1259. }
  1260. var got4 []Level2
  1261. if err := DB.Preload("Level1s", "value IN (?)", []string{"zh", "ru"}).Find(&got4, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
  1262. t.Error(err)
  1263. }
  1264. var got5 Level2
  1265. DB.Preload("Level1s").First(&got5, "value = ?", "bogus")
  1266. var ruLevel1 Level1
  1267. var zhLevel1 Level1
  1268. DB.First(&ruLevel1, "value = ?", "ru")
  1269. DB.First(&zhLevel1, "value = ?", "zh")
  1270. got.Level1s = []*Level1{&ruLevel1}
  1271. got2.Level1s = []*Level1{&zhLevel1}
  1272. if !reflect.DeepEqual(got4, []Level2{got, got2}) {
  1273. t.Errorf("got %s; want %s", toJSONString(got4), toJSONString([]Level2{got, got2}))
  1274. }
  1275. }
  1276. func TestNilPointerSlice(t *testing.T) {
  1277. type (
  1278. Level3 struct {
  1279. ID uint
  1280. Value string
  1281. }
  1282. Level2 struct {
  1283. ID uint
  1284. Value string
  1285. Level3ID uint
  1286. Level3 *Level3
  1287. }
  1288. Level1 struct {
  1289. ID uint
  1290. Value string
  1291. Level2ID uint
  1292. Level2 *Level2
  1293. }
  1294. )
  1295. DB.DropTableIfExists(&Level3{})
  1296. DB.DropTableIfExists(&Level2{})
  1297. DB.DropTableIfExists(&Level1{})
  1298. if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
  1299. t.Error(err)
  1300. }
  1301. want := Level1{
  1302. Value: "Bob",
  1303. Level2: &Level2{
  1304. Value: "en",
  1305. Level3: &Level3{
  1306. Value: "native",
  1307. },
  1308. },
  1309. }
  1310. if err := DB.Save(&want).Error; err != nil {
  1311. t.Error(err)
  1312. }
  1313. want2 := Level1{
  1314. Value: "Tom",
  1315. Level2: nil,
  1316. }
  1317. if err := DB.Save(&want2).Error; err != nil {
  1318. t.Error(err)
  1319. }
  1320. var got []Level1
  1321. if err := DB.Preload("Level2").Preload("Level2.Level3").Find(&got).Error; err != nil {
  1322. t.Error(err)
  1323. }
  1324. if len(got) != 2 {
  1325. t.Errorf("got %v items, expected 2", len(got))
  1326. }
  1327. if !reflect.DeepEqual(got[0], want) && !reflect.DeepEqual(got[1], want) {
  1328. t.Errorf("got %s; want array containing %s", toJSONString(got), toJSONString(want))
  1329. }
  1330. if !reflect.DeepEqual(got[0], want2) && !reflect.DeepEqual(got[1], want2) {
  1331. t.Errorf("got %s; want array containing %s", toJSONString(got), toJSONString(want2))
  1332. }
  1333. }
  1334. func TestNilPointerSlice2(t *testing.T) {
  1335. type (
  1336. Level4 struct {
  1337. ID uint
  1338. }
  1339. Level3 struct {
  1340. ID uint
  1341. Level4ID sql.NullInt64 `sql:"index"`
  1342. Level4 *Level4
  1343. }
  1344. Level2 struct {
  1345. ID uint
  1346. Level3s []*Level3 `gorm:"many2many:level2_level3s"`
  1347. }
  1348. Level1 struct {
  1349. ID uint
  1350. Level2ID sql.NullInt64 `sql:"index"`
  1351. Level2 *Level2
  1352. }
  1353. )
  1354. DB.DropTableIfExists(new(Level4))
  1355. DB.DropTableIfExists(new(Level3))
  1356. DB.DropTableIfExists(new(Level2))
  1357. DB.DropTableIfExists(new(Level1))
  1358. if err := DB.AutoMigrate(new(Level4), new(Level3), new(Level2), new(Level1)).Error; err != nil {
  1359. t.Error(err)
  1360. }
  1361. want := new(Level1)
  1362. if err := DB.Save(want).Error; err != nil {
  1363. t.Error(err)
  1364. }
  1365. got := new(Level1)
  1366. err := DB.Preload("Level2.Level3s.Level4").Last(&got).Error
  1367. if err != nil {
  1368. t.Error(err)
  1369. }
  1370. if !reflect.DeepEqual(got, want) {
  1371. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  1372. }
  1373. }
  1374. func TestPrefixedPreloadDuplication(t *testing.T) {
  1375. type (
  1376. Level4 struct {
  1377. ID uint
  1378. Name string
  1379. Level3ID uint
  1380. }
  1381. Level3 struct {
  1382. ID uint
  1383. Name string
  1384. Level4s []*Level4
  1385. }
  1386. Level2 struct {
  1387. ID uint
  1388. Name string
  1389. Level3ID sql.NullInt64 `sql:"index"`
  1390. Level3 *Level3
  1391. }
  1392. Level1 struct {
  1393. ID uint
  1394. Name string
  1395. Level2ID sql.NullInt64 `sql:"index"`
  1396. Level2 *Level2
  1397. }
  1398. )
  1399. DB.DropTableIfExists(new(Level3))
  1400. DB.DropTableIfExists(new(Level4))
  1401. DB.DropTableIfExists(new(Level2))
  1402. DB.DropTableIfExists(new(Level1))
  1403. if err := DB.AutoMigrate(new(Level3), new(Level4), new(Level2), new(Level1)).Error; err != nil {
  1404. t.Error(err)
  1405. }
  1406. lvl := &Level3{}
  1407. if err := DB.Save(lvl).Error; err != nil {
  1408. t.Error(err)
  1409. }
  1410. sublvl1 := &Level4{Level3ID: lvl.ID}
  1411. if err := DB.Save(sublvl1).Error; err != nil {
  1412. t.Error(err)
  1413. }
  1414. sublvl2 := &Level4{Level3ID: lvl.ID}
  1415. if err := DB.Save(sublvl2).Error; err != nil {
  1416. t.Error(err)
  1417. }
  1418. lvl.Level4s = []*Level4{sublvl1, sublvl2}
  1419. want1 := Level1{
  1420. Level2: &Level2{
  1421. Level3: lvl,
  1422. },
  1423. }
  1424. if err := DB.Save(&want1).Error; err != nil {
  1425. t.Error(err)
  1426. }
  1427. want2 := Level1{
  1428. Level2: &Level2{
  1429. Level3: lvl,
  1430. },
  1431. }
  1432. if err := DB.Save(&want2).Error; err != nil {
  1433. t.Error(err)
  1434. }
  1435. want := []Level1{want1, want2}
  1436. var got []Level1
  1437. err := DB.Preload("Level2.Level3.Level4s").Find(&got).Error
  1438. if err != nil {
  1439. t.Error(err)
  1440. }
  1441. if !reflect.DeepEqual(got, want) {
  1442. t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
  1443. }
  1444. }
  1445. func TestPreloadManyToManyCallbacks(t *testing.T) {
  1446. type (
  1447. Level2 struct {
  1448. ID uint
  1449. Name string
  1450. }
  1451. Level1 struct {
  1452. ID uint
  1453. Name string
  1454. Level2s []Level2 `gorm:"many2many:level1_level2s;AssociationForeignKey:ID;ForeignKey:ID"`
  1455. }
  1456. )
  1457. DB.DropTableIfExists("level1_level2s")
  1458. DB.DropTableIfExists(new(Level1))
  1459. DB.DropTableIfExists(new(Level2))
  1460. if err := DB.AutoMigrate(new(Level1), new(Level2)).Error; err != nil {
  1461. t.Error(err)
  1462. }
  1463. lvl := Level1{
  1464. Name: "l1",
  1465. Level2s: []Level2{
  1466. Level2{Name: "l2-1"}, Level2{Name: "l2-2"},
  1467. },
  1468. }
  1469. DB.Save(&lvl)
  1470. called := 0
  1471. DB.Callback().Query().After("gorm:query").Register("TestPreloadManyToManyCallbacks", func(scope *gorm.Scope) {
  1472. called = called + 1
  1473. })
  1474. DB.Preload("Level2s").First(&Level1{}, "id = ?", lvl.ID)
  1475. if called != 3 {
  1476. t.Errorf("Wanted callback to be called 3 times but got %d", called)
  1477. }
  1478. }
  1479. func toJSONString(v interface{}) []byte {
  1480. r, _ := json.MarshalIndent(v, "", " ")
  1481. return r
  1482. }