package storage import ( "fmt" "strings" ) // ListCategories returns all categories ordered by label. func (s *Store) ListCategories() ([]Lookup, error) { return s.listLookup("categories") } // ListPeople returns all people ("Who") ordered by label. func (s *Store) ListPeople() ([]Lookup, error) { return s.listLookup("people") } // AddCategory inserts a new category label and returns its id. func (s *Store) AddCategory(label string) (int64, error) { return s.addLookup("categories", label) } // AddPerson inserts a new person label and returns its id. func (s *Store) AddPerson(label string) (int64, error) { return s.addLookup("people", label) } // RenameCategory updates a category's label (the change propagates to every // receipt referencing it, since receipts hold the id, not the text). func (s *Store) RenameCategory(id int64, label string) error { return s.renameLookup("categories", id, label) } // RenamePerson updates a person's label. func (s *Store) RenamePerson(id int64, label string) error { return s.renameLookup("people", id, label) } func (s *Store) listLookup(table string) ([]Lookup, error) { rows, err := s.db.Query(`SELECT id, label FROM ` + table + ` ORDER BY label COLLATE NOCASE`) if err != nil { return nil, fmt.Errorf("list %s: %w", table, err) } defer rows.Close() var out []Lookup for rows.Next() { var l Lookup if err := rows.Scan(&l.ID, &l.Label); err != nil { return nil, fmt.Errorf("scan %s: %w", table, err) } out = append(out, l) } return out, rows.Err() } func (s *Store) addLookup(table, label string) (int64, error) { label = strings.TrimSpace(label) if label == "" { return 0, fmt.Errorf("label cannot be empty") } res, err := s.db.Exec(`INSERT INTO `+table+`(label) VALUES (?)`, label) if err != nil { return 0, fmt.Errorf("add %s: %w", table, err) } return res.LastInsertId() } func (s *Store) renameLookup(table string, id int64, label string) error { label = strings.TrimSpace(label) if label == "" { return fmt.Errorf("label cannot be empty") } if _, err := s.db.Exec(`UPDATE `+table+` SET label = ? WHERE id = ?`, label, id); err != nil { return fmt.Errorf("rename %s: %w", table, err) } return nil }