gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/store/etcd/etcd.go (about) 1 // Package etcd is an etcd v3 implementation of kv 2 package etcd 3 4 import ( 5 "context" 6 "log" 7 8 client "github.com/coreos/etcd/clientv3" 9 "github.com/coreos/etcd/mvcc/mvccpb" 10 "gitee.com/liuxuezhan/go-micro-v1.18.0/config/options" 11 "gitee.com/liuxuezhan/go-micro-v1.18.0/store" 12 ) 13 14 type ekv struct { 15 options.Options 16 kv client.KV 17 } 18 19 func (e *ekv) Read(keys ...string) ([]*store.Record, error) { 20 //nolint:prealloc 21 var values []*mvccpb.KeyValue 22 23 for _, key := range keys { 24 keyval, err := e.kv.Get(context.Background(), key) 25 if err != nil { 26 return nil, err 27 } 28 29 if keyval == nil || len(keyval.Kvs) == 0 { 30 return nil, store.ErrNotFound 31 } 32 33 values = append(values, keyval.Kvs...) 34 } 35 36 records := make([]*store.Record, 0, len(values)) 37 38 for _, kv := range values { 39 records = append(records, &store.Record{ 40 Key: string(kv.Key), 41 Value: kv.Value, 42 // TODO: implement expiry 43 }) 44 } 45 46 return records, nil 47 } 48 49 func (e *ekv) Delete(keys ...string) error { 50 var gerr error 51 for _, key := range keys { 52 _, err := e.kv.Delete(context.Background(), key) 53 if err != nil { 54 gerr = err 55 } 56 } 57 return gerr 58 } 59 60 func (e *ekv) Write(records ...*store.Record) error { 61 var gerr error 62 for _, record := range records { 63 // TODO create lease to expire keys 64 _, err := e.kv.Put(context.Background(), record.Key, string(record.Value)) 65 if err != nil { 66 gerr = err 67 } 68 } 69 return gerr 70 } 71 72 func (e *ekv) List() ([]*store.Record, error) { 73 keyval, err := e.kv.Get(context.Background(), "/", client.WithPrefix()) 74 if err != nil { 75 return nil, err 76 } 77 if keyval == nil || len(keyval.Kvs) == 0 { 78 return nil, nil 79 } 80 vals := make([]*store.Record, 0, len(keyval.Kvs)) 81 for _, keyv := range keyval.Kvs { 82 vals = append(vals, &store.Record{ 83 Key: string(keyv.Key), 84 Value: keyv.Value, 85 }) 86 } 87 return vals, nil 88 } 89 90 func (e *ekv) String() string { 91 return "etcd" 92 } 93 94 func NewStore(opts ...options.Option) store.Store { 95 options := options.NewOptions(opts...) 96 97 var endpoints []string 98 99 if e, ok := options.Values().Get("store.nodes"); ok { 100 endpoints = e.([]string) 101 } 102 103 if len(endpoints) == 0 { 104 endpoints = []string{"http://127.0.0.1:2379"} 105 } 106 107 // TODO: parse addresses 108 c, err := client.New(client.Config{ 109 Endpoints: endpoints, 110 }) 111 if err != nil { 112 log.Fatal(err) 113 } 114 115 return &ekv{ 116 Options: options, 117 kv: client.NewKV(c), 118 } 119 }