github.imxd.top/hashicorp/consul@v1.4.5/agent/consul/state/prepared_query_index.go (about) 1 package state 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hashicorp/consul/agent/consul/prepared_query" 8 ) 9 10 // PreparedQueryIndex is a custom memdb indexer used to manage index prepared 11 // query templates. None of the built-in indexers do what we need, and our 12 // use case is pretty specific so it's better to put the logic here. 13 type PreparedQueryIndex struct { 14 } 15 16 // FromObject is used to compute the index key when inserting or updating an 17 // object. 18 func (*PreparedQueryIndex) FromObject(obj interface{}) (bool, []byte, error) { 19 wrapped, ok := obj.(*queryWrapper) 20 if !ok { 21 return false, nil, fmt.Errorf("invalid object given to index as prepared query") 22 } 23 24 query := toPreparedQuery(wrapped) 25 if !prepared_query.IsTemplate(query) { 26 return false, nil, nil 27 } 28 29 // Always prepend a null so that we can represent even an empty name. 30 out := "\x00" + strings.ToLower(query.Name) 31 return true, []byte(out), nil 32 } 33 34 // FromArgs is used when querying for an exact match. Since we don't add any 35 // suffix we can just call the prefix version. 36 func (p *PreparedQueryIndex) FromArgs(args ...interface{}) ([]byte, error) { 37 return p.PrefixFromArgs(args...) 38 } 39 40 // PrefixFromArgs is used when doing a prefix scan for an object. 41 func (*PreparedQueryIndex) PrefixFromArgs(args ...interface{}) ([]byte, error) { 42 if len(args) != 1 { 43 return nil, fmt.Errorf("must provide only a single argument") 44 } 45 arg, ok := args[0].(string) 46 if !ok { 47 return nil, fmt.Errorf("argument must be a string: %#v", args[0]) 48 } 49 arg = "\x00" + strings.ToLower(arg) 50 return []byte(arg), nil 51 }