Haskell 正确的方法做一个;加入;坚持

Haskell 正确的方法做一个;加入;坚持,haskell,persistent,yesod,Haskell,Persistent,Yesod,以模型为例: Player name Text nick Text email Text Maybe phone Text Maybe note Textarea Maybe minutes Int Maybe deriving Table name Text game Text pointsHour Int seats Int Maybe description Text Maybe de

以模型为例:

Player
    name Text
    nick Text
    email Text Maybe
    phone Text Maybe
    note Textarea Maybe
    minutes Int Maybe
    deriving

Table
    name Text
    game Text
    pointsHour Int
    seats Int Maybe
    description Text Maybe
    deriving

GamingSession
    start UTCTime
    end UTCTime Maybe
    player PlayerId
    table TableId
    seat Int Maybe
    deriving
以及功能

getGamingSessionsR :: Handler RepHtml
getGamingSessionsR = do
  sessions <- runDB $ selectList [GamingSessionEnd ==. Nothing] [Desc GamingSessionTable]
  defaultLayout $(widgetFile ("opensessions"))
getGamingSessionsR::Handler RepHtml
getGamingSessionsR=do

sessions目前在persistent中对join的支持有限,我相信它只支持SQL

我有两个助手,用于处理简单的案例。可以找到它们。它不是一个真正的连接,它在每个表中选择一次,然后构建一个元组列表,表示“连接”的行,每个行中都有一个元素

根据您的模型和该助手,您应该能够执行以下操作:

records <- runDB $ do
    sessions <- selectList [] []
    players  <- selectList [] []
    tables   <- selectList [] []

    return $ joinTables3 gamingSessionPlayer gamingSessionTable sessions players tables

forM records $ \(session, player, table) -> do
    --
    -- ...
    --
select $ from $ \(gamingSession `InnerJoin` player) -> do 
    on (gamingSession ^. GamingSessionPlayer ==. player ^. PlayerId)
    where_ $ isNothing $ gamingSession ^. GamingSessionEnd
    orderBy [asc (gamingSession ^. GamingSessionTable)] 
    return (gamingSession, player ^. PlayerId)

记录供将来参考,对于sql,您可以使用esqueleto或rawSQL进行连接-请参阅此答案

如果您想使用联接,在esqueleto中,您的查询将如下所示:

records <- runDB $ do
    sessions <- selectList [] []
    players  <- selectList [] []
    tables   <- selectList [] []

    return $ joinTables3 gamingSessionPlayer gamingSessionTable sessions players tables

forM records $ \(session, player, table) -> do
    --
    -- ...
    --
select $ from $ \(gamingSession `InnerJoin` player) -> do 
    on (gamingSession ^. GamingSessionPlayer ==. player ^. PlayerId)
    where_ $ isNothing $ gamingSession ^. GamingSessionEnd
    orderBy [asc (gamingSession ^. GamingSessionTable)] 
    return (gamingSession, player ^. PlayerId)

这将返回一个(Entity GamingSession,PlayerId)元组

我们支持一对多连接,并且它是根据SQL连接和应用程序连接实现的,因此它可以用于SQL或NoSQL后端。目前文档记录得很差,但希望能很快得到解决。我不认为在Haskell中加入RDBMS首先应该做的事情是可以接受的答案。特别是对于Haskell居住的世界/社区。