Skip to content

Commit 9da35a2

Browse files
author
Chris Elder
committed
FAB-1985 Scope rich queries to chaincode context
Motivation for this change: Need to inject chaincodeid filter on rich queries called from chaincode. Need to add a parameter to QSCC GetQueryResult() to scope queries to a certain chaincode. - This change will add the interface and method signature changes required to add the chaincodeid to the execute query methods. Change-Id: Ia57001d6861862876d5df621a94e2c4b5e288d1d Signed-off-by: Chris Elder <[email protected]>
1 parent 1504eaa commit 9da35a2

File tree

11 files changed

+36
-28
lines changed

11 files changed

+36
-28
lines changed

core/chaincode/handler.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,9 @@ func (handler *Handler) handleGetQueryResult(msg *pb.ChaincodeMessage) {
964964
return
965965
}
966966

967-
executeIter, err := txContext.txsimulator.ExecuteQuery(getQueryResult.Query)
967+
chaincodeID := handler.getCCRootName()
968+
969+
executeIter, err := txContext.txsimulator.ExecuteQuery(chaincodeID, getQueryResult.Query)
968970
if err != nil {
969971
// Send error msg back to chaincode. GetState will not trigger event
970972
payload := []byte(err.Error())

core/ledger/kvledger/txmgmt/statedb/commontests/test_common.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ func TestQuery(t *testing.T, dbProvider statedb.VersionedDBProvider) {
207207
db.ApplyUpdates(batch, savePoint)
208208

209209
// query for owner=jerry
210-
itr, err := db.ExecuteQuery("{\"selector\":{\"owner\":\"jerry\"}}")
210+
itr, err := db.ExecuteQuery("ns1", "{\"selector\":{\"owner\":\"jerry\"}}")
211211
testutil.AssertNoError(t, err, "")
212212

213213
// verify one jerry result
@@ -225,11 +225,11 @@ func TestQuery(t *testing.T, dbProvider statedb.VersionedDBProvider) {
225225
testutil.AssertNil(t, queryResult2)
226226

227227
// query using bad query string
228-
itr, err = db.ExecuteQuery("this is an invalid query string")
228+
itr, err = db.ExecuteQuery("ns1", "this is an invalid query string")
229229
testutil.AssertError(t, err, "Should have received an error for invalid query string")
230230

231231
// query returns 0 records
232-
itr, err = db.ExecuteQuery("{\"selector\":{\"owner\":\"not_a_valid_name\"}}")
232+
itr, err = db.ExecuteQuery("ns1", "{\"selector\":{\"owner\":\"not_a_valid_name\"}}")
233233
testutil.AssertNoError(t, err, "")
234234

235235
// verify no results
@@ -238,7 +238,7 @@ func TestQuery(t *testing.T, dbProvider statedb.VersionedDBProvider) {
238238
testutil.AssertNil(t, queryResult3)
239239

240240
// query with fields
241-
itr, err = db.ExecuteQuery("{\"selector\":{\"owner\":\"jerry\"},\"fields\": [\"owner\", \"asset_name\", \"color\", \"size\"]}")
241+
itr, err = db.ExecuteQuery("ns1", "{\"selector\":{\"owner\":\"jerry\"},\"fields\": [\"owner\", \"asset_name\", \"color\", \"size\"]}")
242242
testutil.AssertNoError(t, err, "")
243243

244244
// verify one jerry result
@@ -256,7 +256,7 @@ func TestQuery(t *testing.T, dbProvider statedb.VersionedDBProvider) {
256256
testutil.AssertNil(t, queryResult2)
257257

258258
// query with complex selector
259-
itr, err = db.ExecuteQuery("{\"selector\":{\"$and\":[{\"size\":{\"$gt\": 5}},{\"size\":{\"$lt\":8}},{\"$not\":{\"size\":6}}]}}")
259+
itr, err = db.ExecuteQuery("ns1", "{\"selector\":{\"$and\":[{\"size\":{\"$gt\": 5}},{\"size\":{\"$lt\":8}},{\"$not\":{\"size\":6}}]}}")
260260
testutil.AssertNoError(t, err, "")
261261

262262
// verify one fred result
@@ -274,7 +274,7 @@ func TestQuery(t *testing.T, dbProvider statedb.VersionedDBProvider) {
274274
testutil.AssertNil(t, queryResult2)
275275

276276
// query with embedded implicit "AND" and explicit "OR"
277-
itr, err = db.ExecuteQuery("{\"selector\":{\"color\":\"green\",\"$or\":[{\"owner\":\"fred\"},{\"owner\":\"mary\"}]}}")
277+
itr, err = db.ExecuteQuery("ns1", "{\"selector\":{\"color\":\"green\",\"$or\":[{\"owner\":\"fred\"},{\"owner\":\"mary\"}]}}")
278278
testutil.AssertNoError(t, err, "")
279279

280280
// verify one green result

core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ Result Wrapped Query:
3434
3535
3636
*/
37-
func ApplyQueryWrapper(queryString string) string {
37+
func ApplyQueryWrapper(namespace, queryString string) string {
38+
39+
//TODO - namespace is being added to support scoping queries to the correct chaincode context
40+
// A followup change will add the implementation for enabling the namespace filter
3841

3942
//create a generic map for the query json
4043
jsonQueryMap := make(map[string]interface{})

core/ledger/kvledger/txmgmt/statedb/statecouchdb/query_wrapper_test.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestSimpleQuery(t *testing.T) {
2828

2929
rawQuery := []byte(`{"selector":{"owner":{"$eq":"jerry"}},"limit": 10,"skip": 0}`)
3030

31-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
31+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
3232

3333
//There should be one wrapped field
3434
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"data.owner\""), 1)
@@ -46,7 +46,7 @@ func TestQueryWithOperator(t *testing.T) {
4646

4747
rawQuery := []byte(`{"selector":{"$or":[{"owner":{"$eq":"jerry"}},{"owner": {"$eq": "frank"}}]},"limit": 10,"skip": 0}`)
4848

49-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
49+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
5050

5151
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"data.owner\""), 2)
5252

@@ -66,7 +66,7 @@ func TestQueryWithImplicitOperatorAndExplicitOperator(t *testing.T) {
6666

6767
rawQuery := []byte(`{"selector":{"color":"green","$or":[{"owner":"fred"},{"owner":"mary"}]}}`)
6868

69-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
69+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
7070

7171
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"data.owner\""), 2)
7272

@@ -88,7 +88,7 @@ func TestQueryWithFields(t *testing.T) {
8888

8989
rawQuery := []byte(`{"selector":{"owner": {"$eq": "tom"}},"fields": ["owner", "asset_name", "color", "size"], "limit": 10, "skip": 0}`)
9090

91-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
91+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
9292

9393
//$eq operator should be unchanged
9494
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"$eq\""), 1)
@@ -112,7 +112,7 @@ func TestQueryWithSortFields(t *testing.T) {
112112

113113
rawQuery := []byte(`{"selector":{"owner": {"$eq": "tom"}},"fields": ["owner", "asset_name", "color", "size"], "sort": ["size", "color"], "limit": 10, "skip": 0}`)
114114

115-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
115+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
116116

117117
//$eq operator should be unchanged
118118
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"$eq\""), 1)
@@ -136,7 +136,7 @@ func TestQueryWithSortObjects(t *testing.T) {
136136

137137
rawQuery := []byte(`{"selector":{"owner": {"$eq": "tom"}},"fields": ["owner", "asset_name", "color", "size"], "sort": [{"size": "desc"}, {"color": "desc"}], "limit": 10, "skip": 0}`)
138138

139-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
139+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
140140

141141
//$eq operator should be unchanged
142142
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"$eq\""), 1)
@@ -173,7 +173,7 @@ func TestQueryLeadingOperator(t *testing.T) {
173173
}
174174
}`)
175175

176-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
176+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
177177

178178
//$and operator should be unchanged
179179
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"$and\""), 1)
@@ -200,7 +200,7 @@ func TestQueryLeadingAndEmbeddedOperator(t *testing.T) {
200200
]
201201
}}`)
202202

