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.

103 lines
2.0 KiB

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