From e36b49a31e145c2d0d9e9e23afa284bcb92e22c3 Mon Sep 17 00:00:00 2001 From: Quaternions <krakow20@gmail.com> Date: Mon, 31 Mar 2025 16:00:23 -0700 Subject: [PATCH] submissions: datastore: duplicate submissions as mapfixes --- pkg/datastore/datastore.go | 12 +++ pkg/datastore/gormstore/gormstore.go | 4 + pkg/datastore/gormstore/mapfixes.go | 132 +++++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 pkg/datastore/gormstore/mapfixes.go diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index 8a256b1..1cc3f48 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -22,11 +22,23 @@ const ( ) type Datastore interface { + Mapfixes() Mapfixes Submissions() Submissions Scripts() Scripts ScriptPolicy() ScriptPolicy } +type Mapfixes interface { + Get(ctx context.Context, id int64) (model.Mapfix, error) + GetList(ctx context.Context, id []int64) ([]model.Mapfix, error) + Create(ctx context.Context, smap model.Mapfix) (model.Mapfix, error) + Update(ctx context.Context, id int64, values OptionalMap) error + IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.MapfixStatus, values OptionalMap) error + IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.MapfixStatus, values OptionalMap) (model.Mapfix, error) + Delete(ctx context.Context, id int64) error + List(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) ([]model.Mapfix, error) +} + type Submissions interface { Get(ctx context.Context, id int64) (model.Submission, error) GetList(ctx context.Context, id []int64) ([]model.Submission, error) diff --git a/pkg/datastore/gormstore/gormstore.go b/pkg/datastore/gormstore/gormstore.go index 6b1f9d9..da16895 100644 --- a/pkg/datastore/gormstore/gormstore.go +++ b/pkg/datastore/gormstore/gormstore.go @@ -9,6 +9,10 @@ type Gormstore struct { db *gorm.DB } +func (g Gormstore) Mapfixes() datastore.Mapfixes { + return &Mapfixes{db: g.db} +} + func (g Gormstore) Submissions() datastore.Submissions { return &Submissions{db: g.db} } diff --git a/pkg/datastore/gormstore/mapfixes.go b/pkg/datastore/gormstore/mapfixes.go new file mode 100644 index 0000000..d80067e --- /dev/null +++ b/pkg/datastore/gormstore/mapfixes.go @@ -0,0 +1,132 @@ +package gormstore + +import ( + "context" + "errors" + + "git.itzana.me/strafesnet/maps-service/pkg/datastore" + "git.itzana.me/strafesnet/maps-service/pkg/model" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +type Mapfixes struct { + db *gorm.DB +} + +func (env *Mapfixes) Get(ctx context.Context, id int64) (model.Mapfix, error) { + var mapfix model.Mapfix + if err := env.db.First(&mapfix, id).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return mapfix, datastore.ErrNotExist + } + return mapfix, err + } + return mapfix, nil +} + +func (env *Mapfixes) GetList(ctx context.Context, id []int64) ([]model.Mapfix, error) { + var mapList []model.Mapfix + if err := env.db.Find(&mapList, "id IN ?", id).Error; err != nil { + return mapList, err + } + + return mapList, nil +} + +func (env *Mapfixes) Create(ctx context.Context, smap model.Mapfix) (model.Mapfix, error) { + if err := env.db.Create(&smap).Error; err != nil { + return smap, err + } + + return smap, nil +} + +func (env *Mapfixes) Update(ctx context.Context, id int64, values datastore.OptionalMap) error { + if err := env.db.Model(&model.Mapfix{}).Where("id = ?", id).Updates(values.Map()).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return datastore.ErrNotExist + } + return err + } + + return nil +} + +// the update can only occur if the status matches one of the provided values. +func (env *Mapfixes) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.MapfixStatus, values datastore.OptionalMap) error { + if err := env.db.Model(&model.Mapfix{}).Where("id = ?", id).Where("status_id IN ?", statuses).Updates(values.Map()).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return datastore.ErrNotExist + } + return err + } + + return nil +} + +// the update can only occur if the status matches one of the provided values. +// returns the updated value +func (env *Mapfixes) IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.MapfixStatus, values datastore.OptionalMap) (model.Mapfix, error) { + var mapfix model.Mapfix + result := env.db.Model(&mapfix). + Clauses(clause.Returning{}). + Where("id = ?", id). + Where("status_id IN ?", statuses). + Updates(values.Map()) + if result.Error != nil { + if result.Error == gorm.ErrRecordNotFound { + return mapfix, datastore.ErrNotExist + } + return mapfix, result.Error + } + + if result.RowsAffected == 0 { + return mapfix, datastore.ErroNoRowsAffected + } + + return mapfix, nil +} + +func (env *Mapfixes) Delete(ctx context.Context, id int64) error { + if err := env.db.Delete(&model.Mapfix{}, id).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return datastore.ErrNotExist + } + return err + } + + return nil +} + +func (env *Mapfixes) List(ctx context.Context, filters datastore.OptionalMap, page model.Page, sort datastore.ListSort) ([]model.Mapfix, error) { + var maps []model.Mapfix + + db := env.db + + switch sort { + case datastore.ListSortDisabled: + // No sort + break + case datastore.ListSortDisplayNameAscending: + db=db.Order("display_name ASC") + break + case datastore.ListSortDisplayNameDescending: + db=db.Order("display_name DESC") + break + case datastore.ListSortDateAscending: + db=db.Order("created_at ASC") + break + case datastore.ListSortDateDescending: + db=db.Order("created_at DESC") + break + default: + return nil, datastore.ErrInvalidListSort + } + + if err := db.Where(filters.Map()).Offset(int((page.Number - 1) * page.Size)).Limit(int(page.Size)).Find(&maps).Error; err != nil { + return nil, err + } + + return maps, nil +}