PageRenderTime 1421ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/service/database/connection.go

https://gitlab.com/mikattack/linksink
Go | 107 lines | 65 code | 18 blank | 24 comment | 16 complexity | 339a21912c04e1cefafe4aed5a5ae1b5 MD5 | raw file
  1. package database
  2. import (
  3. "fmt"
  4. "strings"
  5. _ "github.com/mattn/go-sqlite3"
  6. "github.com/jmoiron/sqlx"
  7. )
  8. const FALLBACK_DB_FILE string = "./linksink.db"
  9. const DEFAULT_IDLE_CONNECTIONS int = 10
  10. const DEFAULT_OPEN_CONNECTIONS int = 10
  11. const DEFAULT_LIMIT int = 100
  12. var connection *sqlx.DB
  13. /*
  14. * Initializes a SQLite database
  15. */
  16. func InitializeDatabasePool(path string) (*sqlx.DB, error) {
  17. if connection != nil {
  18. return connection, nil
  19. }
  20. path = strings.TrimSpace(path)
  21. if len(path) == 0 {
  22. path = FALLBACK_DB_FILE
  23. }
  24. // Open database file
  25. db, err := sqlx.Open("sqlite3", path)
  26. if err != nil {
  27. return connection, err
  28. }
  29. // Initialize schema
  30. stmt := `
  31. CREATE TABLE IF NOT EXISTS links (
  32. id integer primary key,
  33. created DATETIME DEFAULT CURRENT_TIMESTAMP,
  34. label TEXT,
  35. href TEXT
  36. );
  37. `
  38. if _, err := db.Exec(stmt); err != nil {
  39. return connection, err
  40. }
  41. db.SetMaxIdleConns(DEFAULT_IDLE_CONNECTIONS)
  42. db.SetMaxOpenConns(DEFAULT_OPEN_CONNECTIONS)
  43. connection = db
  44. return connection, nil
  45. }
  46. /*
  47. * Return cached pool information and/or initialize a database at the
  48. * default file path.
  49. */
  50. func GetConnection() (*sqlx.DB, error) {
  51. return InitializeDatabasePool("")
  52. }
  53. /*
  54. * Conventience wrapper for executing transactions.
  55. *
  56. * Example:
  57. * func (s Service) DoSomething() error {
  58. * return Transaction(func (tx *sqlx.Tx) error {
  59. * if _, err := tx.Exec(...); err != nil {
  60. * return err
  61. * }
  62. * if _, err := tx.Exec(...); err != nil {
  63. * return err
  64. * }
  65. * })
  66. * }
  67. */
  68. func Transaction(fn func(*sqlx.Tx) error) (error) {
  69. tx, err := connection.Beginx()
  70. if err != nil {
  71. return err
  72. }
  73. defer func() {
  74. if p := recover(); p != nil {
  75. switch p := p.(type) {
  76. case error:
  77. err = p
  78. default:
  79. err = fmt.Errorf("%s", p)
  80. }
  81. }
  82. if err != nil {
  83. tx.Rollback()
  84. return
  85. }
  86. err = tx.Commit()
  87. }()
  88. return fn(tx)
  89. }