{- This file is part of Vervis. - - Written in 2016, 2019 by fr33domlover . - - ♡ Copying is an act of love. Please copy, reuse and share. - - The author(s) have dedicated all copyright and related and neighboring - rights to this software to the public domain worldwide. This software is - distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along - with this software. If not, see - . -} module Vervis.Role ( getProjectRoleGraph ) where import Prelude import Control.Arrow (second, (&&&), (***)) import Data.Graph.Inductive.Graph (mkGraph) import Data.Graph.Inductive.PatriciaTree (Gr) import Data.Tuple (swap) import Database.Esqueleto import Yesod.Persist.Core (runDB) import qualified Data.HashMap.Lazy as M (fromList, lookup) import qualified Database.Persist as P import Vervis.Foundation import Vervis.Model import Vervis.Model.Ident getProjectRoleGraph :: SharerId -> AppDB (Gr RlIdent ()) getProjectRoleGraph sid = do (roles, inhs) <- do prs <- P.selectList [ProjectRoleSharer P.==. sid] [] prhs <- select $ from $ \ (pr `InnerJoin` prh) -> do on $ pr ^. ProjectRoleId ==. prh ^. ProjectRoleInheritParent where_ $ pr ^. ProjectRoleSharer ==. val sid return prh return (prs, prhs) let numbered = zip [1..] roles nodes = map (second $ projectRoleIdent . entityVal) numbered nodeMap = M.fromList $ map (swap . second entityKey) numbered pridToNode prid = case M.lookup prid nodeMap of Nothing -> error "Role graph: Node not found in node map" Just n -> n edges = map ( (\ (c, p) -> (c, p, ())) . (pridToNode *** pridToNode) . (projectRoleInheritChild &&& projectRoleInheritParent) . entityVal ) inhs return $ mkGraph nodes edges