Alexis Hernandez
6 years ago
60 changed files with 231 additions and 214 deletions
@ -1,19 +0,0 @@ |
|||||
package com.xsn.explorer.data.anorm.interpreters |
|
||||
|
|
||||
import scala.annotation.implicitNotFound |
|
||||
|
|
||||
@implicitNotFound( |
|
||||
"No column name resolver found for type ${A}. Try to implement an implicit ColumnNameResolver for this type." |
|
||||
) |
|
||||
trait ColumnNameResolver[A] { |
|
||||
|
|
||||
/** |
|
||||
* Maps a field to the column name on the sql schema. |
|
||||
*/ |
|
||||
def getColumnName(field: A): String |
|
||||
|
|
||||
/** |
|
||||
* This is used to break ties while sorting by non-unique fields, |
|
||||
*/ |
|
||||
def getUniqueColumnName: String |
|
||||
} |
|
@ -1,23 +0,0 @@ |
|||||
package com.xsn.explorer.data.anorm.interpreters |
|
||||
|
|
||||
import com.alexitc.playsonify.models.{FieldOrdering, OrderingCondition} |
|
||||
|
|
||||
class FieldOrderingSQLInterpreter { |
|
||||
|
|
||||
def toOrderByClause[A](fieldOrdering: FieldOrdering[A])(implicit columnNameResolver: ColumnNameResolver[A]) = { |
|
||||
val field = columnNameResolver.getColumnName(fieldOrdering.field) |
|
||||
val condition = getCondition(fieldOrdering.orderingCondition) |
|
||||
val uniqueField = columnNameResolver.getUniqueColumnName |
|
||||
|
|
||||
if (field == uniqueField) { |
|
||||
s"ORDER BY $field $condition" |
|
||||
} else { |
|
||||
s"ORDER BY $field $condition, $uniqueField" |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private def getCondition(ordering: OrderingCondition) = ordering match { |
|
||||
case OrderingCondition.AscendingOrder => "ASC" |
|
||||
case OrderingCondition.DescendingOrder => "DESC" |
|
||||
} |
|
||||
} |
|
@ -1,13 +1,15 @@ |
|||||
package com.xsn.explorer.errors |
package com.xsn.explorer.errors |
||||
|
|
||||
import com.alexitc.playsonify.models.{PublicError, ServerError} |
import com.alexitc.playsonify.core.I18nService |
||||
import play.api.i18n.{Lang, MessagesApi} |
import com.alexitc.playsonify.models.{ErrorId, PublicError, ServerError} |
||||
|
|
||||
sealed trait BalanceError |
sealed trait BalanceError |
||||
|
|
||||
case object BalanceUnknownError extends BalanceError with ServerError { |
case object BalanceUnknownError extends BalanceError with ServerError { |
||||
|
|
||||
|
val id = ErrorId.create |
||||
|
|
||||
override def cause: Option[Throwable] = None |
override def cause: Option[Throwable] = None |
||||
|
|
||||
override def toPublicErrorList(messagesApi: MessagesApi)(implicit lang: Lang): List[PublicError] = List.empty |
override def toPublicErrorList[L](i18nService: I18nService[L])(implicit lang: L): List[PublicError] = List.empty |
||||
} |
} |
||||
|
@ -0,0 +1,15 @@ |
|||||
|
package com.xsn.explorer |
||||
|
|
||||
|
import _root_.play.api.libs.json.{JsNumber, JsString, Writes} |
||||
|
import com.alexitc.playsonify.models.{WrappedInt, WrappedString} |
||||
|
|
||||
|
package object models { |
||||
|
|
||||
|
implicit val stringWrites: Writes[WrappedString] = Writes { obj => |
||||
|
JsString(obj.string) |
||||
|
} |
||||
|
|
||||
|
implicit val numberWrites: Writes[WrappedInt] = Writes { obj => |
||||
|
JsNumber(obj.int) |
||||
|
} |
||||
|
} |
@ -1,24 +1,26 @@ |
|||||
package controllers |
package controllers |
||||
|
|
||||
import javax.inject.Inject |
import com.alexitc.playsonify.models.ordering.OrderingQuery |
||||
|
import com.alexitc.playsonify.models.pagination.{Limit, Offset, PaginatedQuery} |
||||
import com.alexitc.playsonify.models.{Limit, Offset, OrderingQuery, PaginatedQuery} |
|
||||
import com.xsn.explorer.services.MasternodeService |
import com.xsn.explorer.services.MasternodeService |
||||
import controllers.common.{MyJsonController, MyJsonControllerComponents} |
import controllers.common.{Codecs, MyJsonController, MyJsonControllerComponents} |
||||
|
import javax.inject.Inject |
||||
|
|
||||
class MasternodesController @Inject() ( |
class MasternodesController @Inject() ( |
||||
masternodeService: MasternodeService, |
masternodeService: MasternodeService, |
||||
cc: MyJsonControllerComponents) |
cc: MyJsonControllerComponents) |
||||
extends MyJsonController(cc) { |
extends MyJsonController(cc) { |
||||
|
|
||||
def get(offset: Int, limit: Int, ordering: String) = publicNoInput { _ => |
import Codecs._ |
||||
|
|
||||
|
def get(offset: Int, limit: Int, ordering: String) = public { _ => |
||||
val paginatedQuery = PaginatedQuery(Offset(offset), Limit(limit)) |
val paginatedQuery = PaginatedQuery(Offset(offset), Limit(limit)) |
||||
val orderingQuery = OrderingQuery(ordering) |
val orderingQuery = OrderingQuery(ordering) |
||||
|
|
||||
masternodeService.getMasternodes(paginatedQuery, orderingQuery) |
masternodeService.getMasternodes(paginatedQuery, orderingQuery) |
||||
} |
} |
||||
|
|
||||
def getBy(ipAddress: String) = publicNoInput { _ => |
def getBy(ipAddress: String) = public { _ => |
||||
masternodeService.getMasternode(ipAddress) |
masternodeService.getMasternode(ipAddress) |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,16 +1,15 @@ |
|||||
package controllers |
package controllers |
||||
|
|
||||
import javax.inject.Inject |
|
||||
|
|
||||
import com.xsn.explorer.services.StatisticsService |
import com.xsn.explorer.services.StatisticsService |
||||
import controllers.common.{MyJsonController, MyJsonControllerComponents} |
import controllers.common.{MyJsonController, MyJsonControllerComponents} |
||||
|
import javax.inject.Inject |
||||
|
|
||||
class StatisticsController @Inject() ( |
class StatisticsController @Inject() ( |
||||
statisticsService: StatisticsService, |
statisticsService: StatisticsService, |
||||
cc: MyJsonControllerComponents) |
cc: MyJsonControllerComponents) |
||||
extends MyJsonController(cc) { |
extends MyJsonController(cc) { |
||||
|
|
||||
def getStatus() = publicNoInput { _ => |
def getStatus() = public { _ => |
||||
statisticsService.getStatistics() |
statisticsService.getStatistics() |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,30 +1,30 @@ |
|||||
package controllers |
package controllers |
||||
|
|
||||
import javax.inject.Inject |
|
||||
|
|
||||
import com.alexitc.playsonify.models.PublicContextWithModel |
|
||||
import com.xsn.explorer.models.request.{GetLatestTransactionRequest, SendRawTransactionRequest} |
import com.xsn.explorer.models.request.{GetLatestTransactionRequest, SendRawTransactionRequest} |
||||
import com.xsn.explorer.services.TransactionService |
import com.xsn.explorer.services.TransactionService |
||||
import controllers.common.{MyJsonController, MyJsonControllerComponents} |
import controllers.common.{MyJsonController, MyJsonControllerComponents} |
||||
|
import javax.inject.Inject |
||||
|
|
||||
class TransactionsController @Inject() ( |
class TransactionsController @Inject() ( |
||||
transactionService: TransactionService, |
transactionService: TransactionService, |
||||
cc: MyJsonControllerComponents) |
cc: MyJsonControllerComponents) |
||||
extends MyJsonController(cc) { |
extends MyJsonController(cc) { |
||||
|
|
||||
def getTransaction(txid: String) = publicNoInput { _ => |
import Context._ |
||||
|
|
||||
|
def getTransaction(txid: String) = public { _ => |
||||
transactionService.getTransactionDetails(txid) |
transactionService.getTransactionDetails(txid) |
||||
} |
} |
||||
|
|
||||
def getRawTransaction(txid: String) = publicNoInput { _ => |
def getRawTransaction(txid: String) = public { _ => |
||||
transactionService.getRawTransaction(txid) |
transactionService.getRawTransaction(txid) |
||||
} |
} |
||||
|
|
||||
def sendRawTransaction() = publicWithInput { ctx: PublicContextWithModel[SendRawTransactionRequest] => |
def sendRawTransaction() = publicInput { ctx: HasModel[SendRawTransactionRequest] => |
||||
transactionService.sendRawTransaction(ctx.model.hex) |
transactionService.sendRawTransaction(ctx.model.hex) |
||||
} |
} |
||||
|
|
||||
def getLatestByAddresses() = publicWithInput { ctx: PublicContextWithModel[GetLatestTransactionRequest] => |
def getLatestByAddresses() = publicInput { ctx: HasModel[GetLatestTransactionRequest] => |
||||
transactionService.getLatestTransactionBy(ctx.model.addresses) |
transactionService.getLatestTransactionBy(ctx.model.addresses) |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,25 +1,20 @@ |
|||||
package controllers.common |
package controllers.common |
||||
|
|
||||
import com.alexitc.playsonify.AbstractJsonController |
import com.alexitc.playsonify.models.ServerError |
||||
import com.alexitc.playsonify.models.{ErrorId, ServerError} |
import com.alexitc.playsonify.play.AbstractJsonController |
||||
import org.slf4j.LoggerFactory |
import org.slf4j.LoggerFactory |
||||
|
|
||||
abstract class MyJsonController(cc: MyJsonControllerComponents) extends AbstractJsonController[Nothing](cc) { |
abstract class MyJsonController(cc: MyJsonControllerComponents) extends AbstractJsonController[Nothing](cc) { |
||||
|
|
||||
protected val logger = LoggerFactory.getLogger(this.getClass) |
protected val logger = LoggerFactory.getLogger(this.getClass) |
||||
|
|
||||
override def onServerError(error: ServerError, errorId: ErrorId): Unit = { |
override protected def onServerError(error: ServerError): Unit = { |
||||
val message = s"Unexpected server error, id = ${errorId.string}, error = $error" |
error.cause match { |
||||
|
case Some(cause) => |
||||
|
logger.error(s"Unexpected internal error, id = ${error.id.string}, error = $error", cause) |
||||
|
|
||||
error |
case None => |
||||
.cause |
logger.error(s"Unexpected internal error, id = ${error.id.string}, error = $error}") |
||||
.orElse { |
} |
||||
logger.warn(message) |
|
||||
None |
|
||||
} |
|
||||
.foreach { cause => |
|
||||
// we'll log as error when there is an exception involved |
|
||||
logger.error(message, cause) |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
Loading…
Reference in new issue