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.
141 lines
3.2 KiB
141 lines
3.2 KiB
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
|
|
activities *activityRepository
|
|
issues *issueRepository
|
|
issueTasks *issueTaskRepository
|
|
issueItems *issueItemRepository
|
|
items *itemRepository
|
|
projects *projectRepository
|
|
sessions *sessionRepository
|
|
users *userRepository
|
|
projectStatuses *projectStatusRepository
|
|
logs *logRepository
|
|
}
|
|
|
|
func (db *DB) Activities() repositories.ActivityRepository {
|
|
return db.activities
|
|
}
|
|
|
|
func (db *DB) Issues() repositories.IssueRepository {
|
|
return db.issues
|
|
}
|
|
|
|
func (db *DB) IssueTasks() repositories.IssueTaskRepository {
|
|
return db.issueTasks
|
|
}
|
|
|
|
func (db *DB) IssueItems() repositories.IssueItemRepository {
|
|
return db.issueItems
|
|
}
|
|
|
|
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) ProjectStatuses() repositories.ProjectStatusRepository {
|
|
return db.projectStatuses
|
|
}
|
|
|
|
func (db *DB) Logs() repositories.LogRepository {
|
|
return db.logs
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
// Setup repositories
|
|
activities := &activityRepository{db: db}
|
|
issues := &issueRepository{db: db}
|
|
items := &itemRepository{db: db}
|
|
projects := &projectRepository{db: db}
|
|
users := &userRepository{db: db}
|
|
sessions := &sessionRepository{db: db}
|
|
projectStatuses := &projectStatusRepository{db: db}
|
|
issueTasks := &issueTaskRepository{db: db}
|
|
issueItems := &issueItemRepository{db: db}
|
|
logs := &logRepository{db: db}
|
|
|
|
return &DB{
|
|
db: db,
|
|
activities: activities,
|
|
issues: issues,
|
|
issueTasks: issueTasks,
|
|
issueItems: issueItems,
|
|
items: items,
|
|
projects: projects,
|
|
users: users,
|
|
sessions: sessions,
|
|
projectStatuses: projectStatuses,
|
|
logs: logs,
|
|
}, 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
|
|
}
|