haskell - 持久内连接还是应该使用 esqueleto?

标签 haskell haskell-persistent

我有这个描述 NotificationNotified 实体的片段:

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/

相关文章:

haskell - 为什么会立即添加到列表中?

haskell - 从脚本本身获取 Haskell Stack & Turtle 脚本的源目录

haskell - 持久性 - 如何过滤记录列的字段

haskell - 使用持久性从 ID 列表中选择列表

database - haskell "persistent"模型 : How to correctly define cross-reference?

haskell - 持久的 selectList 导致错误 "Couldn' t 匹配类型 ‘BaseBackend backend0’ 与 ‘SqlBackend’"

parsing - 如何用逗号代替小数点来解析 float ?

algorithm - 对列表的两个列表设置操作

haskell - 如何在 Haskell 中获取已创建进程的进程 ID?

haskell - 如何使用持久模型中的字段作为路由文件中的路径片段?