diff --git a/badger.go b/badger.go index b758154..069d3c8 100644 --- a/badger.go +++ b/badger.go @@ -39,12 +39,48 @@ func (b badgerStore) Get(key string, out interface{}) error { }) } +func (b badgerStore) GetItem(key string) (*Item, error) { + out := &Item{} + err := b.db.View(func(txn *badger.Txn) error { + item, err := txn.Get([]byte(key)) + if err != nil { + return err + } + + key := string(item.KeyCopy(nil)) + data, err := item.ValueCopy(nil) + if err != nil { + return err + } + + out.Key = key + out.Data = data + + return nil + }) + return out, err +} + func (b badgerStore) Delete(key string) error { return b.db.Update(func(txn *badger.Txn) error { return txn.Delete([]byte(key)) }) } +func (b badgerStore) Modify(key string, modify ModifyFunc) error { + item, err := b.GetItem(key) + if err != nil { + return err + } + + newVal, err := modify(item) + if err != nil { + return err + } + + return b.Set(key, newVal) +} + func (b badgerStore) Iter() Iter { out := make(chan *Item, 10) go func() { @@ -90,10 +126,18 @@ func (b badgerBucket) Get(key string, out interface{}) error { return b.store.Get(b.name+"\u001f"+key, out) } +func (b badgerBucket) GetItem(key string) (*Item, error) { + return b.store.GetItem(b.name + "\u001f" + key) +} + func (b badgerBucket) Delete(key string) error { return b.store.Delete(b.name + "\u001f" + key) } +func (b badgerBucket) Modify(key string, modify ModifyFunc) error { + return b.store.Modify(b.name+"\u001f"+key, modify) +} + func (b badgerBucket) Iter() Iter { out := make(chan *Item, 10) go func() { diff --git a/main.go b/main.go index 01b8249..325fbba 100644 --- a/main.go +++ b/main.go @@ -8,7 +8,12 @@ type Store interface { Set(key string, val interface{}) error // Get places a value at a key into val Get(key string, val interface{}) error - Delete(key string) error + // GetItem gets an item from the store + GetItem(string) (*Item, error) + // Delete deletes a value from the store + Delete(string) error + // Modify allows editing of a value in the store + Modify(string, ModifyFunc) error // Bucket returns a bucket with the specified name Bucket(name string) Bucket // Iter returns an iterator @@ -23,11 +28,18 @@ type Bucket interface { Set(string, interface{}) error // Get places a value at a key in the bucket into val Get(string, interface{}) error + // GetItem gets an item from the store + GetItem(string) (*Item, error) + // Delete deletes a value from the bucket Delete(key string) error + // Modify allows editing of a value in the bucket + Modify(string, ModifyFunc) error // Iter returns an iterator for the bucket Iter() Iter } +type ModifyFunc func(*Item) (interface{}, error) + // Item represents an iterator item type Item struct { Key string