github.com/s7techlab/cckit@v0.10.5/state/key.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  
     8  	"github.com/hyperledger/fabric-chaincode-go/shim"
     9  
    10  	"github.com/s7techlab/cckit/convert"
    11  )
    12  
    13  // StringsIdToStr helper for passing []string key
    14  func StringsIdToStr(idSlice []string) string {
    15  	return strings.Join(idSlice, "\000")
    16  }
    17  
    18  // StringsIdFromStr helper for restoring []string key
    19  func StringsIdFromStr(idString string) []string {
    20  	return strings.Split(idString, "\000")
    21  }
    22  
    23  type (
    24  	Key []string
    25  
    26  	// StateKey stores origin and transformed state key
    27  	TransformedKey struct {
    28  		Origin Key
    29  		Parts  Key
    30  		String string
    31  	}
    32  
    33  	//KeyerFunc func(string) ([]string, error)
    34  	KeyFunc func() (Key, error)
    35  
    36  	// KeyerFunc transforms string to key
    37  	KeyerFunc func(string) (Key, error)
    38  
    39  	// Keyer interface for entity containing logic of its key creation
    40  	Keyer interface {
    41  		Key() (Key, error)
    42  	}
    43  
    44  	// StringsKeys interface for entity containing logic of its key creation - backward compatibility
    45  	StringsKeyer interface {
    46  		Key() ([]string, error)
    47  	}
    48  
    49  	// KeyValue interface combines Keyer as ToByter methods - state entry representation
    50  	KeyValue interface {
    51  		Keyer
    52  		convert.ToByter
    53  	}
    54  
    55  	stringKeyer struct {
    56  		str   string
    57  		keyer KeyerFunc
    58  	}
    59  )
    60  
    61  func (k Key) Append(key Key) Key {
    62  	return append(k, key...)
    63  }
    64  
    65  // Key human readable representation
    66  func (k Key) String() string {
    67  	return strings.Join(k, ` | `)
    68  }
    69  
    70  // Parts returns object type and attributes slice
    71  func (k Key) Parts() (objectType string, attrs []string) {
    72  	if len(k) > 0 {
    73  		objectType = k[0]
    74  
    75  		if len(k) > 1 {
    76  			attrs = k[1:]
    77  		}
    78  	}
    79  	return
    80  }
    81  
    82  func NormalizeKey(stub shim.ChaincodeStubInterface, key interface{}) (Key, error) {
    83  	switch k := key.(type) {
    84  	case Key:
    85  		return k, nil
    86  	case Keyer:
    87  		return k.Key()
    88  	case StringsKeyer:
    89  		return k.Key()
    90  	case string:
    91  		return KeyFromComposite(stub, k)
    92  	case []string:
    93  		return k, nil
    94  	}
    95  	return nil, fmt.Errorf(`%s: %w`, reflect.TypeOf(key), ErrUnableToCreateStateKey)
    96  }
    97  
    98  func KeyFromComposite(stub shim.ChaincodeStubInterface, key string) (Key, error) {
    99  	var (
   100  		objectType string
   101  		attributes []string
   102  		err        error
   103  	)
   104  
   105  	// contains key delimiter
   106  	if strings.ContainsRune(key, 0) {
   107  		objectType, attributes, err = stub.SplitCompositeKey(key)
   108  		if err != nil {
   109  			return nil, fmt.Errorf(`key from composite: %w`, err)
   110  		}
   111  	} else {
   112  		objectType = key
   113  	}
   114  
   115  	return append([]string{objectType}, attributes...), nil
   116  }
   117  
   118  func KeyToComposite(stub shim.ChaincodeStubInterface, key Key) (string, error) {
   119  	compositeKey, err := stub.CreateCompositeKey(key[0], key[1:])
   120  	if err != nil {
   121  		return ``, fmt.Errorf(`key to composite: %w`, err)
   122  	}
   123  
   124  	return compositeKey, nil
   125  }
   126  
   127  func KeyToString(stub shim.ChaincodeStubInterface, key Key) (string, error) {
   128  	switch len(key) {
   129  	case 0:
   130  		return ``, ErrKeyPartsLength
   131  	case 1:
   132  		return key[0], nil
   133  	default:
   134  		return KeyToComposite(stub, key)
   135  	}
   136  }
   137  
   138  func (sk stringKeyer) Key() (Key, error) {
   139  	return sk.keyer(sk.str)
   140  }
   141  
   142  // StringKeyer constructor for struct implementing Keyer interface
   143  func StringKeyer(str string, keyer KeyerFunc) Keyer {
   144  	return stringKeyer{str, keyer}
   145  }