github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/chaincode/query_response_generator.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode
     8  
     9  import (
    10  	"github.com/golang/protobuf/proto"
    11  	commonledger "github.com/hechain20/hechain/common/ledger"
    12  	pb "github.com/hyperledger/fabric-protos-go/peer"
    13  )
    14  
    15  type QueryResponseGenerator struct {
    16  	MaxResultLimit int
    17  }
    18  
    19  // BuildQueryResponse takes an iterator and fetch state to construct QueryResponse
    20  func (q *QueryResponseGenerator) BuildQueryResponse(txContext *TransactionContext, iter commonledger.ResultsIterator,
    21  	iterID string, isPaginated bool, totalReturnLimit int32) (*pb.QueryResponse, error) {
    22  	pendingQueryResults := txContext.GetPendingQueryResult(iterID)
    23  	totalReturnCount := txContext.GetTotalReturnCount(iterID)
    24  
    25  	for {
    26  		// if the total count has been reached, return the result and prevent the Next() being called
    27  		if *totalReturnCount >= totalReturnLimit {
    28  			return createQueryResponse(txContext, iterID, isPaginated, pendingQueryResults, *totalReturnCount)
    29  		}
    30  
    31  		queryResult, err := iter.Next()
    32  		switch {
    33  		case err != nil:
    34  			chaincodeLogger.Errorf("Failed to get query result from iterator")
    35  			txContext.CleanupQueryContext(iterID)
    36  			return nil, err
    37  
    38  		case queryResult == nil:
    39  
    40  			return createQueryResponse(txContext, iterID, isPaginated, pendingQueryResults, *totalReturnCount)
    41  
    42  		case !isPaginated && pendingQueryResults.Size() == q.MaxResultLimit:
    43  			// if explicit pagination is not used
    44  			// if the max number of results is queued up, cut batch, then add current result to pending batch
    45  			// MaxResultLimit is for batching between chaincode shim and handler
    46  			// MaxResultLimit does not limit the records returned to the client
    47  			batch := pendingQueryResults.Cut()
    48  			if err := pendingQueryResults.Add(queryResult); err != nil {
    49  				txContext.CleanupQueryContext(iterID)
    50  				return nil, err
    51  			}
    52  			*totalReturnCount++
    53  			return &pb.QueryResponse{Results: batch, HasMore: true, Id: iterID}, nil
    54  
    55  		default:
    56  			if err := pendingQueryResults.Add(queryResult); err != nil {
    57  				txContext.CleanupQueryContext(iterID)
    58  				return nil, err
    59  			}
    60  			*totalReturnCount++
    61  		}
    62  	}
    63  }
    64  
    65  func createQueryResponse(txContext *TransactionContext, iterID string, isPaginated bool, pendingQueryResults *PendingQueryResult, totalReturnCount int32) (*pb.QueryResponse, error) {
    66  	batch := pendingQueryResults.Cut()
    67  
    68  	if isPaginated {
    69  		// when explicit pagination is enabled, return the batch with the responseMetadata
    70  		bookmark := txContext.CleanupQueryContextWithBookmark(iterID)
    71  		responseMetadata := createResponseMetadata(totalReturnCount, bookmark)
    72  		responseMetadataBytes, err := proto.Marshal(responseMetadata)
    73  		if err != nil {
    74  			return nil, err
    75  		}
    76  		return &pb.QueryResponse{Results: batch, HasMore: false, Id: iterID, Metadata: responseMetadataBytes}, nil
    77  	}
    78  
    79  	// if explicit pagination is not used, then the end of the resultset has been reached, return the batch
    80  	txContext.CleanupQueryContext(iterID)
    81  	return &pb.QueryResponse{Results: batch, HasMore: false, Id: iterID}, nil
    82  }
    83  
    84  func createResponseMetadata(returnCount int32, bookmark string) *pb.QueryResponseMetadata {
    85  	responseMetadata := &pb.QueryResponseMetadata{}
    86  	responseMetadata.Bookmark = bookmark
    87  	responseMetadata.FetchedRecordsCount = int32(returnCount)
    88  	return responseMetadata
    89  }