mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 15:35:09 +00:00
Fix ledger queries sample - history and pagination (#288)
Fix history query results. Fix paginated query results. Signed-off-by: David Enyeart <enyeart@us.ibm.com>
This commit is contained in:
parent
17dbe839f1
commit
1d6d557570
1 changed files with 38 additions and 35 deletions
|
|
@ -96,13 +96,19 @@ type Asset struct {
|
||||||
AppraisedValue int `json:"appraisedValue"`
|
AppraisedValue int `json:"appraisedValue"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryResult structure used for handling result of query
|
// HistoryQueryResult structure used for returning result of history query
|
||||||
type QueryResult struct {
|
type HistoryQueryResult struct {
|
||||||
Record *Asset
|
Record *Asset `json:"record"`
|
||||||
TxId string `json:"txID"`
|
TxID string `json:"txID"`
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
FetchedRecordsCount int `json:"fetchedRecordsCount"`
|
IsDelete bool `json:"isDelete"`
|
||||||
Bookmark string `json:"bookmark"`
|
}
|
||||||
|
|
||||||
|
// PaginatedQueryResult structure used for returning paginated query results and metadata
|
||||||
|
type PaginatedQueryResult struct {
|
||||||
|
Records []*Asset `json:"records"`
|
||||||
|
FetchedRecordsCount int32 `json:"fetchedRecordsCount"`
|
||||||
|
Bookmark string `json:"bookmark"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAsset initializes a new asset in the ledger
|
// CreateAsset initializes a new asset in the ledger
|
||||||
|
|
@ -158,13 +164,13 @@ func (t *SimpleChaincode) ReadAsset(ctx contractapi.TransactionContextInterface,
|
||||||
return nil, fmt.Errorf("asset %s does not exist", assetID)
|
return nil, fmt.Errorf("asset %s does not exist", assetID)
|
||||||
}
|
}
|
||||||
|
|
||||||
var asset *Asset
|
var asset Asset
|
||||||
err = json.Unmarshal(assetBytes, &asset)
|
err = json.Unmarshal(assetBytes, &asset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return asset, nil
|
return &asset, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAsset removes an asset key-value pair from the ledger
|
// DeleteAsset removes an asset key-value pair from the ledger
|
||||||
|
|
@ -212,12 +218,12 @@ func constructQueryResponseFromIterator(resultsIterator shim.StateQueryIteratorI
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var asset *Asset
|
var asset Asset
|
||||||
err = json.Unmarshal(queryResult.Value, &asset)
|
err = json.Unmarshal(queryResult.Value, &asset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
assets = append(assets, asset)
|
assets = append(assets, &asset)
|
||||||
}
|
}
|
||||||
|
|
||||||
return assets, nil
|
return assets, nil
|
||||||
|
|
@ -325,12 +331,7 @@ func getQueryResultForQueryString(ctx contractapi.TransactionContextInterface, q
|
||||||
// The number of fetched records will be equal to or lesser than the page size.
|
// 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.
|
// Paginated range queries are only valid for read only transactions.
|
||||||
// Example: Pagination with Range Query
|
// Example: Pagination with Range Query
|
||||||
func (t *SimpleChaincode) GetAssetsByRangeWithPagination(
|
func (t *SimpleChaincode) GetAssetsByRangeWithPagination(ctx contractapi.TransactionContextInterface, startKey string, endKey string, pageSize int, bookmark string) ([]*Asset, error) {
|
||||||
ctx contractapi.TransactionContextInterface,
|
|
||||||
startKey,
|
|
||||||
endKey,
|
|
||||||
bookmark string,
|
|
||||||
pageSize int) ([]*Asset, error) {
|
|
||||||
|
|
||||||
resultsIterator, _, err := ctx.GetStub().GetStateByRangeWithPagination(startKey, endKey, int32(pageSize), bookmark)
|
resultsIterator, _, err := ctx.GetStub().GetStateByRangeWithPagination(startKey, endKey, int32(pageSize), bookmark)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -349,48 +350,49 @@ func (t *SimpleChaincode) GetAssetsByRangeWithPagination(
|
||||||
// Only available on state databases that support rich query (e.g. CouchDB)
|
// Only available on state databases that support rich query (e.g. CouchDB)
|
||||||
// Paginated queries are only valid for read only transactions.
|
// Paginated queries are only valid for read only transactions.
|
||||||
// Example: Pagination with Ad hoc Rich Query
|
// Example: Pagination with Ad hoc Rich Query
|
||||||
func (t *SimpleChaincode) QueryAssetsWithPagination(
|
func (t *SimpleChaincode) QueryAssetsWithPagination(ctx contractapi.TransactionContextInterface, queryString string, pageSize int, bookmark string) (*PaginatedQueryResult, error) {
|
||||||
ctx contractapi.TransactionContextInterface,
|
|
||||||
queryString,
|
|
||||||
bookmark string,
|
|
||||||
pageSize int) ([]*Asset, error) {
|
|
||||||
|
|
||||||
return getQueryResultForQueryStringWithPagination(ctx, queryString, int32(pageSize), bookmark)
|
return getQueryResultForQueryStringWithPagination(ctx, queryString, int32(pageSize), bookmark)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getQueryResultForQueryStringWithPagination executes the passed in query string with
|
// getQueryResultForQueryStringWithPagination executes the passed in query string with
|
||||||
// pagination info. The result set is built and returned as a byte array containing the JSON results.
|
// pagination info. The result set is built and returned as a byte array containing the JSON results.
|
||||||
func getQueryResultForQueryStringWithPagination(
|
func getQueryResultForQueryStringWithPagination(ctx contractapi.TransactionContextInterface, queryString string, pageSize int32, bookmark string) (*PaginatedQueryResult, error) {
|
||||||
ctx contractapi.TransactionContextInterface,
|
|
||||||
queryString string,
|
|
||||||
pageSize int32,
|
|
||||||
bookmark string) ([]*Asset, error) {
|
|
||||||
|
|
||||||
resultsIterator, _, err := ctx.GetStub().GetQueryResultWithPagination(queryString, pageSize, bookmark)
|
resultsIterator, responseMetadata, err := ctx.GetStub().GetQueryResultWithPagination(queryString, pageSize, bookmark)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer resultsIterator.Close()
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetHistory returns the chain of custody for an asset since issuance.
|
// GetAssetHistory returns the chain of custody for an asset since issuance.
|
||||||
func (t *SimpleChaincode) GetAssetHistory(ctx contractapi.TransactionContextInterface, assetID string) ([]QueryResult, error) {
|
func (t *SimpleChaincode) GetAssetHistory(ctx contractapi.TransactionContextInterface, assetID string) ([]HistoryQueryResult, error) {
|
||||||
resultsIterator, err := ctx.GetStub().GetHistoryForKey(assetID)
|
resultsIterator, err := ctx.GetStub().GetHistoryForKey(assetID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer resultsIterator.Close()
|
defer resultsIterator.Close()
|
||||||
|
|
||||||
var records []QueryResult
|
var records []HistoryQueryResult
|
||||||
for resultsIterator.HasNext() {
|
for resultsIterator.HasNext() {
|
||||||
response, err := resultsIterator.Next()
|
response, err := resultsIterator.Next()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var asset *Asset
|
var asset Asset
|
||||||
err = json.Unmarshal(response.Value, &asset)
|
err = json.Unmarshal(response.Value, &asset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -400,10 +402,11 @@ func (t *SimpleChaincode) GetAssetHistory(ctx contractapi.TransactionContextInte
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
record := QueryResult{
|
record := HistoryQueryResult{
|
||||||
TxId: response.TxId,
|
TxID: response.TxId,
|
||||||
Timestamp: timestamp,
|
Timestamp: timestamp,
|
||||||
Record: asset,
|
Record: &asset,
|
||||||
|
IsDelete: response.IsDelete,
|
||||||
}
|
}
|
||||||
records = append(records, record)
|
records = append(records, record)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue