PageRenderTime 1190ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/sqlite3_go113_test.go

http://github.com/mattn/go-sqlite3
Go | 119 lines | 96 code | 15 blank | 8 comment | 29 complexity | 461bacaf9cb5fa491cb6027669dc5244 MD5 | raw file
  1. // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. // +build go1.13,cgo
  6. package sqlite3
  7. import (
  8. "context"
  9. "database/sql"
  10. "database/sql/driver"
  11. "errors"
  12. "os"
  13. "testing"
  14. )
  15. func TestBeginTxCancel(t *testing.T) {
  16. srcTempFilename := TempFilename(t)
  17. defer os.Remove(srcTempFilename)
  18. db, err := sql.Open("sqlite3", srcTempFilename)
  19. if err != nil {
  20. t.Fatal(err)
  21. }
  22. db.SetMaxOpenConns(10)
  23. db.SetMaxIdleConns(5)
  24. defer db.Close()
  25. initDatabase(t, db, 100)
  26. // create several go-routines to expose racy issue
  27. for i := 0; i < 1000; i++ {
  28. func() {
  29. ctx, cancel := context.WithCancel(context.Background())
  30. conn, err := db.Conn(ctx)
  31. if err != nil {
  32. t.Fatal(err)
  33. }
  34. defer func() {
  35. if err := conn.Close(); err != nil {
  36. t.Error(err)
  37. }
  38. }()
  39. err = conn.Raw(func(driverConn interface{}) error {
  40. d, ok := driverConn.(driver.ConnBeginTx)
  41. if !ok {
  42. t.Fatal("unexpected: wrong type")
  43. }
  44. // checks that conn.Raw can be used to get *SQLiteConn
  45. if _, ok = driverConn.(*SQLiteConn); !ok {
  46. t.Fatalf("conn.Raw() driverConn type=%T, expected *SQLiteConn", driverConn)
  47. }
  48. go cancel() // make it cancel concurrently with exec("BEGIN");
  49. tx, err := d.BeginTx(ctx, driver.TxOptions{})
  50. switch err {
  51. case nil:
  52. switch err := tx.Rollback(); err {
  53. case nil, sql.ErrTxDone:
  54. default:
  55. return err
  56. }
  57. case context.Canceled:
  58. default:
  59. // must not fail with "cannot start a transaction within a transaction"
  60. return err
  61. }
  62. return nil
  63. })
  64. if err != nil {
  65. t.Fatal(err)
  66. }
  67. }()
  68. }
  69. }
  70. func TestStmtReadonly(t *testing.T) {
  71. db, err := sql.Open("sqlite3", ":memory:")
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. _, err = db.Exec("CREATE TABLE t (count INT)")
  76. if err != nil {
  77. t.Fatal(err)
  78. }
  79. isRO := func(query string) bool {
  80. c, err := db.Conn(context.Background())
  81. if err != nil {
  82. return false
  83. }
  84. var ro bool
  85. c.Raw(func(dc interface{}) error {
  86. stmt, err := dc.(*SQLiteConn).Prepare(query)
  87. if err != nil {
  88. return err
  89. }
  90. if stmt == nil {
  91. return errors.New("stmt is nil")
  92. }
  93. ro = stmt.(*SQLiteStmt).Readonly()
  94. return nil
  95. })
  96. return ro // On errors ro will remain false.
  97. }
  98. if !isRO(`select * from t`) {
  99. t.Error("select not seen as read-only")
  100. }
  101. if isRO(`insert into t values (1), (2)`) {
  102. t.Error("insert seen as read-only")
  103. }
  104. }