Skip to content

Commit

Permalink
api: endpoint /accounts now supports filtering by partial accountId
Browse files Browse the repository at this point in the history
  • Loading branch information
altergui committed Aug 7, 2024
1 parent 0c02847 commit 03b3863
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 40 deletions.
13 changes: 9 additions & 4 deletions api/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ func (a *API) accountListByPageHandler(_ *apirest.APIdata, ctx *httprouter.HTTPC
params, err := parseAccountParams(
ctx.URLParam(ParamPage),
"",
"",
)
if err != nil {
return err
Expand All @@ -548,14 +549,16 @@ func (a *API) accountListByPageHandler(_ *apirest.APIdata, ctx *httprouter.HTTPC
// @Tags Accounts
// @Accept json
// @Produce json
// @Param page query number false "Page"
// @Param limit query number false "Items per page"
// @Success 200 {object} AccountsList
// @Param page query number false "Page"
// @Param limit query number false "Items per page"
// @Param accountId query string false "Filter by partial accountId"
// @Success 200 {object} AccountsList
// @Router /accounts [get]
func (a *API) accountListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error {
params, err := parseAccountParams(
ctx.QueryParam(ParamPage),
ctx.QueryParam(ParamLimit),
ctx.QueryParam(ParamAccountId),
)
if err != nil {
return err
Expand All @@ -571,6 +574,7 @@ func (a *API) sendAccountList(ctx *httprouter.HTTPContext, params *AccountParams
accounts, total, err := a.indexer.AccountList(
params.Limit,
params.Page*params.Limit,
params.AccountID,
)
if err != nil {
return ErrIndexerQueryFailed.WithErr(err)
Expand All @@ -589,13 +593,14 @@ func (a *API) sendAccountList(ctx *httprouter.HTTPContext, params *AccountParams
}

// parseAccountParams returns an AccountParams filled with the passed params
func parseAccountParams(paramPage, paramLimit string) (*AccountParams, error) {
func parseAccountParams(paramPage, paramLimit, paramAccountID string) (*AccountParams, error) {
pagination, err := parsePaginationParams(paramPage, paramLimit)
if err != nil {
return nil, err
}

return &AccountParams{
PaginationParams: pagination,
AccountID: util.TrimHex(paramAccountID),
}, nil
}
1 change: 1 addition & 0 deletions api/api_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type OrganizationParams struct {
// AccountParams allows the client to filter accounts
type AccountParams struct {
PaginationParams
AccountID string `json:"accountId,omitempty"`
}

// TransactionParams allows the client to filter transactions
Expand Down
41 changes: 27 additions & 14 deletions vochain/indexer/db/account.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions vochain/indexer/db/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions vochain/indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,17 +814,19 @@ func (idx *Indexer) CountTotalAccounts() (uint64, error) {
return uint64(count), err
}

// AccountList retrieves all accounts.
func (idx *Indexer) AccountList(limit, offset int) ([]*indexertypes.Account, uint64, error) {
// AccountList returns a list of accounts, accountID is a partial or full hex string,
// and is optional (declared as zero-value will be ignored).
func (idx *Indexer) AccountList(limit, offset int, accountID string) ([]*indexertypes.Account, uint64, error) {
if offset < 0 {
return nil, 0, fmt.Errorf("invalid value: offset cannot be %d", offset)
}
if limit <= 0 {
return nil, 0, fmt.Errorf("invalid value: limit cannot be %d", limit)
}
results, err := idx.readOnlyQuery.GetListAccounts(context.TODO(), indexerdb.GetListAccountsParams{
Limit: int64(limit),
Offset: int64(offset),
results, err := idx.readOnlyQuery.SearchAccounts(context.TODO(), indexerdb.SearchAccountsParams{
Limit: int64(limit),
Offset: int64(offset),
AccountIDSubstr: accountID,
})
if err != nil {
return nil, 0, err
Expand Down
4 changes: 2 additions & 2 deletions vochain/indexer/indexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1564,7 +1564,7 @@ func TestAccountsList(t *testing.T) {

last := 0
for i := 0; i < int(totalAccs); i++ {
accts, _, err := idx.AccountList(10, last)
accts, _, err := idx.AccountList(10, last, "")
qt.Assert(t, err, qt.IsNil)

for j, acc := range accts {
Expand All @@ -1587,7 +1587,7 @@ func TestAccountsList(t *testing.T) {
app.AdvanceTestBlock()

// verify the updated balance and nonce
accts, _, err := idx.AccountList(5, 0)
accts, _, err := idx.AccountList(5, 0, "")
qt.Assert(t, err, qt.IsNil)
// the account in the position 0 must be the updated account balance due it has the major balance
// indexer query has order BY balance DESC
Expand Down
22 changes: 17 additions & 5 deletions vochain/indexer/queries/account.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@ REPLACE INTO accounts (
account, balance, nonce
) VALUES (?, ?, ?);

-- name: GetListAccounts :many
SELECT *,
COUNT(*) OVER() AS total_count
FROM accounts
-- name: SearchAccounts :many
WITH results AS (
SELECT *
FROM accounts
WHERE (
(
sqlc.arg(account_id_substr) = ''
OR (LENGTH(sqlc.arg(account_id_substr)) = 40 AND LOWER(HEX(account)) = LOWER(sqlc.arg(account_id_substr)))
OR (LENGTH(sqlc.arg(account_id_substr)) < 40 AND INSTR(LOWER(HEX(account)), LOWER(sqlc.arg(account_id_substr))) > 0)
-- TODO: consider keeping an account_hex column for faster searches
)
)
)
SELECT *, COUNT(*) OVER() AS total_count
FROM results
ORDER BY balance DESC
LIMIT ? OFFSET ?;
LIMIT sqlc.arg(limit)
OFFSET sqlc.arg(offset);

-- name: CountAccounts :one
SELECT COUNT(*) FROM accounts;

0 comments on commit 03b3863

Please sign in to comment.