Вы можете выполнить несколько запросов в одной транзакции в doobie, используя for-comppresion, например:
val query = for {
_ <- sql"insert into person (name, age) values ($name, $age)".update.run
id <- sql"select lastval()".query[Long].unique
} yield p
Но это решение не будет работать в вашем случае, потому что у вас есть динамический список запросов. К счастью, мы можем использовать traverse от кошек:
import cats.effect.ContextShift
import doobie._
import doobie.implicits._
import cats.effect._
import scala.concurrent.ExecutionContext
import cats.implicits._
import cats._
import cats.data._
def execute(user: String, password: String, database: String, host: String, port: Int, queries: String*): Unit = {
//you can use other executor if you want
//it would be better to pass context shift as implicit argument to method
implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global)
//let's create transactor
val xa = Transactor.fromDriverManager[IO](
"org.postgresql.Driver",
s"jdbc:postgresql://$host:$port/$database", //remember to change url or make it dynamic, if you run it agains another database
user,
password
)
val batch = queries
.toList //we need to change String* to list, since String* doesn't have necessary typeclass for Aplicative
.traverse(query => Update0(query, None).run) //we lift strings to Query0 and then run them, then we change List[ConnectionIO[Int]] to ConnectionIO[List[Int]]
//above can be done in two steps using map and sequence
batch //now we've got single ConnectionIO which will run in one transaction
.transact(xa) //let's make it IO[Int]
.unsafeRunSync() //we need to block since your method returns Unit
}
Возможно, ваша IDE покажет, что этот код недействителен, но он верен. IDE просто не могут справиться с магией Scala.
Вы можете также рассмотреть возможность использования unsafeRunTimed
вместо unsafeRunSync
для добавления ограничения по времени.
Кроме того, не забудьте добавить драйвер postgresql для jdbc и cats к вашему build.sbt
. Doobie использует кошек под капотом, но я думаю, что явная зависимость может быть необходимой.