From a8882aebc2f9ebe5c0d2503d7fbab2a320b6c0d3 Mon Sep 17 00:00:00 2001 From: Kseniya Tomskikh Date: Fri, 27 Oct 2017 14:24:43 +0700 Subject: Fixed bug --- .../scala/xyz/driver/pdsuicommon/db/DbIo.scala | 13 ++++++++++ .../scala/xyz/driver/pdsuicommon/db/JdbcDbIo.scala | 28 ++++++++++++++++++++++ .../driver/pdsuicommon/db/PostgresContext.scala | 24 +++++++++++++++++++ .../driver/pdsuicommon/error/ErrorsResponse.scala | 3 +-- .../xyz/driver/pdsuicommon/http/Directives.scala | 4 ++-- 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 src/main/scala/xyz/driver/pdsuicommon/db/DbIo.scala create mode 100644 src/main/scala/xyz/driver/pdsuicommon/db/JdbcDbIo.scala (limited to 'src') diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/DbIo.scala b/src/main/scala/xyz/driver/pdsuicommon/db/DbIo.scala new file mode 100644 index 0000000..7c290d1 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/db/DbIo.scala @@ -0,0 +1,13 @@ +package xyz.driver.pdsuicommon.db + +import scala.concurrent.Future + +/** + * Where queries should run + */ +trait DbIo { + def runAsync[T](f: => T): Future[T] + def runSync[T](f: => T): T = f + def runAsyncTx[T](f: => T): Future[T] + def runSyncTx[T](f: => T): Unit +} diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/JdbcDbIo.scala b/src/main/scala/xyz/driver/pdsuicommon/db/JdbcDbIo.scala new file mode 100644 index 0000000..44f177c --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/db/JdbcDbIo.scala @@ -0,0 +1,28 @@ +package xyz.driver.pdsuicommon.db + +import xyz.driver.pdsuicommon.logging._ + +import scala.concurrent.Future +import scala.util.{Failure, Success, Try} + +class JdbcDbIo(sqlContext: TransactionalContext) extends DbIo with PhiLogging { + + override def runAsync[T](f: => T): Future[T] = { + Future(f)(sqlContext.executionContext) + } + + override def runAsyncTx[T](f: => T): Future[T] = { + import sqlContext.executionContext + + Future(sqlContext.transaction(f)).andThen { + case Failure(e) => logger.error(phi"Can't run a transaction: $e") + } + } + + override def runSyncTx[T](f: => T): Unit = { + Try(sqlContext.transaction(f)) match { + case Success(_) => + case Failure(e) => logger.error(phi"Can't run a transaction: $e") + } + } +} diff --git a/src/main/scala/xyz/driver/pdsuicommon/db/PostgresContext.scala b/src/main/scala/xyz/driver/pdsuicommon/db/PostgresContext.scala index bb8d322..0098a64 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/db/PostgresContext.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/db/PostgresContext.scala @@ -1,12 +1,15 @@ package xyz.driver.pdsuicommon.db import java.io.Closeable +import java.time.{LocalDateTime, ZoneOffset} +import java.util.UUID import java.util.concurrent.Executors import javax.sql.DataSource import io.getquill._ import xyz.driver.pdsuicommon.concurrent.MdcExecutionContext import xyz.driver.pdsuicommon.db.PostgresContext.Settings +import xyz.driver.pdsuicommon.domain.UuidId import xyz.driver.pdsuicommon.logging._ import scala.concurrent.ExecutionContext @@ -45,4 +48,25 @@ class PostgresContext(val dataSource: DataSource with Closeable, settings: Setti super.close() tpe.shutdownNow() } + + /** + * Usable for QueryBuilder's extractors + */ + def timestampToLocalDateTime(timestamp: java.sql.Timestamp): LocalDateTime = { + LocalDateTime.ofInstant(timestamp.toInstant, ZoneOffset.UTC) + } + + implicit def encodeUuidId[T] = MappedEncoding[UuidId[T], String](_.toString) + implicit def decodeUuidId[T] = MappedEncoding[String, UuidId[T]] { uuid => + UuidId[T](UUID.fromString(uuid)) + } + + def decodeOptUuidId[T] = MappedEncoding[Option[String], Option[UuidId[T]]] { + case Some(x) => Option(x).map(y => UuidId[T](UUID.fromString(y))) + case None => None + } + + implicit def decodeUuid[T] = MappedEncoding[String, UUID] { uuid => + UUID.fromString(uuid) + } } diff --git a/src/main/scala/xyz/driver/pdsuicommon/error/ErrorsResponse.scala b/src/main/scala/xyz/driver/pdsuicommon/error/ErrorsResponse.scala index 540bfbb..ccb84c2 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/error/ErrorsResponse.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/error/ErrorsResponse.scala @@ -1,7 +1,6 @@ package xyz.driver.pdsuicommon.error import spray.json._ -import ErrorCode._ import ErrorsResponse.ResponseError import xyz.driver.pdsuicommon.auth.RequestId @@ -17,7 +16,7 @@ object ErrorsResponse { * * @see https://driverinc.atlassian.net/wiki/display/RA/REST+API+Specification#RESTAPISpecification-HTTPStatuscodes */ - final case class ResponseError(data: Option[String], message: String, code: ErrorCode) + final case class ResponseError(data: Option[String], message: String, code: Int) object ResponseError { diff --git a/src/main/scala/xyz/driver/pdsuicommon/http/Directives.scala b/src/main/scala/xyz/driver/pdsuicommon/http/Directives.scala index 37e7687..c3c60bd 100644 --- a/src/main/scala/xyz/driver/pdsuicommon/http/Directives.scala +++ b/src/main/scala/xyz/driver/pdsuicommon/http/Directives.scala @@ -72,7 +72,7 @@ trait Directives { def domainExceptionHandler(req: RequestId): ExceptionHandler = { def errorResponse(ex: Throwable) = - ErrorsResponse(Seq(ResponseError(None, ex.getMessage, ErrorCode.Unspecified)), req) + ErrorsResponse(Seq(ResponseError(None, ex.getMessage, 1)), req) ExceptionHandler { case ex: AuthenticationException => complete(StatusCodes.Unauthorized -> errorResponse(ex)) case ex: AuthorizationException => complete(StatusCodes.Forbidden -> errorResponse(ex)) @@ -85,7 +85,7 @@ trait Directives { def domainRejectionHandler(req: RequestId): RejectionHandler = { def wrapContent(message: String) = { import ErrorsResponse._ - val err: ErrorsResponse = ErrorsResponse(Seq(ResponseError(None, message, ErrorCode.Unspecified)), req) + val err: ErrorsResponse = ErrorsResponse(Seq(ResponseError(None, message, 1)), req) val text = errorsResponseJsonFormat.write(err).toString() HttpEntity(ContentTypes.`application/json`, text) } -- cgit v1.2.3