get records from attributes
This commit is contained in:
parent
a43b8fee5c
commit
b38e3a9106
@ -30,12 +30,13 @@ func (q Querier) ListRecords(c context.Context, req *types.QueryListRecordsReque
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
attributes := req.GetAttributes()
|
||||
all := req.GetAll()
|
||||
records := []types.Record{}
|
||||
|
||||
var records []types.Record
|
||||
if len(attributes) > 0 {
|
||||
records = q.Keeper.MatchRecords(ctx, func(record *types.RecordType) bool {
|
||||
return MatchOnAttributes(record, attributes, all)
|
||||
})
|
||||
var err error
|
||||
records, err = q.Keeper.RecordsFromAttributes(ctx, attributes, all)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
records = q.Keeper.ListRecords(ctx)
|
||||
}
|
||||
@ -113,115 +114,3 @@ func (q Querier) GetAuthorityExpiryQueue(c context.Context, _ *types.QueryGetAut
|
||||
authorities := q.Keeper.GetAuthorityExpiryQueue(ctx)
|
||||
return &types.QueryGetAuthorityExpiryQueueResponse{Authorities: authorities}, nil
|
||||
}
|
||||
|
||||
func matchOnRecordField(record *types.RecordType, attr *types.QueryListRecordsRequest_KeyValueInput) (fieldFound bool, matched bool) {
|
||||
fieldFound = false
|
||||
matched = true
|
||||
|
||||
switch attr.Key {
|
||||
case BondIDAttributeName:
|
||||
{
|
||||
fieldFound = true
|
||||
if record.BondId != attr.Value.GetString_() {
|
||||
matched = false
|
||||
return
|
||||
}
|
||||
}
|
||||
case ExpiryTimeAttributeName:
|
||||
{
|
||||
fieldFound = true
|
||||
if record.ExpiryTime != attr.Value.GetString_() {
|
||||
matched = false
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func MatchOnAttributes(record *types.RecordType, attributes []*types.QueryListRecordsRequest_KeyValueInput, all bool) bool {
|
||||
// Filter deleted records.
|
||||
if record.Deleted {
|
||||
return false
|
||||
}
|
||||
|
||||
// If ONLY named records are requested, check for that condition first.
|
||||
if !all && len(record.Names) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
recAttrs := record.Attributes
|
||||
|
||||
for _, attr := range attributes {
|
||||
// First try matching on record struct fields.
|
||||
fieldFound, matched := matchOnRecordField(record, attr)
|
||||
|
||||
if fieldFound {
|
||||
if !matched {
|
||||
return false
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
recAttrVal, recAttrFound := recAttrs[attr.Key]
|
||||
if !recAttrFound {
|
||||
return false
|
||||
}
|
||||
|
||||
if attr.Value.Type == "int" {
|
||||
recAttrValInt, ok := recAttrVal.(int)
|
||||
if !ok || int(attr.Value.GetInt()) != recAttrValInt {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if attr.Value.Type == "float" {
|
||||
recAttrValFloat, ok := recAttrVal.(float64)
|
||||
if !ok || attr.Value.GetFloat() != recAttrValFloat {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if attr.Value.Type == "string" {
|
||||
recAttrValString, ok := recAttrVal.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if attr.Value.GetString_() != recAttrValString {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if attr.Value.Type == "boolean" {
|
||||
recAttrValBool, ok := recAttrVal.(bool)
|
||||
if !ok || attr.Value.GetBoolean() != recAttrValBool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if attr.Value.Type == "reference" {
|
||||
obj, ok := recAttrVal.(map[string]interface{})
|
||||
if !ok {
|
||||
// Attr value is not an object.
|
||||
return false
|
||||
}
|
||||
|
||||
if _, ok := obj["/"].(string); !ok {
|
||||
// Attr value is not a reference.
|
||||
return false
|
||||
}
|
||||
|
||||
recAttrValRefID := obj["/"].(string)
|
||||
if recAttrValRefID != attr.Value.GetReference().GetId() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Handle arrays.
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -131,29 +131,61 @@ func (k Keeper) ListRecords(ctx sdk.Context) []types.Record {
|
||||
return records
|
||||
}
|
||||
|
||||
// MatchRecords - get all matching records.
|
||||
func (k Keeper) MatchRecords(ctx sdk.Context, matchFn func(*types.RecordType) bool) []types.Record {
|
||||
var records []types.Record
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixCIDToRecordIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var obj types.Record
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
obj = recordObjToRecord(store, k.cdc, obj)
|
||||
record := obj.ToRecordType()
|
||||
if matchFn(&record) {
|
||||
records = append(records, obj)
|
||||
}
|
||||
func (k Keeper) RecordsFromAttributes(ctx sdk.Context, attributes []*types.QueryListRecordsRequest_KeyValueInput, all bool) ([]types.Record, error) {
|
||||
resultRecordIds := []string{}
|
||||
for i, attr := range attributes {
|
||||
attributeIndex := GetAttributesIndexKey(attr.Key, attr.Value)
|
||||
recordIds, err := k.GetAttributeMapping(ctx, attributeIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if i == 0 {
|
||||
resultRecordIds = recordIds
|
||||
} else {
|
||||
resultRecordIds = getIntersection(recordIds, resultRecordIds)
|
||||
}
|
||||
}
|
||||
|
||||
return records
|
||||
records := []types.Record{}
|
||||
for _, id := range resultRecordIds {
|
||||
record := k.GetRecord(ctx, id)
|
||||
if record.Deleted {
|
||||
continue
|
||||
}
|
||||
if !all && len(record.Names) == 0 {
|
||||
continue
|
||||
}
|
||||
records = append(records, record)
|
||||
}
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func getIntersection(a []string, b []string) []string {
|
||||
result := []string{}
|
||||
if len(a) < len(b) {
|
||||
for _, str := range a {
|
||||
if contains(b, str) {
|
||||
result = append(result, str)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, str := range b {
|
||||
if contains(a, str) {
|
||||
result = append(result, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func contains(arr []string, str string) bool {
|
||||
for _, s := range arr {
|
||||
if s == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (k Keeper) GetRecordExpiryQueue(ctx sdk.Context) []*types.ExpiryQueueRecord {
|
||||
var records []*types.ExpiryQueueRecord
|
||||
|
||||
@ -292,6 +324,9 @@ func (k Keeper) ProcessAttributes(ctx sdk.Context, record types.RecordType) erro
|
||||
return fmt.Errorf("unsupported record type %s", record.Attributes["type"])
|
||||
}
|
||||
|
||||
expiryTimeKey := GetAttributesIndexKey(ExpiryTimeAttributeName, record.ExpiryTime)
|
||||
k.SetAttributeMapping(ctx, expiryTimeKey, record.Id)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -320,6 +355,22 @@ func (k Keeper) SetAttributeMapping(ctx sdk.Context, key []byte, recordId string
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) GetAttributeMapping(ctx sdk.Context, key []byte) ([]string, error) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
if !store.Has(key) {
|
||||
return nil, fmt.Errorf("store doesn't have key")
|
||||
}
|
||||
|
||||
var recordIds []string
|
||||
if err := json.Unmarshal(store.Get(key), &recordIds); err != nil {
|
||||
return nil, fmt.Errorf("cannont unmarshal byte array, error, %w", err)
|
||||
}
|
||||
|
||||
return recordIds, nil
|
||||
|
||||
}
|
||||
|
||||
// AddBondToRecordIndexEntry adds the Bond ID -> [Record] index entry.
|
||||
func (k Keeper) AddBondToRecordIndexEntry(ctx sdk.Context, bondID string, id string) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
@ -161,6 +161,9 @@ func (m msgServer) DeleteName(c context.Context, msg *types.MsgDeleteNameAuthori
|
||||
func (m msgServer) RenewRecord(c context.Context, msg *types.MsgRenewRecord) (*types.MsgRenewRecordResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessRenewRecord(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -264,6 +267,9 @@ func (m msgServer) ReAssociateRecords(c context.Context, msg *types.MsgReAssocia
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessReAssociateRecords(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeReAssociateRecords,
|
||||
|
@ -651,7 +651,6 @@ func (k Keeper) GetAllExpiredAuthorities(ctx sdk.Context, currTime time.Time) (e
|
||||
defer itr.Close()
|
||||
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
timeslice := []string{}
|
||||
timeslice, err := helpers.BytesArrToStringArr(itr.Value())
|
||||
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user