github.com/eris-ltd/erisdb@v0.25.0/event/query/tags.go (about)

     1  package query
     2  
     3  import (
     4  	"sort"
     5  	"strings"
     6  )
     7  
     8  type Tagged interface {
     9  	Keys() []string
    10  	Get(key string) (value string, ok bool)
    11  	// Len returns the number of tags.
    12  	Len() int
    13  }
    14  
    15  type TagMap map[string]interface{}
    16  
    17  func MapFromTagged(tagged Tagged) map[string]interface{} {
    18  	tags := make(map[string]interface{})
    19  	for _, k := range tagged.Keys() {
    20  		v, ok := tagged.Get(k)
    21  		if ok {
    22  			tags[k] = v
    23  		}
    24  	}
    25  	return tags
    26  }
    27  
    28  func (ts TagMap) Get(key string) (value string, ok bool) {
    29  	var vint interface{}
    30  	vint, ok = ts[key]
    31  	if !ok {
    32  		return "", false
    33  	}
    34  	return StringFromValue(vint), true
    35  }
    36  
    37  func (ts TagMap) Len() int {
    38  	return len(ts)
    39  }
    40  
    41  func (ts TagMap) Map() map[string]interface{} {
    42  	return ts
    43  }
    44  
    45  func (ts TagMap) Keys() []string {
    46  	keys := make([]string, 0, len(ts))
    47  	for k := range ts {
    48  		keys = append(keys, k)
    49  	}
    50  	sort.Strings(keys)
    51  	return keys
    52  }
    53  
    54  type CombinedTags struct {
    55  	keys   []string
    56  	ks     map[string][]Tagged
    57  	concat bool
    58  }
    59  
    60  func NewCombinedTags() *CombinedTags {
    61  	return &CombinedTags{
    62  		ks: make(map[string][]Tagged),
    63  	}
    64  }
    65  
    66  func MergeTags(tags ...Tagged) *CombinedTags {
    67  	ct := NewCombinedTags()
    68  	ct.AddTags(false, tags...)
    69  	return ct
    70  }
    71  
    72  func ConcatTags(tags ...Tagged) *CombinedTags {
    73  	ct := NewCombinedTags()
    74  	ct.AddTags(true, tags...)
    75  	return ct
    76  }
    77  
    78  // Adds each of tagsList to CombinedTags - choosing whether values for the same key should
    79  // be concatenated or whether the first should value should stick
    80  func (ct *CombinedTags) AddTags(concat bool, tagsList ...Tagged) {
    81  	for _, t := range tagsList {
    82  		for _, k := range t.Keys() {
    83  			if len(ct.ks[k]) == 0 {
    84  				ct.keys = append(ct.keys, k)
    85  				// Store reference to key-holder amongst Taggeds
    86  				ct.ks[k] = append(ct.ks[k], t)
    87  			} else if concat {
    88  				// Store additional tag reference only if concat, otherwise first key-holder wins
    89  				ct.ks[k] = append(ct.ks[k], t)
    90  			}
    91  		}
    92  	}
    93  }
    94  
    95  func (ct *CombinedTags) Get(key string) (string, bool) {
    96  	ts := ct.ks[key]
    97  	if len(ts) == 0 {
    98  		return "", false
    99  	}
   100  	values := make([]string, 0, len(ts))
   101  	for _, t := range ts {
   102  		value, ok := t.Get(key)
   103  		if ok {
   104  			values = append(values, value)
   105  		}
   106  	}
   107  	if len(values) == 0 {
   108  		return "", false
   109  	}
   110  	return strings.Join(values, MultipleValueTagSeparator), true
   111  }
   112  
   113  func (ct *CombinedTags) Len() (length int) {
   114  	return len(ct.keys)
   115  }
   116  
   117  func (ct *CombinedTags) Keys() []string {
   118  	return ct.keys
   119  }