在 IHP 中处理复杂的查询结果而无需手动指定列?
Dealing with complex query results in IHP without having to manually specify columns?
https://ihp.digitallyinduced.com/Guide/database.html 的“处理复杂查询结果”部分展示了如何在查询数据库类型时通过创建如下类型来“包含额外数据”:
data PostWithCommentsCount = PostWithCommentsCount
{ id :: Id Post
, title :: Text
, commentsCount :: Int
}
deriving (Eq, Show)
这很好用,但缺点是您需要手动指定 posts
的所有列以包含在新的 PostWithCommentsCount
类型中:
instance FromRow PostWithCommentsCount where
fromRow =
PostWithCommentsCount
<$> field
<*> field
<*> field
fetchPostsWithCommentsCount :: (?modelContext :: ModelContext) => IO [PostWithCommentsCount]
fetchPostsWithCommentsCount = do
trackTableRead "posts" -- This is needed when using auto refresh, so auto refresh knows that your action is accessing the posts table
sqlQuery "SELECT posts.id, posts.title, (SELECT COUNT(*) FROM comments WHERE comments.post_id = posts.id) AS comments_count FROM posts" ()
随着时间的推移维护起来很繁琐,如果 posts
table 中的更改意味着您还必须更改此手动查询。我认为如果类型看起来像这样会更好:
data PostWithCommentsCount = PostWithCommentsCount
{ post :: Post
, commentsCount :: Int
}
deriving (Eq, Show)
这样我就不必手动指定我感兴趣的 posts
的所有列 - 我会得到整个 Post
。目前有办法实现吗?
是的,如果您使用以下 FromRow
实例,这是可能的:
instance FromRow PostWithCommentsCount where
fromRow = do
post <- fromRow
commentsCount <- field
pure PostWithCommentsCount { post, commentsCount }
你也可以用上面的运算符写成这样:
instance FromRow PostWithCommentsCount where
fromRow = PostWithCommentsCount
<$> fromRow
<*> field
https://ihp.digitallyinduced.com/Guide/database.html 的“处理复杂查询结果”部分展示了如何在查询数据库类型时通过创建如下类型来“包含额外数据”:
data PostWithCommentsCount = PostWithCommentsCount
{ id :: Id Post
, title :: Text
, commentsCount :: Int
}
deriving (Eq, Show)
这很好用,但缺点是您需要手动指定 posts
的所有列以包含在新的 PostWithCommentsCount
类型中:
instance FromRow PostWithCommentsCount where
fromRow =
PostWithCommentsCount
<$> field
<*> field
<*> field
fetchPostsWithCommentsCount :: (?modelContext :: ModelContext) => IO [PostWithCommentsCount]
fetchPostsWithCommentsCount = do
trackTableRead "posts" -- This is needed when using auto refresh, so auto refresh knows that your action is accessing the posts table
sqlQuery "SELECT posts.id, posts.title, (SELECT COUNT(*) FROM comments WHERE comments.post_id = posts.id) AS comments_count FROM posts" ()
随着时间的推移维护起来很繁琐,如果 posts
table 中的更改意味着您还必须更改此手动查询。我认为如果类型看起来像这样会更好:
data PostWithCommentsCount = PostWithCommentsCount
{ post :: Post
, commentsCount :: Int
}
deriving (Eq, Show)
这样我就不必手动指定我感兴趣的 posts
的所有列 - 我会得到整个 Post
。目前有办法实现吗?
是的,如果您使用以下 FromRow
实例,这是可能的:
instance FromRow PostWithCommentsCount where
fromRow = do
post <- fromRow
commentsCount <- field
pure PostWithCommentsCount { post, commentsCount }
你也可以用上面的运算符写成这样:
instance FromRow PostWithCommentsCount where
fromRow = PostWithCommentsCount
<$> fromRow
<*> field