storage.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. The "storage" package in Kurz provides the data model.
  3. In its current implementation:
  4. - it is specific to MySQL/MariaDB and compatibles SQL engines.
  5. - data model and data access are not isolated
  6. - it assumes the DB has been initialized by importing the data/db-schema.sql file
  7. - it initializes the connection info based on the "dsn" CLI flag
  8. */
  9. package storage
  10. /**
  11. TODO use a CLI flag to clear the database on init
  12. TODO use a CLI flag to install the database schema
  13. */
  14. import (
  15. "database/sql"
  16. "flag"
  17. _ "github.com/go-sql-driver/mysql"
  18. "log"
  19. )
  20. type Storage struct {
  21. DB *sql.DB
  22. DSN string
  23. truncateList []string
  24. }
  25. var Service Storage = Storage{}
  26. /*
  27. Open() established the database connection, making sure it is actually available instead of just preparing the connection info.
  28. */
  29. func (s *Storage) Open() error {
  30. var err error
  31. s.DB, err = sql.Open("mysql", s.DSN)
  32. if err == nil {
  33. err = s.DB.Ping()
  34. }
  35. return err
  36. }
  37. /*
  38. Close() closes the database connection and releases its information.
  39. */
  40. func (s *Storage) Close() {
  41. if s.DB != nil {
  42. for _, name := range s.truncateList {
  43. s.Truncate(name)
  44. }
  45. s.DB.Close()
  46. }
  47. s.DB = nil
  48. }
  49. func (s *Storage) AddToTruncateList(name string) {
  50. s.truncateList = append(s.truncateList, name)
  51. }
  52. func (s *Storage) Truncate(name string) {
  53. if s.DB == nil {
  54. panic("Cannot truncate a non-connected database.")
  55. }
  56. // Cannot use truncate on a master table (longurl vs shorturl) with MySQL.
  57. _, err := s.DB.Exec("DELETE FROM " + name)
  58. if err != nil {
  59. log.Printf("Error truncating %s: %+v\n", name, err)
  60. }
  61. }
  62. /*
  63. SetDSN() sets the DSN information for the storage.
  64. */
  65. func (s *Storage) SetDSN(dsn string) {
  66. s.DSN = dsn
  67. }
  68. type StorageController interface {
  69. Table() string
  70. }
  71. /*
  72. init() initializes the storage information from the command-line flag "dsn".
  73. */
  74. func init() {
  75. var dsn = flag.String("dsn", "root:@tcp(localhost:3306)/go_kurz", "some_user:some_pass@tcp(some_host:some_port)/some_db")
  76. flag.Parse()
  77. Service.SetDSN(*dsn)
  78. }