sqlite_concurrent_demo.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package main
  2. import (
  3. "database/sql"
  4. "log"
  5. "os"
  6. "strconv"
  7. "sync"
  8. "time"
  9. _ "github.com/mattn/go-sqlite3"
  10. )
  11. const (
  12. File = "demo.db"
  13. // DSN points to a local DB file without cache enabled.
  14. DSN = "file:" + File
  15. )
  16. func setup() {
  17. _ = os.Remove(File)
  18. db, err := sql.Open("sqlite3", DSN)
  19. if err != nil {
  20. log.Fatalf("open: %v", err)
  21. }
  22. defer func() {
  23. _ = db.Close()
  24. log.Println("finishing setup")
  25. }()
  26. if _, err = db.Exec(`
  27. CREATE TABLE foo (
  28. id SERIAL PRIMARY KEY,
  29. description VARCHAR(255)
  30. );
  31. `); err != nil {
  32. log.Fatalf("creating schema: %v", err)
  33. }
  34. }
  35. func ping(wg *sync.WaitGroup, id int, start, linger time.Duration) {
  36. logger := log.New(os.Stderr, "("+strconv.Itoa(id)+") ", log.LstdFlags)
  37. defer func() {
  38. wg.Done()
  39. }()
  40. time.Sleep(start)
  41. db, err := sql.Open("sqlite3", DSN)
  42. if err != nil {
  43. logger.Fatalf("open: %v", err)
  44. }
  45. logger.Println("open: OK")
  46. res, err := db.Exec(`
  47. INSERT INTO foo(id, description)
  48. VALUES (?, ?)
  49. `, id, strconv.Itoa(id))
  50. if err != nil {
  51. logger.Fatalf("insert: %v", err)
  52. } else {
  53. ra, _ := res.RowsAffected()
  54. last, _ := res.LastInsertId()
  55. logger.Printf("inserted count %d / last %d", ra, last)
  56. }
  57. row := db.QueryRow(`
  58. SELECT COUNT(id)
  59. FROM foo
  60. `)
  61. count := 0
  62. if err = row.Scan(&count); err != nil {
  63. logger.Fatalf("scanning: %v", err)
  64. }
  65. logger.Printf("select %d rows: OK", count)
  66. time.Sleep(linger)
  67. if err := db.Close(); err != nil {
  68. logger.Fatalf("close: %v", err)
  69. }
  70. logger.Println("close: OK")
  71. }
  72. func main() {
  73. setup()
  74. wg := sync.WaitGroup{}
  75. wg.Add(2)
  76. go ping(&wg, 1, 0, 2*time.Second)
  77. go ping(&wg, 2, time.Second, 0)
  78. wg.Wait()
  79. log.Println("all done")
  80. }