THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1027 lines
24KB

  1. // Copyright 2017 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package xorm
  5. import (
  6. "errors"
  7. "fmt"
  8. "reflect"
  9. "testing"
  10. "time"
  11. "github.com/stretchr/testify/assert"
  12. )
  13. func TestInsertOne(t *testing.T) {
  14. assert.NoError(t, prepareEngine())
  15. type Test struct {
  16. Id int64 `xorm:"autoincr pk"`
  17. Msg string `xorm:"varchar(255)"`
  18. Created time.Time `xorm:"created"`
  19. }
  20. assert.NoError(t, testEngine.Sync2(new(Test)))
  21. data := Test{Msg: "hi"}
  22. _, err := testEngine.InsertOne(data)
  23. assert.NoError(t, err)
  24. }
  25. func TestInsertMulti(t *testing.T) {
  26. assert.NoError(t, prepareEngine())
  27. type TestMulti struct {
  28. Id int64 `xorm:"int(11) pk"`
  29. Name string `xorm:"varchar(255)"`
  30. }
  31. assert.NoError(t, testEngine.Sync2(new(TestMulti)))
  32. num, err := insertMultiDatas(1,
  33. append([]TestMulti{}, TestMulti{1, "test1"}, TestMulti{2, "test2"}, TestMulti{3, "test3"}))
  34. assert.NoError(t, err)
  35. assert.EqualValues(t, 3, num)
  36. }
  37. func insertMultiDatas(step int, datas interface{}) (num int64, err error) {
  38. sliceValue := reflect.Indirect(reflect.ValueOf(datas))
  39. var iLen int64
  40. if sliceValue.Kind() != reflect.Slice {
  41. return 0, fmt.Errorf("not silce")
  42. }
  43. iLen = int64(sliceValue.Len())
  44. if iLen == 0 {
  45. return
  46. }
  47. session := testEngine.NewSession()
  48. defer session.Close()
  49. if err = callbackLooper(datas, step,
  50. func(innerDatas interface{}) error {
  51. n, e := session.InsertMulti(innerDatas)
  52. if e != nil {
  53. return e
  54. }
  55. num += n
  56. return nil
  57. }); err != nil {
  58. return 0, err
  59. } else if num != iLen {
  60. return 0, fmt.Errorf("num error: %d - %d", num, iLen)
  61. }
  62. return
  63. }
  64. func callbackLooper(datas interface{}, step int, actionFunc func(interface{}) error) (err error) {
  65. sliceValue := reflect.Indirect(reflect.ValueOf(datas))
  66. if sliceValue.Kind() != reflect.Slice {
  67. return fmt.Errorf("not slice")
  68. }
  69. if sliceValue.Len() <= 0 {
  70. return
  71. }
  72. tempLen := 0
  73. processedLen := sliceValue.Len()
  74. for i := 0; i < sliceValue.Len(); i += step {
  75. if processedLen > step {
  76. tempLen = i + step
  77. } else {
  78. tempLen = sliceValue.Len()
  79. }
  80. var tempInterface []interface{}
  81. for j := i; j < tempLen; j++ {
  82. tempInterface = append(tempInterface, sliceValue.Index(j).Interface())
  83. }
  84. if err = actionFunc(tempInterface); err != nil {
  85. return
  86. }
  87. processedLen = processedLen - step
  88. }
  89. return
  90. }
  91. func TestInsertOneIfPkIsPoint(t *testing.T) {
  92. assert.NoError(t, prepareEngine())
  93. type TestPoint struct {
  94. Id *int64 `xorm:"autoincr pk notnull 'id'"`
  95. Msg *string `xorm:"varchar(255)"`
  96. Created *time.Time `xorm:"created"`
  97. }
  98. assert.NoError(t, testEngine.Sync2(new(TestPoint)))
  99. msg := "hi"
  100. data := TestPoint{Msg: &msg}
  101. _, err := testEngine.InsertOne(&data)
  102. assert.NoError(t, err)
  103. }
  104. func TestInsertOneIfPkIsPointRename(t *testing.T) {
  105. assert.NoError(t, prepareEngine())
  106. type ID *int64
  107. type TestPoint2 struct {
  108. Id ID `xorm:"autoincr pk notnull 'id'"`
  109. Msg *string `xorm:"varchar(255)"`
  110. Created *time.Time `xorm:"created"`
  111. }
  112. assert.NoError(t, testEngine.Sync2(new(TestPoint2)))
  113. msg := "hi"
  114. data := TestPoint2{Msg: &msg}
  115. _, err := testEngine.InsertOne(&data)
  116. assert.NoError(t, err)
  117. }
  118. func TestInsert(t *testing.T) {
  119. assert.NoError(t, prepareEngine())
  120. assertSync(t, new(Userinfo))
  121. user := Userinfo{0, "xiaolunwen", "dev", "lunny", time.Now(),
  122. Userdetail{Id: 1}, 1.78, []byte{1, 2, 3}, true}
  123. cnt, err := testEngine.Insert(&user)
  124. assert.NoError(t, err)
  125. assert.EqualValues(t, 1, cnt, "insert not returned 1")
  126. assert.True(t, user.Uid > 0, "not return id error")
  127. user.Uid = 0
  128. cnt, err = testEngine.Insert(&user)
  129. // Username is unique, so this should return error
  130. assert.Error(t, err, "insert should fail but no error returned")
  131. assert.EqualValues(t, 0, cnt, "insert not returned 1")
  132. if err == nil {
  133. panic("should return err")
  134. }
  135. }
  136. func TestInsertAutoIncr(t *testing.T) {
  137. assert.NoError(t, prepareEngine())
  138. assertSync(t, new(Userinfo))
  139. // auto increment insert
  140. user := Userinfo{Username: "xiaolunwen2", Departname: "dev", Alias: "lunny", Created: time.Now(),
  141. Detail: Userdetail{Id: 1}, Height: 1.78, Avatar: []byte{1, 2, 3}, IsMan: true}
  142. cnt, err := testEngine.Insert(&user)
  143. fmt.Println(user.Uid)
  144. if err != nil {
  145. t.Error(err)
  146. panic(err)
  147. }
  148. if cnt != 1 {
  149. err = errors.New("insert not returned 1")
  150. t.Error(err)
  151. panic(err)
  152. }
  153. if user.Uid <= 0 {
  154. t.Error(errors.New("not return id error"))
  155. }
  156. }
  157. type DefaultInsert struct {
  158. Id int64
  159. Status int `xorm:"default -1"`
  160. Name string
  161. Created time.Time `xorm:"created"`
  162. Updated time.Time `xorm:"updated"`
  163. }
  164. func TestInsertDefault(t *testing.T) {
  165. assert.NoError(t, prepareEngine())
  166. di := new(DefaultInsert)
  167. err := testEngine.Sync2(di)
  168. assert.NoError(t, err)
  169. var di2 = DefaultInsert{Name: "test"}
  170. _, err = testEngine.Omit(testEngine.GetColumnMapper().Obj2Table("Status")).Insert(&di2)
  171. assert.NoError(t, err)
  172. has, err := testEngine.Desc("(id)").Get(di)
  173. assert.NoError(t, err)
  174. if !has {
  175. err = errors.New("error with no data")
  176. t.Error(err)
  177. panic(err)
  178. }
  179. if di.Status != -1 {
  180. err = errors.New("inserted error data")
  181. t.Error(err)
  182. panic(err)
  183. }
  184. if di2.Updated.Unix() != di.Updated.Unix() {
  185. err = errors.New("updated should equal")
  186. t.Error(err, di.Updated, di2.Updated)
  187. panic(err)
  188. }
  189. if di2.Created.Unix() != di.Created.Unix() {
  190. err = errors.New("created should equal")
  191. t.Error(err, di.Created, di2.Created)
  192. panic(err)
  193. }
  194. }
  195. type DefaultInsert2 struct {
  196. Id int64
  197. Name string
  198. Url string `xorm:"text"`
  199. CheckTime time.Time `xorm:"not null default '2000-01-01 00:00:00' TIMESTAMP"`
  200. }
  201. func TestInsertDefault2(t *testing.T) {
  202. assert.NoError(t, prepareEngine())
  203. di := new(DefaultInsert2)
  204. err := testEngine.Sync2(di)
  205. if err != nil {
  206. t.Error(err)
  207. }
  208. var di2 = DefaultInsert2{Name: "test"}
  209. _, err = testEngine.Omit(testEngine.GetColumnMapper().Obj2Table("CheckTime")).Insert(&di2)
  210. if err != nil {
  211. t.Error(err)
  212. }
  213. has, err := testEngine.Desc("(id)").Get(di)
  214. if err != nil {
  215. t.Error(err)
  216. }
  217. if !has {
  218. err = errors.New("error with no data")
  219. t.Error(err)
  220. panic(err)
  221. }
  222. has, err = testEngine.NoAutoCondition().Desc("(id)").Get(&di2)
  223. if err != nil {
  224. t.Error(err)
  225. }
  226. if !has {
  227. err = errors.New("error with no data")
  228. t.Error(err)
  229. panic(err)
  230. }
  231. if *di != di2 {
  232. err = fmt.Errorf("%v is not equal to %v", di, di2)
  233. t.Error(err)
  234. panic(err)
  235. }
  236. /*if di2.Updated.Unix() != di.Updated.Unix() {
  237. err = errors.New("updated should equal")
  238. t.Error(err, di.Updated, di2.Updated)
  239. panic(err)
  240. }
  241. if di2.Created.Unix() != di.Created.Unix() {
  242. err = errors.New("created should equal")
  243. t.Error(err, di.Created, di2.Created)
  244. panic(err)
  245. }*/
  246. }
  247. type CreatedInsert struct {
  248. Id int64
  249. Created time.Time `xorm:"created"`
  250. }
  251. type CreatedInsert2 struct {
  252. Id int64
  253. Created int64 `xorm:"created"`
  254. }
  255. type CreatedInsert3 struct {
  256. Id int64
  257. Created int `xorm:"created bigint"`
  258. }
  259. type CreatedInsert4 struct {
  260. Id int64
  261. Created int `xorm:"created"`
  262. }
  263. type CreatedInsert5 struct {
  264. Id int64
  265. Created time.Time `xorm:"created bigint"`
  266. }
  267. type CreatedInsert6 struct {
  268. Id int64
  269. Created time.Time `xorm:"created bigint"`
  270. }
  271. func TestInsertCreated(t *testing.T) {
  272. assert.NoError(t, prepareEngine())
  273. di := new(CreatedInsert)
  274. err := testEngine.Sync2(di)
  275. if err != nil {
  276. t.Fatal(err)
  277. }
  278. ci := &CreatedInsert{}
  279. _, err = testEngine.Insert(ci)
  280. if err != nil {
  281. t.Fatal(err)
  282. }
  283. has, err := testEngine.Desc("(id)").Get(di)
  284. if err != nil {
  285. t.Fatal(err)
  286. }
  287. if !has {
  288. t.Fatal(ErrNotExist)
  289. }
  290. if ci.Created.Unix() != di.Created.Unix() {
  291. t.Fatal("should equal:", ci, di)
  292. }
  293. fmt.Println("ci:", ci, "di:", di)
  294. di2 := new(CreatedInsert2)
  295. err = testEngine.Sync2(di2)
  296. if err != nil {
  297. t.Fatal(err)
  298. }
  299. ci2 := &CreatedInsert2{}
  300. _, err = testEngine.Insert(ci2)
  301. if err != nil {
  302. t.Fatal(err)
  303. }
  304. has, err = testEngine.Desc("(id)").Get(di2)
  305. if err != nil {
  306. t.Fatal(err)
  307. }
  308. if !has {
  309. t.Fatal(ErrNotExist)
  310. }
  311. if ci2.Created != di2.Created {
  312. t.Fatal("should equal:", ci2, di2)
  313. }
  314. fmt.Println("ci2:", ci2, "di2:", di2)
  315. di3 := new(CreatedInsert3)
  316. err = testEngine.Sync2(di3)
  317. if err != nil {
  318. t.Fatal(err)
  319. }
  320. ci3 := &CreatedInsert3{}
  321. _, err = testEngine.Insert(ci3)
  322. if err != nil {
  323. t.Fatal(err)
  324. }
  325. has, err = testEngine.Desc("(id)").Get(di3)
  326. if err != nil {
  327. t.Fatal(err)
  328. }
  329. if !has {
  330. t.Fatal(ErrNotExist)
  331. }
  332. if ci3.Created != di3.Created {
  333. t.Fatal("should equal:", ci3, di3)
  334. }
  335. fmt.Println("ci3:", ci3, "di3:", di3)
  336. di4 := new(CreatedInsert4)
  337. err = testEngine.Sync2(di4)
  338. if err != nil {
  339. t.Fatal(err)
  340. }
  341. ci4 := &CreatedInsert4{}
  342. _, err = testEngine.Insert(ci4)
  343. if err != nil {
  344. t.Fatal(err)
  345. }
  346. has, err = testEngine.Desc("(id)").Get(di4)
  347. if err != nil {
  348. t.Fatal(err)
  349. }
  350. if !has {
  351. t.Fatal(ErrNotExist)
  352. }
  353. if ci4.Created != di4.Created {
  354. t.Fatal("should equal:", ci4, di4)
  355. }
  356. fmt.Println("ci4:", ci4, "di4:", di4)
  357. di5 := new(CreatedInsert5)
  358. err = testEngine.Sync2(di5)
  359. if err != nil {
  360. t.Fatal(err)
  361. }
  362. ci5 := &CreatedInsert5{}
  363. _, err = testEngine.Insert(ci5)
  364. if err != nil {
  365. t.Fatal(err)
  366. }
  367. has, err = testEngine.Desc("(id)").Get(di5)
  368. if err != nil {
  369. t.Fatal(err)
  370. }
  371. if !has {
  372. t.Fatal(ErrNotExist)
  373. }
  374. if ci5.Created.Unix() != di5.Created.Unix() {
  375. t.Fatal("should equal:", ci5, di5)
  376. }
  377. fmt.Println("ci5:", ci5, "di5:", di5)
  378. di6 := new(CreatedInsert6)
  379. err = testEngine.Sync2(di6)
  380. if err != nil {
  381. t.Fatal(err)
  382. }
  383. oldTime := time.Now().Add(-time.Hour)
  384. ci6 := &CreatedInsert6{Created: oldTime}
  385. _, err = testEngine.Insert(ci6)
  386. if err != nil {
  387. t.Fatal(err)
  388. }
  389. has, err = testEngine.Desc("(id)").Get(di6)
  390. if err != nil {
  391. t.Fatal(err)
  392. }
  393. if !has {
  394. t.Fatal(ErrNotExist)
  395. }
  396. if ci6.Created.Unix() != di6.Created.Unix() {
  397. t.Fatal("should equal:", ci6, di6)
  398. }
  399. fmt.Println("ci6:", ci6, "di6:", di6)
  400. }
  401. type JsonTime time.Time
  402. func (j JsonTime) format() string {
  403. t := time.Time(j)
  404. if t.IsZero() {
  405. return ""
  406. }
  407. return t.Format("2006-01-02")
  408. }
  409. func (j JsonTime) MarshalText() ([]byte, error) {
  410. return []byte(j.format()), nil
  411. }
  412. func (j JsonTime) MarshalJSON() ([]byte, error) {
  413. return []byte(`"` + j.format() + `"`), nil
  414. }
  415. func TestDefaultTime3(t *testing.T) {
  416. type PrepareTask struct {
  417. Id int `xorm:"not null pk autoincr INT(11)" json:"id"`
  418. // ...
  419. StartTime JsonTime `xorm:"not null default '2006-01-02 15:04:05' TIMESTAMP index" json:"start_time"`
  420. EndTime JsonTime `xorm:"not null default '2006-01-02 15:04:05' TIMESTAMP" json:"end_time"`
  421. Cuser string `xorm:"not null default '' VARCHAR(64) index" json:"cuser"`
  422. Muser string `xorm:"not null default '' VARCHAR(64)" json:"muser"`
  423. Ctime JsonTime `xorm:"not null default CURRENT_TIMESTAMP TIMESTAMP created" json:"ctime"`
  424. Mtime JsonTime `xorm:"not null default CURRENT_TIMESTAMP TIMESTAMP updated" json:"mtime"`
  425. }
  426. assert.NoError(t, prepareEngine())
  427. assertSync(t, new(PrepareTask))
  428. prepareTask := &PrepareTask{
  429. StartTime: JsonTime(time.Now()),
  430. Cuser: "userId",
  431. Muser: "userId",
  432. }
  433. cnt, err := testEngine.Omit("end_time").InsertOne(prepareTask)
  434. assert.NoError(t, err)
  435. assert.EqualValues(t, 1, cnt)
  436. }
  437. type MyJsonTime struct {
  438. Id int64 `json:"id"`
  439. Created JsonTime `xorm:"created" json:"created_at"`
  440. }
  441. func TestCreatedJsonTime(t *testing.T) {
  442. assert.NoError(t, prepareEngine())
  443. di5 := new(MyJsonTime)
  444. err := testEngine.Sync2(di5)
  445. if err != nil {
  446. t.Fatal(err)
  447. }
  448. ci5 := &MyJsonTime{}
  449. _, err = testEngine.Insert(ci5)
  450. if err != nil {
  451. t.Fatal(err)
  452. }
  453. has, err := testEngine.Desc("(id)").Get(di5)
  454. if err != nil {
  455. t.Fatal(err)
  456. }
  457. if !has {
  458. t.Fatal(ErrNotExist)
  459. }
  460. if time.Time(ci5.Created).Unix() != time.Time(di5.Created).Unix() {
  461. t.Fatal("should equal:", time.Time(ci5.Created).Unix(), time.Time(di5.Created).Unix())
  462. }
  463. fmt.Println("ci5:", ci5, "di5:", di5)
  464. var dis = make([]MyJsonTime, 0)
  465. err = testEngine.Find(&dis)
  466. if err != nil {
  467. t.Fatal(err)
  468. }
  469. }
  470. func TestInsertMulti2(t *testing.T) {
  471. assert.NoError(t, prepareEngine())
  472. assertSync(t, new(Userinfo))
  473. users := []Userinfo{
  474. {Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  475. {Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  476. {Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  477. {Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  478. }
  479. cnt, err := testEngine.Insert(&users)
  480. if err != nil {
  481. t.Error(err)
  482. panic(err)
  483. }
  484. if cnt != int64(len(users)) {
  485. err = errors.New("insert not returned 1")
  486. t.Error(err)
  487. panic(err)
  488. return
  489. }
  490. users2 := []*Userinfo{
  491. &Userinfo{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  492. &Userinfo{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  493. &Userinfo{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  494. &Userinfo{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  495. }
  496. cnt, err = testEngine.Insert(&users2)
  497. if err != nil {
  498. t.Error(err)
  499. panic(err)
  500. }
  501. if cnt != int64(len(users2)) {
  502. err = errors.New(fmt.Sprintf("insert not returned %v", len(users2)))
  503. t.Error(err)
  504. panic(err)
  505. }
  506. }
  507. func TestInsertTwoTable(t *testing.T) {
  508. assert.NoError(t, prepareEngine())
  509. assertSync(t, new(Userinfo), new(Userdetail))
  510. userdetail := Userdetail{ /*Id: 1, */ Intro: "I'm a very beautiful women.", Profile: "sfsaf"}
  511. userinfo := Userinfo{Username: "xlw3", Departname: "dev", Alias: "lunny4", Created: time.Now(), Detail: userdetail}
  512. cnt, err := testEngine.Insert(&userinfo, &userdetail)
  513. if err != nil {
  514. t.Error(err)
  515. panic(err)
  516. }
  517. if userinfo.Uid <= 0 {
  518. err = errors.New("not return id error")
  519. t.Error(err)
  520. panic(err)
  521. }
  522. if userdetail.Id <= 0 {
  523. err = errors.New("not return id error")
  524. t.Error(err)
  525. panic(err)
  526. }
  527. if cnt != 2 {
  528. err = errors.New("insert not returned 2")
  529. t.Error(err)
  530. panic(err)
  531. }
  532. }
  533. func TestInsertCreatedInt64(t *testing.T) {
  534. assert.NoError(t, prepareEngine())
  535. type TestCreatedInt64 struct {
  536. Id int64 `xorm:"autoincr pk"`
  537. Msg string `xorm:"varchar(255)"`
  538. Created int64 `xorm:"created"`
  539. }
  540. assert.NoError(t, testEngine.Sync2(new(TestCreatedInt64)))
  541. data := TestCreatedInt64{Msg: "hi"}
  542. now := time.Now()
  543. cnt, err := testEngine.Insert(&data)
  544. assert.NoError(t, err)
  545. assert.EqualValues(t, 1, cnt)
  546. assert.True(t, now.Unix() <= data.Created)
  547. var data2 TestCreatedInt64
  548. has, err := testEngine.Get(&data2)
  549. assert.NoError(t, err)
  550. assert.True(t, has)
  551. assert.EqualValues(t, data.Created, data2.Created)
  552. }
  553. type MyUserinfo Userinfo
  554. func (MyUserinfo) TableName() string {
  555. return "user_info"
  556. }
  557. func TestInsertMulti3(t *testing.T) {
  558. assert.NoError(t, prepareEngine())
  559. testEngine.ShowSQL(true)
  560. assertSync(t, new(MyUserinfo))
  561. users := []MyUserinfo{
  562. {Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  563. {Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  564. {Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  565. {Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  566. }
  567. cnt, err := testEngine.Insert(&users)
  568. assert.NoError(t, err)
  569. assert.EqualValues(t, len(users), cnt)
  570. users2 := []*MyUserinfo{
  571. &MyUserinfo{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  572. &MyUserinfo{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  573. &MyUserinfo{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  574. &MyUserinfo{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  575. }
  576. cnt, err = testEngine.Insert(&users2)
  577. assert.NoError(t, err)
  578. assert.EqualValues(t, len(users), cnt)
  579. }
  580. type MyUserinfo2 struct {
  581. Uid int64 `xorm:"id pk not null autoincr"`
  582. Username string `xorm:"unique"`
  583. Departname string
  584. Alias string `xorm:"-"`
  585. Created time.Time
  586. Detail Userdetail `xorm:"detail_id int(11)"`
  587. Height float64
  588. Avatar []byte
  589. IsMan bool
  590. }
  591. func (MyUserinfo2) TableName() string {
  592. return "user_info"
  593. }
  594. func TestInsertMulti4(t *testing.T) {
  595. assert.NoError(t, prepareEngine())
  596. testEngine.ShowSQL(false)
  597. assertSync(t, new(MyUserinfo2))
  598. testEngine.ShowSQL(true)
  599. users := []MyUserinfo2{
  600. {Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  601. {Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  602. {Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  603. {Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  604. }
  605. cnt, err := testEngine.Insert(&users)
  606. assert.NoError(t, err)
  607. assert.EqualValues(t, len(users), cnt)
  608. users2 := []*MyUserinfo2{
  609. &MyUserinfo2{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  610. &MyUserinfo2{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  611. &MyUserinfo2{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  612. &MyUserinfo2{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  613. }
  614. cnt, err = testEngine.Insert(&users2)
  615. assert.NoError(t, err)
  616. assert.EqualValues(t, len(users), cnt)
  617. }
  618. func TestAnonymousStruct(t *testing.T) {
  619. type PlainObject struct {
  620. ID uint64 `json:"id,string" xorm:"'ID' pk autoincr"`
  621. Desc string `json:"desc" xorm:"'DESC' notnull"`
  622. }
  623. type PlainFoo struct {
  624. PlainObject `xorm:"extends"` // primary key defined in extends struct
  625. Width uint32 `json:"width" xorm:"'WIDTH' notnull"`
  626. Height uint32 `json:"height" xorm:"'HEIGHT' notnull"`
  627. Ext struct {
  628. F1 uint32 `json:"f1,omitempty"`
  629. F2 uint32 `json:"f2,omitempty"`
  630. } `json:"ext" xorm:"'EXT' json notnull"`
  631. }
  632. assert.NoError(t, prepareEngine())
  633. assertSync(t, new(PlainFoo))
  634. _, err := testEngine.Insert(&PlainFoo{
  635. PlainObject: PlainObject{
  636. Desc: "test",
  637. },
  638. Width: 10,
  639. Height: 20,
  640. Ext: struct {
  641. F1 uint32 `json:"f1,omitempty"`
  642. F2 uint32 `json:"f2,omitempty"`
  643. }{
  644. F1: 11,
  645. F2: 12,
  646. },
  647. })
  648. assert.NoError(t, err)
  649. }
  650. func TestInsertMap(t *testing.T) {
  651. type InsertMap struct {
  652. Id int64
  653. Width uint32
  654. Height uint32
  655. Name string
  656. }
  657. assert.NoError(t, prepareEngine())
  658. assertSync(t, new(InsertMap))
  659. cnt, err := testEngine.Table(new(InsertMap)).Insert(map[string]interface{}{
  660. "width": 20,
  661. "height": 10,
  662. "name": "lunny",
  663. })
  664. assert.NoError(t, err)
  665. assert.EqualValues(t, 1, cnt)
  666. var im InsertMap
  667. has, err := testEngine.Get(&im)
  668. assert.NoError(t, err)
  669. assert.True(t, has)
  670. assert.EqualValues(t, 20, im.Width)
  671. assert.EqualValues(t, 10, im.Height)
  672. assert.EqualValues(t, "lunny", im.Name)
  673. cnt, err = testEngine.Table("insert_map").Insert(map[string]interface{}{
  674. "width": 30,
  675. "height": 10,
  676. "name": "lunny",
  677. })
  678. assert.NoError(t, err)
  679. assert.EqualValues(t, 1, cnt)
  680. var ims []InsertMap
  681. err = testEngine.Find(&ims)
  682. assert.NoError(t, err)
  683. assert.EqualValues(t, 2, len(ims))
  684. assert.EqualValues(t, 20, ims[0].Width)
  685. assert.EqualValues(t, 10, ims[0].Height)
  686. assert.EqualValues(t, "lunny", ims[0].Name)
  687. assert.EqualValues(t, 30, ims[1].Width)
  688. assert.EqualValues(t, 10, ims[1].Height)
  689. assert.EqualValues(t, "lunny", ims[1].Name)
  690. cnt, err = testEngine.Table("insert_map").Insert([]map[string]interface{}{
  691. {
  692. "width": 40,
  693. "height": 10,
  694. "name": "lunny",
  695. },
  696. {
  697. "width": 50,
  698. "height": 10,
  699. "name": "lunny",
  700. },
  701. })
  702. assert.NoError(t, err)
  703. assert.EqualValues(t, 2, cnt)
  704. ims = make([]InsertMap, 0, 4)
  705. err = testEngine.Find(&ims)
  706. assert.NoError(t, err)
  707. assert.EqualValues(t, 4, len(ims))
  708. assert.EqualValues(t, 20, ims[0].Width)
  709. assert.EqualValues(t, 10, ims[0].Height)
  710. assert.EqualValues(t, "lunny", ims[1].Name)
  711. assert.EqualValues(t, 30, ims[1].Width)
  712. assert.EqualValues(t, 10, ims[1].Height)
  713. assert.EqualValues(t, "lunny", ims[1].Name)
  714. assert.EqualValues(t, 40, ims[2].Width)
  715. assert.EqualValues(t, 10, ims[2].Height)
  716. assert.EqualValues(t, "lunny", ims[2].Name)
  717. assert.EqualValues(t, 50, ims[3].Width)
  718. assert.EqualValues(t, 10, ims[3].Height)
  719. assert.EqualValues(t, "lunny", ims[3].Name)
  720. }
  721. /*INSERT INTO `issue` (`repo_id`, `poster_id`, ... ,`name`, `content`, ... ,`index`)
  722. SELECT $1, $2, ..., $14, $15, ..., MAX(`index`) + 1 FROM `issue` WHERE `repo_id` = $1;
  723. */
  724. func TestInsertWhere(t *testing.T) {
  725. type InsertWhere struct {
  726. Id int64
  727. Index int `xorm:"unique(s) notnull"`
  728. RepoId int64 `xorm:"unique(s)"`
  729. Width uint32
  730. Height uint32
  731. Name string
  732. IsTrue bool
  733. }
  734. assert.NoError(t, prepareEngine())
  735. assertSync(t, new(InsertWhere))
  736. var i = InsertWhere{
  737. RepoId: 1,
  738. Width: 10,
  739. Height: 20,
  740. Name: "trest",
  741. }
  742. inserted, err := testEngine.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  743. Where("repo_id=?", 1).
  744. Insert(&i)
  745. assert.NoError(t, err)
  746. assert.EqualValues(t, 1, inserted)
  747. assert.EqualValues(t, 1, i.Id)
  748. var j InsertWhere
  749. has, err := testEngine.ID(i.Id).Get(&j)
  750. assert.NoError(t, err)
  751. assert.True(t, has)
  752. i.Index = 1
  753. assert.EqualValues(t, i, j)
  754. inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1).
  755. SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  756. Insert(map[string]interface{}{
  757. "repo_id": 1,
  758. "width": 20,
  759. "height": 40,
  760. "name": "trest2",
  761. })
  762. assert.NoError(t, err)
  763. assert.EqualValues(t, 1, inserted)
  764. var j2 InsertWhere
  765. has, err = testEngine.ID(2).Get(&j2)
  766. assert.NoError(t, err)
  767. assert.True(t, has)
  768. assert.EqualValues(t, 1, j2.RepoId)
  769. assert.EqualValues(t, 20, j2.Width)
  770. assert.EqualValues(t, 40, j2.Height)
  771. assert.EqualValues(t, "trest2", j2.Name)
  772. assert.EqualValues(t, 2, j2.Index)
  773. inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1).
  774. SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  775. SetExpr("repo_id", "1").
  776. Insert(map[string]string{
  777. "name": "trest3",
  778. })
  779. assert.NoError(t, err)
  780. assert.EqualValues(t, 1, inserted)
  781. var j3 InsertWhere
  782. has, err = testEngine.ID(3).Get(&j3)
  783. assert.NoError(t, err)
  784. assert.True(t, has)
  785. assert.EqualValues(t, "trest3", j3.Name)
  786. assert.EqualValues(t, 3, j3.Index)
  787. inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1).
  788. SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  789. Insert(map[string]interface{}{
  790. "repo_id": 1,
  791. "name": "10';delete * from insert_where; --",
  792. })
  793. assert.NoError(t, err)
  794. assert.EqualValues(t, 1, inserted)
  795. var j4 InsertWhere
  796. has, err = testEngine.ID(4).Get(&j4)
  797. assert.NoError(t, err)
  798. assert.True(t, has)
  799. assert.EqualValues(t, "10';delete * from insert_where; --", j4.Name)
  800. assert.EqualValues(t, 4, j4.Index)
  801. inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1).
  802. SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  803. Insert(map[string]interface{}{
  804. "repo_id": 1,
  805. "name": "10\\';delete * from insert_where; --",
  806. })
  807. assert.NoError(t, err)
  808. assert.EqualValues(t, 1, inserted)
  809. var j5 InsertWhere
  810. has, err = testEngine.ID(5).Get(&j5)
  811. assert.NoError(t, err)
  812. assert.True(t, has)
  813. assert.EqualValues(t, "10\\';delete * from insert_where; --", j5.Name)
  814. assert.EqualValues(t, 5, j5.Index)
  815. }
  816. type NightlyRate struct {
  817. ID int64 `xorm:"'id' not null pk BIGINT(20)" json:"id"`
  818. }
  819. func (NightlyRate) TableName() string {
  820. return "prd_nightly_rate"
  821. }
  822. func TestMultipleInsertTableName(t *testing.T) {
  823. assert.NoError(t, prepareEngine())
  824. tableName := `prd_nightly_rate_16`
  825. assert.NoError(t, testEngine.Table(tableName).Sync2(new(NightlyRate)))
  826. trans := testEngine.NewSession()
  827. defer trans.Close()
  828. err := trans.Begin()
  829. assert.NoError(t, err)
  830. rtArr := []interface{}{
  831. []*NightlyRate{
  832. {ID: 1},
  833. {ID: 2},
  834. },
  835. []*NightlyRate{
  836. {ID: 3},
  837. {ID: 4},
  838. },
  839. []*NightlyRate{
  840. {ID: 5},
  841. },
  842. }
  843. _, err = trans.Table(tableName).Insert(rtArr...)
  844. assert.NoError(t, err)
  845. assert.NoError(t, trans.Commit())
  846. }
  847. func TestInsertMultiWithOmit(t *testing.T) {
  848. assert.NoError(t, prepareEngine())
  849. type TestMultiOmit struct {
  850. Id int64 `xorm:"int(11) pk"`
  851. Name string `xorm:"varchar(255)"`
  852. Omitted string `xorm:"varchar(255) 'omitted'"`
  853. }
  854. assert.NoError(t, testEngine.Sync2(new(TestMultiOmit)))
  855. l := []interface{}{
  856. TestMultiOmit{Id: 1, Name: "1", Omitted: "1"},
  857. TestMultiOmit{Id: 2, Name: "1", Omitted: "2"},
  858. TestMultiOmit{Id: 3, Name: "1", Omitted: "3"},
  859. }
  860. check := func() {
  861. var ls []TestMultiOmit
  862. err := testEngine.Find(&ls)
  863. assert.NoError(t, err)
  864. assert.EqualValues(t, 3, len(ls))
  865. for e := range ls {
  866. assert.EqualValues(t, "", ls[e].Omitted)
  867. }
  868. }
  869. num, err := testEngine.Omit("omitted").Insert(l...)
  870. assert.NoError(t, err)
  871. assert.EqualValues(t, 3, num)
  872. check()
  873. num, err = testEngine.Delete(TestMultiOmit{Name: "1"})
  874. assert.NoError(t, err)
  875. assert.EqualValues(t, 3, num)
  876. num, err = testEngine.Omit("omitted").Insert(l)
  877. assert.NoError(t, err)
  878. assert.EqualValues(t, 3, num)
  879. check()
  880. }