Update channel names when retrieving user tasks

Usertasks hold their arguments in an opaque json structure that is not
connected to the other data at the db level. When loading tasks that
holds references (like channels) they could have changed in the
meantime. This is now a hacky way around that updates the channels
when loading. Should they be deleted, the tasks fails when running.
This commit is contained in:
eikek
2022-01-30 17:09:52 +01:00
parent 0097d2bc73
commit 14a413e787
10 changed files with 102 additions and 15 deletions

View File

@ -56,6 +56,9 @@ trait DSL extends DoobieMeta {
def union(s1: Select, sn: Select*): Select =
Select.Union(s1, sn.toVector)
def union(selects: Nel[Select]): Select =
Select.Union(selects.head, selects.tail.toVector)
def intersect(s1: Select, sn: Select*): Select =
Select.Intersect(s1, sn.toVector)

View File

@ -6,11 +6,12 @@
package docspell.store.records
import cats.data.OptionT
import cats.data.{NonEmptyList => Nel, OptionT}
import cats.implicits._
import docspell.common._
import docspell.notification.api.{Channel, ChannelRef, ChannelType}
import docspell.store.qb.DSL._
import doobie._
@ -130,6 +131,22 @@ object RNotificationChannel {
RNotificationChannelHttp.getById(userId)(ref.id).map(_.map(Http.apply))
}
def resolveRefs(refs: Nel[ChannelRef]): ConnectionIO[List[ChannelRef]] = {
val byType = refs.groupByNem(_.channelType)
val queries = byType.toNel
.map {
case (ChannelType.Mail, refs) =>
RNotificationChannelMail.findRefs(refs.map(_.id))
case (ChannelType.Matrix, refs) =>
RNotificationChannelMatrix.findRefs(refs.map(_.id))
case (ChannelType.Gotify, refs) =>
RNotificationChannelGotify.findRefs(refs.map(_.id))
case (ChannelType.Http, refs) =>
RNotificationChannelHttp.findRefs(refs.map(_.id))
}
union(queries).build.query[ChannelRef].to[List]
}
def getByHook(hook: RNotificationHook): ConnectionIO[Vector[RNotificationChannel]] = {
def opt(id: Option[Ident]): OptionT[ConnectionIO, Ident] =
OptionT.fromOption(id)

View File

@ -9,6 +9,7 @@ package docspell.store.records
import cats.data.NonEmptyList
import docspell.common._
import docspell.notification.api.ChannelType
import docspell.store.qb.DSL._
import docspell.store.qb._
@ -97,4 +98,11 @@ object RNotificationChannelGotify {
T.id === id && T.uid.in(Select(select(u.uid), from(u), u.isAccount(account)))
)
}
def findRefs(ids: NonEmptyList[Ident]): Select =
Select(
select(T.id.s, const(ChannelType.Gotify.name), T.name.s),
from(T),
T.id.in(ids)
)
}

View File

@ -9,6 +9,7 @@ package docspell.store.records
import cats.data.NonEmptyList
import docspell.common._
import docspell.notification.api.ChannelType
import docspell.store.qb.DSL._
import docspell.store.qb._
@ -80,4 +81,11 @@ object RNotificationChannelHttp {
T.id === id && T.uid.in(Select(select(u.uid), from(u), u.isAccount(account)))
)
}
def findRefs(ids: NonEmptyList[Ident]): Select =
Select(
select(T.id.s, const(ChannelType.Http.name), T.name.s),
from(T),
T.id.in(ids)
)
}

View File

@ -9,6 +9,7 @@ package docspell.store.records
import cats.data.NonEmptyList
import docspell.common._
import docspell.notification.api.ChannelType
import docspell.store.qb.DSL._
import docspell.store.qb._
@ -90,4 +91,11 @@ object RNotificationChannelMail {
T.id === id && T.uid.in(Select(select(u.uid), from(u), u.isAccount(account)))
)
}
def findRefs(ids: NonEmptyList[Ident]): Select =
Select(
select(T.id.s, const(ChannelType.Mail.name), T.name.s),
from(T),
T.id.in(ids)
)
}

View File

@ -9,6 +9,7 @@ package docspell.store.records
import cats.data.NonEmptyList
import docspell.common._
import docspell.notification.api.ChannelType
import docspell.store.qb.DSL._
import docspell.store.qb._
@ -106,4 +107,11 @@ object RNotificationChannelMatrix {
T.id === id && T.uid.in(Select(select(u.uid), from(u), u.isAccount(account)))
)
}
def findRefs(ids: NonEmptyList[Ident]): Select =
Select(
select(T.id.s, const(ChannelType.Matrix.name), T.name.s),
from(T),
T.id.in(ids)
)
}

View File

@ -29,6 +29,11 @@ case class UserTask[A](
def encode(implicit E: Encoder[A]): UserTask[String] =
copy(args = E(args).noSpaces)
def withArgs[B](newArgs: B): UserTask[B] =
copy(args = newArgs)
def mapArgs[B](f: A => B): UserTask[B] =
withArgs(f(args))
}
object UserTask {