go-ssb-room/admindb/sqlite/notices.go

188 lines
4.1 KiB
Go
Raw Normal View History

package sqlite
import (
"context"
"database/sql"
"fmt"
2021-02-23 19:23:50 +00:00
"github.com/friendsofgo/errors"
"github.com/volatiletech/sqlboiler/v4/boil"
2021-02-23 19:23:50 +00:00
"github.com/volatiletech/sqlboiler/v4/queries/qm"
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
"github.com/ssb-ngi-pointer/go-ssb-room/admindb/sqlite/models"
)
// make sure to implement interfaces correctly
var _ admindb.PinnedNoticesService = (*PinnedNotices)(nil)
type PinnedNotices struct {
db *sql.DB
}
2021-02-23 19:23:50 +00:00
// List returns a sortable map of all the pinned notices
func (pn PinnedNotices) List(ctx context.Context) (admindb.PinnedNotices, error) {
// get all the pins and eager-load the related notices
lst, err := models.Pins(qm.Load("Notices")).All(ctx, pn.db)
if err != nil {
return nil, err
}
// prepare a map for them
var pinnedMap = make(admindb.PinnedNotices, len(lst))
for _, entry := range lst {
// skip a pin if it has no entries
noticeCount := len(entry.R.Notices)
if noticeCount == 0 {
continue
}
name := admindb.PinnedNoticeName(entry.Name)
// get the exisint map entry or create a new slice
notices, has := pinnedMap[name]
if !has {
notices = make([]admindb.Notice, 0, noticeCount)
}
// add all the related notice to the slice
for _, n := range entry.R.Notices {
relatedNotice := admindb.Notice{
ID: n.ID,
Title: n.Title,
Content: n.Content,
Language: n.Language,
}
notices = append(notices, relatedNotice)
}
// update the map
pinnedMap[name] = notices
}
return pinnedMap, nil
}
func (pn PinnedNotices) Get(ctx context.Context, name admindb.PinnedNoticeName, lang string) (*admindb.Notice, error) {
p, err := models.Pins(
qm.Where("name = ?", name),
qm.Load("Notices", qm.Where("language = ?", lang)),
).One(ctx, pn.db)
if err != nil {
return nil, err
}
if n := len(p.R.Notices); n != 1 {
return nil, fmt.Errorf("pinnedNotice: expected 1 notice but got %d", n)
}
modelNotice := p.R.Notices[0]
return &admindb.Notice{
ID: modelNotice.ID,
Title: modelNotice.Title,
Content: modelNotice.Content,
Language: modelNotice.Language,
}, nil
}
func (pn PinnedNotices) Set(ctx context.Context, name admindb.PinnedNoticeName, noticeID int64) error {
if !name.Valid() {
2021-02-23 19:23:50 +00:00
return fmt.Errorf("pinned notice: invalid notice name: %s", name)
}
n, err := models.FindNotice(ctx, pn.db, noticeID)
if err != nil {
return err
}
p, err := models.Pins(qm.Where("name = ?", name)).One(ctx, pn.db)
if err != nil {
return err
}
2021-02-23 19:23:50 +00:00
err = p.AddNotices(ctx, pn.db, false, n)
if err != nil {
return err
}
return nil
}
// make sure to implement interfaces correctly
var _ admindb.NoticesService = (*Notices)(nil)
type Notices struct {
db *sql.DB
}
2021-02-23 19:23:50 +00:00
func (n Notices) GetByID(ctx context.Context, id int64) (admindb.Notice, error) {
var notice admindb.Notice
2021-02-23 19:23:50 +00:00
dbEntry, err := models.FindNotice(ctx, n.db, id)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
2021-02-23 19:23:50 +00:00
return notice, admindb.ErrNotFound
}
2021-02-23 19:23:50 +00:00
return notice, err
}
// convert models type to admindb type
2021-02-23 19:23:50 +00:00
notice.ID = dbEntry.ID
notice.Title = dbEntry.Title
notice.Language = dbEntry.Language
notice.Content = dbEntry.Content
2021-02-23 19:23:50 +00:00
return notice, nil
}
2021-02-23 19:23:50 +00:00
func (n Notices) RemoveID(ctx context.Context, id int64) error {
dbEntry, err := models.FindNotice(ctx, n.db, id)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return admindb.ErrNotFound
}
return err
}
2021-02-23 19:23:50 +00:00
_, err = dbEntry.Delete(ctx, n.db)
if err != nil {
return err
}
return nil
}
2021-02-23 19:23:50 +00:00
func (n Notices) Save(ctx context.Context, p *admindb.Notice) error {
if p.ID == 0 {
var newEntry models.Notice
newEntry.Title = p.Title
newEntry.Content = p.Content
newEntry.Language = p.Language
2021-02-23 19:23:50 +00:00
err := newEntry.Insert(ctx, n.db, boil.Whitelist("title", "content", "language"))
if err != nil {
return err
}
p.ID = newEntry.ID
return nil
}
var existing models.Notice
existing.ID = p.ID
existing.Title = p.Title
existing.Content = p.Content
existing.Language = p.Language
2021-02-23 19:23:50 +00:00
_, err := existing.Update(ctx, n.db, boil.Whitelist("title", "content", "language"))
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return admindb.ErrNotFound
}
return err
}
return nil
}