query_test.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. package gorm_test
  2. import (
  3. "fmt"
  4. "reflect"
  5. "github.com/jinzhu/gorm"
  6. "testing"
  7. "time"
  8. )
  9. func TestFirstAndLast(t *testing.T) {
  10. DB.Save(&User{Name: "user1", Emails: []Email{{Email: "user1@example.com"}}})
  11. DB.Save(&User{Name: "user2", Emails: []Email{{Email: "user2@example.com"}}})
  12. var user1, user2, user3, user4 User
  13. DB.First(&user1)
  14. DB.Order("id").Limit(1).Find(&user2)
  15. ptrOfUser3 := &user3
  16. DB.Last(&ptrOfUser3)
  17. DB.Order("id desc").Limit(1).Find(&user4)
  18. if user1.Id != user2.Id || user3.Id != user4.Id {
  19. t.Errorf("First and Last should by order by primary key")
  20. }
  21. var users []User
  22. DB.First(&users)
  23. if len(users) != 1 {
  24. t.Errorf("Find first record as slice")
  25. }
  26. var user User
  27. if DB.Joins("left join emails on emails.user_id = users.id").First(&user).Error != nil {
  28. t.Errorf("Should not raise any error when order with Join table")
  29. }
  30. if user.Email != "" {
  31. t.Errorf("User's Email should be blank as no one set it")
  32. }
  33. }
  34. func TestFirstAndLastWithNoStdPrimaryKey(t *testing.T) {
  35. DB.Save(&Animal{Name: "animal1"})
  36. DB.Save(&Animal{Name: "animal2"})
  37. var animal1, animal2, animal3, animal4 Animal
  38. DB.First(&animal1)
  39. DB.Order("counter").Limit(1).Find(&animal2)
  40. DB.Last(&animal3)
  41. DB.Order("counter desc").Limit(1).Find(&animal4)
  42. if animal1.Counter != animal2.Counter || animal3.Counter != animal4.Counter {
  43. t.Errorf("First and Last should work correctly")
  44. }
  45. }
  46. func TestFirstAndLastWithRaw(t *testing.T) {
  47. user1 := User{Name: "user", Emails: []Email{{Email: "user1@example.com"}}}
  48. user2 := User{Name: "user", Emails: []Email{{Email: "user2@example.com"}}}
  49. DB.Save(&user1)
  50. DB.Save(&user2)
  51. var user3, user4 User
  52. DB.Raw("select * from users WHERE name = ?", "user").First(&user3)
  53. if user3.Id != user1.Id {
  54. t.Errorf("Find first record with raw")
  55. }
  56. DB.Raw("select * from users WHERE name = ?", "user").Last(&user4)
  57. if user4.Id != user2.Id {
  58. t.Errorf("Find last record with raw")
  59. }
  60. }
  61. func TestUIntPrimaryKey(t *testing.T) {
  62. var animal Animal
  63. DB.First(&animal, uint64(1))
  64. if animal.Counter != 1 {
  65. t.Errorf("Fetch a record from with a non-int primary key should work, but failed")
  66. }
  67. DB.Model(Animal{}).Where(Animal{Counter: uint64(2)}).Scan(&animal)
  68. if animal.Counter != 2 {
  69. t.Errorf("Fetch a record from with a non-int primary key should work, but failed")
  70. }
  71. }
  72. func TestCustomizedTypePrimaryKey(t *testing.T) {
  73. type ID uint
  74. type CustomizedTypePrimaryKey struct {
  75. ID ID
  76. Name string
  77. }
  78. DB.AutoMigrate(&CustomizedTypePrimaryKey{})
  79. p1 := CustomizedTypePrimaryKey{Name: "p1"}
  80. p2 := CustomizedTypePrimaryKey{Name: "p2"}
  81. p3 := CustomizedTypePrimaryKey{Name: "p3"}
  82. DB.Create(&p1)
  83. DB.Create(&p2)
  84. DB.Create(&p3)
  85. var p CustomizedTypePrimaryKey
  86. if err := DB.First(&p, p2.ID).Error; err == nil {
  87. t.Errorf("Should return error for invalid query condition")
  88. }
  89. if err := DB.First(&p, "id = ?", p2.ID).Error; err != nil {
  90. t.Errorf("No error should happen when querying with customized type for primary key, got err %v", err)
  91. }
  92. if p.Name != "p2" {
  93. t.Errorf("Should find correct value when querying with customized type for primary key")
  94. }
  95. }
  96. func TestStringPrimaryKeyForNumericValueStartingWithZero(t *testing.T) {
  97. type AddressByZipCode struct {
  98. ZipCode string `gorm:"primary_key"`
  99. Address string
  100. }
  101. DB.AutoMigrate(&AddressByZipCode{})
  102. DB.Create(&AddressByZipCode{ZipCode: "00501", Address: "Holtsville"})
  103. var address AddressByZipCode
  104. DB.First(&address, "00501")
  105. if address.ZipCode != "00501" {
  106. t.Errorf("Fetch a record from with a string primary key for a numeric value starting with zero should work, but failed, zip code is %v", address.ZipCode)
  107. }
  108. }
  109. func TestFindAsSliceOfPointers(t *testing.T) {
  110. DB.Save(&User{Name: "user"})
  111. var users []User
  112. DB.Find(&users)
  113. var userPointers []*User
  114. DB.Find(&userPointers)
  115. if len(users) == 0 || len(users) != len(userPointers) {
  116. t.Errorf("Find slice of pointers")
  117. }
  118. }
  119. func TestSearchWithPlainSQL(t *testing.T) {
  120. user1 := User{Name: "PlainSqlUser1", Age: 1, Birthday: parseTime("2000-1-1")}
  121. user2 := User{Name: "PlainSqlUser2", Age: 10, Birthday: parseTime("2010-1-1")}
  122. user3 := User{Name: "PlainSqlUser3", Age: 20, Birthday: parseTime("2020-1-1")}
  123. DB.Save(&user1).Save(&user2).Save(&user3)
  124. scopedb := DB.Where("name LIKE ?", "%PlainSqlUser%")
  125. if DB.Where("name = ?", user1.Name).First(&User{}).RecordNotFound() {
  126. t.Errorf("Search with plain SQL")
  127. }
  128. if DB.Where("name LIKE ?", "%"+user1.Name+"%").First(&User{}).RecordNotFound() {
  129. t.Errorf("Search with plan SQL (regexp)")
  130. }
  131. var users []User
  132. DB.Find(&users, "name LIKE ? and age > ?", "%PlainSqlUser%", 1)
  133. if len(users) != 2 {
  134. t.Errorf("Should found 2 users that age > 1, but got %v", len(users))
  135. }
  136. DB.Where("name LIKE ?", "%PlainSqlUser%").Where("age >= ?", 1).Find(&users)
  137. if len(users) != 3 {
  138. t.Errorf("Should found 3 users that age >= 1, but got %v", len(users))
  139. }
  140. scopedb.Where("age <> ?", 20).Find(&users)
  141. if len(users) != 2 {
  142. t.Errorf("Should found 2 users age != 20, but got %v", len(users))
  143. }
  144. scopedb.Where("birthday > ?", parseTime("2000-1-1")).Find(&users)
  145. if len(users) != 2 {
  146. t.Errorf("Should found 2 users' birthday > 2000-1-1, but got %v", len(users))
  147. }
  148. scopedb.Where("birthday > ?", "2002-10-10").Find(&users)
  149. if len(users) != 2 {
  150. t.Errorf("Should found 2 users' birthday >= 2002-10-10, but got %v", len(users))
  151. }
  152. scopedb.Where("birthday >= ?", "2010-1-1").Where("birthday < ?", "2020-1-1").Find(&users)
  153. if len(users) != 1 {
  154. t.Errorf("Should found 1 users' birthday < 2020-1-1 and >= 2010-1-1, but got %v", len(users))
  155. }
  156. DB.Where("name in (?)", []string{user1.Name, user2.Name}).Find(&users)
  157. if len(users) != 2 {
  158. t.Errorf("Should found 2 users, but got %v", len(users))
  159. }
  160. DB.Where("id in (?)", []int64{user1.Id, user2.Id, user3.Id}).Find(&users)
  161. if len(users) != 3 {
  162. t.Errorf("Should found 3 users, but got %v", len(users))
  163. }
  164. DB.Where("id in (?)", user1.Id).Find(&users)
  165. if len(users) != 1 {
  166. t.Errorf("Should found 1 users, but got %v", len(users))
  167. }
  168. if err := DB.Where("id IN (?)", []string{}).Find(&users).Error; err != nil {
  169. t.Error("no error should happen when query with empty slice, but got: ", err)
  170. }
  171. if err := DB.Not("id IN (?)", []string{}).Find(&users).Error; err != nil {
  172. t.Error("no error should happen when query with empty slice, but got: ", err)
  173. }
  174. if DB.Where("name = ?", "none existing").Find(&[]User{}).RecordNotFound() {
  175. t.Errorf("Should not get RecordNotFound error when looking for none existing records")
  176. }
  177. }
  178. func TestSearchWithTwoDimensionalArray(t *testing.T) {
  179. var users []User
  180. user1 := User{Name: "2DSearchUser1", Age: 1, Birthday: parseTime("2000-1-1")}
  181. user2 := User{Name: "2DSearchUser2", Age: 10, Birthday: parseTime("2010-1-1")}
  182. user3 := User{Name: "2DSearchUser3", Age: 20, Birthday: parseTime("2020-1-1")}
  183. DB.Create(&user1)
  184. DB.Create(&user2)
  185. DB.Create(&user3)
  186. if dialect := DB.Dialect().GetName(); dialect == "mysql" || dialect == "postgres" {
  187. if err := DB.Where("(name, age) IN (?)", [][]interface{}{{"2DSearchUser1", 1}, {"2DSearchUser2", 10}}).Find(&users).Error; err != nil {
  188. t.Errorf("No error should happen when query with 2D array, but got %v", err)
  189. if len(users) != 2 {
  190. t.Errorf("Should find 2 users with 2D array, but got %v", len(users))
  191. }
  192. }
  193. }
  194. if dialect := DB.Dialect().GetName(); dialect == "mssql" {
  195. if err := DB.Joins("JOIN (VALUES ?) AS x (col1, col2) ON x.col1 = name AND x.col2 = age", [][]interface{}{{"2DSearchUser1", 1}, {"2DSearchUser2", 10}}).Find(&users).Error; err != nil {
  196. t.Errorf("No error should happen when query with 2D array, but got %v", err)
  197. if len(users) != 2 {
  198. t.Errorf("Should find 2 users with 2D array, but got %v", len(users))
  199. }
  200. }
  201. }
  202. }
  203. func TestSearchWithStruct(t *testing.T) {
  204. user1 := User{Name: "StructSearchUser1", Age: 1, Birthday: parseTime("2000-1-1")}
  205. user2 := User{Name: "StructSearchUser2", Age: 10, Birthday: parseTime("2010-1-1")}
  206. user3 := User{Name: "StructSearchUser3", Age: 20, Birthday: parseTime("2020-1-1")}
  207. DB.Save(&user1).Save(&user2).Save(&user3)
  208. if DB.Where(user1.Id).First(&User{}).RecordNotFound() {
  209. t.Errorf("Search with primary key")
  210. }
  211. if DB.First(&User{}, user1.Id).RecordNotFound() {
  212. t.Errorf("Search with primary key as inline condition")
  213. }
  214. if DB.First(&User{}, fmt.Sprintf("%v", user1.Id)).RecordNotFound() {
  215. t.Errorf("Search with primary key as inline condition")
  216. }
  217. var users []User
  218. DB.Where([]int64{user1.Id, user2.Id, user3.Id}).Find(&users)
  219. if len(users) != 3 {
  220. t.Errorf("Should found 3 users when search with primary keys, but got %v", len(users))
  221. }
  222. var user User
  223. DB.First(&user, &User{Name: user1.Name})
  224. if user.Id == 0 || user.Name != user1.Name {
  225. t.Errorf("Search first record with inline pointer of struct")
  226. }
  227. DB.First(&user, User{Name: user1.Name})
  228. if user.Id == 0 || user.Name != user1.Name {
  229. t.Errorf("Search first record with inline struct")
  230. }
  231. DB.Where(&User{Name: user1.Name}).First(&user)
  232. if user.Id == 0 || user.Name != user1.Name {
  233. t.Errorf("Search first record with where struct")
  234. }
  235. DB.Find(&users, &User{Name: user2.Name})
  236. if len(users) != 1 {
  237. t.Errorf("Search all records with inline struct")
  238. }
  239. }
  240. func TestSearchWithMap(t *testing.T) {
  241. companyID := 1
  242. user1 := User{Name: "MapSearchUser1", Age: 1, Birthday: parseTime("2000-1-1")}
  243. user2 := User{Name: "MapSearchUser2", Age: 10, Birthday: parseTime("2010-1-1")}
  244. user3 := User{Name: "MapSearchUser3", Age: 20, Birthday: parseTime("2020-1-1")}
  245. user4 := User{Name: "MapSearchUser4", Age: 30, Birthday: parseTime("2020-1-1"), CompanyID: &companyID}
  246. DB.Save(&user1).Save(&user2).Save(&user3).Save(&user4)
  247. var user User
  248. DB.First(&user, map[string]interface{}{"name": user1.Name})
  249. if user.Id == 0 || user.Name != user1.Name {
  250. t.Errorf("Search first record with inline map")
  251. }
  252. user = User{}
  253. DB.Where(map[string]interface{}{"name": user2.Name}).First(&user)
  254. if user.Id == 0 || user.Name != user2.Name {
  255. t.Errorf("Search first record with where map")
  256. }
  257. var users []User
  258. DB.Where(map[string]interface{}{"name": user3.Name}).Find(&users)
  259. if len(users) != 1 {
  260. t.Errorf("Search all records with inline map")
  261. }
  262. DB.Find(&users, map[string]interface{}{"name": user3.Name})
  263. if len(users) != 1 {
  264. t.Errorf("Search all records with inline map")
  265. }
  266. DB.Find(&users, map[string]interface{}{"name": user4.Name, "company_id": nil})
  267. if len(users) != 0 {
  268. t.Errorf("Search all records with inline map containing null value finding 0 records")
  269. }
  270. DB.Find(&users, map[string]interface{}{"name": user1.Name, "company_id": nil})
  271. if len(users) != 1 {
  272. t.Errorf("Search all records with inline map containing null value finding 1 record")
  273. }
  274. DB.Find(&users, map[string]interface{}{"name": user4.Name, "company_id": companyID})
  275. if len(users) != 1 {
  276. t.Errorf("Search all records with inline multiple value map")
  277. }
  278. }
  279. func TestSearchWithEmptyChain(t *testing.T) {
  280. user1 := User{Name: "ChainSearchUser1", Age: 1, Birthday: parseTime("2000-1-1")}
  281. user2 := User{Name: "ChainearchUser2", Age: 10, Birthday: parseTime("2010-1-1")}
  282. user3 := User{Name: "ChainearchUser3", Age: 20, Birthday: parseTime("2020-1-1")}
  283. DB.Save(&user1).Save(&user2).Save(&user3)
  284. if DB.Where("").Where("").First(&User{}).Error != nil {
  285. t.Errorf("Should not raise any error if searching with empty strings")
  286. }
  287. if DB.Where(&User{}).Where("name = ?", user1.Name).First(&User{}).Error != nil {
  288. t.Errorf("Should not raise any error if searching with empty struct")
  289. }
  290. if DB.Where(map[string]interface{}{}).Where("name = ?", user1.Name).First(&User{}).Error != nil {
  291. t.Errorf("Should not raise any error if searching with empty map")
  292. }
  293. }
  294. func TestSelect(t *testing.T) {
  295. user1 := User{Name: "SelectUser1"}
  296. DB.Save(&user1)
  297. var user User
  298. DB.Where("name = ?", user1.Name).Select("name").Find(&user)
  299. if user.Id != 0 {
  300. t.Errorf("Should not have ID because only selected name, %+v", user.Id)
  301. }
  302. if user.Name != user1.Name {
  303. t.Errorf("Should have user Name when selected it")
  304. }
  305. }
  306. func TestOrderAndPluck(t *testing.T) {
  307. user1 := User{Name: "OrderPluckUser1", Age: 1}
  308. user2 := User{Name: "OrderPluckUser2", Age: 10}
  309. user3 := User{Name: "OrderPluckUser3", Age: 20}
  310. DB.Save(&user1).Save(&user2).Save(&user3)
  311. scopedb := DB.Model(&User{}).Where("name like ?", "%OrderPluckUser%")
  312. var user User
  313. scopedb.Order(gorm.Expr("case when name = ? then 0 else 1 end", "OrderPluckUser2")).First(&user)
  314. if user.Name != "OrderPluckUser2" {
  315. t.Errorf("Order with sql expression")
  316. }
  317. var ages []int64
  318. scopedb.Order("age desc").Pluck("age", &ages)
  319. if ages[0] != 20 {
  320. t.Errorf("The first age should be 20 when order with age desc")
  321. }
  322. var ages1, ages2 []int64
  323. scopedb.Order("age desc").Pluck("age", &ages1).Pluck("age", &ages2)
  324. if !reflect.DeepEqual(ages1, ages2) {
  325. t.Errorf("The first order is the primary order")
  326. }
  327. var ages3, ages4 []int64
  328. scopedb.Model(&User{}).Order("age desc").Pluck("age", &ages3).Order("age", true).Pluck("age", &ages4)
  329. if reflect.DeepEqual(ages3, ages4) {
  330. t.Errorf("Reorder should work")
  331. }
  332. var names []string
  333. var ages5 []int64
  334. scopedb.Model(User{}).Order("name").Order("age desc").Pluck("age", &ages5).Pluck("name", &names)
  335. if names != nil && ages5 != nil {
  336. if !(names[0] == user1.Name && names[1] == user2.Name && names[2] == user3.Name && ages5[2] == 20) {
  337. t.Errorf("Order with multiple orders")
  338. }
  339. } else {
  340. t.Errorf("Order with multiple orders")
  341. }
  342. var ages6 []int64
  343. if err := scopedb.Order("").Pluck("age", &ages6).Error; err != nil {
  344. t.Errorf("An empty string as order clause produces invalid queries")
  345. }
  346. DB.Model(User{}).Select("name, age").Find(&[]User{})
  347. }
  348. func TestLimit(t *testing.T) {
  349. user1 := User{Name: "LimitUser1", Age: 1}
  350. user2 := User{Name: "LimitUser2", Age: 10}
  351. user3 := User{Name: "LimitUser3", Age: 20}
  352. user4 := User{Name: "LimitUser4", Age: 10}
  353. user5 := User{Name: "LimitUser5", Age: 20}
  354. DB.Save(&user1).Save(&user2).Save(&user3).Save(&user4).Save(&user5)
  355. var users1, users2, users3 []User
  356. DB.Order("age desc").Limit(3).Find(&users1).Limit(5).Find(&users2).Limit(-1).Find(&users3)
  357. if len(users1) != 3 || len(users2) != 5 || len(users3) <= 5 {
  358. t.Errorf("Limit should works")
  359. }
  360. }
  361. func TestOffset(t *testing.T) {
  362. for i := 0; i < 20; i++ {
  363. DB.Save(&User{Name: fmt.Sprintf("OffsetUser%v", i)})
  364. }
  365. var users1, users2, users3, users4 []User
  366. DB.Limit(100).Where("name like ?", "OffsetUser%").Order("age desc").Find(&users1).Offset(3).Find(&users2).Offset(5).Find(&users3).Offset(-1).Find(&users4)
  367. if (len(users1) != len(users4)) || (len(users1)-len(users2) != 3) || (len(users1)-len(users3) != 5) {
  368. t.Errorf("Offset should work")
  369. }
  370. }
  371. func TestLimitAndOffsetSQL(t *testing.T) {
  372. user1 := User{Name: "TestLimitAndOffsetSQL1", Age: 10}
  373. user2 := User{Name: "TestLimitAndOffsetSQL2", Age: 20}
  374. user3 := User{Name: "TestLimitAndOffsetSQL3", Age: 30}
  375. user4 := User{Name: "TestLimitAndOffsetSQL4", Age: 40}
  376. user5 := User{Name: "TestLimitAndOffsetSQL5", Age: 50}
  377. if err := DB.Save(&user1).Save(&user2).Save(&user3).Save(&user4).Save(&user5).Error; err != nil {
  378. t.Fatal(err)
  379. }
  380. tests := []struct {
  381. name string
  382. limit, offset interface{}
  383. users []*User
  384. ok bool
  385. }{
  386. {
  387. name: "OK",
  388. limit: float64(2),
  389. offset: float64(2),
  390. users: []*User{
  391. &User{Name: "TestLimitAndOffsetSQL3", Age: 30},
  392. &User{Name: "TestLimitAndOffsetSQL2", Age: 20},
  393. },
  394. ok: true,
  395. },
  396. {
  397. name: "Limit parse error",
  398. limit: float64(1000000), // 1e+06
  399. offset: float64(2),
  400. ok: false,
  401. },
  402. {
  403. name: "Offset parse error",
  404. limit: float64(2),
  405. offset: float64(1000000), // 1e+06
  406. ok: false,
  407. },
  408. }
  409. for _, tt := range tests {
  410. t.Run(tt.name, func(t *testing.T) {
  411. var users []*User
  412. err := DB.Where("name LIKE ?", "TestLimitAndOffsetSQL%").Order("age desc").Limit(tt.limit).Offset(tt.offset).Find(&users).Error
  413. if tt.ok {
  414. if err != nil {
  415. t.Errorf("error expected nil, but got %v", err)
  416. }
  417. if len(users) != len(tt.users) {
  418. t.Errorf("users length expected %d, but got %d", len(tt.users), len(users))
  419. }
  420. for i := range tt.users {
  421. if users[i].Name != tt.users[i].Name {
  422. t.Errorf("users[%d] name expected %s, but got %s", i, tt.users[i].Name, users[i].Name)
  423. }
  424. if users[i].Age != tt.users[i].Age {
  425. t.Errorf("users[%d] age expected %d, but got %d", i, tt.users[i].Age, users[i].Age)
  426. }
  427. }
  428. } else {
  429. if err == nil {
  430. t.Error("error expected not nil, but got nil")
  431. }
  432. }
  433. })
  434. }
  435. }
  436. func TestOr(t *testing.T) {
  437. user1 := User{Name: "OrUser1", Age: 1}
  438. user2 := User{Name: "OrUser2", Age: 10}
  439. user3 := User{Name: "OrUser3", Age: 20}
  440. DB.Save(&user1).Save(&user2).Save(&user3)
  441. var users []User
  442. DB.Where("name = ?", user1.Name).Or("name = ?", user2.Name).Find(&users)
  443. if len(users) != 2 {
  444. t.Errorf("Find users with or")
  445. }
  446. }
  447. func TestCount(t *testing.T) {
  448. user1 := User{Name: "CountUser1", Age: 1}
  449. user2 := User{Name: "CountUser2", Age: 10}
  450. user3 := User{Name: "CountUser3", Age: 20}
  451. DB.Save(&user1).Save(&user2).Save(&user3)
  452. var count, count1, count2 int64
  453. var users []User
  454. if err := DB.Where("name = ?", user1.Name).Or("name = ?", user3.Name).Find(&users).Count(&count).Error; err != nil {
  455. t.Errorf(fmt.Sprintf("Count should work, but got err %v", err))
  456. }
  457. if count != int64(len(users)) {
  458. t.Errorf("Count() method should get correct value")
  459. }
  460. DB.Model(&User{}).Where("name = ?", user1.Name).Count(&count1).Or("name in (?)", []string{user2.Name, user3.Name}).Count(&count2)
  461. if count1 != 1 || count2 != 3 {
  462. t.Errorf("Multiple count in chain")
  463. }
  464. var count3 int
  465. if err := DB.Model(&User{}).Where("name in (?)", []string{user2.Name, user2.Name, user3.Name}).Group("id").Count(&count3).Error; err != nil {
  466. t.Errorf("Not error should happen, but got %v", err)
  467. }
  468. if count3 != 2 {
  469. t.Errorf("Should get correct count, but got %v", count3)
  470. }
  471. }
  472. func TestNot(t *testing.T) {
  473. DB.Create(getPreparedUser("user1", "not"))
  474. DB.Create(getPreparedUser("user2", "not"))
  475. DB.Create(getPreparedUser("user3", "not"))
  476. user4 := getPreparedUser("user4", "not")
  477. user4.Company = Company{}
  478. DB.Create(user4)
  479. DB := DB.Where("role = ?", "not")
  480. var users1, users2, users3, users4, users5, users6, users7, users8, users9 []User
  481. if DB.Find(&users1).RowsAffected != 4 {
  482. t.Errorf("should find 4 not users")
  483. }
  484. DB.Not(users1[0].Id).Find(&users2)
  485. if len(users1)-len(users2) != 1 {
  486. t.Errorf("Should ignore the first users with Not")
  487. }
  488. DB.Not([]int{}).Find(&users3)
  489. if len(users1)-len(users3) != 0 {
  490. t.Errorf("Should find all users with a blank condition")
  491. }
  492. var name3Count int64
  493. DB.Table("users").Where("name = ?", "user3").Count(&name3Count)
  494. DB.Not("name", "user3").Find(&users4)
  495. if len(users1)-len(users4) != int(name3Count) {
  496. t.Errorf("Should find all users' name not equal 3")
  497. }
  498. DB.Not("name = ?", "user3").Find(&users4)
  499. if len(users1)-len(users4) != int(name3Count) {
  500. t.Errorf("Should find all users' name not equal 3")
  501. }
  502. DB.Not("name <> ?", "user3").Find(&users4)
  503. if len(users4) != int(name3Count) {
  504. t.Errorf("Should find all users' name not equal 3")
  505. }
  506. DB.Not(User{Name: "user3"}).Find(&users5)
  507. if len(users1)-len(users5) != int(name3Count) {
  508. t.Errorf("Should find all users' name not equal 3")
  509. }
  510. DB.Not(map[string]interface{}{"name": "user3"}).Find(&users6)
  511. if len(users1)-len(users6) != int(name3Count) {
  512. t.Errorf("Should find all users' name not equal 3")
  513. }
  514. DB.Not(map[string]interface{}{"name": "user3", "company_id": nil}).Find(&users7)
  515. if len(users1)-len(users7) != 2 { // not user3 or user4
  516. t.Errorf("Should find all user's name not equal to 3 who do not have company id")
  517. }
  518. DB.Not("name", []string{"user3"}).Find(&users8)
  519. if len(users1)-len(users8) != int(name3Count) {
  520. t.Errorf("Should find all users' name not equal 3")
  521. }
  522. var name2Count int64
  523. DB.Table("users").Where("name = ?", "user2").Count(&name2Count)
  524. DB.Not("name", []string{"user3", "user2"}).Find(&users9)
  525. if len(users1)-len(users9) != (int(name3Count) + int(name2Count)) {
  526. t.Errorf("Should find all users' name not equal 3")
  527. }
  528. }
  529. func TestFillSmallerStruct(t *testing.T) {
  530. user1 := User{Name: "SmallerUser", Age: 100}
  531. DB.Save(&user1)
  532. type SimpleUser struct {
  533. Name string
  534. Id int64
  535. UpdatedAt time.Time
  536. CreatedAt time.Time
  537. }
  538. var simpleUser SimpleUser
  539. DB.Table("users").Where("name = ?", user1.Name).First(&simpleUser)
  540. if simpleUser.Id == 0 || simpleUser.Name == "" {
  541. t.Errorf("Should fill data correctly into smaller struct")
  542. }
  543. }
  544. func TestFindOrInitialize(t *testing.T) {
  545. var user1, user2, user3, user4, user5, user6 User
  546. DB.Where(&User{Name: "find or init", Age: 33}).FirstOrInit(&user1)
  547. if user1.Name != "find or init" || user1.Id != 0 || user1.Age != 33 {
  548. t.Errorf("user should be initialized with search value")
  549. }
  550. DB.Where(User{Name: "find or init", Age: 33}).FirstOrInit(&user2)
  551. if user2.Name != "find or init" || user2.Id != 0 || user2.Age != 33 {
  552. t.Errorf("user should be initialized with search value")
  553. }
  554. DB.FirstOrInit(&user3, map[string]interface{}{"name": "find or init 2"})
  555. if user3.Name != "find or init 2" || user3.Id != 0 {
  556. t.Errorf("user should be initialized with inline search value")
  557. }
  558. DB.Where(&User{Name: "find or init"}).Attrs(User{Age: 44}).FirstOrInit(&user4)
  559. if user4.Name != "find or init" || user4.Id != 0 || user4.Age != 44 {
  560. t.Errorf("user should be initialized with search value and attrs")
  561. }
  562. DB.Where(&User{Name: "find or init"}).Assign("age", 44).FirstOrInit(&user4)
  563. if user4.Name != "find or init" || user4.Id != 0 || user4.Age != 44 {
  564. t.Errorf("user should be initialized with search value and assign attrs")
  565. }
  566. DB.Save(&User{Name: "find or init", Age: 33})
  567. DB.Where(&User{Name: "find or init"}).Attrs("age", 44).FirstOrInit(&user5)
  568. if user5.Name != "find or init" || user5.Id == 0 || user5.Age != 33 {
  569. t.Errorf("user should be found and not initialized by Attrs")
  570. }
  571. DB.Where(&User{Name: "find or init", Age: 33}).FirstOrInit(&user6)
  572. if user6.Name != "find or init" || user6.Id == 0 || user6.Age != 33 {
  573. t.Errorf("user should be found with FirstOrInit")
  574. }
  575. DB.Where(&User{Name: "find or init"}).Assign(User{Age: 44}).FirstOrInit(&user6)
  576. if user6.Name != "find or init" || user6.Id == 0 || user6.Age != 44 {
  577. t.Errorf("user should be found and updated with assigned attrs")
  578. }
  579. }
  580. func TestFindOrCreate(t *testing.T) {
  581. var user1, user2, user3, user4, user5, user6, user7, user8 User
  582. DB.Where(&User{Name: "find or create", Age: 33}).FirstOrCreate(&user1)
  583. if user1.Name != "find or create" || user1.Id == 0 || user1.Age != 33 {
  584. t.Errorf("user should be created with search value")
  585. }
  586. DB.Where(&User{Name: "find or create", Age: 33}).FirstOrCreate(&user2)
  587. if user1.Id != user2.Id || user2.Name != "find or create" || user2.Id == 0 || user2.Age != 33 {
  588. t.Errorf("user should be created with search value")
  589. }
  590. DB.FirstOrCreate(&user3, map[string]interface{}{"name": "find or create 2"})
  591. if user3.Name != "find or create 2" || user3.Id == 0 {
  592. t.Errorf("user should be created with inline search value")
  593. }
  594. DB.Where(&User{Name: "find or create 3"}).Attrs("age", 44).FirstOrCreate(&user4)
  595. if user4.Name != "find or create 3" || user4.Id == 0 || user4.Age != 44 {
  596. t.Errorf("user should be created with search value and attrs")
  597. }
  598. updatedAt1 := user4.UpdatedAt
  599. DB.Where(&User{Name: "find or create 3"}).Assign("age", 55).FirstOrCreate(&user4)
  600. if updatedAt1.Format(time.RFC3339Nano) == user4.UpdatedAt.Format(time.RFC3339Nano) {
  601. t.Errorf("UpdateAt should be changed when update values with assign")
  602. }
  603. DB.Where(&User{Name: "find or create 4"}).Assign(User{Age: 44}).FirstOrCreate(&user4)
  604. if user4.Name != "find or create 4" || user4.Id == 0 || user4.Age != 44 {
  605. t.Errorf("user should be created with search value and assigned attrs")
  606. }
  607. DB.Where(&User{Name: "find or create"}).Attrs("age", 44).FirstOrInit(&user5)
  608. if user5.Name != "find or create" || user5.Id == 0 || user5.Age != 33 {
  609. t.Errorf("user should be found and not initialized by Attrs")
  610. }
  611. DB.Where(&User{Name: "find or create"}).Assign(User{Age: 44}).FirstOrCreate(&user6)
  612. if user6.Name != "find or create" || user6.Id == 0 || user6.Age != 44 {
  613. t.Errorf("user should be found and updated with assigned attrs")
  614. }
  615. DB.Where(&User{Name: "find or create"}).Find(&user7)
  616. if user7.Name != "find or create" || user7.Id == 0 || user7.Age != 44 {
  617. t.Errorf("user should be found and updated with assigned attrs")
  618. }
  619. DB.Where(&User{Name: "find or create embedded struct"}).Assign(User{Age: 44, CreditCard: CreditCard{Number: "1231231231"}, Emails: []Email{{Email: "jinzhu@assign_embedded_struct.com"}, {Email: "jinzhu-2@assign_embedded_struct.com"}}}).FirstOrCreate(&user8)
  620. if DB.Where("email = ?", "jinzhu-2@assign_embedded_struct.com").First(&Email{}).RecordNotFound() {
  621. t.Errorf("embedded struct email should be saved")
  622. }
  623. if DB.Where("email = ?", "1231231231").First(&CreditCard{}).RecordNotFound() {
  624. t.Errorf("embedded struct credit card should be saved")
  625. }
  626. }
  627. func TestSelectWithEscapedFieldName(t *testing.T) {
  628. user1 := User{Name: "EscapedFieldNameUser", Age: 1}
  629. user2 := User{Name: "EscapedFieldNameUser", Age: 10}
  630. user3 := User{Name: "EscapedFieldNameUser", Age: 20}
  631. DB.Save(&user1).Save(&user2).Save(&user3)
  632. var names []string
  633. DB.Model(User{}).Where(&User{Name: "EscapedFieldNameUser"}).Pluck("\"name\"", &names)
  634. if len(names) != 3 {
  635. t.Errorf("Expected 3 name, but got: %d", len(names))
  636. }
  637. }
  638. func TestSelectWithVariables(t *testing.T) {
  639. DB.Save(&User{Name: "jinzhu"})
  640. rows, _ := DB.Table("users").Select("? as fake", gorm.Expr("name")).Rows()
  641. if !rows.Next() {
  642. t.Errorf("Should have returned at least one row")
  643. } else {
  644. columns, _ := rows.Columns()
  645. if !reflect.DeepEqual(columns, []string{"fake"}) {
  646. t.Errorf("Should only contains one column")
  647. }
  648. }
  649. rows.Close()
  650. }
  651. func TestSelectWithArrayInput(t *testing.T) {
  652. DB.Save(&User{Name: "jinzhu", Age: 42})
  653. var user User
  654. DB.Select([]string{"name", "age"}).Where("age = 42 AND name = 'jinzhu'").First(&user)
  655. if user.Name != "jinzhu" || user.Age != 42 {
  656. t.Errorf("Should have selected both age and name")
  657. }
  658. }
  659. func TestPluckWithSelect(t *testing.T) {
  660. var (
  661. user = User{Name: "matematik7_pluck_with_select", Age: 25}
  662. combinedName = fmt.Sprintf("%v%v", user.Name, user.Age)
  663. combineUserAgeSQL = fmt.Sprintf("concat(%v, %v)", DB.Dialect().Quote("name"), DB.Dialect().Quote("age"))
  664. )
  665. if dialect := DB.Dialect().GetName(); dialect == "sqlite3" {
  666. combineUserAgeSQL = fmt.Sprintf("(%v || %v)", DB.Dialect().Quote("name"), DB.Dialect().Quote("age"))
  667. }
  668. DB.Save(&user)
  669. selectStr := combineUserAgeSQL + " as user_age"
  670. var userAges []string
  671. err := DB.Model(&User{}).Where("age = ?", 25).Select(selectStr).Pluck("user_age", &userAges).Error
  672. if err != nil {
  673. t.Error(err)
  674. }
  675. if len(userAges) != 1 || userAges[0] != combinedName {
  676. t.Errorf("Should correctly pluck with select, got: %s", userAges)
  677. }
  678. selectStr = combineUserAgeSQL + fmt.Sprintf(" as %v", DB.Dialect().Quote("user_age"))
  679. userAges = userAges[:0]
  680. err = DB.Model(&User{}).Where("age = ?", 25).Select(selectStr).Pluck("user_age", &userAges).Error
  681. if err != nil {
  682. t.Error(err)
  683. }
  684. if len(userAges) != 1 || userAges[0] != combinedName {
  685. t.Errorf("Should correctly pluck with select, got: %s", userAges)
  686. }
  687. }