Fork github.com/mattn/go-sqlite3 with adjustment for go1.16.2
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.

275 lines
6.1 KiB

  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 cgo
  6. package sqlite3
  7. import (
  8. "database/sql"
  9. "io/ioutil"
  10. "os"
  11. "path"
  12. "testing"
  13. )
  14. func TestSimpleError(t *testing.T) {
  15. e := ErrError.Error()
  16. if e != "SQL logic error or missing database" && e != "SQL logic error" {
  17. t.Error("wrong error code: " + e)
  18. }
  19. }
  20. func TestCorruptDbErrors(t *testing.T) {
  21. dirName, err := ioutil.TempDir("", "sqlite3")
  22. if err != nil {
  23. t.Fatal(err)
  24. }
  25. defer os.RemoveAll(dirName)
  26. dbFileName := path.Join(dirName, "test.db")
  27. f, err := os.Create(dbFileName)
  28. if err != nil {
  29. t.Error(err)
  30. }
  31. f.Write([]byte{1, 2, 3, 4, 5})
  32. f.Close()
  33. db, err := sql.Open("sqlite3", dbFileName)
  34. if err == nil {
  35. _, err = db.Exec("drop table foo")
  36. }
  37. sqliteErr := err.(Error)
  38. if sqliteErr.Code != ErrNotADB {
  39. t.Error("wrong error code for corrupted DB")
  40. }
  41. if err.Error() == "" {
  42. t.Error("wrong error string for corrupted DB")
  43. }
  44. db.Close()
  45. }
  46. func TestSqlLogicErrors(t *testing.T) {
  47. dirName, err := ioutil.TempDir("", "sqlite3")
  48. if err != nil {
  49. t.Fatal(err)
  50. }
  51. defer os.RemoveAll(dirName)
  52. dbFileName := path.Join(dirName, "test.db")
  53. db, err := sql.Open("sqlite3", dbFileName)
  54. if err != nil {
  55. t.Error(err)
  56. }
  57. defer db.Close()
  58. _, err = db.Exec("CREATE TABLE Foo (id INTEGER PRIMARY KEY)")
  59. if err != nil {
  60. t.Error(err)
  61. }
  62. const expectedErr = "table Foo already exists"
  63. _, err = db.Exec("CREATE TABLE Foo (id INTEGER PRIMARY KEY)")
  64. if err.Error() != expectedErr {
  65. t.Errorf("Unexpected error: %s, expected %s", err.Error(), expectedErr)
  66. }
  67. }
  68. func TestExtendedErrorCodes_ForeignKey(t *testing.T) {
  69. dirName, err := ioutil.TempDir("", "sqlite3-err")
  70. if err != nil {
  71. t.Fatal(err)
  72. }
  73. defer os.RemoveAll(dirName)
  74. dbFileName := path.Join(dirName, "test.db")
  75. db, err := sql.Open("sqlite3", dbFileName)
  76. if err != nil {
  77. t.Error(err)
  78. }
  79. defer db.Close()
  80. _, err = db.Exec("PRAGMA foreign_keys=ON;")
  81. if err != nil {
  82. t.Errorf("PRAGMA foreign_keys=ON: %v", err)
  83. }
  84. _, err = db.Exec(`CREATE TABLE Foo (
  85. id INTEGER PRIMARY KEY AUTOINCREMENT,
  86. value INTEGER NOT NULL,
  87. ref INTEGER NULL REFERENCES Foo (id),
  88. UNIQUE(value)
  89. );`)
  90. if err != nil {
  91. t.Error(err)
  92. }
  93. _, err = db.Exec("INSERT INTO Foo (ref, value) VALUES (100, 100);")
  94. if err == nil {
  95. t.Error("No error!")
  96. } else {
  97. sqliteErr := err.(Error)
  98. if sqliteErr.Code != ErrConstraint {
  99. t.Errorf("Wrong basic error code: %d != %d",
  100. sqliteErr.Code, ErrConstraint)
  101. }
  102. if sqliteErr.ExtendedCode != ErrConstraintForeignKey {
  103. t.Errorf("Wrong extended error code: %d != %d",
  104. sqliteErr.ExtendedCode, ErrConstraintForeignKey)
  105. }
  106. }
  107. }
  108. func TestExtendedErrorCodes_NotNull(t *testing.T) {
  109. dirName, err := ioutil.TempDir("", "sqlite3-err")
  110. if err != nil {
  111. t.Fatal(err)
  112. }
  113. defer os.RemoveAll(dirName)
  114. dbFileName := path.Join(dirName, "test.db")
  115. db, err := sql.Open("sqlite3", dbFileName)
  116. if err != nil {
  117. t.Error(err)
  118. }
  119. defer db.Close()
  120. _, err = db.Exec("PRAGMA foreign_keys=ON;")
  121. if err != nil {
  122. t.Errorf("PRAGMA foreign_keys=ON: %v", err)
  123. }
  124. _, err = db.Exec(`CREATE TABLE Foo (
  125. id INTEGER PRIMARY KEY AUTOINCREMENT,
  126. value INTEGER NOT NULL,
  127. ref INTEGER NULL REFERENCES Foo (id),
  128. UNIQUE(value)
  129. );`)
  130. if err != nil {
  131. t.Error(err)
  132. }
  133. res, err := db.Exec("INSERT INTO Foo (value) VALUES (100);")
  134. if err != nil {
  135. t.Fatalf("Creating first row: %v", err)
  136. }
  137. id, err := res.LastInsertId()
  138. if err != nil {
  139. t.Fatalf("Retrieving last insert id: %v", err)
  140. }
  141. _, err = db.Exec("INSERT INTO Foo (ref) VALUES (?);", id)
  142. if err == nil {
  143. t.Error("No error!")
  144. } else {
  145. sqliteErr := err.(Error)
  146. if sqliteErr.Code != ErrConstraint {
  147. t.Errorf("Wrong basic error code: %d != %d",
  148. sqliteErr.Code, ErrConstraint)
  149. }
  150. if sqliteErr.ExtendedCode != ErrConstraintNotNull {
  151. t.Errorf("Wrong extended error code: %d != %d",
  152. sqliteErr.ExtendedCode, ErrConstraintNotNull)
  153. }
  154. }
  155. }
  156. func TestExtendedErrorCodes_Unique(t *testing.T) {
  157. dirName, err := ioutil.TempDir("", "sqlite3-err")
  158. if err != nil {
  159. t.Fatal(err)
  160. }
  161. defer os.RemoveAll(dirName)
  162. dbFileName := path.Join(dirName, "test.db")
  163. db, err := sql.Open("sqlite3", dbFileName)
  164. if err != nil {
  165. t.Error(err)
  166. }
  167. defer db.Close()
  168. _, err = db.Exec("PRAGMA foreign_keys=ON;")
  169. if err != nil {
  170. t.Errorf("PRAGMA foreign_keys=ON: %v", err)
  171. }
  172. _, err = db.Exec(`CREATE TABLE Foo (
  173. id INTEGER PRIMARY KEY AUTOINCREMENT,
  174. value INTEGER NOT NULL,
  175. ref INTEGER NULL REFERENCES Foo (id),
  176. UNIQUE(value)
  177. );`)
  178. if err != nil {
  179. t.Error(err)
  180. }
  181. res, err := db.Exec("INSERT INTO Foo (value) VALUES (100);")
  182. if err != nil {
  183. t.Fatalf("Creating first row: %v", err)
  184. }
  185. id, err := res.LastInsertId()
  186. if err != nil {
  187. t.Fatalf("Retrieving last insert id: %v", err)
  188. }
  189. _, err = db.Exec("INSERT INTO Foo (ref, value) VALUES (?, 100);", id)
  190. if err == nil {
  191. t.Error("No error!")
  192. } else {
  193. sqliteErr := err.(Error)
  194. if sqliteErr.Code != ErrConstraint {
  195. t.Errorf("Wrong basic error code: %d != %d",
  196. sqliteErr.Code, ErrConstraint)
  197. }
  198. if sqliteErr.ExtendedCode != ErrConstraintUnique {
  199. t.Errorf("Wrong extended error code: %d != %d",
  200. sqliteErr.ExtendedCode, ErrConstraintUnique)
  201. }
  202. extended := sqliteErr.Code.Extend(3).Error()
  203. expected := "constraint failed"
  204. if extended != expected {
  205. t.Errorf("Wrong basic error code: %q != %q",
  206. extended, expected)
  207. }
  208. }
  209. }
  210. func TestError_SystemErrno(t *testing.T) {
  211. _, n, _ := Version()
  212. if n < 3012000 {
  213. t.Skip("sqlite3_system_errno requires sqlite3 >= 3.12.0")
  214. }
  215. // open a non-existent database in read-only mode so we get an IO error.
  216. db, err := sql.Open("sqlite3", "file:nonexistent.db?mode=ro")
  217. if err != nil {
  218. t.Fatal(err)
  219. }
  220. defer db.Close()
  221. err = db.Ping()
  222. if err == nil {
  223. t.Fatal("expected error pinging read-only non-existent database, but got nil")
  224. }
  225. serr, ok := err.(Error)
  226. if !ok {
  227. t.Fatalf("expected error to be of type Error, but got %[1]T %[1]v", err)
  228. }
  229. if serr.SystemErrno == 0 {
  230. t.Fatal("expected SystemErrno to be set")
  231. }
  232. if !os.IsNotExist(serr.SystemErrno) {
  233. t.Errorf("expected SystemErrno to be a not exists error, but got %v", serr.SystemErrno)
  234. }
  235. }