github.com/annwntech/go-micro/v2@v2.9.5/config/source/etcd/util.go (about)

     1  package etcd
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/coreos/etcd/clientv3"
     7  	"github.com/coreos/etcd/mvcc/mvccpb"
     8  	"github.com/annwntech/go-micro/v2/config/encoder"
     9  )
    10  
    11  func makeEvMap(e encoder.Encoder, data map[string]interface{}, kv []*clientv3.Event, stripPrefix string) map[string]interface{} {
    12  	if data == nil {
    13  		data = make(map[string]interface{})
    14  	}
    15  
    16  	for _, v := range kv {
    17  		switch mvccpb.Event_EventType(v.Type) {
    18  		case mvccpb.DELETE:
    19  			data = update(e, data, (*mvccpb.KeyValue)(v.Kv), "delete", stripPrefix)
    20  		default:
    21  			data = update(e, data, (*mvccpb.KeyValue)(v.Kv), "insert", stripPrefix)
    22  		}
    23  	}
    24  
    25  	return data
    26  }
    27  
    28  func makeMap(e encoder.Encoder, kv []*mvccpb.KeyValue, stripPrefix string) map[string]interface{} {
    29  	data := make(map[string]interface{})
    30  
    31  	for _, v := range kv {
    32  		data = update(e, data, v, "put", stripPrefix)
    33  	}
    34  
    35  	return data
    36  }
    37  
    38  func update(e encoder.Encoder, data map[string]interface{}, v *mvccpb.KeyValue, action, stripPrefix string) map[string]interface{} {
    39  	// remove prefix if non empty, and ensure leading / is removed as well
    40  	vkey := strings.TrimPrefix(strings.TrimPrefix(string(v.Key), stripPrefix), "/")
    41  	// split on prefix
    42  	haveSplit := strings.Contains(vkey, "/")
    43  	keys := strings.Split(vkey, "/")
    44  
    45  	var vals interface{}
    46  	e.Decode(v.Value, &vals)
    47  
    48  	if !haveSplit && len(keys) == 1 {
    49  		switch action {
    50  		case "delete":
    51  			data = make(map[string]interface{})
    52  		default:
    53  			v, ok := vals.(map[string]interface{})
    54  			if ok {
    55  				data = v
    56  			}
    57  		}
    58  		return data
    59  	}
    60  
    61  	// set data for first iteration
    62  	kvals := data
    63  	// iterate the keys and make maps
    64  	for i, k := range keys {
    65  		kval, ok := kvals[k].(map[string]interface{})
    66  		if !ok {
    67  			// create next map
    68  			kval = make(map[string]interface{})
    69  			// set it
    70  			kvals[k] = kval
    71  		}
    72  
    73  		// last key: write vals
    74  		if l := len(keys) - 1; i == l {
    75  			switch action {
    76  			case "delete":
    77  				delete(kvals, k)
    78  			default:
    79  				kvals[k] = vals
    80  			}
    81  			break
    82  		}
    83  
    84  		// set kvals for next iterator
    85  		kvals = kval
    86  	}
    87  
    88  	return data
    89  }