Skip to content

Commit

Permalink
fix(ledger): balance filter on accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
gfyrag committed Feb 28, 2024
1 parent ad78bdb commit 6b4537e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
24 changes: 20 additions & 4 deletions components/ledger/internal/storage/ledgerstore/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ledgerstore
import (
"context"
"errors"
"fmt"
"regexp"

"github.com/formancehq/stack/libs/go-libs/bun/bunpaginate"
Expand Down Expand Up @@ -54,6 +55,21 @@ func (store *Store) accountQueryContext(qb query.Builder, q GetAccountsQuery) (s
balanceRegex := regexp.MustCompile("balance\\[(.*)\\]")

return qb.Build(query.ContextFn(func(key, operator string, value any) (string, []any, error) {
convertOperatorToSQL := func() string {
switch operator {
case "$match":
return "="
case "$lt":
return "<"
case "$gt":
return ">"
case "$lte":
return "<="
case "$gte":
return ">="
}
panic("unreachable")
}
switch {
case key == "address":
// TODO: Should allow comparison operator only if segments not used
Expand Down Expand Up @@ -83,21 +99,21 @@ func (store *Store) accountQueryContext(qb query.Builder, q GetAccountsQuery) (s
case balanceRegex.Match([]byte(key)):
match := balanceRegex.FindAllStringSubmatch(key, 2)

return `(
return fmt.Sprintf(`(
select balance_from_volumes(post_commit_volumes)
from moves
where asset = ? and account_address = accounts.address and ledger = ?
order by seq desc
limit 1
) < ?`, []any{match[0][1], store.name, value}, nil
) %s ?`, convertOperatorToSQL()), []any{match[0][1], store.name, value}, nil
case key == "balance":
return `(
return fmt.Sprintf(`(
select balance_from_volumes(post_commit_volumes)
from moves
where account_address = accounts.address and ledger = ?
order by seq desc
limit 1
) < ?`, []any{store.name, value}, nil
) %s ?`, convertOperatorToSQL()), []any{store.name, value}, nil
default:
return "", nil, newErrInvalidQuery("unknown key '%s' when building query", key)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@ func TestGetAccounts(t *testing.T) {
))
require.NoError(t, err)
require.Len(t, accounts.Data, 1) // world

accounts, err = store.GetAccountsWithVolumes(context.Background(), NewGetAccountsQuery(NewPaginatedQueryOptions(PITFilterWithVolumes{}).
WithQueryBuilder(query.Gt("balance[USD]", 0)),
))
require.NoError(t, err)
require.Len(t, accounts.Data, 2) // world
require.Equal(t, "account:1", accounts.Data[0].Account.Address)
require.Equal(t, "bank", accounts.Data[1].Account.Address)
})
t.Run("list using filter invalid field", func(t *testing.T) {
t.Parallel()
Expand Down

0 comments on commit 6b4537e

Please sign in to comment.