88 "github.com/pkg/errors"
99 "go.uber.org/zap"
1010
11+ pb "github.com/hyperledger/fabric-protos-go/peer"
12+
1113 "github.com/s7techlab/cckit/convert"
1214)
1315
@@ -56,6 +58,10 @@ type State interface {
5658 // namespace can be part of key (string or []string) or entity with defined mapping
5759 List (namespace interface {}, target ... interface {}) (interface {}, error )
5860
61+ // ListPaginated returns slice of target type with pagination
62+ // namespace can be part of key (string or []string) or entity with defined mapping
63+ ListPaginated (namespace interface {}, pageSize int32 , bookmark string , target ... interface {}) (interface {}, * pb.QueryResponseMetadata , error )
64+
5965 // Keys returns slice of keys
6066 // namespace can be part of key (string or []string) or entity with defined mapping
6167 Keys (namespace interface {}) ([]string , error )
@@ -111,10 +117,11 @@ type Impl struct {
111117 logger * zap.Logger
112118
113119 // wrappers for state access methods
114- PutState func (string , []byte ) error
115- GetState func (string ) ([]byte , error )
116- DelState func (string ) error
117- GetStateByPartialCompositeKey func (objectType string , keys []string ) (shim.StateQueryIteratorInterface , error )
120+ PutState func (string , []byte ) error
121+ GetState func (string ) ([]byte , error )
122+ DelState func (string ) error
123+ GetStateByPartialCompositeKey func (objectType string , keys []string ) (shim.StateQueryIteratorInterface , error )
124+ GetStateByPartialCompositeKeyWithPagination func (objectType string , keys []string , pageSize int32 , bookmark string ) (shim.StateQueryIteratorInterface , * pb.QueryResponseMetadata , error )
118125
119126 StateKeyTransformer KeyTransformer
120127 StateKeyReverseTransformer KeyTransformer
@@ -156,6 +163,12 @@ func NewState(stub shim.ChaincodeStubInterface, logger *zap.Logger) *Impl {
156163 return stub .GetStateByPartialCompositeKey (objectType , keys )
157164 }
158165
166+ i .GetStateByPartialCompositeKeyWithPagination = func (
167+ objectType string , keys []string , pageSize int32 , bookmark string ) (
168+ shim.StateQueryIteratorInterface , * pb.QueryResponseMetadata , error ) {
169+ return stub .GetStateByPartialCompositeKeyWithPagination (objectType , keys , pageSize , bookmark )
170+ }
171+
159172 return i
160173}
161174
@@ -167,10 +180,11 @@ func (s *Impl) Clone() State {
167180 GetState : s .GetState ,
168181 DelState : s .DelState ,
169182 GetStateByPartialCompositeKey : s .GetStateByPartialCompositeKey ,
170- StateKeyTransformer : s .StateKeyTransformer ,
171- StateKeyReverseTransformer : s .StateKeyReverseTransformer ,
172- StateGetTransformer : s .StateGetTransformer ,
173- StatePutTransformer : s .StatePutTransformer ,
183+ GetStateByPartialCompositeKeyWithPagination : s .GetStateByPartialCompositeKeyWithPagination ,
184+ StateKeyTransformer : s .StateKeyTransformer ,
185+ StateKeyReverseTransformer : s .StateKeyReverseTransformer ,
186+ StateGetTransformer : s .StateGetTransformer ,
187+ StatePutTransformer : s .StatePutTransformer ,
174188 }
175189}
176190
@@ -308,31 +322,72 @@ func (s *Impl) List(namespace interface{}, target ...interface{}) (interface{},
308322}
309323
310324func (s * Impl ) createStateQueryIterator (namespace interface {}) (shim.StateQueryIteratorInterface , error ) {
311- key , err := NormalizeKey (s .stub , namespace )
312- if err != nil {
313- return nil , fmt .Errorf (`list prefix: %w` , err )
314- }
315-
316- keyTransformed , err := s .StateKeyTransformer (key )
325+ n , t , err := s .normalizeAndTransformKey (namespace )
317326 if err != nil {
318327 return nil , err
319328 }
320329 s .logger .Debug (`state KEYS with composite key` ,
321- zap .String (`key` , key .String ()), zap .String (`transformed` , keyTransformed .String ()))
330+ zap .String (`key` , n .String ()), zap .String (`transformed` , t .String ()))
322331
323- if len (keyTransformed ) == 0 || keyTransformed [0 ] == `` {
332+ objectType , attrs := t .Parts ()
333+ if objectType == `` {
324334 return s .stub .GetStateByRange (`` , `` ) // all state entries
325335 }
326- var (
327- objectType = keyTransformed [0 ]
328- attrs []string
329- )
330336
331- if len (keyTransformed ) > 1 {
332- attrs = keyTransformed [1 :]
337+ return s .GetStateByPartialCompositeKey (objectType , attrs )
338+ }
339+
340+ // normalizeAndTransformKey returns normalized and transformed key or error if occur
341+ func (s * Impl ) normalizeAndTransformKey (namespace interface {}) (Key , Key , error ) {
342+ normal , err := NormalizeKey (s .stub , namespace )
343+ if err != nil {
344+ return nil , nil , fmt .Errorf (`list prefix: %w` , err )
345+ }
346+
347+ transformed , err := s .StateKeyTransformer (normal )
348+ if err != nil {
349+ return nil , nil , err
333350 }
334351
335- return s .GetStateByPartialCompositeKey (objectType , attrs )
352+ return normal , transformed , nil
353+ }
354+
355+ func (s * Impl ) ListPaginated (
356+ namespace interface {}, pageSize int32 , bookmark string , target ... interface {}) (
357+ interface {}, * pb.QueryResponseMetadata , error ) {
358+ stateList , err := NewStateList (target ... )
359+ if err != nil {
360+ return nil , nil , err
361+ }
362+
363+ iter , md , err := s .createStateQueryPagedIterator (namespace , pageSize , bookmark )
364+ if err != nil {
365+ return nil , nil , errors .Wrap (err , `state iterator` )
366+ }
367+
368+ defer func () { _ = iter .Close () }()
369+ list , err := stateList .Fill (iter , s .StateGetTransformer )
370+
371+ return list , md , err
372+ }
373+
374+ func (s * Impl ) createStateQueryPagedIterator (namespace interface {}, pageSize int32 , bookmark string ) (
375+ shim.StateQueryIteratorInterface , * pb.QueryResponseMetadata , error ) {
376+ n , t , err := s .normalizeAndTransformKey (namespace )
377+ if err != nil {
378+ return nil , nil , err
379+ }
380+
381+ s .logger .Debug (`state KEYS with composite key` ,
382+ zap .String (`key` , n .String ()), zap .String (`transformed` , t .String ()),
383+ zap .Int32 ("pageSize" , pageSize ), zap .String ("bookmark" , bookmark ))
384+
385+ objectType , attrs := t .Parts ()
386+ if objectType == `` {
387+ return s .stub .GetStateByRangeWithPagination (`` , `` , pageSize , bookmark )
388+ }
389+
390+ return s .GetStateByPartialCompositeKeyWithPagination (objectType , attrs , pageSize , bookmark )
336391}
337392
338393func (s * Impl ) Keys (namespace interface {}) ([]string , error ) {
0 commit comments