|
18 | 18 | // peer chaincode query -C myc1 -n marbles -c '{"Args":["readMarble","marble1"]}'
|
19 | 19 | // peer chaincode query -C myc1 -n marbles -c '{"Args":["getMarblesByRange","marble1","marble3"]}'
|
20 | 20 | // peer chaincode query -C myc1 -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}'
|
| 21 | +// peer chaincode query -C myc1 -n marbles -c '{"Args":["getMarblesByRangeWithPagination","marble1","marble3","3",""]}' |
21 | 22 |
|
22 | 23 | // Rich Query (Only supported if CouchDB is used as state database):
|
23 |
| -// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarblesByOwner","tom"]}' |
24 |
| -// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"tom\"}}"]}' |
| 24 | +// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarblesByOwner","tom"]}' |
| 25 | +// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"tom\"}}"]}' |
| 26 | + |
| 27 | +// Rich Query with Pagination (Only supported if CouchDB is used as state database): |
| 28 | +// peer chaincode query -C myc1 -n marbles -c '{"Args":["queryMarblesWithPagination","{\"selector\":{\"owner\":\"tom\"}}","3",""]}' |
25 | 29 |
|
26 | 30 | 'use strict';
|
27 | 31 | const shim = require('fabric-shim');
|
@@ -404,6 +408,74 @@ let Chaincode = class {
|
404 | 408 |
|
405 | 409 | return Buffer.from(JSON.stringify(results));
|
406 | 410 | }
|
| 411 | + |
| 412 | + // ====== Pagination ========================================================================= |
| 413 | + // Pagination provides a method to retrieve records with a defined pagesize and |
| 414 | + // start point (bookmark). An empty string bookmark defines the first "page" of a query |
| 415 | + // result. Paginated queries return a bookmark that can be used in |
| 416 | + // the next query to retrieve the next page of results. Paginated queries extend |
| 417 | + // rich queries and range queries to include a pagesize and bookmark. |
| 418 | + // |
| 419 | + // Two examples are provided in this example. The first is getMarblesByRangeWithPagination |
| 420 | + // which executes a paginated range query. |
| 421 | + // The second example is a paginated query for rich ad-hoc queries. |
| 422 | + // ========================================================================================= |
| 423 | + |
| 424 | + // ====== Example: Pagination with Range Query =============================================== |
| 425 | + // getMarblesByRangeWithPagination performs a range query based on the start & end key, |
| 426 | + // page size and a bookmark. |
| 427 | + // |
| 428 | + // The number of fetched records will be equal to or lesser than the page size. |
| 429 | + // Paginated range queries are only valid for read only transactions. |
| 430 | + // =========================================================================================== |
| 431 | + async getMarblesByRangeWithPagination(stub, args, thisClass) { |
| 432 | + if (args.length < 2) { |
| 433 | + throw new Error('Incorrect number of arguments. Expecting 2'); |
| 434 | + } |
| 435 | + const startKey = args[0]; |
| 436 | + const endKey = args[1]; |
| 437 | + |
| 438 | + const pageSize = parseInt(args[2], 10); |
| 439 | + const bookmark = args[3]; |
| 440 | + |
| 441 | + const { iterator, metadata } = await stub.getStateByRangeWithPagination(startKey, endKey, pageSize, bookmark); |
| 442 | + const getAllResults = thisClass['getAllResults']; |
| 443 | + const results = await getAllResults(iterator, false); |
| 444 | + // use RecordsCount and Bookmark to keep consistency with the go sample |
| 445 | + results.ResponseMetadata = { |
| 446 | + RecordsCount: metadata.fetched_records_count, |
| 447 | + Bookmark: metadata.bookmark, |
| 448 | + }; |
| 449 | + return Buffer.from(JSON.stringify(results)); |
| 450 | + } |
| 451 | + |
| 452 | + // ========================================================================================= |
| 453 | + // getQueryResultForQueryStringWithPagination executes the passed in query string with |
| 454 | + // pagination info. Result set is built and returned as a byte array containing the JSON results. |
| 455 | + // ========================================================================================= |
| 456 | + async queryMarblesWithPagination(stub, args, thisClass) { |
| 457 | + |
| 458 | + // 0 |
| 459 | + // "queryString" |
| 460 | + if (args.length < 3) { |
| 461 | + return shim.Error("Incorrect number of arguments. Expecting 3") |
| 462 | + } |
| 463 | + |
| 464 | + const queryString = args[0]; |
| 465 | + const pageSize = parseInt(args[2], 10); |
| 466 | + const bookmark = args[3]; |
| 467 | + |
| 468 | + const { iterator, metadata } = await stub.GetQueryResultWithPagination(queryString, pageSize, bookmark); |
| 469 | + const getAllResults = thisClass['getAllResults']; |
| 470 | + const results = await getAllResults(iterator, false); |
| 471 | + // use RecordsCount and Bookmark to keep consistency with the go sample |
| 472 | + results.ResponseMetadata = { |
| 473 | + RecordsCount: metadata.fetched_records_count, |
| 474 | + Bookmark: metadata.bookmark, |
| 475 | + }; |
| 476 | + |
| 477 | + return Buffer.from(JSON.stringify(results)); |
| 478 | + } |
407 | 479 | };
|
408 | 480 |
|
409 | 481 | shim.start(new Chaincode());
|
0 commit comments