diff --git a/asset-transfer-ledger-queries/application-java/src/main/java/application/java/App.java b/asset-transfer-ledger-queries/application-java/src/main/java/application/java/App.java index 2a1b74cb..b8cd2799 100644 --- a/asset-transfer-ledger-queries/application-java/src/main/java/application/java/App.java +++ b/asset-transfer-ledger-queries/application-java/src/main/java/application/java/App.java @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -// Running TestApp: -// gradle runApp +// Running TestApp: +// gradle runApp package application.java; @@ -128,7 +128,7 @@ public class App { result = contract.evaluateTransaction("QueryAssets","{\"selector\":{\"docType\":\"asset\",\"owner\":\"Jin Soo\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}"); System.out.println("result: " + new String(result)); - // Rich Query with Pagination (Only supported if CouchDB is used as state database) + // Range Query with Pagination System.out.println("\n"); System.out.println("Evaluate Transaction:GetAssetsByRangeWithPagination assets 3-5"); result = contract.evaluateTransaction("GetAssetsByRangeWithPagination", "asset3", "asset6", "3",""); diff --git a/asset-transfer-ledger-queries/application-javascript/app.js b/asset-transfer-ledger-queries/application-javascript/app.js index 73fc83a1..f10f400f 100644 --- a/asset-transfer-ledger-queries/application-javascript/app.js +++ b/asset-transfer-ledger-queries/application-javascript/app.js @@ -181,8 +181,8 @@ async function main() { result = await contract.evaluateTransaction('AssetExists', 'asset7'); console.log(`*** Result: ${prettyJSONString(result.toString())}`); - console.log('\n--> Submit Transaction: TransferAsset, transfer asset(asset2) to new owner(Tom)'); - await contract.submitTransaction('TransferAsset', 'asset2', 'Tom'); + console.log('\n--> Submit Transaction: TransferAsset, transfer asset(asset2) to new owner(Max)'); + await contract.submitTransaction('TransferAsset', 'asset2', 'Max'); console.log('*** Result: committed'); console.log('\n--> Evaluate Transaction: ReadAsset, function returns information about an asset with ID(asset2)'); @@ -190,15 +190,15 @@ async function main() { console.log(`*** Result: ${prettyJSONString(result.toString())}`); // Rich Query with Pagination (Only supported if CouchDB is used as state database) - console.log('\n--> Evaluate Transaction: QueryAssetsWithPagination, function returns "Tom" assets'); - result = await contract.evaluateTransaction('QueryAssetsWithPagination', '{"selector":{"docType":"asset","owner":"Tom"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}', '1', ''); + console.log('\n--> Evaluate Transaction: QueryAssetsWithPagination, function returns "Max" assets'); + result = await contract.evaluateTransaction('QueryAssetsWithPagination', '{"selector":{"docType":"asset","owner":"Max"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}', '1', ''); console.log(`*** Result: ${prettyJSONString(result.toString())}`); // Recover the bookmark from previous query. Normally it will be inside a variable. const resultJson = JSON.parse(result.toString()); - console.log('\n--> Evaluate Transaction: QueryAssetsWithPagination, function returns "Tom" assets next page'); - result = await contract.evaluateTransaction('QueryAssetsWithPagination', '{"selector":{"docType":"asset","owner":"Tom"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}', '1', resultJson.ResponseMetadata.Bookmark); + console.log('\n--> Evaluate Transaction: QueryAssetsWithPagination, function returns "Max" assets next page'); + result = await contract.evaluateTransaction('QueryAssetsWithPagination', '{"selector":{"docType":"asset","owner":"Max"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}', '1', resultJson.bookmark); console.log(`*** Result: ${prettyJSONString(result.toString())}`); console.log('\n--> Submit Transaction: TransferAssetByColor, transfer all yellow assets to new owner(Michel)'); @@ -224,14 +224,14 @@ async function main() { result = await contract.evaluateTransaction('QueryAssets', '{"selector":{"docType":"asset","owner":"Jin Soo"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}'); console.log(`*** Result: ${prettyJSONString(result.toString())}`); - // Rich Query with Pagination (Only supported if CouchDB is used as state database) - console.log('\n--> Evaluate Transaction: GetAssetsByRangeWithPagination - get page 1 of assets from asset3 to asset6 (asset3, asset4)'); - result = await contract.evaluateTransaction('GetAssetsByRangeWithPagination', 'asset3', 'asset6', '2', ''); + // Range Query with Pagination + console.log('\n--> Evaluate Transaction: GetAssetsByRangeWithPagination - get page 1 of assets from asset2 to asset6 (asset2, asset3)'); + result = await contract.evaluateTransaction('GetAssetsByRangeWithPagination', 'asset2', 'asset6', '2', ''); console.log(`*** Result: ${prettyJSONString(result.toString())}`); - // Rich Query with Pagination (Only supported if CouchDB is used as state database) - console.log('\n--> Evaluate Transaction: GetAssetsByRangeWithPagination - get page 2 of assets from asset3 to asset6 (asset4, asset5)'); - result = await contract.evaluateTransaction('GetAssetsByRangeWithPagination', 'asset3', 'asset6', '2', 'asset4'); + // Range Query with Pagination + console.log('\n--> Evaluate Transaction: GetAssetsByRangeWithPagination - get page 2 of assets from asset2 to asset6 (asset4, asset5)'); + result = await contract.evaluateTransaction('GetAssetsByRangeWithPagination', 'asset2', 'asset6', '2', 'asset4'); console.log(`*** Result: ${prettyJSONString(result.toString())}`); console.log('*** all tests completed'); diff --git a/asset-transfer-ledger-queries/chaincode-go/asset_transfer_ledger_chaincode.go b/asset-transfer-ledger-queries/chaincode-go/asset_transfer_ledger_chaincode.go index 44cbdb1f..fb2a6cb9 100644 --- a/asset-transfer-ledger-queries/chaincode-go/asset_transfer_ledger_chaincode.go +++ b/asset-transfer-ledger-queries/chaincode-go/asset_transfer_ledger_chaincode.go @@ -99,7 +99,7 @@ type Asset struct { // HistoryQueryResult structure used for returning result of history query type HistoryQueryResult struct { Record *Asset `json:"record"` - TxId string `json:"txId"` + TxId string `json:"txId"` Timestamp time.Time `json:"timestamp"` IsDelete bool `json:"isDelete"` } @@ -331,15 +331,24 @@ func getQueryResultForQueryString(ctx contractapi.TransactionContextInterface, q // The number of fetched records will be equal to or lesser than the page size. // Paginated range queries are only valid for read only transactions. // Example: Pagination with Range Query -func (t *SimpleChaincode) GetAssetsByRangeWithPagination(ctx contractapi.TransactionContextInterface, startKey string, endKey string, pageSize int, bookmark string) ([]*Asset, error) { +func (t *SimpleChaincode) GetAssetsByRangeWithPagination(ctx contractapi.TransactionContextInterface, startKey string, endKey string, pageSize int, bookmark string) (*PaginatedQueryResult, error) { - resultsIterator, _, err := ctx.GetStub().GetStateByRangeWithPagination(startKey, endKey, int32(pageSize), bookmark) + resultsIterator, responseMetadata, err := ctx.GetStub().GetStateByRangeWithPagination(startKey, endKey, int32(pageSize), bookmark) if err != nil { return nil, err } defer resultsIterator.Close() - return constructQueryResponseFromIterator(resultsIterator) + assets, err := constructQueryResponseFromIterator(resultsIterator) + if err != nil { + return nil, err + } + + return &PaginatedQueryResult{ + Records: assets, + FetchedRecordsCount: responseMetadata.FetchedRecordsCount, + Bookmark: responseMetadata.Bookmark, + }, nil } // QueryAssetsWithPagination uses a query string, page size and a bookmark to perform a query diff --git a/asset-transfer-ledger-queries/chaincode-javascript/lib/asset_transfer_ledger_chaincode.js b/asset-transfer-ledger-queries/chaincode-javascript/lib/asset_transfer_ledger_chaincode.js index 1fe1d29d..fbd92152 100644 --- a/asset-transfer-ledger-queries/chaincode-javascript/lib/asset_transfer_ledger_chaincode.js +++ b/asset-transfer-ledger-queries/chaincode-javascript/lib/asset_transfer_ledger_chaincode.js @@ -266,10 +266,9 @@ class Chaincode extends Contract { results.results = await this._GetAllResults(iterator, false); - results.ResponseMetadata = { - RecordsCount: metadata.fetchedRecordsCount, - Bookmark: metadata.bookmark, - }; + results.fetchedRecordsCount = metadata.fetchedRecordsCount; + + results.bookmark = metadata.bookmark; return JSON.stringify(results); } @@ -289,10 +288,9 @@ class Chaincode extends Contract { results.results = await this._GetAllResults(iterator, false); - results.ResponseMetadata = { - RecordsCount: metadata.fetchedRecordsCount, - Bookmark: metadata.bookmark, - }; + results.fetchedRecordsCount = metadata.fetchedRecordsCount; + + results.bookmark = metadata.bookmark; return JSON.stringify(results); }