Функциональный способ реализации доступа к БД с дополнительной логикой - PullRequest
0 голосов
/ 20 ноября 2018

В настоящее время моей целью является взаимодействие с БД с использованием подхода CRUD.Между простой операцией у меня могут быть некоторые дополнительные шаги (дополнительная бизнес-логика, которая может вызвать некоторые ошибки).

import cats.effect.IO
import scalikejdbc._

IO(NamedDB(MyDB) localTx {
  implicit session => {
   val x = for {
      a <- IO(select()) // Option[Something]  (1)
      _ <- IO(log(a)) // Option[Something]  (2)
      _ <- IO(insert()) // Something (3)
      _ <- IO(insert()) // Something (4)
      c <- IO(select()) // Option[Something] (5)
      r <- IO(fileSystemOperation(a, c)) // (6)
      _ <- operation(r) // Either[Throwable, Unit] (7)
    } yield ()

    x.unsafeRunSync() // (8)
  }
}).attempt.unsafeRunSync() match { // (9)
  case Left(value) => println("Error")
  case Right(value) => println("Success") // in reality i want to return some result here
}

Первая проблема возникает (2): я получил ошибку:

Несоответствие типа ошибки;найдено: cats.effect.IO [Unit] требуется: опция [?] _ <- IO (log (a)) </p>

Но если я записываю результат любой вставки ((3) или * 1012)*) тогда все ок.Возможно, это из-за разницы в типе результата Option[Something] против Something, но я подумал, что это будет так же, как это:

for {
    a <- Option(1)
    ....
}

Второй вопрос - как правильно обрабатывать ошибки в (7) откатить транзакцию?Должен ли я использовать сопоставление с образцом и сделать что-то вроде этого:

operation(r) match {
    case Left(e) => throw e
}

, или я могу выдать ошибку внутри моего operation и вернуть Unit вместо Either[Throwable, Unit]?

Также, у меня есть вопрос о (8) и (9).Это правильный способ начать фактическую обработку и обработать любую ошибку или нет?

Я попытался сделать те же шаги, используя этот подход:

select() match {
    case Some(_) =>
        .....
        operation(r) match {
            case Left(e) => throw e
            case Right(_) => ....
        }
    case None => ....
}

Но в результате я получил слишком глубоко match-case статей, и это было трудно читать и понимать.Я новичок в FP, но я хочу реализовать это в FP.

...