Skip to content

Commit 44e7850

Browse files
committed
[FAB-1917] Fix chaincode query API
Address review comments from: https://gerrit.hyperledger.org/r/#/c/4767/ Updates to logging and comments per Murali's feedback. Rename ExecuteQuery() to GetQueryResult() per Binh's feedback. The rename is only made at the top level chaincode function The name change will be propagated to all the underlying helper functions and messages as part of a larger refactor that Murali has planned for post-alpha. Fix handler.go result type (KV should be QueryRecord). Tested that chaincode calls to GetQueryResult() work end-to-end. Change-Id: I9cda95bab237e03880243be0b15110d119f033e8 Signed-off-by: denyeart <[email protected]>
1 parent bb41bbc commit 44e7850

File tree

6 files changed

+58
-40
lines changed

6 files changed

+58
-40
lines changed

core/chaincode/handler.go

+18-18
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ func (handler *Handler) handleRangeQueryState(msg *pb.ChaincodeMessage) {
714714
}()
715715
}
716716

717-
// afterRangeQueryState handles a RANGE_QUERY_STATE_NEXT request from the chaincode.
717+
// afterQueryStateNext handles a QUERY_STATE_NEXT request from the chaincode.
718718
func (handler *Handler) afterQueryStateNext(e *fsm.Event, state string) {
719719
msg, ok := e.Args[0].(*pb.ChaincodeMessage)
720720
if !ok {
@@ -725,10 +725,10 @@ func (handler *Handler) afterQueryStateNext(e *fsm.Event, state string) {
725725

726726
// Query ledger for state
727727
handler.handleQueryStateNext(msg)
728-
chaincodeLogger.Debug("Exiting RANGE_QUERY_STATE_NEXT")
728+
chaincodeLogger.Debug("Exiting QUERY_STATE_NEXT")
729729
}
730730

731-
// Handles query to ledger to rage query state next
731+
// Handles query to ledger for query state next
732732
func (handler *Handler) handleQueryStateNext(msg *pb.ChaincodeMessage) {
733733
// The defer followed by triggering a go routine dance is needed to ensure that the previous state transition
734734
// is completed before the next one is triggered. The previous state transition is deemed complete only when
@@ -754,17 +754,17 @@ func (handler *Handler) handleQueryStateNext(msg *pb.ChaincodeMessage) {
754754
unmarshalErr := proto.Unmarshal(msg.Payload, queryStateNext)
755755
if unmarshalErr != nil {
756756
payload := []byte(unmarshalErr.Error())
757-
chaincodeLogger.Errorf("Failed to unmarshall state range next query request. Sending %s", pb.ChaincodeMessage_ERROR)
757+
chaincodeLogger.Errorf("Failed to unmarshall state next query request. Sending %s", pb.ChaincodeMessage_ERROR)
758758
serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
759759
return
760760
}
761761

762762
txContext := handler.getTxContext(msg.Txid)
763-
rangeIter := handler.getQueryIterator(txContext, queryStateNext.ID)
763+
queryIter := handler.getQueryIterator(txContext, queryStateNext.ID)
764764

765-
if rangeIter == nil {
766-
payload := []byte("Range query iterator not found")
767-
chaincodeLogger.Errorf("Range query iterator not found. Sending %s", pb.ChaincodeMessage_ERROR)
765+
if queryIter == nil {
766+
payload := []byte("query iterator not found")
767+
chaincodeLogger.Errorf("query iterator not found. Sending %s", pb.ChaincodeMessage_ERROR)
768768
serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
769769
return
770770
}
@@ -775,7 +775,7 @@ func (handler *Handler) handleQueryStateNext(msg *pb.ChaincodeMessage) {
775775
var qresult ledger.QueryResult
776776
var err error
777777
for ; i < maxRangeQueryStateLimit; i++ {
778-
qresult, err = rangeIter.Next()
778+
qresult, err = queryIter.Next()
779779
if err != nil {
780780
chaincodeLogger.Errorf("Failed to get query result from iterator. Sending %s", pb.ChaincodeMessage_ERROR)
781781
return
@@ -789,14 +789,14 @@ func (handler *Handler) handleQueryStateNext(msg *pb.ChaincodeMessage) {
789789
}
790790

791791
if qresult != nil {
792-
rangeIter.Close()
792+
queryIter.Close()
793793
handler.deleteQueryIterator(txContext, queryStateNext.ID)
794794
}
795795

796796
payload := &pb.QueryStateResponse{KeysAndValues: keysAndValues, HasMore: qresult != nil, ID: queryStateNext.ID}
797797
payloadBytes, err := proto.Marshal(payload)
798798
if err != nil {
799-
rangeIter.Close()
799+
queryIter.Close()
800800
handler.deleteQueryIterator(txContext, queryStateNext.ID)
801801

802802
// Send error msg back to chaincode. GetState will not trigger event
@@ -812,7 +812,7 @@ func (handler *Handler) handleQueryStateNext(msg *pb.ChaincodeMessage) {
812812
}()
813813
}
814814

815-
// afterRangeQueryState handles a RANGE_QUERY_STATE_CLOSE request from the chaincode.
815+
// afterRangeQueryState handles a QUERY_STATE_CLOSE request from the chaincode.
816816
func (handler *Handler) afterQueryStateClose(e *fsm.Event, state string) {
817817
msg, ok := e.Args[0].(*pb.ChaincodeMessage)
818818
if !ok {
@@ -823,7 +823,7 @@ func (handler *Handler) afterQueryStateClose(e *fsm.Event, state string) {
823823

824824
// Query ledger for state
825825
handler.handleQueryStateClose(msg)
826-
chaincodeLogger.Debug("Exiting RANGE_QUERY_STATE_CLOSE")
826+
chaincodeLogger.Debug("Exiting QUERY_STATE_CLOSE")
827827
}
828828

829829
// Handles the closing of a state iterator
@@ -852,7 +852,7 @@ func (handler *Handler) handleQueryStateClose(msg *pb.ChaincodeMessage) {
852852
unmarshalErr := proto.Unmarshal(msg.Payload, queryStateClose)
853853
if unmarshalErr != nil {
854854
payload := []byte(unmarshalErr.Error())
855-
chaincodeLogger.Errorf("Failed to unmarshall state range query close request. Sending %s", pb.ChaincodeMessage_ERROR)
855+
chaincodeLogger.Errorf("Failed to unmarshall state query close request. Sending %s", pb.ChaincodeMessage_ERROR)
856856
serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
857857
return
858858
}
@@ -923,7 +923,7 @@ func (handler *Handler) handleExecuteQueryState(msg *pb.ChaincodeMessage) {
923923
unmarshalErr := proto.Unmarshal(msg.Payload, executeQueryState)
924924
if unmarshalErr != nil {
925925
payload := []byte(unmarshalErr.Error())
926-
chaincodeLogger.Errorf("Failed to unmarshall range query request. Sending %s", pb.ChaincodeMessage_ERROR)
926+
chaincodeLogger.Errorf("Failed to unmarshall query request. Sending %s", pb.ChaincodeMessage_ERROR)
927927
serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
928928
return
929929
}
@@ -936,7 +936,7 @@ func (handler *Handler) handleExecuteQueryState(msg *pb.ChaincodeMessage) {
936936
if txContext == nil {
937937
return
938938
}
939-
fmt.Println("==CENDHU==" + executeQueryState.Query)
939+
940940
executeIter, err := txContext.txsimulator.ExecuteQuery(executeQueryState.Query)
941941
if err != nil {
942942
// Send error msg back to chaincode. GetState will not trigger event
@@ -960,8 +960,8 @@ func (handler *Handler) handleExecuteQueryState(msg *pb.ChaincodeMessage) {
960960
if qresult == nil {
961961
break
962962
}
963-
kv := qresult.(*ledger.KV)
964-
keyAndValue := pb.QueryStateKeyValue{Key: kv.Key, Value: kv.Value}
963+
queryRecord := qresult.(*ledger.QueryRecord)
964+
keyAndValue := pb.QueryStateKeyValue{Key: queryRecord.Key, Value: queryRecord.Record}
965965
keysAndValues = append(keysAndValues, &keyAndValue)
966966
}
967967

core/chaincode/shim/chaincode.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,12 @@ func (stub *ChaincodeStub) RangeQueryState(startKey, endKey string) (StateQueryI
336336
return &StateQueryIterator{stub.handler, stub.TxID, response, 0}, nil
337337
}
338338

339-
func (stub *ChaincodeStub) ExecuteQuery(query string) (StateQueryIteratorInterface, error) {
339+
// GetQueryResult function can be invoked by a chaincode to perform a
340+
// rich query against state database. Only supported by state database implementations
341+
// that support rich query. The query string is in the syntax of the underlying
342+
// state database. An iterator is returned which can be used to iterate (next) over
343+
// the query result set
344+
func (stub *ChaincodeStub) GetQueryResult(query string) (StateQueryIteratorInterface, error) {
340345
response, err := stub.handler.handleExecuteQueryState(query, stub.TxID)
341346
if err != nil {
342347
return nil, err

core/chaincode/shim/handler.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -552,11 +552,11 @@ func (handler *Handler) handleQueryStateNext(id, txid string) (*pb.QueryStateRes
552552

553553
defer handler.deleteChannel(txid)
554554

555-
// Send RANGE_QUERY_STATE_NEXT message to validator chaincode support
555+
// Send QUERY_STATE_NEXT message to validator chaincode support
556556
payload := &pb.QueryStateNext{ID: id}
557557
payloadBytes, err := proto.Marshal(payload)
558558
if err != nil {
559-
return nil, errors.New("Failed to process range query state next request")
559+
return nil, errors.New("Failed to process query state next request")
560560
}
561561
msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Payload: payloadBytes, Txid: txid}
562562
chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_NEXT)
@@ -574,7 +574,7 @@ func (handler *Handler) handleQueryStateNext(id, txid string) (*pb.QueryStateRes
574574
unmarshalErr := proto.Unmarshal(responseMsg.Payload, queryResponse)
575575
if unmarshalErr != nil {
576576
chaincodeLogger.Errorf("[%s]unmarshall error", shorttxid(responseMsg.Txid))
577-
return nil, errors.New("Error unmarshalling RangeQueryStateResponse.")
577+
return nil, errors.New("Error unmarshalling QueryStateResponse.")
578578
}
579579

580580
return queryResponse, nil
@@ -600,11 +600,11 @@ func (handler *Handler) handleQueryStateClose(id, txid string) (*pb.QueryStateRe
600600

601601
defer handler.deleteChannel(txid)
602602

603-
// Send RANGE_QUERY_STATE_CLOSE message to validator chaincode support
603+
// Send QUERY_STATE_CLOSE message to validator chaincode support
604604
payload := &pb.QueryStateClose{ID: id}
605605
payloadBytes, err := proto.Marshal(payload)
606606
if err != nil {
607-
return nil, errors.New("Failed to process range query state close request")
607+
return nil, errors.New("Failed to process query state close request")
608608
}
609609
msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Payload: payloadBytes, Txid: txid}
610610
chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_CLOSE)
@@ -622,7 +622,7 @@ func (handler *Handler) handleQueryStateClose(id, txid string) (*pb.QueryStateRe
622622
unmarshalErr := proto.Unmarshal(responseMsg.Payload, queryResponse)
623623
if unmarshalErr != nil {
624624
chaincodeLogger.Errorf("[%s]unmarshall error", shorttxid(responseMsg.Txid))
625-
return nil, errors.New("Error unmarshalling RangeQueryStateResponse.")
625+
return nil, errors.New("Error unmarshalling QueryStateResponse.")
626626
}
627627

628628
return queryResponse, nil
@@ -652,7 +652,7 @@ func (handler *Handler) handleExecuteQueryState(query string, txid string) (*pb.
652652
payload := &pb.ExecuteQueryState{Query: query}
653653
payloadBytes, err := proto.Marshal(payload)
654654
if err != nil {
655-
return nil, errors.New("Failed to process range query state request")
655+
return nil, errors.New("Failed to process query state request")
656656
}
657657
msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_EXECUTE_QUERY_STATE, Payload: payloadBytes, Txid: txid}
658658
chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_EXECUTE_QUERY_STATE)

core/chaincode/shim/interfaces.go

+17-12
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,31 @@ type ChaincodeStubInterface interface {
6666
// RangeQueryState function can be invoked by a chaincode to query of a range
6767
// of keys in the state. Assuming the startKey and endKey are in lexical
6868
// an iterator will be returned that can be used to iterate over all keys
69-
// between the startKey and endKey, inclusive. The order in which keys are
69+
// between the startKey (inclusive) and endKey (exclusive). The order in which keys are
7070
// returned by the iterator is random.
7171
RangeQueryState(startKey, endKey string) (StateQueryIteratorInterface, error)
7272

73-
//PartialCompositeKeyQuery function can be invoked by a chaincode to query the
74-
//state based on a given partial composite key. This function returns an
75-
//iterator which can be used to iterate over all composite keys whose prefix
76-
//matches the given partial composite key. This function should be used only for
77-
//a partial composite key. For a full composite key, an iter with empty response
78-
//would be returned.
73+
// PartialCompositeKeyQuery function can be invoked by a chaincode to query the
74+
// state based on a given partial composite key. This function returns an
75+
// iterator which can be used to iterate over all composite keys whose prefix
76+
// matches the given partial composite key. This function should be used only for
77+
// a partial composite key. For a full composite key, an iter with empty response
78+
// would be returned.
7979
PartialCompositeKeyQuery(objectType string, keys []string) (StateQueryIteratorInterface, error)
8080

81-
//Given a list of attributes, CreateCompositeKey function combines these attributes
82-
//to form a composite key.
81+
// Given a list of attributes, CreateCompositeKey function combines these attributes
82+
// to form a composite key.
8383
CreateCompositeKey(objectType string, attributes []string) (string, error)
8484

85-
ExecuteQuery(query string) (StateQueryIteratorInterface, error)
85+
// GetQueryResult function can be invoked by a chaincode to perform a
86+
// rich query against state database. Only supported by state database implementations
87+
// that support rich query. The query string is in the syntax of the underlying
88+
// state database. An iterator is returned which can be used to iterate (next) over
89+
// the query result set
90+
GetQueryResult(query string) (StateQueryIteratorInterface, error)
8691

87-
//Given a composite key, SplitCompositeKey function splits the key into attributes
88-
//on which the composite key was formed.
92+
// Given a composite key, SplitCompositeKey function splits the key into attributes
93+
// on which the composite key was formed.
8994
SplitCompositeKey(compositeKey string) (string, []string, error)
9095

9196
// GetCallerCertificate returns caller certificate

core/chaincode/shim/mockstub.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,15 @@ func (stub *MockStub) RangeQueryState(startKey, endKey string) (StateQueryIterat
192192
return NewMockStateRangeQueryIterator(stub, startKey, endKey), nil
193193
}
194194

195-
func (stub *MockStub) ExecuteQuery(query string) (StateQueryIteratorInterface, error) {
195+
// GetQueryResult function can be invoked by a chaincode to perform a
196+
// rich query against state database. Only supported by state database implementations
197+
// that support rich query. The query string is in the syntax of the underlying
198+
// state database. An iterator is returned which can be used to iterate (next) over
199+
// the query result set
200+
func (stub *MockStub) GetQueryResult(query string) (StateQueryIteratorInterface, error) {
201+
// Not implemented since the mock engine does not have a query engine.
202+
// However, a very simple query engine that supports string matching
203+
// could be implemented to test that the framework supports queries
196204
return nil, errors.New("Not Implemented")
197205
}
198206

examples/chaincode/go/map/map.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
115115
return shim.Success(jsonKeys)
116116
case "query":
117117
query := args[0]
118-
keysIter, err := stub.ExecuteQuery(query)
118+
keysIter, err := stub.GetQueryResult(query)
119119
if err != nil {
120120
return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err))
121121
}

0 commit comments

Comments
 (0)