diff --git a/server/app/com/xsn/explorer/data/BalanceDataHandler.scala b/server/app/com/xsn/explorer/data/BalanceDataHandler.scala new file mode 100644 index 0000000..5a38801 --- /dev/null +++ b/server/app/com/xsn/explorer/data/BalanceDataHandler.scala @@ -0,0 +1,16 @@ +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 scala.language.higherKinds + +trait BalanceDataHandler[F[_]] { + + def upsert(balance: Balance): F[Balance] + + def getRichest(query: PaginatedQuery): F[PaginatedResult[Balance]] +} + +trait BalanceBlockingDataHandler extends BalanceDataHandler[ApplicationResult] diff --git a/server/app/com/xsn/explorer/data/anorm/BalancePostgresDataHandler.scala b/server/app/com/xsn/explorer/data/anorm/BalancePostgresDataHandler.scala index e8bd330..ba26cf4 100644 --- a/server/app/com/xsn/explorer/data/anorm/BalancePostgresDataHandler.scala +++ b/server/app/com/xsn/explorer/data/anorm/BalancePostgresDataHandler.scala @@ -2,20 +2,32 @@ package com.xsn.explorer.data.anorm import javax.inject.Inject +import com.alexitc.playsonify.core.ApplicationResult +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 org.scalactic.{One, Or} +import com.xsn.explorer.models.base.{PaginatedQuery, PaginatedResult} +import org.scalactic.{Good, One, Or} import play.api.db.Database class BalancePostgresDataHandler @Inject() ( override val database: Database, balancePostgresDAO: BalancePostgresDAO) - extends AnormPostgresDataHandler { + extends BalanceBlockingDataHandler + with AnormPostgresDataHandler { - def upsert(balance: Balance) = withConnection { implicit conn => + override def upsert(balance: Balance): ApplicationResult[Balance] = withConnection { implicit conn => val maybe = balancePostgresDAO.upsert(balance) Or.from(maybe, One(BalanceUnknownError)) } + + override def getRichest(query: PaginatedQuery): ApplicationResult[PaginatedResult[Balance]] = withConnection { implicit conn => + val balances = balancePostgresDAO.getRichest(query) + val total = balancePostgresDAO.countRichest + val result = PaginatedResult(query.offset, query.limit, total, balances) + + Good(result) + } } diff --git a/server/app/com/xsn/explorer/data/anorm/dao/BalancePostgresDAO.scala b/server/app/com/xsn/explorer/data/anorm/dao/BalancePostgresDAO.scala index baf38d6..5b3be13 100644 --- a/server/app/com/xsn/explorer/data/anorm/dao/BalancePostgresDAO.scala +++ b/server/app/com/xsn/explorer/data/anorm/dao/BalancePostgresDAO.scala @@ -5,6 +5,7 @@ import java.sql.Connection import anorm._ import com.xsn.explorer.data.anorm.parsers.BalanceParsers._ import com.xsn.explorer.models.Balance +import com.xsn.explorer.models.base.{Count, PaginatedQuery} class BalancePostgresDAO { @@ -28,4 +29,38 @@ class BalancePostgresDAO { 'available -> balance.available ).as(parseBalance.singleOpt).flatten } + + def getRichest(query: PaginatedQuery)(implicit conn: Connection): List[Balance] = { + SQL( + """ + |SELECT address, received, spent, available + |FROM balances + |WHERE address NOT IN ( + | SELECT address + | FROM hidden_addresses + |) + |ORDER BY available DESC + |OFFSET {offset} + |LIMIT {limit} + """.stripMargin + ).on( + 'offset -> query.offset.int, + 'limit -> query.limit.int + ).as(parseBalance.*).flatten + } + + def countRichest(implicit conn: Connection): Count = { + val result = SQL( + """ + |SELECT COUNT(*) + |FROM balances + |WHERE address NOT IN ( + | SELECT address + | FROM hidden_addresses + |) + """.stripMargin + ).as(SqlParser.scalar[Int].single) + + Count(result) + } } diff --git a/server/app/com/xsn/explorer/modules/DataHandlerModule.scala b/server/app/com/xsn/explorer/modules/DataHandlerModule.scala index 024f937..e8b6c4e 100644 --- a/server/app/com/xsn/explorer/modules/DataHandlerModule.scala +++ b/server/app/com/xsn/explorer/modules/DataHandlerModule.scala @@ -1,12 +1,13 @@ package com.xsn.explorer.modules import com.google.inject.AbstractModule -import com.xsn.explorer.data.BlockBlockingDataHandler -import com.xsn.explorer.data.anorm.BlockPostgresDataHandler +import com.xsn.explorer.data.anorm.{BalancePostgresDataHandler, BlockPostgresDataHandler} +import com.xsn.explorer.data.{BalanceBlockingDataHandler, BlockBlockingDataHandler} class DataHandlerModule extends AbstractModule { override def configure(): Unit = { bind(classOf[BlockBlockingDataHandler]).to(classOf[BlockPostgresDataHandler]) + bind(classOf[BalanceBlockingDataHandler]).to(classOf[BalancePostgresDataHandler]) } }