Skip to content

Commit

Permalink
Merge branch 'devel' into CM-XXX
Browse files Browse the repository at this point in the history
  • Loading branch information
njmurarka committed Mar 10, 2020
2 parents 2a57364 + cc1cb3c commit c8064a5
Show file tree
Hide file tree
Showing 17 changed files with 364 additions and 27 deletions.
19 changes: 19 additions & 0 deletions x/crud/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command {
GetCmdBLZQHas(storeKey, cdc),
GetCmdBLZQKeys(storeKey, cdc),
GetCmdBLZQKeyValues(storeKey, cdc),
GetCmdBLZQCount(storeKey, cdc),
)...)

return crudQueryCmd
Expand Down Expand Up @@ -128,3 +129,21 @@ func GetCmdBLZQKeyValues(queryRoute string, cdc *codec.Codec) *cobra.Command {
},
}
}

func GetCmdBLZQCount(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "count [UUID]",
Short: "count UUID",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
UUID := args[0]
res, _, _ := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/count/%s", queryRoute, UUID), nil)

var out types.QueryResultCount
cdc.MustUnmarshalJSON(res, &out)

return cliCtx.PrintOutput(out)
},
}
}
22 changes: 22 additions & 0 deletions x/crud/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func GetTxCmd(_ string, cdc *codec.Codec) *cobra.Command {
GetCmdBLZHas(cdc),
GetCmdBLZRename(cdc),
GetCmdBLZKeyValues(cdc),
GetCmdBLZCount(cdc),
)...)

return crudTxCmd
Expand Down Expand Up @@ -217,3 +218,24 @@ func GetCmdBLZRename(cdc *codec.Codec) *cobra.Command {
},
}
}

func GetCmdBLZCount(cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "count [UUID]",
Short: "count of existing entries in the database",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
inBuf := bufio.NewReader(cmd.InOrStdin())
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
msg := types.NewMsgCount(args[0], cliCtx.GetFromAddress())

err := msg.ValidateBasic()
if err != nil {
return err
}

return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}
}
10 changes: 10 additions & 0 deletions x/crud/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,13 @@ func BlzQKeyValuesHandler(cliCtx context.CLIContext, storeName string) http.Hand
rest.PostProcessResponse(w, cliCtx, res)
}
}

func BlzQCountHandler(cliCtx context.CLIContext, storeName string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)

res, _, _ := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/count/%s", storeName, vars["UUID"]), nil)

rest.PostProcessResponse(w, cliCtx, res)
}
}
2 changes: 2 additions & 0 deletions x/crud/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string)
r.HandleFunc(fmt.Sprintf("/%s/keys", storeName), BlzKeysHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/%s/keyvalues", storeName), BlzKeyValuesHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/%s/rename", storeName), BlzRenameHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/%s/count", storeName), BlzCountHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/%s/count/{UUID}", storeName), BlzQCountHandler(cliCtx, storeName)).Methods("GET")
}
39 changes: 39 additions & 0 deletions x/crud/client/rest/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,42 @@ func BlzRenameHandler(cliCtx context.CLIContext) http.HandlerFunc {
utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}

///////////////////////////////////////////////////////////////////////////////
// Rename
type countReq struct {
BaseReq rest.BaseReq
UUID string
Owner string
}

func BlzCountHandler(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req countReq

if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request")
return
}

baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w) {
return
}

addr, err := sdk.AccAddressFromBech32(req.Owner)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

msg := types.NewMsgCount(req.UUID, addr)
err = msg.ValidateBasic()
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}
16 changes: 16 additions & 0 deletions x/crud/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func NewHandler(keeper keeper.IKeeper) sdk.Handler {
return handleMsgBLZRename(ctx, keeper, msg)
case types.MsgBLZKeyValues:
return handleMsgBLZKeyValues(ctx, keeper, msg)
case types.MsgCount:
return handleMsgCount(ctx, keeper, msg)
default:
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, fmt.Sprintf("Unrecognized crud msg type: %v", msg.Type()))
}
Expand Down Expand Up @@ -182,3 +184,17 @@ func handleMsgBLZKeyValues(ctx sdk.Context, keeper keeper.IKeeper, msg types.Msg

return &sdk.Result{Data: json_data}, nil
}

