2015-11-16 48 views
2

我有這樣的片段描述NotificationNotified實體:內部加入持久性或應該使用esqueleto?

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來處理它,所以我不確定是否切換。

如何用persistent(如果可能)正確地寫markAsRead

回答

1

正如格雷格所說,Esqueleto是要走的路。您可以嘗試閱讀its main module documentation

目前Esqueleto不支持連接UPDATE s。但是,您可以使用子查詢來達到相同的效果。

未經測試的代碼,讓你開始:

-- | 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) 
+0

因此,這意味着我應該使用Esquelto接口的一切,而不是持續性的界面? – Mark

+0

不一定。您可以同時使用這兩個接口。唯一的小問題是兩者之間有標識符衝突,所以其中一個需要合格。 –

+0

剛剛嘗試過。它不進行類型檢查:不能與'ValueList(Key Notification)'匹配'Value(Key Notification)'。預期類型:'SqlExpr(ValueList(Key Notification))',實際類型'(Value(Key Notification))'。突出顯示「sub_select」。 – Mark

1

是Esqueleto如果你想要加入。如果您的數據庫和您的數據建模支持該數據,則持續良好地與嵌入數據。