package models import ( "context" "database/sql" "fmt" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect/sqlitedialect" "github.com/uptrace/bun/driver/sqliteshim" ) type Persistence interface { CreateCapture(context.Context, *Capture) error UpdateCapture(context.Context, *Capture) error GetCaptures(context.Context) ([]Capture, error) GetCapturesByID(context.Context, int64) (*Capture, error) DeleteCapture(context.Context, int64) error GetRecentMapScore(context.Context, int64) (*MapScore, error) SetMapScoreConted(context.Context, int64, bool) error CreateMapScore(context.Context, *MapScore) error CreateOrUpdateScores(context.Context, []Score) error } type SQLitePersistence struct { db *bun.DB } func NewSQLitePersistence(dbloc string) (*SQLitePersistence, error) { sqldb, err := sql.Open(sqliteshim.ShimName, fmt.Sprintf("file:%s", dbloc)) if err != nil { return nil, err } db := bun.NewDB(sqldb, sqlitedialect.New()) ctx := context.Background() for _, model := range []interface{}{(*Capture)(nil), (*MapScore)(nil), (*Score)(nil)} { _, err := db.NewCreateTable().Model(model).IfNotExists().Exec(ctx) if err != nil { return nil, err } } return &SQLitePersistence{ db, }, nil } func (s *SQLitePersistence) GetCaptures(ctx context.Context) ([]Capture, error) { var captures []Capture err := s.db.NewSelect().Model(&captures).Scan(ctx) if err != nil { return nil, err } return captures, nil } func (s *SQLitePersistence) GetCapturesByID(ctx context.Context, id int64) (*Capture, error) { capture := Capture{ ID: id, } err := s.db.NewSelect().Model(&capture).WherePK().Relation("MapScores").Relation("MapScores.ScoreList").Scan(ctx) return &capture, err } func (s *SQLitePersistence) UpdateCapture(ctx context.Context, capture *Capture) error { _, err := s.db.NewUpdate().Model(capture).WherePK().Exec(ctx) return err } func (s *SQLitePersistence) DeleteCapture(ctx context.Context, id int64) error { capture := Capture{ ID: id, } _, err := s.db.NewDelete().Model(&capture).WherePK().Exec(ctx) return err } func (s *SQLitePersistence) CreateCapture(ctx context.Context, capture *Capture) error { _, err := s.db.NewInsert().Model(capture).Exec(ctx) return err } func (s *SQLitePersistence) GetRecentMapScore(ctx context.Context, captureid int64) (*MapScore, error) { var scores []MapScore err := s.db.NewSelect().Model(&scores).Where("capture_id = ?", captureid).Limit(1).Order("start_time DESC").Scan(ctx) if err != nil { return nil, err } if len(scores) <= 0 { return nil, nil } return &scores[0], nil } func (s *SQLitePersistence) SetMapScoreConted(ctx context.Context, mapscoreid int64, counted bool) error { mapscore := MapScore{ ID: mapscoreid, } _, err := s.db.NewUpdate().Model(&mapscore).WherePK().Set("counted = ?", counted).Exec(ctx) return err } func (s *SQLitePersistence) CreateMapScore(ctx context.Context, mapscore *MapScore) error { _, err := s.db.NewInsert().Model(mapscore).Exec(ctx) return err } func (s *SQLitePersistence) CreateOrUpdateScores(ctx context.Context, scores []Score) error { _, err := s.db.NewInsert().Model(&scores).On("CONFLICT (name, mapscore_id) DO UPDATE").Exec(ctx) return err }