Учитывая модель данных (<- указывает на зависимость внешнего ключа) </p>
TableA <- TableB <- TableC
^ v
-----------------
Мне нужно выполнить операцию API DELETE API, которая мягко удаляет строку в TableC.Это удаление также должно инициировать вызов другой службы (требующей значений из TableA и TableB), если больше нет восстановленных записей TableC, которые ссылаются на родителя этой строки в TableB.Если внешний вызов не удастся, я хочу отменить мягкое удаление.Я хочу сделать все это идиоматическим способом (я фактически новичок в scala / slick) и использую транзакции для отката
На основании прочитанного я должен использовать дляпонимание, чтобы собрать запросы, но у меня есть проблемы с получением операций базы данных, чтобы хорошо сочетаться с внешним вызовом службы.Мой первоначальный план был:
val select = for {
tableCRow <- tableBDao.TableQueryC.filter(_.id === idParam)
tableBRow <- tableBDao.TableQueryB if tableCRow.tableBForeignKey === tableBRow.id
tableARow <- TableADao.TableQueryA if tableCRow.tableAForeignKey === tableARow.id
count <- tableBDao.TableQueryC.filter(_.tableBForeignKey === tableBRow.id).map(_.id).countDefined
_ <- tableBDao.softDeleteRow(idParam)
_ <- if (count > 1) DBIO.successful(httpRequestService.deleteOtherResource(tableARow.someValue, tableBRow.someValue))
} yield ()
db.run(select.result)
Но у него были проблемы, потому что я не мог передать значения Rep [T] Слика моему методу httpRequestService.Затем я попытался разбить его на две части - сначала ВЫБРАТЬ, а затем УДАЛИТЬ, вот так:
val select = for {
tableCRow <- tableBDao.TableQueryC.filter(_.id === idParam)
tableBRow <- tableBDao.TableQueryB if tableCRow.tableBForeignKey === tableBRow.id
tableARow <- TableADao.TableQueryA if tableCRow.tableAForeignKey === tableARow.id
count <- tableBDao.TableQueryC.filter(_.tableBForeignKey === tableBRow.id).map(_.id).countDefined
} yield (tableBRow.date.formatted("yyyy-MM-DD"), tableARow.externalServiceId, count)
val result: Future[Option[(String, Long, Integer)]] = db.run(select.result.headOption)
result.map {
case None => throw new IllegalArgumentException("exception message")
case Some(data) =>
val delete = for {
_ <- tableBDao.softDeleteRow(idParam)
_ <- if (data._3 > 1) DBIO.successful(httpRequestService.cancelSchedulerJob(data._2, data._1))
} yield numRows
db.run(delete.transactionally)
}
Но, несмотря на то, что это на самом деле проходит проверки IntelliJ IDEA, он не скомпилируется как мой запрос count
возвращает Rep [Int], в котором отсутствует функция map
.Кроме того, каждая из таблиц строк моей таблицы (A | B | C) вызывает ошибку, потому что они ожидают slick.lifted.Query[Nothing,Nothing,Seq]
и получают slick.lifted.Query[Nothing,T,Seq]
.Наконец, оператор db.run
не хочет использовать headOption
и, по-видимому, возвращает Any
, который не поддерживает map
halp