func handleMsgCount(ctx sdk.Context, keeper keeper.IKeeper, msg types.MsgCount) (*sdk.Result, error) {
if len(msg.UUID) == 0 || msg.Owner.Empty() {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid message")
}

json_data, err := json.Marshal(keeper.GetCount(ctx, keeper.GetKVStore(ctx), msg.UUID, msg.Owner))
if err != nil {
fmt.Println(err)
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "could not marshal result to JSON")
}

return &sdk.Result{Data: json_data}, nil
}
35 changes: 35 additions & 0 deletions x/crud/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,38 @@ func Test_handleMsgBLZKeyValues(t *testing.T) {
assert.NotNil(t, err)
}
}

func Test_handleMsgCount(t *testing.T) {
mockCtrl, mockKeeper, ctx, owner := initTest(t)
defer mockCtrl.Finish()

// Simple keys test key does not exist
{
countMsg := types.MsgCount{
UUID: "uuid",
Owner: owner,
}
assert.Equal(t, countMsg.Type(), "count")

// always return nil for a store...
mockKeeper.EXPECT().GetKVStore(ctx).AnyTimes().Return(nil)
mockKeeper.EXPECT().GetCount(ctx, nil, "uuid", gomock.Any()).Return(types.QueryResultCount{UUID: "uuid", Count: uint64(123)})
result, err := NewHandler(mockKeeper)(ctx, countMsg)
assert.Nil(t, err)

json_result := types.QueryResultCount{}
json.Unmarshal(result.Data, &json_result)

assert.Equal(t, countMsg.UUID, json_result.UUID)
assert.Equal(t, uint64(123), json_result.Count)
}

// Test for empty message parameters
{
_, err := handleMsgCount(ctx, mockKeeper, types.MsgCount{})
assert.NotNil(t, err)

_, err = handleMsgCount(ctx, mockKeeper, types.MsgCount{UUID: "uuid"})
assert.NotNil(t, err)
}
}
31 changes: 26 additions & 5 deletions x/crud/internal/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type IKeeper interface {
RenameBLZKey(ctx sdk.Context, store sdk.KVStore, UUID string, key string, newkey string) bool
GetCdc() *codec.Codec
GetKeyValues(ctx sdk.Context, store sdk.KVStore, UUID string, owner sdk.AccAddress) types.QueryResultKeyValues
GetCount(ctx sdk.Context, store sdk.KVStore, UUID string, owner sdk.AccAddress) types.QueryResultCount
}

