db_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. // Copyright 2019 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 core
  5. import (
  6. "errors"
  7. "flag"
  8. "os"
  9. "testing"
  10. "time"
  11. _ "github.com/go-sql-driver/mysql"
  12. _ "github.com/mattn/go-sqlite3"
  13. )
  14. var (
  15. dbtype = flag.String("dbtype", "mysql", "database type")
  16. dbConn = flag.String("dbConn", "root:@/core_test?charset=utf8", "database connect string")
  17. createTableSql string
  18. )
  19. type User struct {
  20. Id int64
  21. Name string
  22. Title string
  23. Age float32
  24. Alias string
  25. NickName string
  26. Created NullTime
  27. }
  28. func init() {
  29. flag.Parse()
  30. switch *dbtype {
  31. case "sqlite3":
  32. createTableSql = "CREATE TABLE IF NOT EXISTS `user` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NULL, " +
  33. "`title` TEXT NULL, `age` FLOAT NULL, `alias` TEXT NULL, `nick_name` TEXT NULL, `created` datetime);"
  34. case "mysql":
  35. createTableSql = "CREATE TABLE IF NOT EXISTS `user` (`id` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, `name` TEXT NULL, " +
  36. "`title` TEXT NULL, `age` FLOAT NULL, `alias` TEXT NULL, `nick_name` TEXT NULL, `created` datetime);"
  37. default:
  38. panic("no db type")
  39. }
  40. }
  41. func testOpen() (*DB, error) {
  42. switch *dbtype {
  43. case "sqlite3":
  44. os.Remove("./test.db")
  45. return Open("sqlite3", "./test.db")
  46. case "mysql":
  47. return Open("mysql", *dbConn)
  48. default:
  49. panic("no db type")
  50. }
  51. }
  52. func BenchmarkOriQuery(b *testing.B) {
  53. b.StopTimer()
  54. db, err := testOpen()
  55. if err != nil {
  56. b.Error(err)
  57. }
  58. defer db.Close()
  59. _, err = db.Exec(createTableSql)
  60. if err != nil {
  61. b.Error(err)
  62. }
  63. for i := 0; i < 50; i++ {
  64. _, err = db.Exec("insert into user (`name`, title, age, alias, nick_name, created) values (?,?,?,?,?, ?)",
  65. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  66. if err != nil {
  67. b.Error(err)
  68. }
  69. }
  70. b.StartTimer()
  71. for i := 0; i < b.N; i++ {
  72. rows, err := db.Query("select * from user")
  73. if err != nil {
  74. b.Error(err)
  75. }
  76. for rows.Next() {
  77. var Id int64
  78. var Name, Title, Alias, NickName string
  79. var Age float32
  80. var Created NullTime
  81. err = rows.Scan(&Id, &Name, &Title, &Age, &Alias, &NickName, &Created)
  82. if err != nil {
  83. b.Error(err)
  84. }
  85. //fmt.Println(Id, Name, Title, Age, Alias, NickName)
  86. }
  87. rows.Close()
  88. }
  89. }
  90. func BenchmarkStructQuery(b *testing.B) {
  91. b.StopTimer()
  92. db, err := testOpen()
  93. if err != nil {
  94. b.Error(err)
  95. }
  96. defer db.Close()
  97. _, err = db.Exec(createTableSql)
  98. if err != nil {
  99. b.Error(err)
  100. }
  101. for i := 0; i < 50; i++ {
  102. _, err = db.Exec("insert into user (`name`, title, age, alias, nick_name, created) values (?,?,?,?,?, ?)",
  103. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  104. if err != nil {
  105. b.Error(err)
  106. }
  107. }
  108. b.StartTimer()
  109. for i := 0; i < b.N; i++ {
  110. rows, err := db.Query("select * from user")
  111. if err != nil {
  112. b.Error(err)
  113. }
  114. for rows.Next() {
  115. var user User
  116. err = rows.ScanStructByIndex(&user)
  117. if err != nil {
  118. b.Error(err)
  119. }
  120. if user.Name != "xlw" {
  121. b.Log(user)
  122. b.Error(errors.New("name should be xlw"))
  123. }
  124. }
  125. rows.Close()
  126. }
  127. }
  128. func BenchmarkStruct2Query(b *testing.B) {
  129. b.StopTimer()
  130. db, err := testOpen()
  131. if err != nil {
  132. b.Error(err)
  133. }
  134. defer db.Close()
  135. _, err = db.Exec(createTableSql)
  136. if err != nil {
  137. b.Error(err)
  138. }
  139. for i := 0; i < 50; i++ {
  140. _, err = db.Exec("insert into user (`name`, title, age, alias, nick_name, created) values (?,?,?,?,?,?)",
  141. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  142. if err != nil {
  143. b.Error(err)
  144. }
  145. }
  146. db.Mapper = NewCacheMapper(&SnakeMapper{})
  147. b.StartTimer()
  148. for i := 0; i < b.N; i++ {
  149. rows, err := db.Query("select * from user")
  150. if err != nil {
  151. b.Error(err)
  152. }
  153. for rows.Next() {
  154. var user User
  155. err = rows.ScanStructByName(&user)
  156. if err != nil {
  157. b.Error(err)
  158. }
  159. if user.Name != "xlw" {
  160. b.Log(user)
  161. b.Error(errors.New("name should be xlw"))
  162. }
  163. }
  164. rows.Close()
  165. }
  166. }
  167. func BenchmarkSliceInterfaceQuery(b *testing.B) {
  168. b.StopTimer()
  169. db, err := testOpen()
  170. if err != nil {
  171. b.Error(err)
  172. }
  173. defer db.Close()
  174. _, err = db.Exec(createTableSql)
  175. if err != nil {
  176. b.Error(err)
  177. }
  178. for i := 0; i < 50; i++ {
  179. _, err = db.Exec("insert into user (`name`, title, age, alias, nick_name,created) values (?,?,?,?,?,?)",
  180. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  181. if err != nil {
  182. b.Error(err)
  183. }
  184. }
  185. b.StartTimer()
  186. for i := 0; i < b.N; i++ {
  187. rows, err := db.Query("select * from user")
  188. if err != nil {
  189. b.Error(err)
  190. }
  191. cols, err := rows.Columns()
  192. if err != nil {
  193. b.Error(err)
  194. }
  195. for rows.Next() {
  196. slice := make([]interface{}, len(cols))
  197. err = rows.ScanSlice(&slice)
  198. if err != nil {
  199. b.Error(err)
  200. }
  201. b.Log(slice)
  202. switch slice[1].(type) {
  203. case *string:
  204. if *slice[1].(*string) != "xlw" {
  205. b.Error(errors.New("name should be xlw"))
  206. }
  207. case []byte:
  208. if string(slice[1].([]byte)) != "xlw" {
  209. b.Error(errors.New("name should be xlw"))
  210. }
  211. }
  212. }
  213. rows.Close()
  214. }
  215. }
  216. /*func BenchmarkSliceBytesQuery(b *testing.B) {
  217. b.StopTimer()
  218. os.Remove("./test.db")
  219. db, err := Open("sqlite3", "./test.db")
  220. if err != nil {
  221. b.Error(err)
  222. }
  223. defer db.Close()
  224. _, err = db.Exec(createTableSql)
  225. if err != nil {
  226. b.Error(err)
  227. }
  228. for i := 0; i < 50; i++ {
  229. _, err = db.Exec("insert into user (name, title, age, alias, nick_name,created) values (?,?,?,?,?,?)",
  230. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  231. if err != nil {
  232. b.Error(err)
  233. }
  234. }
  235. b.StartTimer()
  236. for i := 0; i < b.N; i++ {
  237. rows, err := db.Query("select * from user")
  238. if err != nil {
  239. b.Error(err)
  240. }
  241. cols, err := rows.Columns()
  242. if err != nil {
  243. b.Error(err)
  244. }
  245. for rows.Next() {
  246. slice := make([][]byte, len(cols))
  247. err = rows.ScanSlice(&slice)
  248. if err != nil {
  249. b.Error(err)
  250. }
  251. if string(slice[1]) != "xlw" {
  252. fmt.Println(slice)
  253. b.Error(errors.New("name should be xlw"))
  254. }
  255. }
  256. rows.Close()
  257. }
  258. }
  259. */
  260. func BenchmarkSliceStringQuery(b *testing.B) {
  261. b.StopTimer()
  262. db, err := testOpen()
  263. if err != nil {
  264. b.Error(err)
  265. }
  266. defer db.Close()
  267. _, err = db.Exec(createTableSql)
  268. if err != nil {
  269. b.Error(err)
  270. }
  271. for i := 0; i < 50; i++ {
  272. _, err = db.Exec("insert into user (name, title, age, alias, nick_name, created) values (?,?,?,?,?,?)",
  273. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  274. if err != nil {
  275. b.Error(err)
  276. }
  277. }
  278. b.StartTimer()
  279. for i := 0; i < b.N; i++ {
  280. rows, err := db.Query("select * from user")
  281. if err != nil {
  282. b.Error(err)
  283. }
  284. cols, err := rows.Columns()
  285. if err != nil {
  286. b.Error(err)
  287. }
  288. for rows.Next() {
  289. slice := make([]*string, len(cols))
  290. err = rows.ScanSlice(&slice)
  291. if err != nil {
  292. b.Error(err)
  293. }
  294. if (*slice[1]) != "xlw" {
  295. b.Log(slice)
  296. b.Error(errors.New("name should be xlw"))
  297. }
  298. }
  299. rows.Close()
  300. }
  301. }
  302. func BenchmarkMapInterfaceQuery(b *testing.B) {
  303. b.StopTimer()
  304. db, err := testOpen()
  305. if err != nil {
  306. b.Error(err)
  307. }
  308. defer db.Close()
  309. _, err = db.Exec(createTableSql)
  310. if err != nil {
  311. b.Error(err)
  312. }
  313. for i := 0; i < 50; i++ {
  314. _, err = db.Exec("insert into user (name, title, age, alias, nick_name,created) values (?,?,?,?,?,?)",
  315. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  316. if err != nil {
  317. b.Error(err)
  318. }
  319. }
  320. b.StartTimer()
  321. for i := 0; i < b.N; i++ {
  322. rows, err := db.Query("select * from user")
  323. if err != nil {
  324. b.Error(err)
  325. }
  326. for rows.Next() {
  327. m := make(map[string]interface{})
  328. err = rows.ScanMap(&m)
  329. if err != nil {
  330. b.Error(err)
  331. }
  332. switch m["name"].(type) {
  333. case string:
  334. if m["name"].(string) != "xlw" {
  335. b.Log(m)
  336. b.Error(errors.New("name should be xlw"))
  337. }
  338. case []byte:
  339. if string(m["name"].([]byte)) != "xlw" {
  340. b.Log(m)
  341. b.Error(errors.New("name should be xlw"))
  342. }
  343. }
  344. }
  345. rows.Close()
  346. }
  347. }
  348. /*func BenchmarkMapBytesQuery(b *testing.B) {
  349. b.StopTimer()
  350. os.Remove("./test.db")
  351. db, err := Open("sqlite3", "./test.db")
  352. if err != nil {
  353. b.Error(err)
  354. }
  355. defer db.Close()
  356. _, err = db.Exec(createTableSql)
  357. if err != nil {
  358. b.Error(err)
  359. }
  360. for i := 0; i < 50; i++ {
  361. _, err = db.Exec("insert into user (name, title, age, alias, nick_name,created) values (?,?,?,?,?,?)",
  362. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  363. if err != nil {
  364. b.Error(err)
  365. }
  366. }
  367. b.StartTimer()
  368. for i := 0; i < b.N; i++ {
  369. rows, err := db.Query("select * from user")
  370. if err != nil {
  371. b.Error(err)
  372. }
  373. for rows.Next() {
  374. m := make(map[string][]byte)
  375. err = rows.ScanMap(&m)
  376. if err != nil {
  377. b.Error(err)
  378. }
  379. if string(m["name"]) != "xlw" {
  380. fmt.Println(m)
  381. b.Error(errors.New("name should be xlw"))
  382. }
  383. }
  384. rows.Close()
  385. }
  386. }
  387. */
  388. /*
  389. func BenchmarkMapStringQuery(b *testing.B) {
  390. b.StopTimer()
  391. os.Remove("./test.db")
  392. db, err := Open("sqlite3", "./test.db")
  393. if err != nil {
  394. b.Error(err)
  395. }
  396. defer db.Close()
  397. _, err = db.Exec(createTableSql)
  398. if err != nil {
  399. b.Error(err)
  400. }
  401. for i := 0; i < 50; i++ {
  402. _, err = db.Exec("insert into user (name, title, age, alias, nick_name,created) values (?,?,?,?,?,?)",
  403. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  404. if err != nil {
  405. b.Error(err)
  406. }
  407. }
  408. b.StartTimer()
  409. for i := 0; i < b.N; i++ {
  410. rows, err := db.Query("select * from user")
  411. if err != nil {
  412. b.Error(err)
  413. }
  414. for rows.Next() {
  415. m := make(map[string]string)
  416. err = rows.ScanMap(&m)
  417. if err != nil {
  418. b.Error(err)
  419. }
  420. if m["name"] != "xlw" {
  421. fmt.Println(m)
  422. b.Error(errors.New("name should be xlw"))
  423. }
  424. }
  425. rows.Close()
  426. }
  427. }*/
  428. func BenchmarkExec(b *testing.B) {
  429. b.StopTimer()
  430. db, err := testOpen()
  431. if err != nil {
  432. b.Error(err)
  433. }
  434. defer db.Close()
  435. _, err = db.Exec(createTableSql)
  436. if err != nil {
  437. b.Error(err)
  438. }
  439. b.StartTimer()
  440. for i := 0; i < b.N; i++ {
  441. _, err = db.Exec("insert into user (`name`, title, age, alias, nick_name,created) values (?,?,?,?,?,?)",
  442. "xlw", "tester", 1.2, "lunny", "lunny xiao", time.Now())
  443. if err != nil {
  444. b.Error(err)
  445. }
  446. }
  447. }
  448. func BenchmarkExecMap(b *testing.B) {
  449. b.StopTimer()
  450. db, err := testOpen()
  451. if err != nil {
  452. b.Error(err)
  453. }
  454. defer db.Close()
  455. _, err = db.Exec(createTableSql)
  456. if err != nil {
  457. b.Error(err)
  458. }
  459. b.StartTimer()
  460. mp := map[string]interface{}{
  461. "name": "xlw",
  462. "title": "tester",
  463. "age": 1.2,
  464. "alias": "lunny",
  465. "nick_name": "lunny xiao",
  466. "created": time.Now(),
  467. }
  468. for i := 0; i < b.N; i++ {
  469. _, err = db.ExecMap("insert into user (`name`, title, age, alias, nick_name, created) "+
  470. "values (?name,?title,?age,?alias,?nick_name,?created)",
  471. &mp)
  472. if err != nil {
  473. b.Error(err)
  474. }
  475. }
  476. }
  477. func TestExecMap(t *testing.T) {
  478. db, err := testOpen()
  479. if err != nil {
  480. t.Error(err)
  481. }
  482. defer db.Close()
  483. _, err = db.Exec(createTableSql)
  484. if err != nil {
  485. t.Error(err)
  486. }
  487. mp := map[string]interface{}{
  488. "name": "xlw",
  489. "title": "tester",
  490. "age": 1.2,
  491. "alias": "lunny",
  492. "nick_name": "lunny xiao",
  493. "created": time.Now(),
  494. }
  495. _, err = db.ExecMap("insert into user (`name`, title, age, alias, nick_name,created) "+
  496. "values (?name,?title,?age,?alias,?nick_name,?created)",
  497. &mp)
  498. if err != nil {
  499. t.Error(err)
  500. }
  501. rows, err := db.Query("select * from user")
  502. if err != nil {
  503. t.Error(err)
  504. }
  505. for rows.Next() {
  506. var user User
  507. err = rows.ScanStructByName(&user)
  508. if err != nil {
  509. t.Error(err)
  510. }
  511. t.Log("--", user)
  512. }
  513. }
  514. func TestExecStruct(t *testing.T) {
  515. db, err := testOpen()
  516. if err != nil {
  517. t.Error(err)
  518. }
  519. defer db.Close()
  520. _, err = db.Exec(createTableSql)
  521. if err != nil {
  522. t.Error(err)
  523. }
  524. user := User{Name: "xlw",
  525. Title: "tester",
  526. Age: 1.2,
  527. Alias: "lunny",
  528. NickName: "lunny xiao",
  529. Created: NullTime(time.Now()),
  530. }
  531. _, err = db.ExecStruct("insert into user (`name`, title, age, alias, nick_name,created) "+
  532. "values (?Name,?Title,?Age,?Alias,?NickName,?Created)",
  533. &user)
  534. if err != nil {
  535. t.Error(err)
  536. }
  537. rows, err := db.QueryStruct("select * from user where `name` = ?Name", &user)
  538. if err != nil {
  539. t.Error(err)
  540. }
  541. for rows.Next() {
  542. var user User
  543. err = rows.ScanStructByName(&user)
  544. if err != nil {
  545. t.Error(err)
  546. }
  547. t.Log("1--", user)
  548. }
  549. }
  550. func BenchmarkExecStruct(b *testing.B) {
  551. b.StopTimer()
  552. db, err := testOpen()
  553. if err != nil {
  554. b.Error(err)
  555. }
  556. defer db.Close()
  557. _, err = db.Exec(createTableSql)
  558. if err != nil {
  559. b.Error(err)
  560. }
  561. b.StartTimer()
  562. user := User{Name: "xlw",
  563. Title: "tester",
  564. Age: 1.2,
  565. Alias: "lunny",
  566. NickName: "lunny xiao",
  567. Created: NullTime(time.Now()),
  568. }
  569. for i := 0; i < b.N; i++ {
  570. _, err = db.ExecStruct("insert into user (`name`, title, age, alias, nick_name,created) "+
  571. "values (?Name,?Title,?Age,?Alias,?NickName,?Created)",
  572. &user)
  573. if err != nil {
  574. b.Error(err)
  575. }
  576. }
  577. }