diff --git a/boltrest.go b/boltrest.go index f4d19a7..9a3f29b 100644 --- a/boltrest.go +++ b/boltrest.go @@ -37,6 +37,39 @@ func Open(filename string) (*DB, error) { return &b, nil } +// MkBucketPath builds all buckets in the string slice +func (b *DB) MkBucketPath(path []string) error { + // TODO: Make sure local db is fresh (or offline) + err := b.localDB.Update(func(tx *bolt.Tx) error { + var err error + bkt := tx.Bucket([]byte(path[0])) + if bkt == nil { + // Create it + bkt, err = tx.CreateBucket([]byte(path[0])) + if err != nil { + // error creating + return err + } + } + if len(path) > 1 { + path = path[1:] + for i := range path { + nextBkt := bkt.Bucket([]byte(path[i])) + if nextBkt == nil { + // Create it + nextBkt, err = bkt.CreateBucket([]byte(path[i])) + if err != nil { + return err + } + } + bkt = nextBkt + } + } + return err + }) + return err +} + // GetValue returns the value at path // path is a '/' separated list of tokens // the last token is a key, all others are buckets @@ -67,7 +100,10 @@ func (b *DB) GetValue(path []string, key string) (string, error) { // SetValue sets the value at path to val // path is a slice of tokens func (b *DB) SetValue(path []string, key, val string) error { - var err error + err := b.MkBucketPath(path) + if err != nil { + return err + } b.localDB.Update(func(tx *bolt.Tx) error { newBkt := tx.Bucket([]byte(path[0])) if newBkt == nil { @@ -154,14 +190,19 @@ func (b *DB) GetBucketList(path []string) ([]string, error) { return fmt.Errorf("Couldn't find bucket " + path[0]) } var newBkt *bolt.Bucket - for idx := 1; idx < len(path); idx++ { - newBkt = bkt.Bucket([]byte(path[idx])) - if newBkt == nil { - return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/")) + var berr error + if len(path) > 1 { + for idx := 1; idx < len(path); idx++ { + newBkt = bkt.Bucket([]byte(path[idx])) + if newBkt == nil { + return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/")) + } } + bkt = newBkt } + // newBkt should have the last bucket in the path - berr := newBkt.ForEach(func(k, v []byte) error { + berr = bkt.ForEach(func(k, v []byte) error { if v == nil { // Must be a bucket ret = append(ret, string(k)) @@ -184,15 +225,18 @@ func (b *DB) GetKeyList(path []string) ([]string, error) { if bkt == nil { return fmt.Errorf("Couldn't find bucket " + path[0]) } - var newBkt *bolt.Bucket - for idx := 1; idx < len(path); idx++ { - newBkt = bkt.Bucket([]byte(path[idx])) - if newBkt == nil { - return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/")) + if len(path) > 1 { + var newBkt *bolt.Bucket + for idx := 1; idx < len(path); idx++ { + newBkt = bkt.Bucket([]byte(path[idx])) + if newBkt == nil { + return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/")) + } } + bkt = newBkt } // newBkt should have the last bucket in the path - berr := newBkt.ForEach(func(k, v []byte) error { + berr := bkt.ForEach(func(k, v []byte) error { if v != nil { // Not a bucket ret = append(ret, string(k)) @@ -214,17 +258,20 @@ func (b *DB) DeletePair(path []string, key string) error { if bkt == nil { return fmt.Errorf("Couldn't find bucket " + path[0]) } - var newBkt *bolt.Bucket - for idx := 1; idx < len(path); idx++ { - newBkt = bkt.Bucket([]byte(path[idx])) - if newBkt == nil { - return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/")) + if len(path) > 1 { + var newBkt *bolt.Bucket + for idx := 1; idx < len(path); idx++ { + newBkt = bkt.Bucket([]byte(path[idx])) + if newBkt == nil { + return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/")) + } } + bkt = newBkt } - // newBkt should have the last bucket in the path + // bkt should have the last bucket in the path // Test to make sure that key is a pair, if so, delete it - if tst := newBkt.Bucket([]byte(key)); tst == nil { - return newBkt.Delete([]byte(key)) + if tst := bkt.Bucket([]byte(key)); tst == nil { + return bkt.Delete([]byte(key)) } return nil })