2

我有这个片段描述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 ]

这可行,但是将通知列表提取为列表,然后使用它来选择另一个表中的内容……这并不完全正确。显然我需要在这里加入,然后我将能够有效地更新所有内容。

如何在纯中做到这一点persistent?是否有可能,在这种情况下继续persistent执行此类任务是否是个好主意?我应该esqueleto改用吗?看来我需要学习不同的 DSL 才能使用它,所以我不确定是否要切换。

如何markAsRead正确书写persistent(如果可能)?

4

2 回答 2

1

是的 Esqueleto,如果你想加入的话。如果您的数据库和数据建模支持,那么持久性可以很好地嵌入数据。

于 2015-11-16T19:08:01.360 回答
1

正如格雷格所提到的,Esqueleto 是要走的路。您可以尝试阅读其主要模块文档

目前 Esqueleto 不支持在UPDATEs 上连接。但是,您可以使用子查询来达到相同的效果。

未经测试的代码可以帮助您入门:

-- | 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)
于 2015-11-16T19:18:56.963 回答