type Keeper struct {
Expand Down Expand Up @@ -111,11 +112,12 @@ func (k Keeper) GetKeys(ctx sdk.Context, store sdk.KVStore, UUID string, owner s

keysSize := uint64(0)
for ; iterator.Valid(); iterator.Next() {
var bz = store.Get([]byte(iterator.Key()))
var value types.BLZValue
k.cdc.MustUnmarshalBinaryBare(bz, &value)

if owner == nil || reflect.DeepEqual(value.Owner, owner) {
if (owner == nil) || func() bool {
var bz = store.Get([]byte(iterator.Key()))
var value types.BLZValue
k.cdc.MustUnmarshalBinaryBare(bz, &value)
return reflect.DeepEqual(value.Owner, owner)
}() {
key := string(iterator.Key())[len(prefix):]
keysSize = uint64(len(key)) + keysSize
if ctx.GasMeter().IsPastLimit() {
Expand Down Expand Up @@ -191,3 +193,22 @@ func (k Keeper) GetKeyValues(ctx sdk.Context, store sdk.KVStore, UUID string, ow
}
return keyValues
}

func (k Keeper) GetCount(ctx sdk.Context, store sdk.KVStore, UUID string, owner sdk.AccAddress) types.QueryResultCount {
prefix := UUID + "\x00"
iterator := sdk.KVStorePrefixIterator(store, []byte(prefix))
defer iterator.Close()
count := types.QueryResultCount{UUID: UUID}

for ; iterator.Valid(); iterator.Next() {
if (owner == nil) || func() bool {
var bz = store.Get([]byte(iterator.Key()))
var value types.BLZValue
k.cdc.MustUnmarshalBinaryBare(bz, &value)
return reflect.DeepEqual(value.Owner, owner)
}() {
count.Count += 1
}
}
return count
}
57 changes: 51 additions & 6 deletions x/crud/internal/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,13 @@ func TestKeeper_GetKeyValues(t *testing.T) {
keeper.SetBLZValue(ctx, testStore, "uuid", "key2", types.BLZValue{Value: "value2", Owner: owner})
keeper.SetBLZValue(ctx, testStore, "uuid", "key3", types.BLZValue{Value: "value3"})

kvs = keeper.GetKeyValues(ctx, testStore, "uuid", nil)
kvs = keeper.GetKeyValues(ctx, testStore, "uuid", owner)
assert.Equal(t, "uuid", kvs.UUID)
assert.Len(t, kvs.KeyValues, 4)
assert.Len(t, kvs.KeyValues, 3)

assert.Equal(t, kvs.KeyValues[0], types.KeyValue{Key: "key0", Value: "value0"})
assert.Equal(t, kvs.KeyValues[1], types.KeyValue{Key: "key1", Value: "value1"})
assert.Equal(t, kvs.KeyValues[2], types.KeyValue{Key: "key2", Value: "value2"})
assert.Equal(t, kvs.KeyValues[3], types.KeyValue{Key: "key3", Value: "value3"})
assert.Equal(t, types.KeyValue{Key: "key0", Value: "value0"}, kvs.KeyValues[0])
assert.Equal(t, types.KeyValue{Key: "key1", Value: "value1"}, kvs.KeyValues[1])
assert.Equal(t, types.KeyValue{Key: "key2", Value: "value2"}, kvs.KeyValues[2])
}

func TestKeeper_GetKeyValues_no_owner_for_query_usage(t *testing.T) {
Expand Down Expand Up @@ -336,3 +335,49 @@ func TestKeeper_GetKeyValues_MaxSize(t *testing.T) {
assert.Len(t, keyValues.KeyValues, 0)
}
}

func TestKeeper_GetCount(t *testing.T) {
ctx, testStore, owner, cdc := initKeeperTest(t)
keeper := NewKeeper(nil, nil, cdc, MaxKeeperSizes{})

count := keeper.GetCount(ctx, testStore, "uuid", nil)

assert.Equal(t, "uuid", count.UUID)
assert.Equal(t, uint64(0), count.Count)

keeper.SetBLZValue(ctx, testStore, "uuid", "key0", types.BLZValue{Value: "value", Owner: owner})
keeper.SetBLZValue(ctx, testStore, "uuid", "key1", types.BLZValue{Value: "value", Owner: owner})
keeper.SetBLZValue(ctx, testStore, "uuid", "key2", types.BLZValue{Value: "value", Owner: owner})
keeper.SetBLZValue(ctx, testStore, "uuid", "key3", types.BLZValue{Value: "value", Owner: owner})
keeper.SetBLZValue(ctx, testStore, "uuid0", "key0", types.BLZValue{Value: "value", Owner: owner})

count = keeper.GetCount(ctx, testStore, "uuid", nil)

assert.Equal(t, "uuid", count.UUID)
assert.Equal(t, uint64(4), count.Count)

count = keeper.GetCount(ctx, testStore, "uuid0", owner)

assert.Equal(t, "uuid0", count.UUID)
assert.Equal(t, uint64(1), count.Count)
}

func TestKeeper_GetCount_no_owner_for_query_usage(t *testing.T) {
ctx, testStore, owner, cdc := initKeeperTest(t)
keeper := NewKeeper(nil, nil, cdc, MaxKeeperSizes{})

count := keeper.GetCount(ctx, testStore, "uuid", nil)
assert.Equal(t, "uuid", count.UUID)
assert.Equal(t, uint64(0), count.Count)

keeper.SetBLZValue(ctx, testStore, "uuid", "key0", types.BLZValue{Value: "value", Owner: owner})
keeper.SetBLZValue(ctx, testStore, "uuid", "key1", types.BLZValue{Value: "value", Owner: owner})
keeper.SetBLZValue(ctx, testStore, "uuid", "key2", types.BLZValue{Value: "value", Owner: owner})
keeper.SetBLZValue(ctx, testStore, "uuid", "key3", types.BLZValue{Value: "value",
Owner: []byte("bluzelle1rnnpyp9wr6law2u5jwa23t0ywtmrduldf6h4wq")})

count = keeper.GetCount(ctx, testStore, "uuid", nil)

assert.Equal(t, "uuid", count.UUID)
assert.Equal(t, uint64(4), count.Count)
}
12 changes: 12 additions & 0 deletions x/crud/internal/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
QueryHas = "has"
QueryKeys = "keys"
QueryKeyValues = "keyvalues"
QueryCount = "count"
)

func NewQuerier(keeper IKeeper) sdk.Querier {
Expand All @@ -40,6 +41,8 @@ func NewQuerier(keeper IKeeper) sdk.Querier {
return queryKeys(ctx, path[1:], req, keeper, keeper.GetCdc())
case QueryKeyValues:
return queryKeyValues(ctx, path[1:], req, keeper, keeper.GetCdc())
case QueryCount:
return queryCount(ctx, path[1:], req, keeper, keeper.GetCdc())
default:
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown crud query endpoint")
}
Expand Down Expand Up @@ -89,3 +92,12 @@ func queryKeyValues(ctx sdk.Context, path []string, _ abci.RequestQuery, keeper

return res, nil
}

func queryCount(ctx sdk.Context, path []string, _ abci.RequestQuery, keeper IKeeper, cdc *codec.Codec) ([]byte, error) {
res, err := codec.MarshalJSONIndent(cdc, keeper.GetCount(ctx, keeper.GetKVStore(ctx), path[0], nil))
if err != nil {
panic("could not marshal result to JSON")
}

return res, nil
}
21 changes: 21 additions & 0 deletions x/crud/internal/keeper/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,24 @@ func Test_queryKeyValues(t *testing.T) {

assert.True(t, reflect.DeepEqual(acceptedKeyValues, json_result))
}

func Test_queryCount(t *testing.T) {
ctx, cdc, mockKeeper := initTest(t)

// always return nil for a store...
mockKeeper.EXPECT().GetKVStore(ctx).AnyTimes().Return(nil)
mockKeeper.EXPECT().GetCount(ctx, nil, "uuid", nil).Return(types.QueryResultCount{
UUID: "uuid",
Count: 2,
})
mockKeeper.EXPECT().GetCdc().Return(cdc)

result, err := NewQuerier(mockKeeper)(ctx, []string{"count", "uuid"}, abci.RequestQuery{})
assert.Nil(t, err)

json_result := types.QueryResultCount{}
json.Unmarshal(result, &json_result)

assert.Equal(t, "uuid", json_result.UUID)
assert.Equal(t, uint64(2), json_result.Count)
}
1 change: 1 addition & 0 deletions x/crud/internal/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterConcrete(MsgBLZKeyValues{}, "crud/keyvalues", nil)
cdc.RegisterConcrete(MsgBLZHas{}, "crud/has", nil)
cdc.RegisterConcrete(MsgBLZRename{}, "crud/rename", nil)
cdc.RegisterConcrete(MsgCount{}, "crud/count", nil)
}
Loading

0 comments on commit c8064a5

Please sign in to comment.