package users import ( "encoding/json" "go.etcd.io/bbolt" ) var _ UserStore = &BoltUserStore{} var keyUsers = []byte("users") type BoltUserStore struct { db *bbolt.DB } func NewBoltUserStore(path string) (*BoltUserStore, error) { db, err := bbolt.Open(path, 0666, nil) if err != nil { return nil, err } if err := db.Update(func(tx *bbolt.Tx) error { _, err := tx.CreateBucketIfNotExists(keyUsers) return err }); err != nil { return nil, err } return &BoltUserStore{db: db}, nil } func (s *BoltUserStore) Close() error { return s.db.Close() } func (s *BoltUserStore) Get(username string) (*User, error) { var user User err := s.db.View(func(tx *bbolt.Tx) error { bkt := tx.Bucket(keyUsers) rawUser := bkt.Get([]byte(username)) if err := json.Unmarshal(rawUser, &user); err != nil { return err } return nil }) if err != nil { return nil, err } return &user, nil } func (s *BoltUserStore) Store(user *User) error { return s.db.Update(func(tx *bbolt.Tx) error { bkt := tx.Bucket(keyUsers) data, err := json.Marshal(user) if err != nil { return err } return bkt.Put([]byte(user.Username), data) }) } func (s *BoltUserStore) Delete(username string) error { return s.db.Update(func(tx *bbolt.Tx) error { bkt := tx.Bucket(keyUsers) return bkt.Delete([]byte(username)) }) } func (s *BoltUserStore) List() ([]string, error) { var ids []string err := s.db.View(func(tx *bbolt.Tx) error { bkt := tx.Bucket(keyUsers) c := bkt.Cursor() for k, _ := c.First(); k != nil; k, _ = c.Next() { ids = append(ids, string(k)) } return nil }) if err != nil { return nil, err } return ids, nil }