Browse Source

server: Allow to specify ordering on GET /balances

scalafmt-draft
Alexis Hernandez 7 years ago
parent
commit
1a59506179
  1. 5
      server/app/com/xsn/explorer/data/BalanceDataHandler.scala
  2. 10
      server/app/com/xsn/explorer/data/anorm/BalancePostgresDataHandler.scala
  3. 18
      server/app/com/xsn/explorer/data/anorm/dao/BalancePostgresDAO.scala
  4. 7
      server/app/com/xsn/explorer/data/async/BalanceFutureDataHandler.scala
  5. 11
      server/app/com/xsn/explorer/services/BalanceService.scala
  6. 10
      server/app/controllers/BalancesController.scala
  7. 2
      server/conf/routes
  8. 14
      server/test/com/xsn/explorer/data/BalancePostgresDataHandlerSpec.scala
  9. 3
      server/test/com/xsn/explorer/processors/BlockEventsProcessorSpec.scala
  10. 3
      server/test/controllers/BalancesControllerSpec.scala

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

@ -2,7 +2,8 @@ package com.xsn.explorer.data
import com.alexitc.playsonify.core.ApplicationResult
import com.xsn.explorer.models.Balance
import com.xsn.explorer.models.base.{PaginatedQuery, PaginatedResult}
import com.xsn.explorer.models.base.{FieldOrdering, PaginatedQuery, PaginatedResult}
import com.xsn.explorer.models.fields.BalanceField
import scala.language.higherKinds
@ -10,7 +11,7 @@ trait BalanceDataHandler[F[_]] {
def upsert(balance: Balance): F[Balance]
def getRichest(query: PaginatedQuery): F[PaginatedResult[Balance]]
def get(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): F[PaginatedResult[Balance]]
}
trait BalanceBlockingDataHandler extends BalanceDataHandler[ApplicationResult]

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

