我有这个描述 Notification
和 Notified
实体的片段:
Notification
type NotiType
release ReleaseId
date UTCTime
Notified
aboutWhat NotificationId
unread Bool
user UserId
现在我想写这个:
-- | Mark specified notification as already seen by specific user. Note that
-- we use 'ReleaseId' to select notification, so this may result in several
-- notifications marked as “read” if they happen to be about the same
-- release. This is generally what you want.
markAsRead
:: ReleaseId -- ^ Release in question
-> UserId -- ^ User who has seen mentioned release
-> SqlPersistM ()
markAsRead release user = do
ns <- selectKeysList [ NotificationRelease ==. release ] []
updateWhere [ NotifiedAboutWhat <-. ns
, NotifiedUnread ==. True
, NotifiedUser ==. user ]
[ NotifiedUnread =. False ]
这是可行的,但是将通知列表提取为列表,然后使用它来选择另一个表中的内容......这并不完全正确。显然我需要在这里加入,然后我才能有效地更新所有内容。
如何以纯粹的持久性
做到这一点?在这种情况下,继续使用持久性来完成此类任务是否可能?这是一个好主意吗?我应该使用 esqueleto 来代替吗?看来我需要学习不同的 DSL 才能使用它,所以我不确定是否要切换。
如何使用persistent
正确编写markAsRead
(如果可能)?
最佳答案
正如 Greg 提到的,Esqueleto 是正确的选择。您可以尝试阅读its main module documentation .
目前 Esqueleto 不支持 UPDATE
上的联接。但是,您可以使用子查询达到相同的效果。
未经测试的代码可帮助您入门:
-- | Mark specified notification as already seen by specific user. Note that
-- we use 'ReleaseId' to select notification, so this may result in several
-- notifications marked as “read” if they happen to be about the same
-- release. This is generally what you want.
markAsRead
:: ReleaseId -- ^ Release in question
-> UserId -- ^ User who has seen mentioned release
-> SqlPersistM ()
markAsRead release user =
update $ \n -> do
set n [ NotifiedUnread =. val False ]
where_ $
n ^. NotifiedUnread ==. val True &&.
n ^. NotifiedUser ==. val user &&.
n ^. NotifiedAboutWhat `in_`
(subList_select $
from $ \t -> do
where_ $ t ^. NotificationRelease ==. val release
return $ t ^. NotificationId)
关于haskell - 持久内连接还是应该使用 esqueleto?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33733853/