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

     1  package state
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/golang/protobuf/ptypes"
     7  
     8  	"github.com/golang/protobuf/proto"
     9  	"github.com/hyperledger/fabric-chaincode-go/shim"
    10  	"github.com/pkg/errors"
    11  	"github.com/s7techlab/cckit/state/schema"
    12  )
    13  
    14  type (
    15  	StateList struct {
    16  		itemTarget interface{}
    17  		listTarget interface{}
    18  		list       []interface{}
    19  	}
    20  )
    21  
    22  func NewStateList(config ...interface{}) (sl *StateList, err error) {
    23  	var (
    24  		itemTarget, listTarget interface{}
    25  	)
    26  	if len(config) > 0 {
    27  		itemTarget = config[0]
    28  	}
    29  	if len(config) > 1 {
    30  		listTarget = config[1]
    31  	}
    32  
    33  	return &StateList{itemTarget: itemTarget, listTarget: listTarget}, nil
    34  }
    35  
    36  func (sl *StateList) Fill(
    37  	iter shim.StateQueryIteratorInterface, fromBytes FromBytesTransformer) (list interface{}, err error) {
    38  
    39  	for iter.HasNext() {
    40  		kv, err := iter.Next()
    41  		if err != nil {
    42  			return nil, err
    43  		}
    44  		item, err := fromBytes(kv.Value, sl.itemTarget)
    45  		if err != nil {
    46  			return nil, errors.Wrap(err, `transform list entry`)
    47  		}
    48  		sl.list = append(sl.list, item)
    49  	}
    50  	return sl.Get()
    51  }
    52  
    53  func (sl *StateList) Get() (list interface{}, err error) {
    54  
    55  	// custom list proto.Message
    56  	if _, isListProto := sl.listTarget.(proto.Message); isListProto {
    57  
    58  		customList := proto.Clone(sl.listTarget.(proto.Message))
    59  		items := reflect.ValueOf(customList).Elem().FieldByName(`Items`)
    60  		for _, v := range sl.list {
    61  			items.Set(reflect.Append(items, reflect.ValueOf(v)))
    62  		}
    63  		return customList, nil
    64  
    65  		// default list proto.Message ( with repeated Any)
    66  	} else if _, isItemProto := sl.itemTarget.(proto.Message); isItemProto {
    67  		defList := &schema.List{}
    68  
    69  		for _, item := range sl.list {
    70  			any, err := ptypes.MarshalAny(item.(proto.Message))
    71  			if err != nil {
    72  				return nil, err
    73  			}
    74  			defList.Items = append(defList.Items, any)
    75  		}
    76  		return defList, nil
    77  	}
    78  
    79  	return sl.list, nil
    80  }
    81  
    82  func (sl *StateList) AddElementToList(elem interface{}) {
    83  	sl.list = append(sl.list, elem)
    84  }