148 lines
3.0 KiB
Go
148 lines
3.0 KiB
Go
package storage
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"time"
|
|
|
|
"github.com/teris-io/shortid"
|
|
bolt "go.etcd.io/bbolt"
|
|
)
|
|
|
|
func (s *Storage) CreateEntry(category, title, link string) (*Entry, error) {
|
|
entry := &Entry{
|
|
ID: shortid.MustGenerate(),
|
|
Category: category,
|
|
Title: title,
|
|
Link: link,
|
|
Timestamp: time.Now(),
|
|
}
|
|
|
|
err := s.db.Update(func(tx *bolt.Tx) error {
|
|
b := tx.Bucket(bucketEntries)
|
|
data, err := encodeJSON(entry)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return b.Put([]byte(entry.ID), data)
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return entry, nil
|
|
}
|
|
|
|
func (s *Storage) GetEntry(id string) (*Entry, error) {
|
|
var entry *Entry
|
|
err := s.db.View(func(tx *bolt.Tx) error {
|
|
b := tx.Bucket(bucketEntries)
|
|
data := b.Get([]byte(id))
|
|
if data == nil {
|
|
return fmt.Errorf("entry %q not found", id)
|
|
}
|
|
entry = &Entry{}
|
|
return decodeJSON(data, entry)
|
|
})
|
|
return entry, err
|
|
}
|
|
|
|
func (s *Storage) DeleteEntry(id string) error {
|
|
return s.db.Update(func(tx *bolt.Tx) error {
|
|
b := tx.Bucket(bucketEntries)
|
|
if b.Get([]byte(id)) == nil {
|
|
return fmt.Errorf("entry %q not found", id)
|
|
}
|
|
return b.Delete([]byte(id))
|
|
})
|
|
}
|
|
|
|
func (s *Storage) UpdateEntryTitle(id, title string) error {
|
|
return s.db.Update(func(tx *bolt.Tx) error {
|
|
b := tx.Bucket(bucketEntries)
|
|
data := b.Get([]byte(id))
|
|
if data == nil {
|
|
return fmt.Errorf("entry %q not found", id)
|
|
}
|
|
|
|
var entry Entry
|
|
if err := decodeJSON(data, &entry); err != nil {
|
|
return err
|
|
}
|
|
|
|
entry.Title = title
|
|
newData, err := encodeJSON(entry)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return b.Put([]byte(id), newData)
|
|
})
|
|
}
|
|
|
|
func (s *Storage) UpdateEntryCategory(id, category string) error {
|
|
return s.db.Update(func(tx *bolt.Tx) error {
|
|
b := tx.Bucket(bucketEntries)
|
|
data := b.Get([]byte(id))
|
|
if data == nil {
|
|
return fmt.Errorf("entry %q not found", id)
|
|
}
|
|
|
|
var entry Entry
|
|
if err := decodeJSON(data, &entry); err != nil {
|
|
return err
|
|
}
|
|
|
|
entry.Category = category
|
|
newData, err := encodeJSON(entry)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return b.Put([]byte(id), newData)
|
|
})
|
|
}
|
|
|
|
func (s *Storage) ListEntries(category string) ([]Entry, error) {
|
|
var entries []Entry
|
|
err := s.db.View(func(tx *bolt.Tx) error {
|
|
b := tx.Bucket(bucketEntries)
|
|
return b.ForEach(func(k, v []byte) error {
|
|
var entry Entry
|
|
if err := decodeJSON(v, &entry); err != nil {
|
|
return err
|
|
}
|
|
if category == "" || entry.Category == category {
|
|
entries = append(entries, entry)
|
|
}
|
|
return nil
|
|
})
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sort.Slice(entries, func(i, j int) bool {
|
|
return entries[i].Timestamp.Before(entries[j].Timestamp)
|
|
})
|
|
|
|
return entries, nil
|
|
}
|
|
|
|
func (s *Storage) ListAllEntries() ([]Entry, error) {
|
|
return s.ListEntries("")
|
|
}
|
|
|
|
func (s *Storage) GetEntriesByCategory() (map[string][]Entry, error) {
|
|
entries, err := s.ListAllEntries()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result := make(map[string][]Entry)
|
|
for _, e := range entries {
|
|
result[e.Category] = append(result[e.Category], e)
|
|
}
|
|
return result, nil
|
|
}
|