diff --git a/server/app/com/xsn/explorer/data/anorm/TransactionPostgresDataHandler.scala b/server/app/com/xsn/explorer/data/anorm/TransactionPostgresDataHandler.scala index 382cd34..f292e5e 100644 --- a/server/app/com/xsn/explorer/data/anorm/TransactionPostgresDataHandler.scala +++ b/server/app/com/xsn/explorer/data/anorm/TransactionPostgresDataHandler.scala @@ -1,7 +1,7 @@ package com.xsn.explorer.data.anorm import com.alexitc.playsonify.core.ApplicationResult -import com.alexitc.playsonify.models.ordering.FieldOrdering +import com.alexitc.playsonify.models.ordering.{FieldOrdering, OrderingCondition} import com.alexitc.playsonify.models.pagination.{Limit, PaginatedQuery, PaginatedResult} import com.xsn.explorer.data.TransactionBlockingDataHandler import com.xsn.explorer.data.anorm.dao.TransactionPostgresDAO @@ -31,8 +31,8 @@ class TransactionPostgresDataHandler @Inject() ( def getLatestBy(address: Address, limit: Limit, lastSeenTxid: Option[TransactionId]): ApplicationResult[List[Transaction]] = withConnection { implicit conn => val transactions = lastSeenTxid - .map { transactionPostgresDAO.getLatestBy(address, _, limit) } - .getOrElse { transactionPostgresDAO.getLatestBy(address, limit) } + .map { transactionPostgresDAO.getBy(address, _, limit, OrderingCondition.DescendingOrder) } + .getOrElse { transactionPostgresDAO.getBy(address, limit, OrderingCondition.DescendingOrder) } Good(transactions) } diff --git a/server/app/com/xsn/explorer/data/anorm/dao/TransactionPostgresDAO.scala b/server/app/com/xsn/explorer/data/anorm/dao/TransactionPostgresDAO.scala index 016e8c0..2aaeb6e 100644 --- a/server/app/com/xsn/explorer/data/anorm/dao/TransactionPostgresDAO.scala +++ b/server/app/com/xsn/explorer/data/anorm/dao/TransactionPostgresDAO.scala @@ -3,7 +3,7 @@ package com.xsn.explorer.data.anorm.dao import java.sql.Connection import anorm._ -import com.alexitc.playsonify.models.ordering.FieldOrdering +import com.alexitc.playsonify.models.ordering.{FieldOrdering, OrderingCondition} import com.alexitc.playsonify.models.pagination.{Count, Limit, PaginatedQuery} import com.alexitc.playsonify.sql.FieldOrderingSQLInterpreter import com.xsn.explorer.data.anorm.parsers.TransactionParsers._ @@ -89,15 +89,17 @@ class TransactionPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderi } /** - * Get the latest transactions by the given address. + * Get the transactions by the given address (sorted by time). */ - def getLatestBy(address: Address, limit: Limit)(implicit conn: Connection): List[Transaction] = { + def getBy(address: Address, limit: Limit, orderingCondition: OrderingCondition)(implicit conn: Connection): List[Transaction] = { + val order = toSQL(orderingCondition) + SQL( - """ + s""" |SELECT t.txid, t.blockhash, t.time, t.size |FROM transactions t JOIN address_transaction_details USING (txid) |WHERE address = {address} - |ORDER BY time DESC + |ORDER BY time $order |LIMIT {limit} """.stripMargin ).on( @@ -107,16 +109,26 @@ class TransactionPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderi } /** - * Get the latest transactions by the given address that occurred before the last seen transaction. + * Get the transactions by the given address (sorted by time). + * + * - When orderingCondition = DescendingOrder, the transactions that occurred before the last seen transaction are retrieved. + * - When orderingCondition = AscendingOrder, the transactions that occurred after the last seen transaction are retrieved. */ - def getLatestBy( + def getBy( address: Address, lastSeenTxid: TransactionId, - limit: Limit)( + limit: Limit, + orderingCondition: OrderingCondition)( implicit conn: Connection): List[Transaction] = { + val order = toSQL(orderingCondition) + val comparator = orderingCondition match { + case OrderingCondition.DescendingOrder => "<" + case OrderingCondition.AscendingOrder => ">" + } + SQL( - """ + s""" |WITH CTE AS ( | SELECT time AS lastSeenTime | FROM transactions @@ -126,8 +138,8 @@ class TransactionPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderi |FROM CTE CROSS JOIN transactions t | JOIN address_transaction_details USING (txid) |WHERE address = {address} AND - | (t.time < lastSeenTime OR (t.time = lastSeenTime AND t.txid > {lastSeenTxid})) - |ORDER BY time DESC + | (t.time $comparator lastSeenTime OR (t.time = lastSeenTime AND t.txid > {lastSeenTxid})) + |ORDER BY time $order |LIMIT {limit} """.stripMargin ).on( @@ -453,4 +465,9 @@ class TransactionPostgresDAO @Inject() (fieldOrderingSQLInterpreter: FieldOrderi result } + + private def toSQL(condition: OrderingCondition): String = condition match { + case OrderingCondition.AscendingOrder => "ASC" + case OrderingCondition.DescendingOrder => "DESC" + } }