@ -7,7 +7,8 @@ import com.xsn.explorer.data.BalanceBlockingDataHandler
import com.xsn.explorer.data.anorm.dao.BalancePostgresDAO
import com.xsn.explorer.errors.BalanceUnknownError
import com.xsn.explorer.models.Balance
import com.xsn.explorer.models.base.{PaginatedQuery, PaginatedResult}
import com.xsn.explorer.models.base.{FieldOrdering, PaginatedQuery, PaginatedResult}
import com.xsn.explorer.models.fields.BalanceField
import org.scalactic.{Good, One, Or}
import play.api.db.Database
@ -23,8 +24,11 @@ class BalancePostgresDataHandler @Inject() (
Or.from(maybe, One(BalanceUnknownError))
}
override def getRichest(query: PaginatedQuery): ApplicationResult[PaginatedResult[Balance]] = withConnection { implicit conn =>
val balances = balancePostgresDAO.getRichest(query)
override def get(
query: PaginatedQuery,
ordering: FieldOrdering[BalanceField]): ApplicationResult[PaginatedResult[Balance]] = withConnection { implicit conn =>
val balances = balancePostgresDAO.get(query, ordering)
val total = balancePostgresDAO.countRichest
val result = PaginatedResult(query.offset, query.limit, total, balances)

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

@ -1,13 +1,16 @@
package com.xsn.explorer.data.anorm.dao
import java.sql.Connection
import javax.inject.Inject
import anorm._
import com.xsn.explorer.data.anorm.interpreters.FieldOrderingSQLInterpreter
import com.xsn.explorer.data.anorm.parsers.BalanceParsers._
import com.xsn.explorer.models.Balance
import com.xsn.explorer.models.base.{Count, PaginatedQuery}
import com.xsn.explorer.models.base.{Count, FieldOrdering, PaginatedQuery}
import com.xsn.explorer.models.fields.BalanceField
class BalancePostgresDAO {
class BalancePostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderingSQLInterpreter) {
def upsert(balance: Balance)(implicit conn: Connection): Option[Balance] = {
SQL(
@ -30,16 +33,21 @@ class BalancePostgresDAO {
).as(parseBalance.singleOpt).flatten
}
def getRichest(query: PaginatedQuery)(implicit conn: Connection): List[Balance] = {
def get(
query: PaginatedQuery,
ordering: FieldOrdering[BalanceField])(
implicit conn: Connection): List[Balance] = {
val orderBy = fieldOrderingSQLInterpreter.toOrderByClause(ordering)
SQL(
"""
s"""
|SELECT address, received, spent, available
|FROM balances
|WHERE address NOT IN (
| SELECT address
| FROM hidden_addresses
|)
|ORDER BY available DESC
|$orderBy
|OFFSET {offset}
|LIMIT {limit}
""".stripMargin

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

@ -6,7 +6,8 @@ import com.alexitc.playsonify.core.FutureApplicationResult
import com.xsn.explorer.data.{BalanceBlockingDataHandler, BalanceDataHandler}
import com.xsn.explorer.executors.DatabaseExecutionContext
import com.xsn.explorer.models.Balance
import com.xsn.explorer.models.base.{PaginatedQuery, PaginatedResult}
import com.xsn.explorer.models.base.{FieldOrdering, PaginatedQuery, PaginatedResult}
import com.xsn.explorer.models.fields.BalanceField
import scala.concurrent.Future
@ -19,7 +20,7 @@ class BalanceFutureDataHandler @Inject() (
blockingDataHandler.upsert(balance)
}
override def getRichest(query: PaginatedQuery): FutureApplicationResult[PaginatedResult[Balance]] = Future {
blockingDataHandler.getRichest(query)
override def get(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): FutureApplicationResult[PaginatedResult[Balance]] = Future {
blockingDataHandler.get(query, ordering)
}
}

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

@ -6,20 +6,23 @@ import com.alexitc.playsonify.core.FutureApplicationResult
import com.alexitc.playsonify.core.FutureOr.Implicits.{FutureOps, OrOps}
import com.xsn.explorer.data.async.BalanceFutureDataHandler
import com.xsn.explorer.models.Balance
import com.xsn.explorer.models.base.{PaginatedQuery, PaginatedResult}
import com.xsn.explorer.models.base.{OrderingQuery, PaginatedQuery, PaginatedResult}
import com.xsn.explorer.parsers.BalanceOrderingParser
import com.xsn.explorer.services.validators.PaginatedQueryValidator
import scala.concurrent.ExecutionContext
class BalanceService @Inject() (
paginatedQueryValidator: PaginatedQueryValidator,
balanceOrderingParser: BalanceOrderingParser,
balanceFutureDataHandler: BalanceFutureDataHandler)(
implicit ec: ExecutionContext) {
def getRichest(query: PaginatedQuery): FutureApplicationResult[PaginatedResult[Balance]] = {
def get(paginatedQuery: PaginatedQuery, orderingQuery: OrderingQuery): FutureApplicationResult[PaginatedResult[Balance]] = {
val result = for {
validatedQuery <- paginatedQueryValidator.validate(query).toFutureOr
balances <- balanceFutureDataHandler.getRichest(validatedQuery).toFutureOr
validatedQuery <- paginatedQueryValidator.validate(paginatedQuery).toFutureOr
ordering <- balanceOrderingParser.from(orderingQuery).toFutureOr
balances <- balanceFutureDataHandler.get(validatedQuery, ordering).toFutureOr
} yield balances
result.toFuture

10
server/app/controllers/BalancesController.scala

@ -2,7 +2,7 @@ package controllers
import javax.inject.Inject
import com.xsn.explorer.models.base.{Limit, Offset, PaginatedQuery}
import com.xsn.explorer.models.base.{Limit, Offset, OrderingQuery, PaginatedQuery}
import com.xsn.explorer.services.BalanceService
import controllers.common.{MyJsonController, MyJsonControllerComponents}
@ -11,8 +11,10 @@ class BalancesController @Inject() (
cc: MyJsonControllerComponents)
extends MyJsonController(cc) {
def getRichest(offset: Int, limit: Int) = publicNoInput { _ =>
val query = PaginatedQuery(Offset(offset), Limit(limit))
balanceService.getRichest(query)
def get(offset: Int, limit: Int, ordering: String) = publicNoInput { _ =>
val paginatedQuery = PaginatedQuery(Offset(offset), Limit(limit))
val orderingQuery = OrderingQuery(ordering)
balanceService.get(paginatedQuery, orderingQuery)
}
}

2
server/conf/routes

@ -14,4 +14,4 @@ GET /blocks/:blockhash controllers.BlocksController.getDetails(blockhash:
GET /stats controllers.StatisticsController.getStatus()
GET /balances controllers.BalancesController.getRichest(offset: Int ?= 0, limit: Int ?= 10)
GET /balances controllers.BalancesController.get(offset: Int ?= 0, limit: Int ?= 10, orderBy: String ?= "")

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

@ -2,15 +2,19 @@ package com.xsn.explorer.data
import com.xsn.explorer.data.anorm.BalancePostgresDataHandler
import com.xsn.explorer.data.anorm.dao.BalancePostgresDAO
import com.xsn.explorer.data.anorm.interpreters.FieldOrderingSQLInterpreter
import com.xsn.explorer.data.common.PostgresDataHandlerSpec
import com.xsn.explorer.helpers.DataHelper
import com.xsn.explorer.models.Balance
import com.xsn.explorer.models.base.{Limit, Offset, PaginatedQuery}
import com.xsn.explorer.models.base._
import com.xsn.explorer.models.fields.BalanceField
import org.scalactic.Good
class BalancePostgresDataHandlerSpec extends PostgresDataHandlerSpec {
lazy val dataHandler = new BalancePostgresDataHandler(database, new BalancePostgresDAO)
lazy val dataHandler = new BalancePostgresDataHandler(database, new BalancePostgresDAO(new FieldOrderingSQLInterpreter))
val defaultOrdering = FieldOrdering(BalanceField.Available, OrderingCondition.DescendingOrder)
"upsert" should {
"create an empty balance" in {
@ -49,7 +53,7 @@ class BalancePostgresDataHandlerSpec extends PostgresDataHandlerSpec {
}
}
"getRichest" should {
"get" should {
val balances = List(
Balance(
@ -86,7 +90,7 @@ class BalancePostgresDataHandlerSpec extends PostgresDataHandlerSpec {
val query = PaginatedQuery(Offset(0), Limit(3))
val expected = balances.take(3)
val result = dataHandler.getRichest(query)
val result = dataHandler.get(query, defaultOrdering)
result.map(_.data) mustEqual Good(expected)
}
@ -95,7 +99,7 @@ class BalancePostgresDataHandlerSpec extends PostgresDataHandlerSpec {
val query = PaginatedQuery(Offset(1), Limit(3))
val expected = balances.drop(1).take(3)
val result = dataHandler.getRichest(query)
val result = dataHandler.get(query, defaultOrdering)
result.map(_.data) mustEqual Good(expected)
}
}

3
server/test/com/xsn/explorer/processors/BlockEventsProcessorSpec.scala

@ -1,6 +1,7 @@
package com.xsn.explorer.processors
import com.xsn.explorer.data.anorm.dao.{BalancePostgresDAO, BlockPostgresDAO, StatisticsPostgresDAO, TransactionPostgresDAO}
import com.xsn.explorer.data.anorm.interpreters.FieldOrderingSQLInterpreter
import com.xsn.explorer.data.anorm.{BlockPostgresDataHandler, DatabasePostgresSeeder, StatisticsPostgresDataHandler}
import com.xsn.explorer.data.async.{BlockFutureDataHandler, DatabaseFutureSeeder}
import com.xsn.explorer.data.common.PostgresDataHandlerSpec
@ -17,7 +18,7 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
database,
new BlockPostgresDAO,
new TransactionPostgresDAO,
new BalancePostgresDAO)
new BalancePostgresDAO(new FieldOrderingSQLInterpreter))
lazy val xsnService = new FileBasedXSNService
lazy val processor = new BlockEventsProcessor(

3
server/test/controllers/BalancesControllerSpec.scala

@ -5,6 +5,7 @@ import com.xsn.explorer.data.BalanceBlockingDataHandler
import com.xsn.explorer.helpers.DataHelper
import com.xsn.explorer.models.Balance
import com.xsn.explorer.models.base._
import com.xsn.explorer.models.fields.BalanceField
import controllers.common.MyAPISpec
import org.scalactic.Good
import play.api.inject.bind
@ -40,7 +41,7 @@ class BalancesControllerSpec extends MyAPISpec {
override def upsert(balance: Balance): ApplicationResult[Balance] = ???
override def getRichest(query: PaginatedQuery): ApplicationResult[PaginatedResult[Balance]] = {
override def get(query: PaginatedQuery, ordering: FieldOrdering[BalanceField]): ApplicationResult[PaginatedResult[Balance]] = {
val list = balances.drop(query.offset.int).take(query.limit.int)
val result = PaginatedResult(
offset = query.offset,

Loading…
Cancel
Save