Browse Source

server: Hide 0 balances from the balances API

It is unnecessary to be listing 0 balances on the richest addresses.
scalafmt-draft
Alexis Hernandez 7 years ago
parent
commit
e9eb79b813
  1. 2
      server/app/com/xsn/explorer/data/BalanceDataHandler.scala
  2. 13
      server/app/com/xsn/explorer/data/anorm/BalancePostgresDataHandler.scala
  3. 41
      server/app/com/xsn/explorer/data/anorm/dao/BalancePostgresDAO.scala
  4. 7
      server/app/com/xsn/explorer/data/async/BalanceFutureDataHandler.scala
  5. 2
      server/app/com/xsn/explorer/services/BalanceService.scala
  6. 26
      server/test/com/xsn/explorer/data/BalancePostgresDataHandlerSpec.scala
  7. 9
      server/test/controllers/BalancesControllerSpec.scala

2
server/app/com/xsn/explorer/data/BalanceDataHandler.scala

@ -12,6 +12,8 @@ trait BalanceDataHandler[F[_]] {
def upsert(balance: Balance): F[Balance]
def get(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): F[PaginatedResult[Balance]]
def getNonZeroBalances(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): F[PaginatedResult[Balance]]
}
trait BalanceBlockingDataHandler extends BalanceDataHandler[ApplicationResult]

13
server/app/com/xsn/explorer/data/anorm/BalancePostgresDataHandler.scala

@ -29,7 +29,18 @@ class BalancePostgresDataHandler @Inject() (
ordering: FieldOrdering[BalanceField]): ApplicationResult[PaginatedResult[Balance]] = withConnection { implicit conn =>
val balances = balancePostgresDAO.get(query, ordering)
val total = balancePostgresDAO.countRichest
val total = balancePostgresDAO.count
val result = PaginatedResult(query.offset, query.limit, total, balances)
Good(result)
}
override def getNonZeroBalances(
query: PaginatedQuery,
ordering: FieldOrdering[BalanceField]): ApplicationResult[PaginatedResult[Balance]] = withConnection { implicit conn =>
val balances = balancePostgresDAO.getNonZeroBalances(query, ordering)
val total = balancePostgresDAO.countNonZeroBalances
val result = PaginatedResult(query.offset, query.limit, total, balances)
Good(result)

41
server/app/com/xsn/explorer/data/anorm/dao/BalancePostgresDAO.scala

@ -55,7 +55,31 @@ class BalancePostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQ
).as(parseBalance.*).flatten
}
def countRichest(implicit conn: Connection): Count = {
def getNonZeroBalances(
query: PaginatedQuery,
ordering: FieldOrdering[BalanceField])(
implicit conn: Connection): List[Balance] = {
val orderBy = fieldOrderingSQLInterpreter.toOrderByClause(ordering)
SQL(
s"""
|SELECT address, received, spent
|FROM balances
|WHERE address NOT IN (
| SELECT address
| FROM hidden_addresses) AND
| (received - spent) > 0
|$orderBy
|OFFSET {offset}
|LIMIT {limit}
""".stripMargin
).on(
'offset -> query.offset.int,
'limit -> query.limit.int
).as(parseBalance.*).flatten
}
def count(implicit conn: Connection): Count = {
val result = SQL(
"""
|SELECT COUNT(*)
@ -69,4 +93,19 @@ class BalancePostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQ
Count(result)
}
def countNonZeroBalances(implicit conn: Connection): Count = {
val result = SQL(
"""
|SELECT COUNT(*)
|FROM balances
|WHERE address NOT IN (
| SELECT address
| FROM hidden_addresses) AND
| (received - spent) > 0
""".stripMargin
).as(SqlParser.scalar[Int].single)
Count(result)
}
}

7
server/app/com/xsn/explorer/data/async/BalanceFutureDataHandler.scala

@ -23,4 +23,11 @@ class BalanceFutureDataHandler @Inject() (
override def get(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): FuturePaginatedResult[Balance] = Future {
blockingDataHandler.get(query, ordering)
}
override def getNonZeroBalances(
query: PaginatedQuery,
ordering: FieldOrdering[BalanceField]): FuturePaginatedResult[Balance] = Future {
blockingDataHandler.getNonZeroBalances(query, ordering)
}
}

2
server/app/com/xsn/explorer/services/BalanceService.scala

@ -22,7 +22,7 @@ class BalanceService @Inject() (
val result = for {
validatedQuery <- paginatedQueryValidator.validate(paginatedQuery, 100).toFutureOr
ordering <- balanceOrderingParser.from(orderingQuery).toFutureOr
balances <- balanceFutureDataHandler.get(validatedQuery, ordering).toFutureOr
balances <- balanceFutureDataHandler.getNonZeroBalances(validatedQuery, ordering).toFutureOr
} yield balances
result.toFuture

26
server/test/com/xsn/explorer/data/BalancePostgresDataHandlerSpec.scala

@ -89,6 +89,32 @@ class BalancePostgresDataHandlerSpec extends PostgresDataHandlerSpec {
}
}
"getNonZeroBalances" should {
val balances = List(
Balance(
address = DataHelper.createAddress("XiHW7SR56uPHeXKwcpeVsE4nUfkHv5RqE3"),
received = BigDecimal("0"),
spent = BigDecimal("0"))
).sortBy(_.available).reverse
def prepare() = {
clearDatabase()
balances
.map(dataHandler.upsert)
.foreach(_.isGood mustEqual true)
}
"ignore addresses with balance = 0" in {
prepare()
val query = PaginatedQuery(Offset(0), Limit(1))
val expected = List.empty[Balance]
val result = dataHandler.getNonZeroBalances(query, defaultOrdering)
result.map(_.data) mustEqual Good(expected)
result.get.total.int mustEqual balances.size - 1
}
}
private def combine(balances: Balance*): Balance = {
balances.reduce { (a, b) =>
Balance(a.address, a.received + b.received, a.spent + b.spent)

9
server/test/controllers/BalancesControllerSpec.scala

@ -41,12 +41,15 @@ class BalancesControllerSpec extends MyAPISpec {
override def upsert(balance: Balance): ApplicationResult[Balance] = ???
override def get(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): ApplicationResult[PaginatedResult[Balance]] = {
val list = balances.drop(query.offset.int).take(query.limit.int)
override def get(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): ApplicationResult[PaginatedResult[Balance]] = ???
override def getNonZeroBalances(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): ApplicationResult[PaginatedResult[Balance]] = {
val filtered = balances.filter(_.available > 0)
val list = filtered.drop(query.offset.int).take(query.limit.int)
val result = PaginatedResult(
offset = query.offset,
limit = query.limit,
total = Count(balances.size),
total = Count(filtered.size),
data = list)
Good(result)

Loading…
Cancel
Save