gte/internal/storage/remote.go

159 lines
3.3 KiB
Go
Raw Normal View History

2021-06-25 09:14:27 +02:00
package storage
2021-01-29 12:29:23 +01:00
import (
"errors"
"fmt"
2021-01-30 15:25:25 +01:00
"strconv"
2021-01-29 12:29:23 +01:00
2021-06-25 09:14:27 +02:00
"git.ewintr.nl/gte/internal/task"
2021-05-13 09:47:06 +02:00
"git.ewintr.nl/gte/pkg/mstore"
2021-01-29 12:29:23 +01:00
)
var (
2021-01-30 11:20:12 +01:00
ErrMStoreError = errors.New("mstore gave error response")
ErrInvalidTask = errors.New("invalid task")
ErrInvalidMessage = errors.New("task contains invalid message")
2021-01-29 12:29:23 +01:00
)
2021-06-25 07:48:58 +02:00
type RemoteRepository struct {
2021-01-29 12:29:23 +01:00
mstore mstore.MStorer
}
2021-06-25 08:33:14 +02:00
func NewRemoteRepository(ms mstore.MStorer) *RemoteRepository {
2021-06-25 07:48:58 +02:00
return &RemoteRepository{
2021-01-29 12:29:23 +01:00
mstore: ms,
}
}
2021-06-25 09:14:27 +02:00
func (rr *RemoteRepository) FindAll(folder string) ([]*task.Task, error) {
2021-06-25 07:48:58 +02:00
msgs, err := rr.mstore.Messages(folder)
2021-01-29 12:29:23 +01:00
if err != nil {
2021-06-25 09:14:27 +02:00
return []*task.Task{}, fmt.Errorf("%w: %v", ErrMStoreError, err)
2021-01-29 12:29:23 +01:00
}
2021-06-25 09:14:27 +02:00
tasks := []*task.Task{}
2021-01-29 12:29:23 +01:00
for _, msg := range msgs {
if msg.Valid() {
2021-06-25 09:14:27 +02:00
tasks = append(tasks, task.NewFromMessage(msg))
2021-01-29 12:29:23 +01:00
}
}
return tasks, nil
}
2021-06-25 09:14:27 +02:00
func (rr *RemoteRepository) Update(t *task.Task) error {
2021-01-30 11:20:12 +01:00
if t == nil {
return ErrInvalidTask
}
2021-01-29 12:29:23 +01:00
// add new
2021-06-25 07:48:58 +02:00
if err := rr.Add(t); err != nil {
2021-05-13 08:15:14 +02:00
return err
2021-01-29 12:29:23 +01:00
}
// remove old
2021-06-25 07:48:58 +02:00
if err := rr.mstore.Remove(t.Message); err != nil {
2021-01-29 12:29:23 +01:00
return fmt.Errorf("%w: %s", ErrMStoreError, err)
}
return nil
}
2021-01-29 19:40:46 +01:00
2021-06-25 09:14:27 +02:00
func (rr *RemoteRepository) Add(t *task.Task) error {
2021-05-13 08:15:14 +02:00
if t == nil {
return ErrInvalidTask
}
2021-06-04 10:45:56 +02:00
msg := t.NextMessage()
2021-06-25 07:48:58 +02:00
if err := rr.mstore.Add(msg.Folder, msg.Subject, msg.Body); err != nil {
2021-05-13 08:15:14 +02:00
return fmt.Errorf("%w: %v", ErrMStoreError, err)
}
return nil
}
2021-01-29 19:40:46 +01:00
// Cleanup removes older versions of tasks
2021-06-25 07:48:58 +02:00
func (rr *RemoteRepository) CleanUp() error {
2021-01-30 15:25:25 +01:00
// loop through folders, get all task version info
type msgInfo struct {
Version int
Message *mstore.Message
}
msgsSet := make(map[string][]msgInfo)
2021-01-29 19:40:46 +01:00
2021-06-25 09:14:27 +02:00
for _, folder := range task.KnownFolders {
2021-06-25 07:48:58 +02:00
msgs, err := rr.mstore.Messages(folder)
2021-01-29 19:40:46 +01:00
if err != nil {
2021-01-30 15:25:25 +01:00
return fmt.Errorf("%w: %v", ErrMStoreError, err)
2021-01-29 19:40:46 +01:00
}
2021-01-30 15:25:25 +01:00
for _, msg := range msgs {
2021-06-25 09:14:27 +02:00
id, _ := task.FieldFromBody(task.FIELD_ID, msg.Body)
versionStr, _ := task.FieldFromBody(task.FIELD_VERSION, msg.Body)
2021-01-30 15:25:25 +01:00
version, _ := strconv.Atoi(versionStr)
if _, ok := msgsSet[id]; !ok {
msgsSet[id] = []msgInfo{}
2021-01-29 19:40:46 +01:00
}
2021-01-30 15:25:25 +01:00
msgsSet[id] = append(msgsSet[id], msgInfo{
Version: version,
Message: msg,
})
2021-01-29 19:40:46 +01:00
}
}
// determine which ones need to be gone
2021-01-30 15:25:25 +01:00
var tobeRemoved []*mstore.Message
for _, mInfos := range msgsSet {
2021-01-30 11:20:12 +01:00
maxVersion := 0
2021-01-30 15:25:25 +01:00
for _, mInfo := range mInfos {
if mInfo.Version > maxVersion {
maxVersion = mInfo.Version
2021-01-29 19:40:46 +01:00
}
}
2021-01-30 15:25:25 +01:00
for _, mInfo := range mInfos {
if mInfo.Version < maxVersion {
tobeRemoved = append(tobeRemoved, mInfo.Message)
2021-01-29 19:40:46 +01:00
}
}
}
// remove them
2021-01-30 15:25:25 +01:00
for _, msg := range tobeRemoved {
2021-06-25 07:48:58 +02:00
if err := rr.mstore.Remove(msg); err != nil {
2021-01-29 19:40:46 +01:00
return err
}
}
return nil
}
2021-07-10 11:29:48 +02:00
func (rr *RemoteRepository) Remove(tasks []*task.Task) error {
tMap := map[string]*task.Task{}
for _, t := range tasks {
tMap[t.Id] = t
}
var toBeRemoved []*mstore.Message
for _, folder := range task.KnownFolders {
msgs, err := rr.mstore.Messages(folder)
if err != nil {
return fmt.Errorf("%w: %v", ErrMStoreError, err)
}
for _, msg := range msgs {
id, _ := task.FieldFromBody(task.FIELD_ID, msg.Body)
if _, ok := tMap[id]; ok {
toBeRemoved = append(toBeRemoved, msg)
}
}
}
for _, msg := range toBeRemoved {
if err := rr.mstore.Remove(msg); err != nil {
return fmt.Errorf("%w: %v", ErrMStoreError, err)
}
}
return nil
}