sqlite3_test.go 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350
  1. // Copyright (C) 2014 Yasuhiro Matsumoto <[email protected]>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. package sqlite3
  6. import (
  7. "database/sql"
  8. "database/sql/driver"
  9. "errors"
  10. "fmt"
  11. "io/ioutil"
  12. "net/url"
  13. "os"
  14. "reflect"
  15. "regexp"
  16. "strings"
  17. "sync"
  18. "testing"
  19. "time"
  20. "github.com/mattn/go-sqlite3/sqlite3_test"
  21. )
  22. func TempFilename(t *testing.T) string {
  23. f, err := ioutil.TempFile("", "go-sqlite3-test-")
  24. if err != nil {
  25. t.Fatal(err)
  26. }
  27. f.Close()
  28. return f.Name()
  29. }
  30. func doTestOpen(t *testing.T, option string) (string, error) {
  31. var url string
  32. tempFilename := TempFilename(t)
  33. defer os.Remove(tempFilename)
  34. if option != "" {
  35. url = tempFilename + option
  36. } else {
  37. url = tempFilename
  38. }
  39. db, err := sql.Open("sqlite3", url)
  40. if err != nil {
  41. return "Failed to open database:", err
  42. }
  43. defer os.Remove(tempFilename)
  44. defer db.Close()
  45. _, err = db.Exec("drop table foo")
  46. _, err = db.Exec("create table foo (id integer)")
  47. if err != nil {
  48. return "Failed to create table:", err
  49. }
  50. if stat, err := os.Stat(tempFilename); err != nil || stat.IsDir() {
  51. return "Failed to create ./foo.db", nil
  52. }
  53. return "", nil
  54. }
  55. func TestOpen(t *testing.T) {
  56. cases := map[string]bool{
  57. "": true,
  58. "?_txlock=immediate": true,
  59. "?_txlock=deferred": true,
  60. "?_txlock=exclusive": true,
  61. "?_txlock=bogus": false,
  62. }
  63. for option, expectedPass := range cases {
  64. result, err := doTestOpen(t, option)
  65. if result == "" {
  66. if !expectedPass {
  67. errmsg := fmt.Sprintf("_txlock error not caught at dbOpen with option: %s", option)
  68. t.Fatal(errmsg)
  69. }
  70. } else if expectedPass {
  71. if err == nil {
  72. t.Fatal(result)
  73. } else {
  74. t.Fatal(result, err)
  75. }
  76. }
  77. }
  78. }
  79. func TestReadonly(t *testing.T) {
  80. tempFilename := TempFilename(t)
  81. defer os.Remove(tempFilename)
  82. db1, err := sql.Open("sqlite3", "file:"+tempFilename)
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. db1.Exec("CREATE TABLE test (x int, y float)")
  87. db2, err := sql.Open("sqlite3", "file:"+tempFilename+"?mode=ro")
  88. if err != nil {
  89. t.Fatal(err)
  90. }
  91. _ = db2
  92. _, err = db2.Exec("INSERT INTO test VALUES (1, 3.14)")
  93. if err == nil {
  94. t.Fatal("didn't expect INSERT into read-only database to work")
  95. }
  96. }
  97. func TestClose(t *testing.T) {
  98. tempFilename := TempFilename(t)
  99. defer os.Remove(tempFilename)
  100. db, err := sql.Open("sqlite3", tempFilename)
  101. if err != nil {
  102. t.Fatal("Failed to open database:", err)
  103. }
  104. _, err = db.Exec("drop table foo")
  105. _, err = db.Exec("create table foo (id integer)")
  106. if err != nil {
  107. t.Fatal("Failed to create table:", err)
  108. }
  109. stmt, err := db.Prepare("select id from foo where id = ?")
  110. if err != nil {
  111. t.Fatal("Failed to select records:", err)
  112. }
  113. db.Close()
  114. _, err = stmt.Exec(1)
  115. if err == nil {
  116. t.Fatal("Failed to operate closed statement")
  117. }
  118. }
  119. func TestInsert(t *testing.T) {
  120. tempFilename := TempFilename(t)
  121. defer os.Remove(tempFilename)
  122. db, err := sql.Open("sqlite3", tempFilename)
  123. if err != nil {
  124. t.Fatal("Failed to open database:", err)
  125. }
  126. defer db.Close()
  127. _, err = db.Exec("drop table foo")
  128. _, err = db.Exec("create table foo (id integer)")
  129. if err != nil {
  130. t.Fatal("Failed to create table:", err)
  131. }
  132. res, err := db.Exec("insert into foo(id) values(123)")
  133. if err != nil {
  134. t.Fatal("Failed to insert record:", err)
  135. }
  136. affected, _ := res.RowsAffected()
  137. if affected != 1 {
  138. t.Fatalf("Expected %d for affected rows, but %d:", 1, affected)
  139. }
  140. rows, err := db.Query("select id from foo")
  141. if err != nil {
  142. t.Fatal("Failed to select records:", err)
  143. }
  144. defer rows.Close()
  145. rows.Next()
  146. var result int
  147. rows.Scan(&result)
  148. if result != 123 {
  149. t.Errorf("Expected %d for fetched result, but %d:", 123, result)
  150. }
  151. }
  152. func TestUpdate(t *testing.T) {
  153. tempFilename := TempFilename(t)
  154. defer os.Remove(tempFilename)
  155. db, err := sql.Open("sqlite3", tempFilename)
  156. if err != nil {
  157. t.Fatal("Failed to open database:", err)
  158. }
  159. defer db.Close()
  160. _, err = db.Exec("drop table foo")
  161. _, err = db.Exec("create table foo (id integer)")
  162. if err != nil {
  163. t.Fatal("Failed to create table:", err)
  164. }
  165. res, err := db.Exec("insert into foo(id) values(123)")
  166. if err != nil {
  167. t.Fatal("Failed to insert record:", err)
  168. }
  169. expected, err := res.LastInsertId()
  170. if err != nil {
  171. t.Fatal("Failed to get LastInsertId:", err)
  172. }
  173. affected, _ := res.RowsAffected()
  174. if err != nil {
  175. t.Fatal("Failed to get RowsAffected:", err)
  176. }
  177. if affected != 1 {
  178. t.Fatalf("Expected %d for affected rows, but %d:", 1, affected)
  179. }
  180. res, err = db.Exec("update foo set id = 234")
  181. if err != nil {
  182. t.Fatal("Failed to update record:", err)
  183. }
  184. lastId, err := res.LastInsertId()
  185. if err != nil {
  186. t.Fatal("Failed to get LastInsertId:", err)
  187. }
  188. if expected != lastId {
  189. t.Errorf("Expected %q for last Id, but %q:", expected, lastId)
  190. }
  191. affected, _ = res.RowsAffected()
  192. if err != nil {
  193. t.Fatal("Failed to get RowsAffected:", err)
  194. }
  195. if affected != 1 {
  196. t.Fatalf("Expected %d for affected rows, but %d:", 1, affected)
  197. }
  198. rows, err := db.Query("select id from foo")
  199. if err != nil {
  200. t.Fatal("Failed to select records:", err)
  201. }
  202. defer rows.Close()
  203. rows.Next()
  204. var result int
  205. rows.Scan(&result)
  206. if result != 234 {
  207. t.Errorf("Expected %d for fetched result, but %d:", 234, result)
  208. }
  209. }
  210. func TestDelete(t *testing.T) {
  211. tempFilename := TempFilename(t)
  212. defer os.Remove(tempFilename)
  213. db, err := sql.Open("sqlite3", tempFilename)
  214. if err != nil {
  215. t.Fatal("Failed to open database:", err)
  216. }
  217. defer db.Close()
  218. _, err = db.Exec("drop table foo")
  219. _, err = db.Exec("create table foo (id integer)")
  220. if err != nil {
  221. t.Fatal("Failed to create table:", err)
  222. }
  223. res, err := db.Exec("insert into foo(id) values(123)")
  224. if err != nil {
  225. t.Fatal("Failed to insert record:", err)
  226. }
  227. expected, err := res.LastInsertId()
  228. if err != nil {
  229. t.Fatal("Failed to get LastInsertId:", err)
  230. }
  231. affected, err := res.RowsAffected()
  232. if err != nil {
  233. t.Fatal("Failed to get RowsAffected:", err)
  234. }
  235. if affected != 1 {
  236. t.Errorf("Expected %d for cout of affected rows, but %q:", 1, affected)
  237. }
  238. res, err = db.Exec("delete from foo where id = 123")
  239. if err != nil {
  240. t.Fatal("Failed to delete record:", err)
  241. }
  242. lastId, err := res.LastInsertId()
  243. if err != nil {
  244. t.Fatal("Failed to get LastInsertId:", err)
  245. }
  246. if expected != lastId {
  247. t.Errorf("Expected %q for last Id, but %q:", expected, lastId)
  248. }
  249. affected, err = res.RowsAffected()
  250. if err != nil {
  251. t.Fatal("Failed to get RowsAffected:", err)
  252. }
  253. if affected != 1 {
  254. t.Errorf("Expected %d for cout of affected rows, but %q:", 1, affected)
  255. }
  256. rows, err := db.Query("select id from foo")
  257. if err != nil {
  258. t.Fatal("Failed to select records:", err)
  259. }
  260. defer rows.Close()
  261. if rows.Next() {
  262. t.Error("Fetched row but expected not rows")
  263. }
  264. }
  265. func TestBooleanRoundtrip(t *testing.T) {
  266. tempFilename := TempFilename(t)
  267. defer os.Remove(tempFilename)
  268. db, err := sql.Open("sqlite3", tempFilename)
  269. if err != nil {
  270. t.Fatal("Failed to open database:", err)
  271. }
  272. defer db.Close()
  273. _, err = db.Exec("DROP TABLE foo")
  274. _, err = db.Exec("CREATE TABLE foo(id INTEGER, value BOOL)")
  275. if err != nil {
  276. t.Fatal("Failed to create table:", err)
  277. }
  278. _, err = db.Exec("INSERT INTO foo(id, value) VALUES(1, ?)", true)
  279. if err != nil {
  280. t.Fatal("Failed to insert true value:", err)
  281. }
  282. _, err = db.Exec("INSERT INTO foo(id, value) VALUES(2, ?)", false)
  283. if err != nil {
  284. t.Fatal("Failed to insert false value:", err)
  285. }
  286. rows, err := db.Query("SELECT id, value FROM foo")
  287. if err != nil {
  288. t.Fatal("Unable to query foo table:", err)
  289. }
  290. defer rows.Close()
  291. for rows.Next() {
  292. var id int
  293. var value bool
  294. if err := rows.Scan(&id, &value); err != nil {
  295. t.Error("Unable to scan results:", err)
  296. continue
  297. }
  298. if id == 1 && !value {
  299. t.Error("Value for id 1 should be true, not false")
  300. } else if id == 2 && value {
  301. t.Error("Value for id 2 should be false, not true")
  302. }
  303. }
  304. }
  305. func timezone(t time.Time) string { return t.Format("-07:00") }
  306. func TestTimestamp(t *testing.T) {
  307. tempFilename := TempFilename(t)
  308. defer os.Remove(tempFilename)
  309. db, err := sql.Open("sqlite3", tempFilename)
  310. if err != nil {
  311. t.Fatal("Failed to open database:", err)
  312. }
  313. defer db.Close()
  314. _, err = db.Exec("DROP TABLE foo")
  315. _, err = db.Exec("CREATE TABLE foo(id INTEGER, ts timeSTAMP, dt DATETIME)")
  316. if err != nil {
  317. t.Fatal("Failed to create table:", err)
  318. }
  319. timestamp1 := time.Date(2012, time.April, 6, 22, 50, 0, 0, time.UTC)
  320. timestamp2 := time.Date(2006, time.January, 2, 15, 4, 5, 123456789, time.UTC)
  321. timestamp3 := time.Date(2012, time.November, 4, 0, 0, 0, 0, time.UTC)
  322. tzTest := time.FixedZone("TEST", -9*3600-13*60)
  323. tests := []struct {
  324. value interface{}
  325. expected time.Time
  326. }{
  327. {"nonsense", time.Time{}},
  328. {"0000-00-00 00:00:00", time.Time{}},
  329. {timestamp1, timestamp1},
  330. {timestamp2.Unix(), timestamp2.Truncate(time.Second)},
  331. {timestamp2.UnixNano() / int64(time.Millisecond), timestamp2.Truncate(time.Millisecond)},
  332. {timestamp1.In(tzTest), timestamp1.In(tzTest)},
  333. {timestamp1.Format("2006-01-02 15:04:05.000"), timestamp1},
  334. {timestamp1.Format("2006-01-02T15:04:05.000"), timestamp1},
  335. {timestamp1.Format("2006-01-02 15:04:05"), timestamp1},
  336. {timestamp1.Format("2006-01-02T15:04:05"), timestamp1},
  337. {timestamp2, timestamp2},
  338. {"2006-01-02 15:04:05.123456789", timestamp2},
  339. {"2006-01-02T15:04:05.123456789", timestamp2},
  340. {"2006-01-02T05:51:05.123456789-09:13", timestamp2.In(tzTest)},
  341. {"2012-11-04", timestamp3},
  342. {"2012-11-04 00:00", timestamp3},
  343. {"2012-11-04 00:00:00", timestamp3},
  344. {"2012-11-04 00:00:00.000", timestamp3},
  345. {"2012-11-04T00:00", timestamp3},
  346. {"2012-11-04T00:00:00", timestamp3},
  347. {"2012-11-04T00:00:00.000", timestamp3},
  348. {"2006-01-02T15:04:05.123456789Z", timestamp2},
  349. {"2012-11-04Z", timestamp3},
  350. {"2012-11-04 00:00Z", timestamp3},
  351. {"2012-11-04 00:00:00Z", timestamp3},
  352. {"2012-11-04 00:00:00.000Z", timestamp3},
  353. {"2012-11-04T00:00Z", timestamp3},
  354. {"2012-11-04T00:00:00Z", timestamp3},
  355. {"2012-11-04T00:00:00.000Z", timestamp3},
  356. }
  357. for i := range tests {
  358. _, err = db.Exec("INSERT INTO foo(id, ts, dt) VALUES(?, ?, ?)", i, tests[i].value, tests[i].value)
  359. if err != nil {
  360. t.Fatal("Failed to insert timestamp:", err)
  361. }
  362. }
  363. rows, err := db.Query("SELECT id, ts, dt FROM foo ORDER BY id ASC")
  364. if err != nil {
  365. t.Fatal("Unable to query foo table:", err)
  366. }
  367. defer rows.Close()
  368. seen := 0
  369. for rows.Next() {
  370. var id int
  371. var ts, dt time.Time
  372. if err := rows.Scan(&id, &ts, &dt); err != nil {
  373. t.Error("Unable to scan results:", err)
  374. continue
  375. }
  376. if id < 0 || id >= len(tests) {
  377. t.Error("Bad row id: ", id)
  378. continue
  379. }
  380. seen++
  381. if !tests[id].expected.Equal(ts) {
  382. t.Errorf("Timestamp value for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected, dt)
  383. }
  384. if !tests[id].expected.Equal(dt) {
  385. t.Errorf("Datetime value for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected, dt)
  386. }
  387. if timezone(tests[id].expected) != timezone(ts) {
  388. t.Errorf("Timezone for id %v (%v) should be %v, not %v", id, tests[id].value,
  389. timezone(tests[id].expected), timezone(ts))
  390. }
  391. if timezone(tests[id].expected) != timezone(dt) {
  392. t.Errorf("Timezone for id %v (%v) should be %v, not %v", id, tests[id].value,
  393. timezone(tests[id].expected), timezone(dt))
  394. }
  395. }
  396. if seen != len(tests) {
  397. t.Errorf("Expected to see %d rows", len(tests))
  398. }
  399. }
  400. func TestBoolean(t *testing.T) {
  401. tempFilename := TempFilename(t)
  402. defer os.Remove(tempFilename)
  403. db, err := sql.Open("sqlite3", tempFilename)
  404. if err != nil {
  405. t.Fatal("Failed to open database:", err)
  406. }
  407. defer db.Close()
  408. _, err = db.Exec("CREATE TABLE foo(id INTEGER, fbool BOOLEAN)")
  409. if err != nil {
  410. t.Fatal("Failed to create table:", err)
  411. }
  412. bool1 := true
  413. _, err = db.Exec("INSERT INTO foo(id, fbool) VALUES(1, ?)", bool1)
  414. if err != nil {
  415. t.Fatal("Failed to insert boolean:", err)
  416. }
  417. bool2 := false
  418. _, err = db.Exec("INSERT INTO foo(id, fbool) VALUES(2, ?)", bool2)
  419. if err != nil {
  420. t.Fatal("Failed to insert boolean:", err)
  421. }
  422. bool3 := "nonsense"
  423. _, err = db.Exec("INSERT INTO foo(id, fbool) VALUES(3, ?)", bool3)
  424. if err != nil {
  425. t.Fatal("Failed to insert nonsense:", err)
  426. }
  427. rows, err := db.Query("SELECT id, fbool FROM foo where fbool = ?", bool1)
  428. if err != nil {
  429. t.Fatal("Unable to query foo table:", err)
  430. }
  431. counter := 0
  432. var id int
  433. var fbool bool
  434. for rows.Next() {
  435. if err := rows.Scan(&id, &fbool); err != nil {
  436. t.Fatal("Unable to scan results:", err)
  437. }
  438. counter++
  439. }
  440. if counter != 1 {
  441. t.Fatalf("Expected 1 row but %v", counter)
  442. }
  443. if id != 1 && fbool != true {
  444. t.Fatalf("Value for id 1 should be %v, not %v", bool1, fbool)
  445. }
  446. rows, err = db.Query("SELECT id, fbool FROM foo where fbool = ?", bool2)
  447. if err != nil {
  448. t.Fatal("Unable to query foo table:", err)
  449. }
  450. counter = 0
  451. for rows.Next() {
  452. if err := rows.Scan(&id, &fbool); err != nil {
  453. t.Fatal("Unable to scan results:", err)
  454. }
  455. counter++
  456. }
  457. if counter != 1 {
  458. t.Fatalf("Expected 1 row but %v", counter)
  459. }
  460. if id != 2 && fbool != false {
  461. t.Fatalf("Value for id 2 should be %v, not %v", bool2, fbool)
  462. }
  463. // make sure "nonsense" triggered an error
  464. rows, err = db.Query("SELECT id, fbool FROM foo where id=?;", 3)
  465. if err != nil {
  466. t.Fatal("Unable to query foo table:", err)
  467. }
  468. rows.Next()
  469. err = rows.Scan(&id, &fbool)
  470. if err == nil {
  471. t.Error("Expected error from \"nonsense\" bool")
  472. }
  473. }
  474. func TestFloat32(t *testing.T) {
  475. tempFilename := TempFilename(t)
  476. defer os.Remove(tempFilename)
  477. db, err := sql.Open("sqlite3", tempFilename)
  478. if err != nil {
  479. t.Fatal("Failed to open database:", err)
  480. }
  481. defer db.Close()
  482. _, err = db.Exec("CREATE TABLE foo(id INTEGER)")
  483. if err != nil {
  484. t.Fatal("Failed to create table:", err)
  485. }
  486. _, err = db.Exec("INSERT INTO foo(id) VALUES(null)")
  487. if err != nil {
  488. t.Fatal("Failed to insert null:", err)
  489. }
  490. rows, err := db.Query("SELECT id FROM foo")
  491. if err != nil {
  492. t.Fatal("Unable to query foo table:", err)
  493. }
  494. if !rows.Next() {
  495. t.Fatal("Unable to query results:", err)
  496. }
  497. var id interface{}
  498. if err := rows.Scan(&id); err != nil {
  499. t.Fatal("Unable to scan results:", err)
  500. }
  501. if id != nil {
  502. t.Error("Expected nil but not")
  503. }
  504. }
  505. func TestNull(t *testing.T) {
  506. tempFilename := TempFilename(t)
  507. defer os.Remove(tempFilename)
  508. db, err := sql.Open("sqlite3", tempFilename)
  509. if err != nil {
  510. t.Fatal("Failed to open database:", err)
  511. }
  512. defer db.Close()
  513. rows, err := db.Query("SELECT 3.141592")
  514. if err != nil {
  515. t.Fatal("Unable to query foo table:", err)
  516. }
  517. if !rows.Next() {
  518. t.Fatal("Unable to query results:", err)
  519. }
  520. var v interface{}
  521. if err := rows.Scan(&v); err != nil {
  522. t.Fatal("Unable to scan results:", err)
  523. }
  524. f, ok := v.(float64)
  525. if !ok {
  526. t.Error("Expected float but not")
  527. }
  528. if f != 3.141592 {
  529. t.Error("Expected 3.141592 but not")
  530. }
  531. }
  532. func TestTransaction(t *testing.T) {
  533. tempFilename := TempFilename(t)
  534. defer os.Remove(tempFilename)
  535. db, err := sql.Open("sqlite3", tempFilename)
  536. if err != nil {
  537. t.Fatal("Failed to open database:", err)
  538. }
  539. defer db.Close()
  540. _, err = db.Exec("CREATE TABLE foo(id INTEGER)")
  541. if err != nil {
  542. t.Fatal("Failed to create table:", err)
  543. }
  544. tx, err := db.Begin()
  545. if err != nil {
  546. t.Fatal("Failed to begin transaction:", err)
  547. }
  548. _, err = tx.Exec("INSERT INTO foo(id) VALUES(1)")
  549. if err != nil {
  550. t.Fatal("Failed to insert null:", err)
  551. }
  552. rows, err := tx.Query("SELECT id from foo")
  553. if err != nil {
  554. t.Fatal("Unable to query foo table:", err)
  555. }
  556. err = tx.Rollback()
  557. if err != nil {
  558. t.Fatal("Failed to rollback transaction:", err)
  559. }
  560. if rows.Next() {
  561. t.Fatal("Unable to query results:", err)
  562. }
  563. tx, err = db.Begin()
  564. if err != nil {
  565. t.Fatal("Failed to begin transaction:", err)
  566. }
  567. _, err = tx.Exec("INSERT INTO foo(id) VALUES(1)")
  568. if err != nil {
  569. t.Fatal("Failed to insert null:", err)
  570. }
  571. err = tx.Commit()
  572. if err != nil {
  573. t.Fatal("Failed to commit transaction:", err)
  574. }
  575. rows, err = tx.Query("SELECT id from foo")
  576. if err == nil {
  577. t.Fatal("Expected failure to query")
  578. }
  579. }
  580. func TestWAL(t *testing.T) {
  581. tempFilename := TempFilename(t)
  582. defer os.Remove(tempFilename)
  583. db, err := sql.Open("sqlite3", tempFilename)
  584. if err != nil {
  585. t.Fatal("Failed to open database:", err)
  586. }
  587. defer db.Close()
  588. if _, err = db.Exec("PRAGMA journal_mode=WAL;"); err != nil {
  589. t.Fatal("Failed to Exec PRAGMA journal_mode:", err)
  590. }
  591. if _, err = db.Exec("PRAGMA locking_mode=EXCLUSIVE;"); err != nil {
  592. t.Fatal("Failed to Exec PRAGMA locking_mode:", err)
  593. }
  594. if _, err = db.Exec("CREATE TABLE test (id SERIAL, user TEXT NOT NULL, name TEXT NOT NULL);"); err != nil {
  595. t.Fatal("Failed to Exec CREATE TABLE:", err)
  596. }
  597. if _, err = db.Exec("INSERT INTO test (user, name) VALUES ('user','name');"); err != nil {
  598. t.Fatal("Failed to Exec INSERT:", err)
  599. }
  600. trans, err := db.Begin()
  601. if err != nil {
  602. t.Fatal("Failed to Begin:", err)
  603. }
  604. s, err := trans.Prepare("INSERT INTO test (user, name) VALUES (?, ?);")
  605. if err != nil {
  606. t.Fatal("Failed to Prepare:", err)
  607. }
  608. var count int
  609. if err = trans.QueryRow("SELECT count(user) FROM test;").Scan(&count); err != nil {
  610. t.Fatal("Failed to QueryRow:", err)
  611. }
  612. if _, err = s.Exec("bbbb", "aaaa"); err != nil {
  613. t.Fatal("Failed to Exec prepared statement:", err)
  614. }
  615. if err = s.Close(); err != nil {
  616. t.Fatal("Failed to Close prepared statement:", err)
  617. }
  618. if err = trans.Commit(); err != nil {
  619. t.Fatal("Failed to Commit:", err)
  620. }
  621. }
  622. func TestTimezoneConversion(t *testing.T) {
  623. zones := []string{"UTC", "US/Central", "US/Pacific", "Local"}
  624. for _, tz := range zones {
  625. tempFilename := TempFilename(t)
  626. defer os.Remove(tempFilename)
  627. db, err := sql.Open("sqlite3", tempFilename+"?_loc="+url.QueryEscape(tz))
  628. if err != nil {
  629. t.Fatal("Failed to open database:", err)
  630. }
  631. defer db.Close()
  632. _, err = db.Exec("DROP TABLE foo")
  633. _, err = db.Exec("CREATE TABLE foo(id INTEGER, ts TIMESTAMP, dt DATETIME)")
  634. if err != nil {
  635. t.Fatal("Failed to create table:", err)
  636. }
  637. loc, err := time.LoadLocation(tz)
  638. if err != nil {
  639. t.Fatal("Failed to load location:", err)
  640. }
  641. timestamp1 := time.Date(2012, time.April, 6, 22, 50, 0, 0, time.UTC)
  642. timestamp2 := time.Date(2006, time.January, 2, 15, 4, 5, 123456789, time.UTC)
  643. timestamp3 := time.Date(2012, time.November, 4, 0, 0, 0, 0, time.UTC)
  644. tests := []struct {
  645. value interface{}
  646. expected time.Time
  647. }{
  648. {"nonsense", time.Time{}.In(loc)},
  649. {"0000-00-00 00:00:00", time.Time{}.In(loc)},
  650. {timestamp1, timestamp1.In(loc)},
  651. {timestamp1.Unix(), timestamp1.In(loc)},
  652. {timestamp1.In(time.FixedZone("TEST", -7*3600)), timestamp1.In(loc)},
  653. {timestamp1.Format("2006-01-02 15:04:05.000"), timestamp1.In(loc)},
  654. {timestamp1.Format("2006-01-02T15:04:05.000"), timestamp1.In(loc)},
  655. {timestamp1.Format("2006-01-02 15:04:05"), timestamp1.In(loc)},
  656. {timestamp1.Format("2006-01-02T15:04:05"), timestamp1.In(loc)},
  657. {timestamp2, timestamp2.In(loc)},
  658. {"2006-01-02 15:04:05.123456789", timestamp2.In(loc)},
  659. {"2006-01-02T15:04:05.123456789", timestamp2.In(loc)},
  660. {"2012-11-04", timestamp3.In(loc)},
  661. {"2012-11-04 00:00", timestamp3.In(loc)},
  662. {"2012-11-04 00:00:00", timestamp3.In(loc)},
  663. {"2012-11-04 00:00:00.000", timestamp3.In(loc)},
  664. {"2012-11-04T00:00", timestamp3.In(loc)},
  665. {"2012-11-04T00:00:00", timestamp3.In(loc)},
  666. {"2012-11-04T00:00:00.000", timestamp3.In(loc)},
  667. }
  668. for i := range tests {
  669. _, err = db.Exec("INSERT INTO foo(id, ts, dt) VALUES(?, ?, ?)", i, tests[i].value, tests[i].value)
  670. if err != nil {
  671. t.Fatal("Failed to insert timestamp:", err)
  672. }
  673. }
  674. rows, err := db.Query("SELECT id, ts, dt FROM foo ORDER BY id ASC")
  675. if err != nil {
  676. t.Fatal("Unable to query foo table:", err)
  677. }
  678. defer rows.Close()
  679. seen := 0
  680. for rows.Next() {
  681. var id int
  682. var ts, dt time.Time
  683. if err := rows.Scan(&id, &ts, &dt); err != nil {
  684. t.Error("Unable to scan results:", err)
  685. continue
  686. }
  687. if id < 0 || id >= len(tests) {
  688. t.Error("Bad row id: ", id)
  689. continue
  690. }
  691. seen++
  692. if !tests[id].expected.Equal(ts) {
  693. t.Errorf("Timestamp value for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected, ts)
  694. }
  695. if !tests[id].expected.Equal(dt) {
  696. t.Errorf("Datetime value for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected, dt)
  697. }
  698. if tests[id].expected.Location().String() != ts.Location().String() {
  699. t.Errorf("Location for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected.Location().String(), ts.Location().String())
  700. }
  701. if tests[id].expected.Location().String() != dt.Location().String() {
  702. t.Errorf("Location for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected.Location().String(), dt.Location().String())
  703. }
  704. }
  705. if seen != len(tests) {
  706. t.Errorf("Expected to see %d rows", len(tests))
  707. }
  708. }
  709. }
  710. func TestSuite(t *testing.T) {
  711. tempFilename := TempFilename(t)
  712. defer os.Remove(tempFilename)
  713. db, err := sql.Open("sqlite3", tempFilename+"?_busy_timeout=99999")
  714. if err != nil {
  715. t.Fatal(err)
  716. }
  717. defer db.Close()
  718. sqlite3_test.RunTests(t, db, sqlite3_test.SQLITE)
  719. }
  720. // TODO: Execer & Queryer currently disabled
  721. // https://github.com/mattn/go-sqlite3/issues/82
  722. func TestExecer(t *testing.T) {
  723. tempFilename := TempFilename(t)
  724. defer os.Remove(tempFilename)
  725. db, err := sql.Open("sqlite3", tempFilename)
  726. if err != nil {
  727. t.Fatal("Failed to open database:", err)
  728. }
  729. defer db.Close()
  730. _, err = db.Exec(`
  731. create table foo (id integer); -- one comment
  732. insert into foo(id) values(?);
  733. insert into foo(id) values(?);
  734. insert into foo(id) values(?); -- another comment
  735. `, 1, 2, 3)
  736. if err != nil {
  737. t.Error("Failed to call db.Exec:", err)
  738. }
  739. }
  740. func TestQueryer(t *testing.T) {
  741. tempFilename := TempFilename(t)
  742. defer os.Remove(tempFilename)
  743. db, err := sql.Open("sqlite3", tempFilename)
  744. if err != nil {
  745. t.Fatal("Failed to open database:", err)
  746. }
  747. defer db.Close()
  748. _, err = db.Exec(`
  749. create table foo (id integer);
  750. `)
  751. if err != nil {
  752. t.Error("Failed to call db.Query:", err)
  753. }
  754. rows, err := db.Query(`
  755. insert into foo(id) values(?);
  756. insert into foo(id) values(?);
  757. insert into foo(id) values(?);
  758. select id from foo order by id;
  759. `, 3, 2, 1)
  760. if err != nil {
  761. t.Error("Failed to call db.Query:", err)
  762. }
  763. defer rows.Close()
  764. n := 1
  765. if rows != nil {
  766. for rows.Next() {
  767. var id int
  768. err = rows.Scan(&id)
  769. if err != nil {
  770. t.Error("Failed to db.Query:", err)
  771. }
  772. if id != n {
  773. t.Error("Failed to db.Query: not matched results")
  774. }
  775. }
  776. }
  777. }
  778. func TestStress(t *testing.T) {
  779. tempFilename := TempFilename(t)
  780. defer os.Remove(tempFilename)
  781. db, err := sql.Open("sqlite3", tempFilename)
  782. if err != nil {
  783. t.Fatal("Failed to open database:", err)
  784. }
  785. db.Exec("CREATE TABLE foo (id int);")
  786. db.Exec("INSERT INTO foo VALUES(1);")
  787. db.Exec("INSERT INTO foo VALUES(2);")
  788. db.Close()
  789. for i := 0; i < 10000; i++ {
  790. db, err := sql.Open("sqlite3", tempFilename)
  791. if err != nil {
  792. t.Fatal("Failed to open database:", err)
  793. }
  794. for j := 0; j < 3; j++ {
  795. rows, err := db.Query("select * from foo where id=1;")
  796. if err != nil {
  797. t.Error("Failed to call db.Query:", err)
  798. }
  799. for rows.Next() {
  800. var i int
  801. if err := rows.Scan(&i); err != nil {
  802. t.Errorf("Scan failed: %v\n", err)
  803. }
  804. }
  805. if err := rows.Err(); err != nil {
  806. t.Errorf("Post-scan failed: %v\n", err)
  807. }
  808. rows.Close()
  809. }
  810. db.Close()
  811. }
  812. }
  813. func TestDateTimeLocal(t *testing.T) {
  814. zone := "Asia/Tokyo"
  815. tempFilename := TempFilename(t)
  816. defer os.Remove(tempFilename)
  817. db, err := sql.Open("sqlite3", tempFilename+"?_loc="+zone)
  818. if err != nil {
  819. t.Fatal("Failed to open database:", err)
  820. }
  821. db.Exec("CREATE TABLE foo (dt datetime);")
  822. db.Exec("INSERT INTO foo VALUES('2015-03-05 15:16:17');")
  823. row := db.QueryRow("select * from foo")
  824. var d time.Time
  825. err = row.Scan(&d)
  826. if err != nil {
  827. t.Fatal("Failed to scan datetime:", err)
  828. }
  829. if d.Hour() == 15 || !strings.Contains(d.String(), "JST") {
  830. t.Fatal("Result should have timezone", d)
  831. }
  832. db.Close()
  833. db, err = sql.Open("sqlite3", tempFilename)
  834. if err != nil {
  835. t.Fatal("Failed to open database:", err)
  836. }
  837. row = db.QueryRow("select * from foo")
  838. err = row.Scan(&d)
  839. if err != nil {
  840. t.Fatal("Failed to scan datetime:", err)
  841. }
  842. if d.UTC().Hour() != 15 || !strings.Contains(d.String(), "UTC") {
  843. t.Fatalf("Result should not have timezone %v %v", zone, d.String())
  844. }
  845. _, err = db.Exec("DELETE FROM foo")
  846. if err != nil {
  847. t.Fatal("Failed to delete table:", err)
  848. }
  849. dt, err := time.Parse("2006/1/2 15/4/5 -0700 MST", "2015/3/5 15/16/17 +0900 JST")
  850. if err != nil {
  851. t.Fatal("Failed to parse datetime:", err)
  852. }
  853. db.Exec("INSERT INTO foo VALUES(?);", dt)
  854. db.Close()
  855. db, err = sql.Open("sqlite3", tempFilename+"?_loc="+zone)
  856. if err != nil {
  857. t.Fatal("Failed to open database:", err)
  858. }
  859. row = db.QueryRow("select * from foo")
  860. err = row.Scan(&d)
  861. if err != nil {
  862. t.Fatal("Failed to scan datetime:", err)
  863. }
  864. if d.Hour() != 15 || !strings.Contains(d.String(), "JST") {
  865. t.Fatalf("Result should have timezone %v %v", zone, d.String())
  866. }
  867. }
  868. func TestVersion(t *testing.T) {
  869. s, n, id := Version()
  870. if s == "" || n == 0 || id == "" {
  871. t.Errorf("Version failed %q, %d, %q\n", s, n, id)
  872. }
  873. }
  874. func TestNumberNamedParams(t *testing.T) {
  875. tempFilename := TempFilename(t)
  876. defer os.Remove(tempFilename)
  877. db, err := sql.Open("sqlite3", tempFilename)
  878. if err != nil {
  879. t.Fatal("Failed to open database:", err)
  880. }
  881. defer db.Close()
  882. _, err = db.Exec(`
  883. create table foo (id integer, name text, extra text);
  884. `)
  885. if err != nil {
  886. t.Error("Failed to call db.Query:", err)
  887. }
  888. _, err = db.Exec(`insert into foo(id, name, extra) values($1, $2, $2)`, 1, "foo")
  889. if err != nil {
  890. t.Error("Failed to call db.Exec:", err)
  891. }
  892. row := db.QueryRow(`select id, extra from foo where id = $1 and extra = $2`, 1, "foo")
  893. if row == nil {
  894. t.Error("Failed to call db.QueryRow")
  895. }
  896. var id int
  897. var extra string
  898. err = row.Scan(&id, &extra)
  899. if err != nil {
  900. t.Error("Failed to db.Scan:", err)
  901. }
  902. if id != 1 || extra != "foo" {
  903. t.Error("Failed to db.QueryRow: not matched results")
  904. }
  905. }
  906. func TestStringContainingZero(t *testing.T) {
  907. tempFilename := TempFilename(t)
  908. defer os.Remove(tempFilename)
  909. db, err := sql.Open("sqlite3", tempFilename)
  910. if err != nil {
  911. t.Fatal("Failed to open database:", err)
  912. }
  913. defer db.Close()
  914. _, err = db.Exec(`
  915. create table foo (id integer, name, extra text);
  916. `)
  917. if err != nil {
  918. t.Error("Failed to call db.Query:", err)
  919. }
  920. const text = "foo\x00bar"
  921. _, err = db.Exec(`insert into foo(id, name, extra) values($1, $2, $2)`, 1, text)
  922. if err != nil {
  923. t.Error("Failed to call db.Exec:", err)
  924. }
  925. row := db.QueryRow(`select id, extra from foo where id = $1 and extra = $2`, 1, text)
  926. if row == nil {
  927. t.Error("Failed to call db.QueryRow")
  928. }
  929. var id int
  930. var extra string
  931. err = row.Scan(&id, &extra)
  932. if err != nil {
  933. t.Error("Failed to db.Scan:", err)
  934. }
  935. if id != 1 || extra != text {
  936. t.Error("Failed to db.QueryRow: not matched results")
  937. }
  938. }
  939. const CurrentTimeStamp = "2006-01-02 15:04:05"
  940. type TimeStamp struct{ *time.Time }
  941. func (t TimeStamp) Scan(value interface{}) error {
  942. var err error
  943. switch v := value.(type) {
  944. case string:
  945. *t.Time, err = time.Parse(CurrentTimeStamp, v)
  946. case []byte:
  947. *t.Time, err = time.Parse(CurrentTimeStamp, string(v))
  948. default:
  949. err = errors.New("invalid type for current_timestamp")
  950. }
  951. return err
  952. }
  953. func (t TimeStamp) Value() (driver.Value, error) {
  954. return t.Time.Format(CurrentTimeStamp), nil
  955. }
  956. func TestDateTimeNow(t *testing.T) {
  957. tempFilename := TempFilename(t)
  958. defer os.Remove(tempFilename)
  959. db, err := sql.Open("sqlite3", tempFilename)
  960. if err != nil {
  961. t.Fatal("Failed to open database:", err)
  962. }
  963. defer db.Close()
  964. var d time.Time
  965. err = db.QueryRow("SELECT datetime('now')").Scan(TimeStamp{&d})
  966. if err != nil {
  967. t.Fatal("Failed to scan datetime:", err)
  968. }
  969. }
  970. func TestFunctionRegistration(t *testing.T) {
  971. addi_8_16_32 := func(a int8, b int16) int32 { return int32(a) + int32(b) }
  972. addi_64 := func(a, b int64) int64 { return a + b }
  973. addu_8_16_32 := func(a uint8, b uint16) uint32 { return uint32(a) + uint32(b) }
  974. addu_64 := func(a, b uint64) uint64 { return a + b }
  975. addiu := func(a int, b uint) int64 { return int64(a) + int64(b) }
  976. addf_32_64 := func(a float32, b float64) float64 { return float64(a) + b }
  977. not := func(a bool) bool { return !a }
  978. regex := func(re, s string) (bool, error) {
  979. return regexp.MatchString(re, s)
  980. }
  981. generic := func(a interface{}) int64 {
  982. switch a.(type) {
  983. case int64:
  984. return 1
  985. case float64:
  986. return 2
  987. case []byte:
  988. return 3
  989. case string:
  990. return 4
  991. default:
  992. panic("unreachable")
  993. }
  994. }
  995. variadic := func(a, b int64, c ...int64) int64 {
  996. ret := a + b
  997. for _, d := range c {
  998. ret += d
  999. }
  1000. return ret
  1001. }
  1002. variadicGeneric := func(a ...interface{}) int64 {
  1003. return int64(len(a))
  1004. }
  1005. sql.Register("sqlite3_FunctionRegistration", &SQLiteDriver{
  1006. ConnectHook: func(conn *SQLiteConn) error {
  1007. if err := conn.RegisterFunc("addi_8_16_32", addi_8_16_32, true); err != nil {
  1008. return err
  1009. }
  1010. if err := conn.RegisterFunc("addi_64", addi_64, true); err != nil {
  1011. return err
  1012. }
  1013. if err := conn.RegisterFunc("addu_8_16_32", addu_8_16_32, true); err != nil {
  1014. return err
  1015. }
  1016. if err := conn.RegisterFunc("addu_64", addu_64, true); err != nil {
  1017. return err
  1018. }
  1019. if err := conn.RegisterFunc("addiu", addiu, true); err != nil {
  1020. return err
  1021. }
  1022. if err := conn.RegisterFunc("addf_32_64", addf_32_64, true); err != nil {
  1023. return err
  1024. }
  1025. if err := conn.RegisterFunc("not", not, true); err != nil {
  1026. return err
  1027. }
  1028. if err := conn.RegisterFunc("regex", regex, true); err != nil {
  1029. return err
  1030. }
  1031. if err := conn.RegisterFunc("generic", generic, true); err != nil {
  1032. return err
  1033. }
  1034. if err := conn.RegisterFunc("variadic", variadic, true); err != nil {
  1035. return err
  1036. }
  1037. if err := conn.RegisterFunc("variadicGeneric", variadicGeneric, true); err != nil {
  1038. return err
  1039. }
  1040. return nil
  1041. },
  1042. })
  1043. db, err := sql.Open("sqlite3_FunctionRegistration", ":memory:")
  1044. if err != nil {
  1045. t.Fatal("Failed to open database:", err)
  1046. }
  1047. defer db.Close()
  1048. ops := []struct {
  1049. query string
  1050. expected interface{}
  1051. }{
  1052. {"SELECT addi_8_16_32(1,2)", int32(3)},
  1053. {"SELECT addi_64(1,2)", int64(3)},
  1054. {"SELECT addu_8_16_32(1,2)", uint32(3)},
  1055. {"SELECT addu_64(1,2)", uint64(3)},
  1056. {"SELECT addiu(1,2)", int64(3)},
  1057. {"SELECT addf_32_64(1.5,1.5)", float64(3)},
  1058. {"SELECT not(1)", false},
  1059. {"SELECT not(0)", true},
  1060. {`SELECT regex("^foo.*", "foobar")`, true},
  1061. {`SELECT regex("^foo.*", "barfoobar")`, false},
  1062. {"SELECT generic(1)", int64(1)},
  1063. {"SELECT generic(1.1)", int64(2)},
  1064. {`SELECT generic(NULL)`, int64(3)},
  1065. {`SELECT generic("foo")`, int64(4)},
  1066. {"SELECT variadic(1,2)", int64(3)},
  1067. {"SELECT variadic(1,2,3,4)", int64(10)},
  1068. {"SELECT variadic(1,1,1,1,1,1,1,1,1,1)", int64(10)},
  1069. {`SELECT variadicGeneric(1,"foo",2.3, NULL)`, int64(4)},
  1070. }
  1071. for _, op := range ops {
  1072. ret := reflect.New(reflect.TypeOf(op.expected))
  1073. err = db.QueryRow(op.query).Scan(ret.Interface())
  1074. if err != nil {
  1075. t.Errorf("Query %q failed: %s", op.query, err)
  1076. } else if !reflect.DeepEqual(ret.Elem().Interface(), op.expected) {
  1077. t.Errorf("Query %q returned wrong value: got %v (%T), want %v (%T)", op.query, ret.Elem().Interface(), ret.Elem().Interface(), op.expected, op.expected)
  1078. }
  1079. }
  1080. }
  1081. type sumAggregator int64
  1082. func (s *sumAggregator) Step(x int64) {
  1083. *s += sumAggregator(x)
  1084. }
  1085. func (s *sumAggregator) Done() int64 {
  1086. return int64(*s)
  1087. }
  1088. func TestAggregatorRegistration(t *testing.T) {
  1089. customSum := func() *sumAggregator {
  1090. var ret sumAggregator
  1091. return &ret
  1092. }
  1093. sql.Register("sqlite3_AggregatorRegistration", &SQLiteDriver{
  1094. ConnectHook: func(conn *SQLiteConn) error {
  1095. if err := conn.RegisterAggregator("customSum", customSum, true); err != nil {
  1096. return err
  1097. }
  1098. return nil
  1099. },
  1100. })
  1101. db, err := sql.Open("sqlite3_AggregatorRegistration", ":memory:")
  1102. if err != nil {
  1103. t.Fatal("Failed to open database:", err)
  1104. }
  1105. defer db.Close()
  1106. _, err = db.Exec("create table foo (department integer, profits integer)")
  1107. if err != nil {
  1108. t.Fatal("Failed to create table:", err)
  1109. }
  1110. _, err = db.Exec("insert into foo values (1, 10), (1, 20), (2, 42)")
  1111. if err != nil {
  1112. t.Fatal("Failed to insert records:", err)
  1113. }
  1114. tests := []struct {
  1115. dept, sum int64
  1116. }{
  1117. {1, 30},
  1118. {2, 42},
  1119. }
  1120. for _, test := range tests {
  1121. var ret int64
  1122. err = db.QueryRow("select customSum(profits) from foo where department = $1 group by department", test.dept).Scan(&ret)
  1123. if err != nil {
  1124. t.Fatal("Query failed:", err)
  1125. }
  1126. if ret != test.sum {
  1127. t.Fatalf("Custom sum returned wrong value, got %d, want %d", ret, test.sum)
  1128. }
  1129. }
  1130. }
  1131. func TestDeclTypes(t *testing.T) {
  1132. d := SQLiteDriver{}
  1133. conn, err := d.Open(":memory:")
  1134. if err != nil {
  1135. t.Fatal("Failed to begin transaction:", err)
  1136. }
  1137. defer conn.Close()
  1138. sqlite3conn := conn.(*SQLiteConn)
  1139. _, err = sqlite3conn.Exec("create table foo (id integer not null primary key, name text)", nil)
  1140. if err != nil {
  1141. t.Fatal("Failed to create table:", err)
  1142. }
  1143. _, err = sqlite3conn.Exec("insert into foo(name) values(\"bar\")", nil)
  1144. if err != nil {
  1145. t.Fatal("Failed to insert:", err)
  1146. }
  1147. rs, err := sqlite3conn.Query("select * from foo", nil)
  1148. if err != nil {
  1149. t.Fatal("Failed to select:", err)
  1150. }
  1151. defer rs.Close()
  1152. declTypes := rs.(*SQLiteRows).DeclTypes()
  1153. if !reflect.DeepEqual(declTypes, []string{"integer", "text"}) {
  1154. t.Fatal("Unexpected declTypes:", declTypes)
  1155. }
  1156. }
  1157. var customFunctionOnce sync.Once
  1158. func BenchmarkCustomFunctions(b *testing.B) {
  1159. customFunctionOnce.Do(func() {
  1160. custom_add := func(a, b int64) int64 {
  1161. return a + b
  1162. }
  1163. sql.Register("sqlite3_BenchmarkCustomFunctions", &SQLiteDriver{
  1164. ConnectHook: func(conn *SQLiteConn) error {
  1165. // Impure function to force sqlite to reexecute it each time.
  1166. if err := conn.RegisterFunc("custom_add", custom_add, false); err != nil {
  1167. return err
  1168. }
  1169. return nil
  1170. },
  1171. })
  1172. })
  1173. db, err := sql.Open("sqlite3_BenchmarkCustomFunctions", ":memory:")
  1174. if err != nil {
  1175. b.Fatal("Failed to open database:", err)
  1176. }
  1177. defer db.Close()
  1178. b.ResetTimer()
  1179. for i := 0; i < b.N; i++ {
  1180. var i int64
  1181. err = db.QueryRow("SELECT custom_add(1,2)").Scan(&i)
  1182. if err != nil {
  1183. b.Fatal("Failed to run custom add:", err)
  1184. }
  1185. }
  1186. }