203-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
203+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
204204

205205
//$and operator should be unchanged
206206
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"$and\""), 1)
@@ -242,7 +242,7 @@ func TestQueryEmbeddedOperatorAndArrayOfObjects(t *testing.T) {
242242
}
243243
}`)
244244

245-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
245+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
246246

247247
//$and operator should be unchanged
248248
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"$and\""), 1)
@@ -270,7 +270,7 @@ func TestQueryEmbeddedOperatorAndArrayOfValues(t *testing.T) {
270270
}
271271
}`)
272272

273-
wrappedQuery := []byte(ApplyQueryWrapper(string(rawQuery)))
273+
wrappedQuery := []byte(ApplyQueryWrapper("ns1", string(rawQuery)))
274274

275275
//$gt operator should be unchanged
276276
testutil.AssertEquals(t, strings.Count(string(wrappedQuery), "\"$gt\""), 1)

core/ledger/kvledger/txmgmt/statedb/statecouchdb/statecouchdb.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,14 @@ func (vdb *VersionedDB) GetStateRangeScanIterator(namespace string, startKey str
224224
}
225225

226226
// ExecuteQuery implements method in VersionedDB interface
227-
func (vdb *VersionedDB) ExecuteQuery(query string) (statedb.ResultsIterator, error) {
227+
func (vdb *VersionedDB) ExecuteQuery(namespace, query string) (statedb.ResultsIterator, error) {
228228

229229
//TODO - limit is currently set at 1000, eventually this will need to be changed
230230
//to reflect a config option and potentially return an exception if the threshold is exceeded
231231
// skip (paging) is not utilized by fabric
232-
queryResult, err := vdb.db.QueryDocuments(string(ApplyQueryWrapper(query)), 1000, 0)
232+
queryString := ApplyQueryWrapper(namespace, query)
233+
234+
queryResult, err := vdb.db.QueryDocuments(queryString, 1000, 0)
233235
if err != nil {
234236
logger.Debugf("Error calling QueryDocuments(): %s\n", err.Error())
235237
return nil, err

core/ledger/kvledger/txmgmt/statedb/statedb.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ type VersionedDB interface {
4343
// The returned ResultsIterator contains results of type *VersionedKV
4444
GetStateRangeScanIterator(namespace string, startKey string, endKey string) (ResultsIterator, error)
4545
// ExecuteQuery executes the given query and returns an iterator that contains results of type *VersionedKV.
46-
ExecuteQuery(query string) (ResultsIterator, error)
46+
ExecuteQuery(namespace, query string) (ResultsIterator, error)
4747
// ApplyUpdates applies the batch to the underlying db.
4848
// height is the height of the highest transaction in the Batch that
4949
// a state db implementation is expected to ues as a save point

core/ledger/kvledger/txmgmt/statedb/stateleveldb/stateleveldb.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func (vdb *versionedDB) GetStateRangeScanIterator(namespace string, startKey str
122122
}
123123

124124
// ExecuteQuery implements method in VersionedDB interface
125-
func (vdb *versionedDB) ExecuteQuery(query string) (statedb.ResultsIterator, error) {
125+
func (vdb *versionedDB) ExecuteQuery(namespace, query string) (statedb.ResultsIterator, error) {
126126
return nil, errors.New("ExecuteQuery not supported for leveldb")
127127
}
128128

core/ledger/kvledger/txmgmt/txmgr/commontests/txmgr_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ func testExecuteQuery(t *testing.T, env testEnv) {
559559
queryExecuter, _ := txMgr.NewQueryExecutor()
560560
queryString := "{\"selector\":{\"owner\": {\"$eq\": \"bob\"}},\"limit\": 10,\"skip\": 0}"
561561

562-
itr, _ := queryExecuter.ExecuteQuery(queryString)
562+
itr, _ := queryExecuter.ExecuteQuery("ns1", queryString)
563563

564564
counter := 0
565565
for {

core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/helper.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ func (h *queryHelper) getStateRangeScanIterator(namespace string, startKey strin
7474
return itr, nil
7575
}
7676

77-
func (h *queryHelper) executeQuery(query string) (commonledger.ResultsIterator, error) {
78-
dbItr, err := h.txmgr.db.ExecuteQuery(query)
77+
func (h *queryHelper) executeQuery(namespace, query string) (commonledger.ResultsIterator, error) {
78+
dbItr, err := h.txmgr.db.ExecuteQuery(namespace, query)
7979
if err != nil {
8080
return nil, err
8181
}

core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/lockbased_query_executer.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ func (q *lockBasedQueryExecutor) GetStateRangeScanIterator(namespace string, sta
5353
}
5454

5555
// ExecuteQuery implements method in interface `ledger.QueryExecutor`
56-
func (q *lockBasedQueryExecutor) ExecuteQuery(query string) (ledger.ResultsIterator, error) {
57-
return q.helper.executeQuery(query)
56+
func (q *lockBasedQueryExecutor) ExecuteQuery(namespace, query string) (ledger.ResultsIterator, error) {
57+
return q.helper.executeQuery(namespace, query)
5858
}
5959

6060
// Done implements method in interface `ledger.QueryExecutor`

core/ledger/ledger_interface.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ type QueryExecutor interface {
8686
GetStateRangeScanIterator(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error)
8787
// ExecuteQuery executes the given query and returns an iterator that contains results of type specific to the underlying data store.
8888
// Only used for state databases that support query
89-
ExecuteQuery(query string) (commonledger.ResultsIterator, error)
89+
// For a chaincode, the namespace corresponds to the chaincodeId
90+
ExecuteQuery(namespace, query string) (commonledger.ResultsIterator, error)
9091
// Done releases resources occupied by the QueryExecutor
9192
Done()
9293
}

0 commit comments

Comments
 (0)