Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Main.scala:
- import cats.effect._
- import cats.implicits._
- import doobie.hikari.HikariTransactor
- import doobie.util.ExecutionContexts
- import fs2.Stream
- import org.flywaydb.core.Flyway
- import org.flywaydb.core.internal.jdbc.DriverDataSource
- import org.http4s.HttpApp
- import org.http4s.implicits._
- import org.http4s.server.Router
- import org.http4s.server.blaze.BlazeServerBuilder
- import org.http4s.server.middleware.{CORS, Logger}
- import org.http4s.server.staticcontent._
- import server.setting.{SettingRoutes, SettingService}
- object Main extends IOApp {
- override def run(args: List[String]): IO[ExitCode] = {
- runMigrations()
- val transactor: Resource[IO, HikariTransactor[IO]] = createTransactor()
- transactor.use { tx =>
- val db: Db[IO] = new Db(tx)
- val settingService: SettingService[IO] = new SettingService(db)
- val app: HttpApp[IO] = createApp(settingService)
- val loggedCorsApp: HttpApp[IO] = CORS(Logger.httpApp(logHeaders = true, logBody = true)(app))
- val server: Stream[IO, ExitCode] = createServer(app = loggedCorsApp)
- server.compile.drain.as(ExitCode.Success)
- }
- }
- def createApp[F[_]: Effect : ContextShift](service: SettingService[F]): HttpApp[F] = {
- Router("/" -> fileService[F](FileService.Config("./assets")), "/setting" -> SettingRoutes.routes[F](service)).orNotFound
- }
- def createServer[F[_]: ConcurrentEffect: Timer](host: String = "0.0.0.0", port: Int = 8080, app: HttpApp[F]): Stream[F, ExitCode] = {
- BlazeServerBuilder[F].bindHttp(port, host).withHttpApp(app).serve
- }
- def createTransactor[F[_]: Async : ContextShift](
- driver: String = "org.postgresql.Driver",
- url: String = "jdbc:postgresql://localhost:5432/postgres",
- user: String = "postgres",
- password: String = "postgres",
- connectionThreads: Int = 32
- ): Resource[F, HikariTransactor[F]] = {
- for {
- connectEc <- ExecutionContexts.fixedThreadPool[F](connectionThreads)
- transactEc <- ExecutionContexts.cachedThreadPool[F]
- xa <- HikariTransactor.newHikariTransactor[F](driver, url, user, password, connectEc, transactEc)
- } yield xa
- }
- def runMigrations(driver: String = "org.postgresql.Driver",
- url: String = "jdbc:postgresql://localhost:5432/postgres",
- user: String = "postgres",
- password: String = "postgres"): Int = {
- val source = new DriverDataSource(getClass.getClassLoader, driver, url, user, password)
- Flyway.configure().dataSource(source).load().migrate()
- }
- }
- // Db.scala
- import cats.effect.Bracket
- import doobie.free.connection.ConnectionIO
- import doobie.util.transactor.Transactor
- import doobie.implicits._
- class Db[F[_]](tx: Transactor[F])(implicit ev: Bracket[F, Throwable]) {
- def run[A](program: ConnectionIO[A]): F[A] = program.transact(tx)
- }
- // SettingRoutes.scala:
- import cats.effect._
- import org.http4s.HttpRoutes
- import org.http4s.dsl.Http4sDsl
- object SettingRoutes {
- def routes[F[_] : Sync](service: SettingService[F]): HttpRoutes[F] = {
- val dsl = new Http4sDsl[F] {}
- import dsl._
- import cats.implicits._
- HttpRoutes.of[F] {
- case GET -> Root / "hey" =>
- for {
- count <- service.getCountTest
- ok <- Ok(s"Size = $count")
- } yield ok
- }
- }
- }
- // SettingService.scala:
- import server.Db
- import doobie.implicits._
- class SettingService[F[_]](db: Db[F]) {
- def getCountTest: F[Int] = {
- db.run(sql"""SELECT COUNT(*) FROM user;""".query[Int].unique)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement