Add routes to retrieve sent mails

This commit is contained in:
Eike Kettner
2020-01-10 23:41:03 +01:00
parent b795a22992
commit 2ecfb679d9
9 changed files with 297 additions and 24 deletions

View File

@ -20,6 +20,7 @@ CREATE TABLE "sentmail" (
"uid" varchar(254) not null,
"message_id" varchar(254) not null,
"sender" varchar(254) not null,
"conn_name" varchar(254) not null,
"subject" varchar(254) not null,
"recipients" varchar(254) not null,
"body" text not null,

View File

@ -65,12 +65,6 @@ trait DoobieSyntax {
Fragment.const("SELECT DISTINCT(") ++ commas(cols.map(_.f)) ++
Fragment.const(") FROM ") ++ table ++ this.where(where)
// def selectJoinCollective(cols: Seq[Column], fkCid: Column, table: Fragment, wh: Fragment): Fragment =
// selectSimple(cols.map(_.prefix("a"))
// , table ++ fr"a," ++ RCollective.table ++ fr"b"
// , if (isEmpty(wh)) fkCid.prefix("a") is RCollective.Columns.id.prefix("b")
// else and(wh, fkCid.prefix("a") is RCollective.Columns.id.prefix("b")))
def selectCount(col: Column, table: Fragment, where: Fragment): Fragment =
Fragment.const("SELECT COUNT(") ++ col.f ++ Fragment.const(") FROM ") ++ table ++ this.where(
where

View File

@ -0,0 +1,64 @@
package docspell.store.queries
import cats.data.OptionT
import doobie._
import doobie.implicits._
import docspell.common._
import docspell.store.impl.Column
import docspell.store.impl.Implicits._
import docspell.store.records.{RItem, RSentMail, RSentMailItem, RUser}
object QMails {
def delete(coll: Ident, mailId: Ident): ConnectionIO[Int] =
(for {
m <- OptionT(findMail(coll, mailId))
k <- OptionT.liftF(RSentMailItem.deleteMail(mailId))
n <- OptionT.liftF(RSentMail.delete(m._1.id))
} yield k + n).getOrElse(0)
def findMail(coll: Ident, mailId: Ident): ConnectionIO[Option[(RSentMail, Ident)]] = {
val iColl = RItem.Columns.cid.prefix("i")
val mId = RSentMail.Columns.id.prefix("m")
val (cols, from) = partialFind
val cond = Seq(mId.is(mailId), iColl.is(coll))
selectSimple(cols, from, and(cond)).query[(RSentMail, Ident)].option
}
def findMails(coll: Ident, itemId: Ident): ConnectionIO[Vector[(RSentMail, Ident)]] = {
val iColl = RItem.Columns.cid.prefix("i")
val tItem = RSentMailItem.Columns.itemId.prefix("t")
val mCreated = RSentMail.Columns.created.prefix("m")
val (cols, from) = partialFind
val cond = Seq(tItem.is(itemId), iColl.is(coll))
(selectSimple(cols, from, and(cond)) ++ orderBy(mCreated.f) ++ fr"DESC")
.query[(RSentMail, Ident)]
.to[Vector]
}
private def partialFind: (Seq[Column], Fragment) = {
val iId = RItem.Columns.id.prefix("i")
val tItem = RSentMailItem.Columns.itemId.prefix("t")
val tMail = RSentMailItem.Columns.sentMailId.prefix("t")
val mId = RSentMail.Columns.id.prefix("m")
val mUser = RSentMail.Columns.uid.prefix("m")
val uId = RUser.Columns.uid.prefix("u")
val uLogin = RUser.Columns.login.prefix("u")
val cols = RSentMail.Columns.all.map(_.prefix("m")) :+ uLogin
val from = RSentMail.table ++ fr"m INNER JOIN" ++
RSentMailItem.table ++ fr"t ON" ++ tMail.is(mId) ++
fr"INNER JOIN" ++ RItem.table ++ fr"i ON" ++ tItem.is(iId) ++
fr"INNER JOIN" ++ RUser.table ++ fr"u ON" ++ uId.is(mUser)
(cols, from)
}
}

View File

@ -16,6 +16,7 @@ case class RSentMail(
uid: Ident,
messageId: String,
sender: MailAddress,
connName: Ident,
subject: String,
recipients: List[MailAddress],
body: String,
@ -28,6 +29,7 @@ object RSentMail {
uid: Ident,
messageId: String,
sender: MailAddress,
connName: Ident,
subject: String,
recipients: List[MailAddress],
body: String
@ -35,24 +37,26 @@ object RSentMail {
for {
id <- Ident.randomId[F]
now <- Timestamp.current[F]
} yield RSentMail(id, uid, messageId, sender, subject, recipients, body, now)
} yield RSentMail(id, uid, messageId, sender, connName, subject, recipients, body, now)
def forItem(
itemId: Ident,
accId: AccountId,
messageId: String,
sender: MailAddress,
connName: Ident,
subject: String,
recipients: List[MailAddress],
body: String
): OptionT[ConnectionIO, (RSentMail, RSentMailItem)] =
for {
user <- OptionT(RUser.findByAccount(accId))
sm <- OptionT.liftF(RSentMail[ConnectionIO](user.uid, messageId, sender, subject, recipients, body))
sm <- OptionT.liftF(
RSentMail[ConnectionIO](user.uid, messageId, sender, connName, subject, recipients, body)
)
si <- OptionT.liftF(RSentMailItem[ConnectionIO](itemId, sm.id, Some(sm.created)))
} yield (sm, si)
val table = fr"sentmail"
object Columns {
@ -60,6 +64,7 @@ object RSentMail {
val uid = Column("uid")
val messageId = Column("message_id")
val sender = Column("sender")
val connName = Column("conn_name")
val subject = Column("subject")
val recipients = Column("recipients")
val body = Column("body")
@ -70,6 +75,7 @@ object RSentMail {
uid,
messageId,
sender,
connName,
subject,
recipients,
body,
@ -83,10 +89,12 @@ object RSentMail {
insertRow(
table,
all,
sql"${v.id},${v.uid},${v.messageId},${v.sender},${v.subject},${v.recipients},${v.body},${v.created}"
sql"${v.id},${v.uid},${v.messageId},${v.sender},${v.connName},${v.subject},${v.recipients},${v.body},${v.created}"
).update.run
def findByUser(userId: Ident): Stream[ConnectionIO, RSentMail] =
selectSimple(all, table, uid.is(userId)).query[RSentMail].stream
def delete(mailId: Ident): ConnectionIO[Int] =
deleteFrom(table, id.is(mailId)).update.run
}

View File

@ -52,4 +52,6 @@ object RSentMailItem {
sql"${v.id},${v.itemId},${v.sentMailId},${v.created}"
).update.run
def deleteMail(mailId: Ident): ConnectionIO[Int] =
deleteFrom(table, sentMailId.is(mailId)).update.run
}