gohyperledger-fabricshimhyperledger-chaincode

How does shim.GetStateByPartialCompositeKey iterator works in this code?


I am writing the chaincode in which I am putting some data into ledger and then tried to list it using shim.GetStateByPartialCompositeKey() where I get the list of my data from the iterator. Now I want to sort my data according to the timestamp(which is formatted in terms of date only and not taking hours, minutes or seconds). So, I want to know if the data I listed from the iterator comes in sorted order in terms of timestamp in which they are stored in ledger or do I need to sort them?!

var AvalList = make([]A, 0)
iterator, err := stub.GetStateByPartialCompositeKey("AId~BId", []string{AId})
    if err != nil {
        fmt.Println("error is ", err)
        return shim.Error(err.Error())
    }
    fmt.Println("Iterator is ", iterator)
    if !iterator.HasNext() {
        fmt.Println("---------------------  Iterator not found!!!  --------------------")
        return shim.Error(err.Error())
    }
    defer iterator.Close()

    for i := 0; iterator.HasNext(); i++ {
        ARange, err := iterator.Next()
        if err != nil {
            return shim.Error(err.Error())
        }

        objectType, compositeKeyParts, err := stub.SplitCompositeKey(ARange.Key)
        if err != nil {
            return shim.Error(err.Error())
        }

        returnedA := compositeKeyParts[1]
        fmt.Printf("Found a A of index %s and id %s ", objectType, returnedA)

        ABytes, err := stub.GetState(returnedA)
        if err != nil {
            return shim.Error(err.Error())
        }
        if ABytes == nil {
            fmt.Println("A not found")
            return shim.Error("Entity not found")
        }


        a := A{}
        err = json.Unmarshal(ABytes, &a)
        if err != nil {
            return shim.Error("Failed to unmarshal")
        }

            AvalList = append(AvalList, a)
    }

Solution

  • GetStateByPartialCompositeKey queries the state in the ledger based on a given partial composite key. This function returns an iterator which can be used to iterate over the composite keys whose prefix matches the given partial composite key.

    Read https://github.com/hyperledger/fabric-chaincode-go/blob/master/shim/interfaces.go

    Now, as per the question,

    data I listed from the iterator comes in sorted order in terms of timestamp

    No. It wont be in the sorted order. Such as, if you have bulk data which you are querying then the iterator will get all the composite keys which will not be necessarily in sorted order. Hence you have to sort them.

    One of the way of doing this is to use sort.Sort() function. Similar approach is asked here How to sort by time.Time