stufflog graphql server
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.

119 lines
2.6 KiB

5 years ago
5 years ago
5 years ago
5 years ago
  1. package mysqldriver
  2. import (
  3. "context"
  4. "database/sql"
  5. "git.aiterp.net/stufflog/server/database/repositories"
  6. "github.com/jmoiron/sqlx"
  7. "github.com/pressly/goose"
  8. "strings"
  9. // Mysql Driver
  10. _ "github.com/go-sql-driver/mysql"
  11. )
  12. type DB struct {
  13. db *sqlx.DB
  14. activities *activityRepository
  15. issues *issueRepository
  16. items *itemRepository
  17. projects *projectRepository
  18. sessions *sessionRepository
  19. users *userRepository
  20. projectStatuses *projectStatusRepository
  21. }
  22. func (db *DB) Activities() repositories.ActivityRepository {
  23. return db.activities
  24. }
  25. func (db *DB) Issues() repositories.IssueRepository {
  26. return db.issues
  27. }
  28. func (db *DB) Items() repositories.ItemRepository {
  29. return db.items
  30. }
  31. func (db *DB) Projects() repositories.ProjectRepository {
  32. return db.projects
  33. }
  34. func (db *DB) Session() repositories.SessionRepository {
  35. return db.sessions
  36. }
  37. func (db *DB) Users() repositories.UserRepository {
  38. return db.users
  39. }
  40. func (db *DB) ProjectStatuses() repositories.ProjectStatusRepository {
  41. return db.projectStatuses
  42. }
  43. func (db *DB) Migrate() error {
  44. err := goose.SetDialect("mysql")
  45. if err != nil {
  46. return err
  47. }
  48. return goose.Up(db.db.DB, "migrations/mysql")
  49. }
  50. func Open(connectionString string) (*DB, error) {
  51. // Ensure parseTime is true
  52. qpos := strings.LastIndexByte(connectionString, '?')
  53. if qpos != -1 {
  54. connectionString += "&parseTime=true"
  55. } else {
  56. connectionString += "?parseTime=true"
  57. }
  58. // Connect to the database
  59. db, err := sqlx.Connect("mysql", connectionString)
  60. if err != nil {
  61. return nil, err
  62. }
  63. // Test the connection
  64. err = db.Ping()
  65. if err != nil {
  66. return nil, err
  67. }
  68. activities := &activityRepository{db: db}
  69. issues := &issueRepository{db: db}
  70. items := &itemRepository{db: db}
  71. projects := &projectRepository{db: db}
  72. users := &userRepository{db: db}
  73. sessions := &sessionRepository{db: db}
  74. projectStatuses := &projectStatusRepository{db: db}
  75. return &DB{
  76. db: db,
  77. activities: activities,
  78. issues: issues,
  79. items: items,
  80. projects: projects,
  81. users: users,
  82. sessions: sessions,
  83. projectStatuses: projectStatuses,
  84. }, nil
  85. }
  86. func incCounter(ctx context.Context, tx *sqlx.Tx, kind, name string) (int, error) {
  87. value := 1
  88. err := tx.GetContext(ctx, &value, `
  89. SELECT value FROM counters WHERE kind=? AND name=? FOR UPDATE
  90. `, kind, name)
  91. if err != nil && err != sql.ErrNoRows {
  92. return -1, err
  93. }
  94. _, err = tx.ExecContext(ctx, "REPLACE INTO counters (kind, name, value) VALUES (?, ?, ?)", kind, name, value+1)
  95. if err != nil {
  96. return -1, err
  97. }
  98. return value, nil
  99. }