|
|
package mysqldriver
import ( "context" "database/sql" "git.aiterp.net/stufflog/server/database/repositories" "github.com/jmoiron/sqlx" "github.com/pressly/goose" "strings"
// Mysql Driver
_ "github.com/go-sql-driver/mysql" )
type DB struct { db *sqlx.DB issues *issueRepository items *itemRepository projects *projectRepository sessions *sessionRepository users *userRepository }
func (db *DB) Issues() repositories.IssueRepository { return db.issues }
func (db *DB) Items() repositories.ItemRepository { return db.items }
func (db *DB) Projects() repositories.ProjectRepository { return db.projects }
func (db *DB) Session() repositories.SessionRepository { return db.sessions }
func (db *DB) Users() repositories.UserRepository { return db.users }
func (db *DB) Migrate() error { err := goose.SetDialect("mysql") if err != nil { return err }
return goose.Up(db.db.DB, "migrations/mysql") }
func Open(connectionString string) (*DB, error) { // Ensure parseTime is true
qpos := strings.LastIndexByte(connectionString, '?') if qpos != -1 { connectionString += "&parseTime=true" } else { connectionString += "?parseTime=true" }
// Connect to the database
db, err := sqlx.Connect("mysql", connectionString) if err != nil { return nil, err }
// Test the connection
err = db.Ping() if err != nil { return nil, err }
issues := &issueRepository{db: db} items := &itemRepository{db: db} projects := &projectRepository{db: db} users := &userRepository{db: db}
return &DB{ db: db, issues: issues, items: items, projects: projects, users: users, }, nil }
func incCounter(ctx context.Context, tx *sqlx.Tx, kind, name string) (int, error) { value := 1 err := tx.GetContext(ctx, &value, ` SELECT value FROM counters WHERE kind=? AND name=? FOR UPDATE `, kind, name) if err != nil && err != sql.ErrNoRows { return -1, err }
_, err = tx.ExecContext(ctx, "REPLACE INTO counters (kind, name, value) VALUES (?, ?, ?)", kind, name, value+1) if err != nil { return -1, err }
return value, nil }
|