consul/state: adding KVSList for listing a given prefix

pull/1291/head
Ryan Uber 9 years ago committed by James Phillips
parent a0fd9feda3
commit 4ba89adb7d

@ -755,6 +755,32 @@ func (s *StateStore) KVSGet(key string) (*structs.DirEntry, error) {
return entry.(*structs.DirEntry), nil
}
// KVSList is used to list out all keys under a given prefix. If the
// prefix is left empty, all keys in the KVS will be returned. The
// returned index is the max index of the returned kvs entries.
func (s *StateStore) KVSList(prefix string) (uint64, []string, error) {
tx := s.db.Txn(false)
defer tx.Abort()
// Query the prefix and list the available keys
entries, err := tx.Get("kvs", "id_prefix", prefix)
if err != nil {
return 0, nil, fmt.Errorf("failed kvs lookup: %s", err)
}
// Gather all of the keys found in the store
var keys []string
var lindex uint64
for entry := entries.Next(); entry != nil; entry = entries.Next() {
e := entry.(*structs.DirEntry)
keys = append(keys, e.Key)
if e.ModifyIndex > lindex {
lindex = e.ModifyIndex
}
}
return lindex, keys, nil
}
// KVSDelete is used to perform a shallow delete on a single key in the
// the state store.
func (s *StateStore) KVSDelete(idx uint64, key string) error {

@ -883,3 +883,59 @@ func TestStateStore_KVSDelete(t *testing.T) {
t.Fatalf("bad index: %d", idx)
}
}
func TestStateStore_KVSList(t *testing.T) {
s := testStateStore(t)
// Listing an empty KVS returns nothing
idx, keys, err := s.KVSList("")
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != 0 {
t.Fatalf("bad index: %d", idx)
}
if keys != nil {
t.Fatalf("expected nil, got: %#v", keys)
}
// Create some KVS entries
testSetKey(t, s, 1, "foo", "foo")
testSetKey(t, s, 2, "foo/bar", "bar")
testSetKey(t, s, 3, "foo/bar/zip", "zip")
testSetKey(t, s, 4, "foo/bar/zip/zorp", "zorp")
testSetKey(t, s, 5, "foo/bar/baz", "baz")
// List out all of the keys
idx, keys, err = s.KVSList("")
if err != nil {
t.Fatalf("err: %s", err)
}
// Check the index
if idx != 5 {
t.Fatalf("bad index: %d", idx)
}
// Check that all of the keys were returned
if n := len(keys); n != 5 {
t.Fatalf("expected 5 kvs entries, got: %d", n)
}
// Try listing with a provided prefix
idx, keys, err = s.KVSList("foo/bar/zip")
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != 4 {
t.Fatalf("bad index: %d", idx)
}
// Check that only the keys in the prefix were returned
if n := len(keys); n != 2 {
t.Fatalf("expected 2 kvs entries, got: %d", n)
}
if keys[0] != "foo/bar/zip" || keys[1] != "foo/bar/zip/zorp" {
t.Fatalf("bad: %#v", keys)
}
}

Loading…
Cancel
Save