Files
ddc/internal/history/history.go
T

83 lines
1.6 KiB
Go

package history
import (
"encoding/json"
"errors"
"fmt"
"io/fs"
"os"
"slices"
"sync"
"time"
"ddc/internal/files"
)
const maxEntries = 500
type Entry struct {
FileName string `json:"fileName"`
SourceURL string `json:"sourceUrl"`
Destination string `json:"destination"`
Items []string `json:"items"`
MovedAt time.Time `json:"movedAt"`
}
type Store struct {
mutex sync.Mutex
path string
entries []Entry
}
func Open(path string) (*Store, error) {
store := &Store{path: path, entries: []Entry{}}
data, err := os.ReadFile(path)
if errors.Is(err, fs.ErrNotExist) {
return store, nil
}
if err != nil {
return nil, err
}
if err := json.Unmarshal(data, &store.entries); err != nil {
return nil, fmt.Errorf("history file %s: %w", path, err)
}
if store.entries == nil {
store.entries = []Entry{}
}
return store, nil
}
func (store *Store) List() []Entry {
store.mutex.Lock()
defer store.mutex.Unlock()
return slices.Clone(store.entries)
}
func (store *Store) Add(entry Entry) error {
store.mutex.Lock()
defer store.mutex.Unlock()
next := append([]Entry{entry}, store.entries...)
if len(next) > maxEntries {
next = next[:maxEntries]
}
return store.save(next)
}
func (store *Store) Clear() error {
store.mutex.Lock()
defer store.mutex.Unlock()
return store.save([]Entry{})
}
func (store *Store) save(entries []Entry) error {
data, err := json.MarshalIndent(entries, "", " ")
if err != nil {
return err
}
if err := files.WriteAtomically(store.path, data); err != nil {
return err
}
store.entries = entries
return nil
}