aboutsummaryrefslogtreecommitdiff
path: root/cmd/mi/models
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2024-05-20 08:31:18 -0400
committerXe Iaso <me@xeiaso.net>2024-05-20 08:31:26 -0400
commit62fe9bdef194158ca9bb9d57e56872d2d73d121b (patch)
tree88a66b33e576a542a60d0ee60fe07596a40d7ef0 /cmd/mi/models
parent1d407f9d6170b535d1174ca73dfaa022d2e3d0c5 (diff)
downloadx-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.go112
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
+}