diff options
| author | Xe Iaso <me@xeiaso.net> | 2024-05-20 08:31:18 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2024-05-20 08:31:26 -0400 |
| commit | 62fe9bdef194158ca9bb9d57e56872d2d73d121b (patch) | |
| tree | 88a66b33e576a542a60d0ee60fe07596a40d7ef0 /cmd/mi/models | |
| parent | 1d407f9d6170b535d1174ca73dfaa022d2e3d0c5 (diff) | |
| download | x-62fe9bdef194158ca9bb9d57e56872d2d73d121b.tar.xz x-62fe9bdef194158ca9bb9d57e56872d2d73d121b.zip | |
cmd/mi: move front tracking to a shim
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd/mi/models')
| -rw-r--r-- | cmd/mi/models/dao.go | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/cmd/mi/models/dao.go b/cmd/mi/models/dao.go new file mode 100644 index 0000000..9830bfe --- /dev/null +++ b/cmd/mi/models/dao.go @@ -0,0 +1,112 @@ +package models + +import ( + "context" + "crypto/rand" + "errors" + "time" + + "github.com/oklog/ulid/v2" + "gorm.io/gorm" +) + +var ( + ErrCantSwitchToYourself = errors.New("models: you can't switch to yourself") +) + +type DAO struct { + db *gorm.DB +} + +func New(db *gorm.DB) *DAO { + return &DAO{db: db} +} + +func (d *DAO) Members(ctx context.Context) ([]Member, error) { + var result []Member + if err := d.db.WithContext(ctx).Find(&result).Error; err != nil { + return nil, err + } + + return result, nil +} + +func (d *DAO) WhoIsFront(ctx context.Context) (*Switch, error) { + var sw Switch + if err := d.db.Joins("Member").Order("created_at DESC").First(&sw).Error; err != nil { + return nil, err + } + + return &sw, nil +} + +func (d *DAO) SwitchFront(ctx context.Context, memberName string) (*Switch, *Switch, error) { + var old Switch + tx := d.db.Begin() + + if err := tx.WithContext(ctx).Joins("Member").Where("ended_at IS NULL").First(&old).Error; err != nil { + tx.Rollback() + return nil, nil, err + } + + if old.Member.Name == memberName { + tx.WithContext(ctx).Rollback() + return nil, nil, ErrCantSwitchToYourself + } + + now := time.Now() + old.EndedAt = &now + if err := tx.WithContext(ctx).Save(&old).Error; err != nil { + tx.Rollback() + return nil, nil, err + } + + var newMember Member + if err := tx.WithContext(ctx).Where("name = ?", memberName).First(&newMember).Error; err != nil { + tx.Rollback() + return nil, nil, err + } + + new := Switch{ + ID: ulid.MustNew(ulid.Now(), rand.Reader).String(), + MemberID: newMember.ID, + } + + if err := tx.WithContext(ctx).Create(&new).Error; err != nil { + tx.Rollback() + return nil, nil, err + } + + if err := tx.WithContext(ctx).Commit().Error; err != nil { + tx.Rollback() + return nil, nil, err + } + + return &old, &new, nil +} + +func (d *DAO) GetSwitch(ctx context.Context, id string) (*Switch, error) { + var sw Switch + if err := d.db.WithContext(ctx). + Joins("Member"). + Where("id = ?", id). + First(&sw).Error; err != nil { + return nil, err + } + + return &sw, nil +} + +func (d *DAO) ListSwitches(ctx context.Context, count, page int) ([]Switch, error) { + var switches []Switch + if err := d.db.WithContext(ctx). + Joins("Member"). + Order("rowid DESC"). + Limit(count). + Offset(count * page). + Find(&switches).Error; err != nil { + return nil, err + } + + return switches, nil +} |
