1

I would like to run two effects f1 and f2 updating two different database tables t1 and t2 while staying in the generic F context.

    def update(model:Details): Update0 = sql"""Update details_compta
 set TRANSID=${model.transid}, ACCOUNT=${model.account}, SIDE=${model.side}, OACCOUNT=${model.oaccount},
 AMOUNT=${model.amount}, DUEDATE=${model.duedate}, TEXT=${model.text},  CURRENCY=${model.currency}, COMPANY=${model.company}
 where id =${model.id}""".update

}

def update(model: FinancialsTransaction): Update0 = sql"""Update master_compta
set OID=${model.oid}, COSTCENTER=${model.costcenter}, ACCOUNT=${model.account}, TRANSDATE=${model.transdate}
 , HEADERTEXT=${model.text}, FILE_CONTENT=${model.file_content}, TYPE_JOURNAL=${model.typeJournal}
,  PERIOD=${model.period}
 where id =${model.tid} AND POSTED=false""".update

}

I tried the following which failed to compile:

  def update(model: FinancialsTransaction): F[Int] = {
val l1 = model.lines.map(SQL.FinancialsTransactionDetailsRepo.update(_)) :+ SQL.FinancialsTransactionRepo.update(
  model
)
l1.sequence.run.transact(transactor)

} I got the following error:

doobie/DoobieRepository.scala:892:8: Cannot prove that doobie.util.update.Update0 <:< G[A].[error]     l1.sequence.run.transact(transactor)

PS:I would like to run both effects in a single transaction and in the generic F context. I know the solution when using the Connection[IO[]] for F. But need a solution while remaining in the generic F context if possible. Thanks

Bate
  • 23
  • 8

1 Answers1

0

I solved by introducing a helper function/method

  def getX[A](func: A => Update0, query: A): 
  ConnectionIO[Int] =
  for {
      response <- func(query).run
    } yield response 
  def getXX[A](func: List[A] => List[Update0], query: 
      List[A]): 
      List[ConnectionIO[Int]] =
   for {
       response <- func(query).map(_.run)
    } yield response
 }

Using these function i can implement update

     def update(model: FinancialsTransaction): F[List[Int]] = 
     {
   val result: List[ConnectionIO[Int]] = 
     getXX(SQL.FinancialsTransactionDetails.update, oldLines) 
     ++List(getX(SQL.FinancialsTransaction.update, model))

      result.sequence.transact(transactor)
 }

Where SQL.FinancialsTransactionDetails.update and SQL.FinancialsTransaction.update are also function for getting the SQL update statemenent and yielding Update0 respectively for a single and multiple statement

    def update(model: FinancialsTransactionDetails): Update0 
       = sql"""Update details_compta
      set ACCOUNT=${model.account}, SIDE=${model.side}, 
        OACCOUNT=${model.oaccount},
        AMOUNT=${model.amount}, DUEDATE=${model.duedate}, 
        TEXT=${model.text},  CURRENCY=${model.currency}
      where id =${model.lid} """.update
        }
        override def update(model: FinancialsTransaction): 
         Update0 = sql"""Update master_compta
        set OID=${model.oid}, COSTCENTER=${model.costcenter}, 
             ACCOUNT=${model.account}, 
             TRANSDATE=${model.transdate},
            , HEADERTEXT=${model.text}, 
             FILE_CONTENT=${model.file_content}, 
             TYPE_JOURNAL=${model.typeJournal}
            ,  PERIOD=${model.period}
           where id =${model.tid} AND POSTED=false""".update
          }
Bate
  • 23
  • 8