Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle https://xorm.io
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.

1012 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. assert.NoError(t, err)
  467. }
  468. func TestInsertMulti2(t *testing.T) {
  469. assert.NoError(t, prepareEngine())
  470. assertSync(t, new(Userinfo))
  471. users := []Userinfo{
  472. {Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  473. {Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  474. {Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  475. {Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  476. }
  477. cnt, err := testEngine.Insert(&users)
  478. if err != nil {
  479. t.Error(err)
  480. panic(err)
  481. }
  482. assert.EqualValues(t, len(users), cnt)
  483. users2 := []*Userinfo{
  484. &Userinfo{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  485. &Userinfo{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  486. &Userinfo{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  487. &Userinfo{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  488. }
  489. cnt, err = testEngine.Insert(&users2)
  490. assert.NoError(t, err)
  491. assert.EqualValues(t, len(users2), cnt)
  492. }
  493. func TestInsertTwoTable(t *testing.T) {
  494. assert.NoError(t, prepareEngine())
  495. assertSync(t, new(Userinfo), new(Userdetail))
  496. userdetail := Userdetail{ /*Id: 1, */ Intro: "I'm a very beautiful women.", Profile: "sfsaf"}
  497. userinfo := Userinfo{Username: "xlw3", Departname: "dev", Alias: "lunny4", Created: time.Now(), Detail: userdetail}
  498. cnt, err := testEngine.Insert(&userinfo, &userdetail)
  499. if err != nil {
  500. t.Error(err)
  501. panic(err)
  502. }
  503. if userinfo.Uid <= 0 {
  504. err = errors.New("not return id error")
  505. t.Error(err)
  506. panic(err)
  507. }
  508. if userdetail.Id <= 0 {
  509. err = errors.New("not return id error")
  510. t.Error(err)
  511. panic(err)
  512. }
  513. if cnt != 2 {
  514. err = errors.New("insert not returned 2")
  515. t.Error(err)
  516. panic(err)
  517. }
  518. }
  519. func TestInsertCreatedInt64(t *testing.T) {
  520. assert.NoError(t, prepareEngine())
  521. type TestCreatedInt64 struct {
  522. Id int64 `xorm:"autoincr pk"`
  523. Msg string `xorm:"varchar(255)"`
  524. Created int64 `xorm:"created"`
  525. }
  526. assert.NoError(t, testEngine.Sync2(new(TestCreatedInt64)))
  527. data := TestCreatedInt64{Msg: "hi"}
  528. now := time.Now()
  529. cnt, err := testEngine.Insert(&data)
  530. assert.NoError(t, err)
  531. assert.EqualValues(t, 1, cnt)
  532. assert.True(t, now.Unix() <= data.Created)
  533. var data2 TestCreatedInt64
  534. has, err := testEngine.Get(&data2)
  535. assert.NoError(t, err)
  536. assert.True(t, has)
  537. assert.EqualValues(t, data.Created, data2.Created)
  538. }
  539. type MyUserinfo Userinfo
  540. func (MyUserinfo) TableName() string {
  541. return "user_info"
  542. }
  543. func TestInsertMulti3(t *testing.T) {
  544. assert.NoError(t, prepareEngine())
  545. testEngine.ShowSQL(true)
  546. assertSync(t, new(MyUserinfo))
  547. users := []MyUserinfo{
  548. {Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  549. {Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  550. {Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  551. {Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  552. }
  553. cnt, err := testEngine.Insert(&users)
  554. assert.NoError(t, err)
  555. assert.EqualValues(t, len(users), cnt)
  556. users2 := []*MyUserinfo{
  557. &MyUserinfo{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  558. &MyUserinfo{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  559. &MyUserinfo{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  560. &MyUserinfo{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  561. }
  562. cnt, err = testEngine.Insert(&users2)
  563. assert.NoError(t, err)
  564. assert.EqualValues(t, len(users), cnt)
  565. }
  566. type MyUserinfo2 struct {
  567. Uid int64 `xorm:"id pk not null autoincr"`
  568. Username string `xorm:"unique"`
  569. Departname string
  570. Alias string `xorm:"-"`
  571. Created time.Time
  572. Detail Userdetail `xorm:"detail_id int(11)"`
  573. Height float64
  574. Avatar []byte
  575. IsMan bool
  576. }
  577. func (MyUserinfo2) TableName() string {
  578. return "user_info"
  579. }
  580. func TestInsertMulti4(t *testing.T) {
  581. assert.NoError(t, prepareEngine())
  582. testEngine.ShowSQL(false)
  583. assertSync(t, new(MyUserinfo2))
  584. testEngine.ShowSQL(true)
  585. users := []MyUserinfo2{
  586. {Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  587. {Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  588. {Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  589. {Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  590. }
  591. cnt, err := testEngine.Insert(&users)
  592. assert.NoError(t, err)
  593. assert.EqualValues(t, len(users), cnt)
  594. users2 := []*MyUserinfo2{
  595. &MyUserinfo2{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  596. &MyUserinfo2{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  597. &MyUserinfo2{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
  598. &MyUserinfo2{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
  599. }
  600. cnt, err = testEngine.Insert(&users2)
  601. assert.NoError(t, err)
  602. assert.EqualValues(t, len(users), cnt)
  603. }
  604. func TestAnonymousStruct(t *testing.T) {
  605. type PlainObject struct {
  606. ID uint64 `json:"id,string" xorm:"'ID' pk autoincr"`
  607. Desc string `json:"desc" xorm:"'DESC' notnull"`
  608. }
  609. type PlainFoo struct {
  610. PlainObject `xorm:"extends"` // primary key defined in extends struct
  611. Width uint32 `json:"width" xorm:"'WIDTH' notnull"`
  612. Height uint32 `json:"height" xorm:"'HEIGHT' notnull"`
  613. Ext struct {
  614. F1 uint32 `json:"f1,omitempty"`
  615. F2 uint32 `json:"f2,omitempty"`
  616. } `json:"ext" xorm:"'EXT' json notnull"`
  617. }
  618. assert.NoError(t, prepareEngine())
  619. assertSync(t, new(PlainFoo))
  620. _, err := testEngine.Insert(&PlainFoo{
  621. PlainObject: PlainObject{
  622. Desc: "test",
  623. },
  624. Width: 10,
  625. Height: 20,
  626. Ext: struct {
  627. F1 uint32 `json:"f1,omitempty"`
  628. F2 uint32 `json:"f2,omitempty"`
  629. }{
  630. F1: 11,
  631. F2: 12,
  632. },
  633. })
  634. assert.NoError(t, err)
  635. }
  636. func TestInsertMap(t *testing.T) {
  637. type InsertMap struct {
  638. Id int64
  639. Width uint32
  640. Height uint32
  641. Name string
  642. }
  643. assert.NoError(t, prepareEngine())
  644. assertSync(t, new(InsertMap))
  645. cnt, err := testEngine.Table(new(InsertMap)).Insert(map[string]interface{}{
  646. "width": 20,
  647. "height": 10,
  648. "name": "lunny",
  649. })
  650. assert.NoError(t, err)
  651. assert.EqualValues(t, 1, cnt)
  652. var im InsertMap
  653. has, err := testEngine.Get(&im)
  654. assert.NoError(t, err)
  655. assert.True(t, has)
  656. assert.EqualValues(t, 20, im.Width)
  657. assert.EqualValues(t, 10, im.Height)
  658. assert.EqualValues(t, "lunny", im.Name)
  659. cnt, err = testEngine.Table("insert_map").Insert(map[string]interface{}{
  660. "width": 30,
  661. "height": 10,
  662. "name": "lunny",
  663. })
  664. assert.NoError(t, err)
  665. assert.EqualValues(t, 1, cnt)
  666. var ims []InsertMap
  667. err = testEngine.Find(&ims)
  668. assert.NoError(t, err)
  669. assert.EqualValues(t, 2, len(ims))
  670. assert.EqualValues(t, 20, ims[0].Width)
  671. assert.EqualValues(t, 10, ims[0].Height)
  672. assert.EqualValues(t, "lunny", ims[0].Name)
  673. assert.EqualValues(t, 30, ims[1].Width)
  674. assert.EqualValues(t, 10, ims[1].Height)
  675. assert.EqualValues(t, "lunny", ims[1].Name)
  676. cnt, err = testEngine.Table("insert_map").Insert([]map[string]interface{}{
  677. {
  678. "width": 40,
  679. "height": 10,
  680. "name": "lunny",
  681. },
  682. {
  683. "width": 50,
  684. "height": 10,
  685. "name": "lunny",
  686. },
  687. })
  688. assert.NoError(t, err)
  689. assert.EqualValues(t, 2, cnt)
  690. ims = make([]InsertMap, 0, 4)
  691. err = testEngine.Find(&ims)
  692. assert.NoError(t, err)
  693. assert.EqualValues(t, 4, len(ims))
  694. assert.EqualValues(t, 20, ims[0].Width)
  695. assert.EqualValues(t, 10, ims[0].Height)
  696. assert.EqualValues(t, "lunny", ims[1].Name)
  697. assert.EqualValues(t, 30, ims[1].Width)
  698. assert.EqualValues(t, 10, ims[1].Height)
  699. assert.EqualValues(t, "lunny", ims[1].Name)
  700. assert.EqualValues(t, 40, ims[2].Width)
  701. assert.EqualValues(t, 10, ims[2].Height)
  702. assert.EqualValues(t, "lunny", ims[2].Name)
  703. assert.EqualValues(t, 50, ims[3].Width)
  704. assert.EqualValues(t, 10, ims[3].Height)
  705. assert.EqualValues(t, "lunny", ims[3].Name)
  706. }
  707. /*INSERT INTO `issue` (`repo_id`, `poster_id`, ... ,`name`, `content`, ... ,`index`)
  708. SELECT $1, $2, ..., $14, $15, ..., MAX(`index`) + 1 FROM `issue` WHERE `repo_id` = $1;
  709. */
  710. func TestInsertWhere(t *testing.T) {
  711. type InsertWhere struct {
  712. Id int64
  713. Index int `xorm:"unique(s) notnull"`
  714. RepoId int64 `xorm:"unique(s)"`
  715. Width uint32
  716. Height uint32
  717. Name string
  718. IsTrue bool
  719. }
  720. assert.NoError(t, prepareEngine())
  721. assertSync(t, new(InsertWhere))
  722. var i = InsertWhere{
  723. RepoId: 1,
  724. Width: 10,
  725. Height: 20,
  726. Name: "trest",
  727. }
  728. inserted, err := testEngine.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  729. Where("repo_id=?", 1).
  730. Insert(&i)
  731. assert.NoError(t, err)
  732. assert.EqualValues(t, 1, inserted)
  733. assert.EqualValues(t, 1, i.Id)
  734. var j InsertWhere
  735. has, err := testEngine.ID(i.Id).Get(&j)
  736. assert.NoError(t, err)
  737. assert.True(t, has)
  738. i.Index = 1
  739. assert.EqualValues(t, i, j)
  740. inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1).
  741. SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  742. Insert(map[string]interface{}{
  743. "repo_id": 1,
  744. "width": 20,
  745. "height": 40,
  746. "name": "trest2",
  747. })
  748. assert.NoError(t, err)
  749. assert.EqualValues(t, 1, inserted)
  750. var j2 InsertWhere
  751. has, err = testEngine.ID(2).Get(&j2)
  752. assert.NoError(t, err)
  753. assert.True(t, has)
  754. assert.EqualValues(t, 1, j2.RepoId)
  755. assert.EqualValues(t, 20, j2.Width)
  756. assert.EqualValues(t, 40, j2.Height)
  757. assert.EqualValues(t, "trest2", j2.Name)
  758. assert.EqualValues(t, 2, j2.Index)
  759. inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1).
  760. SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  761. SetExpr("repo_id", "1").
  762. Insert(map[string]string{
  763. "name": "trest3",
  764. })
  765. assert.NoError(t, err)
  766. assert.EqualValues(t, 1, inserted)
  767. var j3 InsertWhere
  768. has, err = testEngine.ID(3).Get(&j3)
  769. assert.NoError(t, err)
  770. assert.True(t, has)
  771. assert.EqualValues(t, "trest3", j3.Name)
  772. assert.EqualValues(t, 3, j3.Index)
  773. inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1).
  774. SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
  775. Insert(map[string]interface{}{
  776. "repo_id": 1,
  777. "name": "10';delete * from insert_where; --",
  778. })
  779. assert.NoError(t, err)
  780. assert.EqualValues(t, 1, inserted)
  781. var j4 InsertWhere
  782. has, err = testEngine.ID(4).Get(&j4)
  783. assert.NoError(t, err)
  784. assert.True(t, has)
  785. assert.EqualValues(t, "10';delete * from insert_where; --", j4.Name)
  786. assert.EqualValues(t, 4, j4.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 j5 InsertWhere
  796. has, err = testEngine.ID(5).Get(&j5)
  797. assert.NoError(t, err)
  798. assert.True(t, has)
  799. assert.EqualValues(t, "10\\';delete * from insert_where; --", j5.Name)
  800. assert.EqualValues(t, 5, j5.Index)
  801. }
  802. type NightlyRate struct {
  803. ID int64 `xorm:"'id' not null pk BIGINT(20)" json:"id"`
  804. }
  805. func (NightlyRate) TableName() string {
  806. return "prd_nightly_rate"
  807. }
  808. func TestMultipleInsertTableName(t *testing.T) {
  809. assert.NoError(t, prepareEngine())
  810. tableName := `prd_nightly_rate_16`
  811. assert.NoError(t, testEngine.Table(tableName).Sync2(new(NightlyRate)))
  812. trans := testEngine.NewSession()
  813. defer trans.Close()
  814. err := trans.Begin()
  815. assert.NoError(t, err)
  816. rtArr := []interface{}{
  817. []*NightlyRate{
  818. {ID: 1},
  819. {ID: 2},
  820. },
  821. []*NightlyRate{
  822. {ID: 3},
  823. {ID: 4},
  824. },
  825. []*NightlyRate{
  826. {ID: 5},
  827. },
  828. }
  829. _, err = trans.Table(tableName).Insert(rtArr...)
  830. assert.NoError(t, err)
  831. assert.NoError(t, trans.Commit())
  832. }
  833. func TestInsertMultiWithOmit(t *testing.T) {
  834. assert.NoError(t, prepareEngine())
  835. type TestMultiOmit struct {
  836. Id int64 `xorm:"int(11) pk"`
  837. Name string `xorm:"varchar(255)"`
  838. Omitted string `xorm:"varchar(255) 'omitted'"`
  839. }
  840. assert.NoError(t, testEngine.Sync2(new(TestMultiOmit)))
  841. l := []interface{}{
  842. TestMultiOmit{Id: 1, Name: "1", Omitted: "1"},
  843. TestMultiOmit{Id: 2, Name: "1", Omitted: "2"},
  844. TestMultiOmit{Id: 3, Name: "1", Omitted: "3"},
  845. }
  846. check := func() {
  847. var ls []TestMultiOmit
  848. err := testEngine.Find(&ls)
  849. assert.NoError(t, err)
  850. assert.EqualValues(t, 3, len(ls))
  851. for e := range ls {
  852. assert.EqualValues(t, "", ls[e].Omitted)
  853. }
  854. }
  855. num, err := testEngine.Omit("omitted").Insert(l...)
  856. assert.NoError(t, err)
  857. assert.EqualValues(t, 3, num)
  858. check()
  859. num, err = testEngine.Delete(TestMultiOmit{Name: "1"})
  860. assert.NoError(t, err)
  861. assert.EqualValues(t, 3, num)
  862. num, err = testEngine.Omit("omitted").Insert(l)
  863. assert.NoError(t, err)
  864. assert.EqualValues(t, 3, num)
  865. check()
  866. }