keFlagMapDB
    :: (Foldable c)
    => c CommentId -> DB (Map CommentId (CommentFlagging, [FlagReason]))
makeFlagMapDB comment_ids = fmap (go . map (\(Entity _ x, Value y) -> (x, y))) $
    select $
    from $ \(cf `InnerJoin` cfr) -> do
    on_ (cf ^. CommentFlaggingId ==. cfr ^. CommentFlaggingReasonFlagging)
    where_ (cf ^. CommentFlaggingComment `in_` valList comment_ids)
    return (cf, cfr ^. CommentFlaggingReasonReason)
  where
    go :: [(CommentFlagging, FlagReason)]
       -> Map CommentId (CommentFlagging, [FlagReason])
    go = foldr
        (\(cf@(CommentFlagging _ _ comment_id _), reason) ->
            M.insertWith combine comment_id (cf, [reason]))
        mempty
      where
        combine :: (CommentFlagging, [FlagReason])
                -> (CommentFlagging, [FlagReason])
                -> (CommentFlagging, [FlagReason])
        combine (cf, reasons1) (_, reasons2) = (cf, reasons1 <> reasons2)

-- | Given a collection of CommentId, make a map from comment ids to sets
-- of watches. Comments that are not watched will simply not be in the map.
--
-- TODO: Return enough info to link to the root of the watch
m
makeFlagMapDB
    :: (Foldable c)
    => c CommentId -> DB (Map CommentId (CommentFlagging, [FlagReason]))
makeFlagMapDB comment_ids = fmap (go . map (\(Entity _ x, Value y) -> (x, y))) $
    select $
    from $ \(cf `InnerJoin` cfr) -> do
    on_ (cf ^. CommentFlaggingId ==. cfr ^. CommentFlaggingReasonFlagging)
    where_ (cf ^. CommentFlaggingComment `in_` valList comment_ids)
    return (cf, cfr ^. CommentFlaggingReasonReason)
  where
    go :: [(CommentFlagging, FlagReason)]
       -> Map CommentId (CommentFlagging, [FlagReason])
    go = foldr
        (\(cf@(CommentFlagging _ _ comment_id _), reason) ->
            M.insertWith combine comment_id (cf, [reason]))
        mempty
      where
        combine :: (CommentFlagging, [FlagReason])
                -> (CommentFlagging, [FlagReason])
                -> (CommentFlagging, [FlagReason])
        combine (cf, reasons1) (_, reasons2) = (cf, reasons1 <> reasons2)

-- | Given a collection of CommentId, make a map from comment ids to sets
-- of watches. Comments that are not watched will simply not be in the map.
--
-- TODO: Return enough info to link to the root of the watch
makeFlagMapDB comment_ids = fmap (go . map (\(Entity _ x, Value y) -> (x, y))) $
    select $
    from $ \(cf `InnerJoin` cfr) -> do
    on_ (cf ^. CommentFlaggingId ==. cfr ^. CommentFlaggingReasonFlagging)
    where_ (cf ^. CommentFlaggingComment `in_` valList comment_ids)
    return (cf, cfr ^. CommentFlaggingReasonReason)
  where
    go :: [(CommentFlagging, FlagReason)]
       -> Map CommentId (CommentFlagging, [FlagReason])
    go = foldr
        (\(cf@(CommentFlagging _ _ comment_id _), reason) ->
            M.insertWith combine comment_id (cf, [reason]))
        mempty
      where
        combine :: (CommentFlagging, [FlagReason])
                -> (CommentFlagging, [FlagReason])
                -> (CommentFlagging, [FlagReason])
        combine (cf, reasons1) (_, reasons2) = (cf, reasons1 <> reasons2)

-- | Given a collection of CommentId, make a map from comment ids to sets
-- of watches. Comments that are not watched will simply not be in the map.
--
-- TODO: Return enough info to link to the root of the watch