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.

601 lines
14KB

  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. "fmt"
  7. "strings"
  8. "testing"
  9. "time"
  10. "github.com/stretchr/testify/assert"
  11. "xorm.io/core"
  12. )
  13. type UserCU struct {
  14. Id int64
  15. Name string
  16. Created time.Time `xorm:"created"`
  17. Updated time.Time `xorm:"updated"`
  18. }
  19. func TestCreatedAndUpdated(t *testing.T) {
  20. assert.NoError(t, prepareEngine())
  21. u := new(UserCU)
  22. err := testEngine.DropTables(u)
  23. assert.NoError(t, err)
  24. err = testEngine.CreateTables(u)
  25. assert.NoError(t, err)
  26. u.Name = "sss"
  27. cnt, err := testEngine.Insert(u)
  28. assert.NoError(t, err)
  29. assert.EqualValues(t, 1, cnt)
  30. u.Name = "xxx"
  31. cnt, err = testEngine.ID(u.Id).Update(u)
  32. assert.NoError(t, err)
  33. assert.EqualValues(t, 1, cnt)
  34. u.Id = 0
  35. u.Created = time.Now().Add(-time.Hour * 24 * 365)
  36. u.Updated = u.Created
  37. cnt, err = testEngine.NoAutoTime().Insert(u)
  38. assert.NoError(t, err)
  39. assert.EqualValues(t, 1, cnt)
  40. }
  41. type StrangeName struct {
  42. Id_t int64 `xorm:"pk autoincr"`
  43. Name string
  44. }
  45. func TestStrangeName(t *testing.T) {
  46. assert.NoError(t, prepareEngine())
  47. err := testEngine.DropTables(new(StrangeName))
  48. assert.NoError(t, err)
  49. err = testEngine.CreateTables(new(StrangeName))
  50. assert.NoError(t, err)
  51. _, err = testEngine.Insert(&StrangeName{Name: "sfsfdsfds"})
  52. assert.NoError(t, err)
  53. beans := make([]StrangeName, 0)
  54. err = testEngine.Find(&beans)
  55. assert.NoError(t, err)
  56. }
  57. func TestCreatedUpdated(t *testing.T) {
  58. assert.NoError(t, prepareEngine())
  59. type CreatedUpdated struct {
  60. Id int64
  61. Name string
  62. Value float64 `xorm:"numeric"`
  63. Created time.Time `xorm:"created"`
  64. Created2 time.Time `xorm:"created"`
  65. Updated time.Time `xorm:"updated"`
  66. }
  67. err := testEngine.Sync2(&CreatedUpdated{})
  68. assert.NoError(t, err)
  69. c := &CreatedUpdated{Name: "test"}
  70. _, err = testEngine.Insert(c)
  71. assert.NoError(t, err)
  72. c2 := new(CreatedUpdated)
  73. has, err := testEngine.ID(c.Id).Get(c2)
  74. assert.NoError(t, err)
  75. assert.True(t, has)
  76. c2.Value -= 1
  77. _, err = testEngine.ID(c2.Id).Update(c2)
  78. assert.NoError(t, err)
  79. }
  80. func TestCreatedUpdatedInt64(t *testing.T) {
  81. assert.NoError(t, prepareEngine())
  82. type CreatedUpdatedInt64 struct {
  83. Id int64
  84. Name string
  85. Value float64 `xorm:"numeric"`
  86. Created int64 `xorm:"created"`
  87. Created2 int64 `xorm:"created"`
  88. Updated int64 `xorm:"updated"`
  89. }
  90. assertSync(t, &CreatedUpdatedInt64{})
  91. c := &CreatedUpdatedInt64{Name: "test"}
  92. _, err := testEngine.Insert(c)
  93. assert.NoError(t, err)
  94. c2 := new(CreatedUpdatedInt64)
  95. has, err := testEngine.ID(c.Id).Get(c2)
  96. assert.NoError(t, err)
  97. assert.True(t, has)
  98. c2.Value -= 1
  99. _, err = testEngine.ID(c2.Id).Update(c2)
  100. assert.NoError(t, err)
  101. }
  102. type Lowercase struct {
  103. Id int64
  104. Name string
  105. ended int64 `xorm:"-"`
  106. }
  107. func TestLowerCase(t *testing.T) {
  108. assert.NoError(t, prepareEngine())
  109. err := testEngine.Sync2(&Lowercase{})
  110. assert.NoError(t, err)
  111. _, err = testEngine.Where("id > 0").Delete(&Lowercase{})
  112. assert.NoError(t, err)
  113. _, err = testEngine.Insert(&Lowercase{ended: 1})
  114. assert.NoError(t, err)
  115. ls := make([]Lowercase, 0)
  116. err = testEngine.Find(&ls)
  117. assert.NoError(t, err)
  118. assert.EqualValues(t, 1, len(ls))
  119. }
  120. func TestAutoIncrTag(t *testing.T) {
  121. assert.NoError(t, prepareEngine())
  122. type TestAutoIncr1 struct {
  123. Id int64
  124. }
  125. tb := testEngine.TableInfo(new(TestAutoIncr1))
  126. cols := tb.Columns()
  127. assert.EqualValues(t, 1, len(cols))
  128. assert.True(t, cols[0].IsAutoIncrement)
  129. assert.True(t, cols[0].IsPrimaryKey)
  130. assert.Equal(t, "id", cols[0].Name)
  131. type TestAutoIncr2 struct {
  132. Id int64 `xorm:"id"`
  133. }
  134. tb = testEngine.TableInfo(new(TestAutoIncr2))
  135. cols = tb.Columns()
  136. assert.EqualValues(t, 1, len(cols))
  137. assert.False(t, cols[0].IsAutoIncrement)
  138. assert.False(t, cols[0].IsPrimaryKey)
  139. assert.Equal(t, "id", cols[0].Name)
  140. type TestAutoIncr3 struct {
  141. Id int64 `xorm:"'ID'"`
  142. }
  143. tb = testEngine.TableInfo(new(TestAutoIncr3))
  144. cols = tb.Columns()
  145. assert.EqualValues(t, 1, len(cols))
  146. assert.False(t, cols[0].IsAutoIncrement)
  147. assert.False(t, cols[0].IsPrimaryKey)
  148. assert.Equal(t, "ID", cols[0].Name)
  149. type TestAutoIncr4 struct {
  150. Id int64 `xorm:"pk"`
  151. }
  152. tb = testEngine.TableInfo(new(TestAutoIncr4))
  153. cols = tb.Columns()
  154. assert.EqualValues(t, 1, len(cols))
  155. assert.False(t, cols[0].IsAutoIncrement)
  156. assert.True(t, cols[0].IsPrimaryKey)
  157. assert.Equal(t, "id", cols[0].Name)
  158. }
  159. func TestTagComment(t *testing.T) {
  160. assert.NoError(t, prepareEngine())
  161. // FIXME: only support mysql
  162. if testEngine.Dialect().DriverName() != core.MYSQL {
  163. return
  164. }
  165. type TestComment1 struct {
  166. Id int64 `xorm:"comment(主键)"`
  167. }
  168. assert.NoError(t, testEngine.Sync2(new(TestComment1)))
  169. tables, err := testEngine.DBMetas()
  170. assert.NoError(t, err)
  171. assert.EqualValues(t, 1, len(tables))
  172. assert.EqualValues(t, 1, len(tables[0].Columns()))
  173. assert.EqualValues(t, "主键", tables[0].Columns()[0].Comment)
  174. assert.NoError(t, testEngine.DropTables(new(TestComment1)))
  175. type TestComment2 struct {
  176. Id int64 `xorm:"comment('主键')"`
  177. }
  178. assert.NoError(t, testEngine.Sync2(new(TestComment2)))
  179. tables, err = testEngine.DBMetas()
  180. assert.NoError(t, err)
  181. assert.EqualValues(t, 1, len(tables))
  182. assert.EqualValues(t, 1, len(tables[0].Columns()))
  183. assert.EqualValues(t, "主键", tables[0].Columns()[0].Comment)
  184. }
  185. func TestTagDefault(t *testing.T) {
  186. assert.NoError(t, prepareEngine())
  187. type DefaultStruct struct {
  188. Id int64
  189. Name string
  190. Age int `xorm:"default(10)"`
  191. }
  192. assertSync(t, new(DefaultStruct))
  193. tables, err := testEngine.DBMetas()
  194. assert.NoError(t, err)
  195. var defaultVal string
  196. var isDefaultExist bool
  197. tableName := testEngine.GetColumnMapper().Obj2Table("DefaultStruct")
  198. for _, table := range tables {
  199. if table.Name == tableName {
  200. col := table.GetColumn("age")
  201. assert.NotNil(t, col)
  202. defaultVal = col.Default
  203. isDefaultExist = !col.DefaultIsEmpty
  204. break
  205. }
  206. }
  207. assert.True(t, isDefaultExist)
  208. assert.EqualValues(t, "10", defaultVal)
  209. cnt, err := testEngine.Omit("age").Insert(&DefaultStruct{
  210. Name: "test",
  211. Age: 20,
  212. })
  213. assert.NoError(t, err)
  214. assert.EqualValues(t, 1, cnt)
  215. var s DefaultStruct
  216. has, err := testEngine.ID(1).Get(&s)
  217. assert.NoError(t, err)
  218. assert.True(t, has)
  219. assert.EqualValues(t, 10, s.Age)
  220. assert.EqualValues(t, "test", s.Name)
  221. }
  222. func TestTagDefault2(t *testing.T) {
  223. assert.NoError(t, prepareEngine())
  224. type DefaultStruct2 struct {
  225. Id int64
  226. Name string
  227. }
  228. assertSync(t, new(DefaultStruct2))
  229. tables, err := testEngine.DBMetas()
  230. assert.NoError(t, err)
  231. var defaultVal string
  232. var isDefaultExist bool
  233. tableName := testEngine.GetColumnMapper().Obj2Table("DefaultStruct2")
  234. for _, table := range tables {
  235. if table.Name == tableName {
  236. col := table.GetColumn("name")
  237. assert.NotNil(t, col)
  238. defaultVal = col.Default
  239. isDefaultExist = !col.DefaultIsEmpty
  240. break
  241. }
  242. }
  243. assert.False(t, isDefaultExist, fmt.Sprintf("default value is --%v--", defaultVal))
  244. assert.EqualValues(t, "", defaultVal)
  245. }
  246. func TestTagDefault3(t *testing.T) {
  247. assert.NoError(t, prepareEngine())
  248. type DefaultStruct3 struct {
  249. Id int64
  250. Name string `xorm:"default('myname')"`
  251. }
  252. assertSync(t, new(DefaultStruct3))
  253. tables, err := testEngine.DBMetas()
  254. assert.NoError(t, err)
  255. var defaultVal string
  256. var isDefaultExist bool
  257. tableName := testEngine.GetColumnMapper().Obj2Table("DefaultStruct3")
  258. for _, table := range tables {
  259. if table.Name == tableName {
  260. col := table.GetColumn("name")
  261. assert.NotNil(t, col)
  262. defaultVal = col.Default
  263. isDefaultExist = !col.DefaultIsEmpty
  264. break
  265. }
  266. }
  267. assert.True(t, isDefaultExist)
  268. assert.EqualValues(t, "'myname'", defaultVal)
  269. }
  270. func TestTagDefault4(t *testing.T) {
  271. assert.NoError(t, prepareEngine())
  272. type DefaultStruct4 struct {
  273. Id int64
  274. Created time.Time `xorm:"default(CURRENT_TIMESTAMP)"`
  275. }
  276. assertSync(t, new(DefaultStruct4))
  277. tables, err := testEngine.DBMetas()
  278. assert.NoError(t, err)
  279. var defaultVal string
  280. var isDefaultExist bool
  281. tableName := testEngine.GetColumnMapper().Obj2Table("DefaultStruct4")
  282. for _, table := range tables {
  283. if table.Name == tableName {
  284. col := table.GetColumn("created")
  285. assert.NotNil(t, col)
  286. defaultVal = col.Default
  287. isDefaultExist = !col.DefaultIsEmpty
  288. break
  289. }
  290. }
  291. assert.True(t, isDefaultExist)
  292. assert.True(t, "CURRENT_TIMESTAMP" == defaultVal ||
  293. "now()" == defaultVal ||
  294. "getdate" == defaultVal, defaultVal)
  295. }
  296. func TestTagDefault5(t *testing.T) {
  297. assert.NoError(t, prepareEngine())
  298. type DefaultStruct5 struct {
  299. Id int64
  300. Created time.Time `xorm:"default('2006-01-02 15:04:05')"`
  301. }
  302. assertSync(t, new(DefaultStruct5))
  303. table := testEngine.TableInfo(new(DefaultStruct5))
  304. createdCol := table.GetColumn("created")
  305. assert.NotNil(t, createdCol)
  306. assert.EqualValues(t, "'2006-01-02 15:04:05'", createdCol.Default)
  307. assert.False(t, createdCol.DefaultIsEmpty)
  308. tables, err := testEngine.DBMetas()
  309. assert.NoError(t, err)
  310. var defaultVal string
  311. var isDefaultExist bool
  312. tableName := testEngine.GetColumnMapper().Obj2Table("DefaultStruct5")
  313. for _, table := range tables {
  314. if table.Name == tableName {
  315. col := table.GetColumn("created")
  316. assert.NotNil(t, col)
  317. defaultVal = col.Default
  318. isDefaultExist = !col.DefaultIsEmpty
  319. break
  320. }
  321. }
  322. assert.True(t, isDefaultExist)
  323. assert.EqualValues(t, "'2006-01-02 15:04:05'", defaultVal)
  324. }
  325. func TestTagDefault6(t *testing.T) {
  326. assert.NoError(t, prepareEngine())
  327. type DefaultStruct6 struct {
  328. Id int64
  329. IsMan bool `xorm:"default(true)"`
  330. }
  331. assertSync(t, new(DefaultStruct6))
  332. tables, err := testEngine.DBMetas()
  333. assert.NoError(t, err)
  334. var defaultVal string
  335. var isDefaultExist bool
  336. tableName := testEngine.GetColumnMapper().Obj2Table("DefaultStruct6")
  337. for _, table := range tables {
  338. if table.Name == tableName {
  339. col := table.GetColumn("is_man")
  340. assert.NotNil(t, col)
  341. defaultVal = col.Default
  342. isDefaultExist = !col.DefaultIsEmpty
  343. break
  344. }
  345. }
  346. assert.True(t, isDefaultExist)
  347. if defaultVal == "1" {
  348. defaultVal = "true"
  349. } else if defaultVal == "0" {
  350. defaultVal = "false"
  351. }
  352. assert.EqualValues(t, "true", defaultVal)
  353. }
  354. func TestTagsDirection(t *testing.T) {
  355. assert.NoError(t, prepareEngine())
  356. type OnlyFromDBStruct struct {
  357. Id int64
  358. Name string
  359. Uuid string `xorm:"<- default '1'"`
  360. }
  361. assertSync(t, new(OnlyFromDBStruct))
  362. cnt, err := testEngine.Insert(&OnlyFromDBStruct{
  363. Name: "test",
  364. Uuid: "2",
  365. })
  366. assert.NoError(t, err)
  367. assert.EqualValues(t, 1, cnt)
  368. var s OnlyFromDBStruct
  369. has, err := testEngine.ID(1).Get(&s)
  370. assert.NoError(t, err)
  371. assert.True(t, has)
  372. assert.EqualValues(t, "1", s.Uuid)
  373. assert.EqualValues(t, "test", s.Name)
  374. cnt, err = testEngine.ID(1).Update(&OnlyFromDBStruct{
  375. Uuid: "3",
  376. Name: "test1",
  377. })
  378. assert.NoError(t, err)
  379. assert.EqualValues(t, 1, cnt)
  380. var s3 OnlyFromDBStruct
  381. has, err = testEngine.ID(1).Get(&s3)
  382. assert.NoError(t, err)
  383. assert.True(t, has)
  384. assert.EqualValues(t, "1", s3.Uuid)
  385. assert.EqualValues(t, "test1", s3.Name)
  386. type OnlyToDBStruct struct {
  387. Id int64
  388. Name string
  389. Uuid string `xorm:"->"`
  390. }
  391. assertSync(t, new(OnlyToDBStruct))
  392. cnt, err = testEngine.Insert(&OnlyToDBStruct{
  393. Name: "test",
  394. Uuid: "2",
  395. })
  396. assert.NoError(t, err)
  397. assert.EqualValues(t, 1, cnt)
  398. var s2 OnlyToDBStruct
  399. has, err = testEngine.ID(1).Get(&s2)
  400. assert.NoError(t, err)
  401. assert.True(t, has)
  402. assert.EqualValues(t, "", s2.Uuid)
  403. assert.EqualValues(t, "test", s2.Name)
  404. }
  405. func TestTagTime(t *testing.T) {
  406. assert.NoError(t, prepareEngine())
  407. type TagUTCStruct struct {
  408. Id int64
  409. Name string
  410. Created time.Time `xorm:"created utc"`
  411. }
  412. assertSync(t, new(TagUTCStruct))
  413. assert.EqualValues(t, time.Local.String(), testEngine.GetTZLocation().String())
  414. s := TagUTCStruct{
  415. Name: "utc",
  416. }
  417. cnt, err := testEngine.Insert(&s)
  418. assert.NoError(t, err)
  419. assert.EqualValues(t, 1, cnt)
  420. var u TagUTCStruct
  421. has, err := testEngine.ID(1).Get(&u)
  422. assert.NoError(t, err)
  423. assert.True(t, has)
  424. assert.EqualValues(t, s.Created.Format("2006-01-02 15:04:05"), u.Created.Format("2006-01-02 15:04:05"))
  425. var tm string
  426. has, err = testEngine.Table("tag_u_t_c_struct").Cols("created").Get(&tm)
  427. assert.NoError(t, err)
  428. assert.True(t, has)
  429. assert.EqualValues(t, s.Created.UTC().Format("2006-01-02 15:04:05"),
  430. strings.Replace(strings.Replace(tm, "T", " ", -1), "Z", "", -1))
  431. }
  432. func TestSplitTag(t *testing.T) {
  433. var cases = []struct {
  434. tag string
  435. tags []string
  436. }{
  437. {"not null default '2000-01-01 00:00:00' TIMESTAMP", []string{"not", "null", "default", "'2000-01-01 00:00:00'", "TIMESTAMP"}},
  438. {"TEXT", []string{"TEXT"}},
  439. {"default('2000-01-01 00:00:00')", []string{"default('2000-01-01 00:00:00')"}},
  440. {"json binary", []string{"json", "binary"}},
  441. }
  442. for _, kase := range cases {
  443. tags := splitTag(kase.tag)
  444. if !sliceEq(tags, kase.tags) {
  445. t.Fatalf("[%d]%v is not equal [%d]%v", len(tags), tags, len(kase.tags), kase.tags)
  446. }
  447. }
  448. }
  449. func TestTagAutoIncr(t *testing.T) {
  450. assert.NoError(t, prepareEngine())
  451. type TagAutoIncr struct {
  452. Id int64
  453. Name string
  454. }
  455. assertSync(t, new(TagAutoIncr))
  456. tables, err := testEngine.DBMetas()
  457. assert.NoError(t, err)
  458. assert.EqualValues(t, 1, len(tables))
  459. assert.EqualValues(t, tableMapper.Obj2Table("TagAutoIncr"), tables[0].Name)
  460. col := tables[0].GetColumn(colMapper.Obj2Table("Id"))
  461. assert.NotNil(t, col)
  462. assert.True(t, col.IsPrimaryKey)
  463. assert.True(t, col.IsAutoIncrement)
  464. col2 := tables[0].GetColumn(colMapper.Obj2Table("Name"))
  465. assert.NotNil(t, col2)
  466. assert.False(t, col2.IsPrimaryKey)
  467. assert.False(t, col2.IsAutoIncrement)
  468. }
  469. func TestTagPrimarykey(t *testing.T) {
  470. assert.NoError(t, prepareEngine())
  471. type TagPrimaryKey struct {
  472. Id int64 `xorm:"pk"`
  473. Name string `xorm:"VARCHAR(20) pk"`
  474. }
  475. assertSync(t, new(TagPrimaryKey))
  476. tables, err := testEngine.DBMetas()
  477. assert.NoError(t, err)
  478. assert.EqualValues(t, 1, len(tables))
  479. assert.EqualValues(t, tableMapper.Obj2Table("TagPrimaryKey"), tables[0].Name)
  480. col := tables[0].GetColumn(colMapper.Obj2Table("Id"))
  481. assert.NotNil(t, col)
  482. assert.True(t, col.IsPrimaryKey)
  483. assert.False(t, col.IsAutoIncrement)
  484. col2 := tables[0].GetColumn(colMapper.Obj2Table("Name"))
  485. assert.NotNil(t, col2)
  486. assert.True(t, col2.IsPrimaryKey)
  487. assert.False(t, col2.IsAutoIncrement)
  488. }