// traverse walks the keyspace and converts anything that looks like an entity // into an entity and returns it as part of the array. // // traverse will log & skip errors to ensure bad data will not break this routine. func (c *Client) traverse(node *client.Node, obj db.Entity) []db.Entity { entities := []db.Entity{} if node.Dir { for _, inner := range node.Nodes { entities = append(entities, c.traverse(inner, obj)...) } } else if copy, err := helpers.ReadAndSet(c, obj, node.Key, []byte(node.Value)); err == nil { entities = append(entities, copy) } return entities }
// ListPrefix lists all the entities under prefix instead of listing the whole keyspace. func (c *Client) ListPrefix(prefix string, obj db.Entity) ([]db.Entity, error) { pairs, _, err := c.client.KV().List(c.qualified(path.Join(obj.Prefix(), prefix)), nil) if err != nil { return nil, err } entities := []db.Entity{} for _, pair := range pairs { copy, err := helpers.ReadAndSet(c, obj, pair.Key, pair.Value) if err != nil { return nil, err } entities = append(entities, copy) } return entities, nil }
func (c *Client) watchInternal(wi helpers.WatchInfo) { var wp *watch.WatchPlan var err error if wi.Recursive { wp, err = watch.Parse(map[string]interface{}{ "type": "keyprefix", "prefix": c.qualified(wi.Path), }) } else { wp, err = watch.Parse(map[string]interface{}{ "type": "key", "key": c.qualified(wi.Path), }) } if err != nil { wi.ErrorChan <- err return } wp.Handler = func(u uint64, i interface{}) { if i == nil { return } switch i.(type) { case api.KVPairs: for _, pair := range i.(api.KVPairs) { if pair == nil { continue } this, err := helpers.ReadAndSet(c, wi.Object, pair.Key, pair.Value) if err != nil { wi.ErrorChan <- err continue } wi.ReturnChan <- this } case *api.KVPair: this, err := helpers.ReadAndSet(c, wi.Object, i.(*api.KVPair).Key, i.(*api.KVPair).Value) if err != nil { wi.ErrorChan <- err return } wi.ReturnChan <- this default: logrus.Errorf("received invalid pair %+v during watch", i) } } go func(wp *watch.WatchPlan) { if err := wp.Run(c.config.Address); err != nil { wi.ErrorChan <- err } }(wp) go func(wp *watch.WatchPlan, wi helpers.WatchInfo) { <-wi.StopChan (*wp).Stop() }(wp, wi) }