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.

127 lines
2.8 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. issueTasks *issueTaskRepository
  17. items *itemRepository
  18. projects *projectRepository
  19. sessions *sessionRepository
  20. users *userRepository
  21. projectStatuses *projectStatusRepository
  22. }
  23. func (db *DB) Activities() repositories.ActivityRepository {
  24. return db.activities
  25. }
  26. func (db *DB) Issues() repositories.IssueRepository {
  27. return db.issues
  28. }
  29. func (db *DB) IssueTasks() repositories.IssueTaskRepository {
  30. return db.issueTasks
  31. }
  32. func (db *DB) Items() repositories.ItemRepository {
  33. return db.items
  34. }
  35. func (db *DB) Projects() repositories.ProjectRepository {
  36. return db.projects
  37. }
  38. func (db *DB) Session() repositories.SessionRepository {
  39. return db.sessions
  40. }
  41. func (db *DB) Users() repositories.UserRepository {
  42. return db.users
  43. }
  44. func (db *DB) ProjectStatuses() repositories.ProjectStatusRepository {
  45. return db.projectStatuses
  46. }
  47. func (db *DB) Migrate() error {
  48. err := goose.SetDialect("mysql")
  49. if err != nil {
  50. return err
  51. }
  52. return goose.Up(db.db.DB, "migrations/mysql")
  53. }
  54. func Open(connectionString string) (*DB, error) {
  55. // Ensure parseTime is true
  56. qpos := strings.LastIndexByte(connectionString, '?')
  57. if qpos != -1 {
  58. connectionString += "&parseTime=true"
  59. } else {
  60. connectionString += "?parseTime=true"
  61. }
  62. // Connect to the database
  63. db, err := sqlx.Connect("mysql", connectionString)
  64. if err != nil {
  65. return nil, err
  66. }
  67. // Test the connection
  68. err = db.Ping()
  69. if err != nil {
  70. return nil, err
  71. }
  72. // Setup repositories
  73. activities := &activityRepository{db: db}
  74. issues := &issueRepository{db: db}
  75. items := &itemRepository{db: db}
  76. projects := &projectRepository{db: db}
  77. users := &userRepository{db: db}
  78. sessions := &sessionRepository{db: db}
  79. projectStatuses := &projectStatusRepository{db: db}
  80. issueTasks := &issueTaskRepository{db: db}
  81. return &DB{
  82. db: db,
  83. activities: activities,
  84. issues: issues,
  85. issueTasks: issueTasks,
  86. items: items,
  87. projects: projects,
  88. users: users,
  89. sessions: sessions,
  90. projectStatuses: projectStatuses,
  91. }, nil
  92. }
  93. func incCounter(ctx context.Context, tx *sqlx.Tx, kind, name string) (int, error) {
  94. value := 1
  95. err := tx.GetContext(ctx, &value, `
  96. SELECT value FROM counters WHERE kind=? AND name=? FOR UPDATE
  97. `, kind, name)
  98. if err != nil && err != sql.ErrNoRows {
  99. return -1, err
  100. }
  101. _, err = tx.ExecContext(ctx, "REPLACE INTO counters (kind, name, value) VALUES (?, ?, ?)", kind, name, value+1)
  102. if err != nil {
  103. return -1, err
  104. }
  105. return value, nil
  106. }