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 }