[TREE]: Add TreeError, HasTreeError and use it throw ServantErr in treeAPI

parent 9c7543e5
...@@ -10,7 +10,7 @@ Portability : POSIX ...@@ -10,7 +10,7 @@ Portability : POSIX
Node API Node API
-} -}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-orphans #-}
{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
...@@ -23,6 +23,7 @@ module Gargantext.API.Node ...@@ -23,6 +23,7 @@ module Gargantext.API.Node
where where
------------------------------------------------------------------- -------------------------------------------------------------------
import Control.Lens (prism')
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
import Control.Monad ((>>)) import Control.Monad ((>>))
--import System.IO (putStrLn, readFile) --import System.IO (putStrLn, readFile)
...@@ -44,7 +45,7 @@ import Gargantext.Database.Node ( getNodesWithParentId ...@@ -44,7 +45,7 @@ import Gargantext.Database.Node ( getNodesWithParentId
, deleteNode, deleteNodes) , deleteNode, deleteNodes)
import Gargantext.Database.Facet (FacetDoc, getDocFacet import Gargantext.Database.Facet (FacetDoc, getDocFacet
,FacetChart) ,FacetChart)
import Gargantext.Database.Tree (treeDB) import Gargantext.Database.Tree (treeDB, HasTreeError(..), TreeError(..))
-- Graph -- Graph
import Gargantext.TextFlow import Gargantext.TextFlow
...@@ -115,10 +116,17 @@ type GraphAPI = Get '[JSON] Graph ...@@ -115,10 +116,17 @@ type GraphAPI = Get '[JSON] Graph
graphAPI :: Connection -> NodeId -> Server GraphAPI graphAPI :: Connection -> NodeId -> Server GraphAPI
graphAPI _ _ = liftIO $ textFlow (Mono EN) (Contexts contextText) graphAPI _ _ = liftIO $ textFlow (Mono EN) (Contexts contextText)
-- TODO(orphan): There should be a proper APIError data type with a case TreeError.
instance HasTreeError ServantErr where
_TreeError = prism' mk (const Nothing) -- Note a prism
where
mk NoRoot = err404 { errBody = "Root node not found" }
mk EmptyRoot = err500 { errBody = "Root node should not be empty" }
mk TooManyRoots = err500 { errBody = "Too many root nodes" }
type TreeAPI = Get '[JSON] (Tree NodeTree) type TreeAPI = Get '[JSON] (Tree NodeTree)
treeAPI :: Connection -> NodeId -> Server TreeAPI treeAPI :: Connection -> NodeId -> Server TreeAPI
treeAPI c n = liftIO $ treeDB c n treeAPI = treeDB
nodeAPI :: Connection -> NodeId -> Server NodeAPI nodeAPI :: Connection -> NodeId -> Server NodeAPI
nodeAPI conn id = liftIO (putStrLn ("/node" :: Text) >> getNode conn id ) nodeAPI conn id = liftIO (putStrLn ("/node" :: Text) >> getNode conn id )
......
...@@ -15,10 +15,13 @@ Let a Root Node, return the Tree of the Node as a directed acyclic graph ...@@ -15,10 +15,13 @@ Let a Root Node, return the Tree of the Node as a directed acyclic graph
{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE QuasiQuotes #-}
module Gargantext.Database.Tree (treeDB) where module Gargantext.Database.Tree (treeDB, TreeError(..), HasTreeError(..)) where
import Control.Lens (Prism', (#), (^..), at, each, _Just, to)
import Control.Monad.Error.Class (MonadError(throwError))
import Control.Monad.IO.Class (MonadIO(liftIO))
import Data.Map (Map, fromListWith, lookup) import Data.Map (Map, fromListWith, lookup)
import Data.Text (Text, pack) import Data.Text (Text)
import Database.PostgreSQL.Simple import Database.PostgreSQL.Simple
import Database.PostgreSQL.Simple.SqlQQ import Database.PostgreSQL.Simple.SqlQQ
...@@ -31,26 +34,38 @@ import Gargantext.Database.Config (typeId2node) ...@@ -31,26 +34,38 @@ import Gargantext.Database.Config (typeId2node)
-- treeTest :: IO (Tree NodeTree) -- treeTest :: IO (Tree NodeTree)
-- treeTest = connectGargandb "gargantext.ini" >>= \c -> treeDB c 347474 -- treeTest = connectGargandb "gargantext.ini" >>= \c -> treeDB c 347474
------------------------------------------------------------------------ ------------------------------------------------------------------------
data TreeError = NoRoot | EmptyRoot | TooManyRoots
deriving (Show)
class HasTreeError e where
_TreeError :: Prism' e TreeError
treeError :: (MonadError e m, HasTreeError e) => TreeError -> m a
treeError te = throwError $ _TreeError # te
-- | Returns the Tree of Nodes in Database -- | Returns the Tree of Nodes in Database
treeDB :: Connection -> RootId -> IO (Tree NodeTree) treeDB :: (MonadIO m, MonadError e m, HasTreeError e)
treeDB c r = toTree <$> toTreeParent <$> dbTree c r => Connection -> RootId -> m (Tree NodeTree)
treeDB c r = toTree =<< (toTreeParent <$> liftIO (dbTree c r))
type RootId = Int type RootId = Int
type ParentId = Int type ParentId = Int
------------------------------------------------------------------------ ------------------------------------------------------------------------
toTree :: Map (Maybe ParentId) [DbTreeNode] -> Tree NodeTree toTree :: (MonadError e m, HasTreeError e)
toTree m = toTree' m n => Map (Maybe ParentId) [DbTreeNode] -> m (Tree NodeTree)
where toTree m =
n = case lookup Nothing m of case lookup Nothing m of
Nothing -> panic $ pack "no root" Just [n] -> pure $ toTree' m n
Just [] -> panic $ pack "empty root" Nothing -> treeError NoRoot
Just [n'] -> n' Just [] -> treeError EmptyRoot
Just _ -> panic $ pack "too many roots" Just _ -> treeError TooManyRoots
toTree' :: Map (Maybe ParentId) [DbTreeNode] -> DbTreeNode -> Tree NodeTree toTree' :: Map (Maybe ParentId) [DbTreeNode] -> DbTreeNode -> Tree NodeTree
toTree' m n = case lookup (Just $ dt_nodeId n) m of toTree' m n =
Nothing -> TreeN (toNodeTree n) [] TreeN (toNodeTree n) $
Just ns -> TreeN (toNodeTree n) (map (toTree' m) ns) m ^.. at (Just $ dt_nodeId n) . _Just . each . to (toTree' m)
------------------------------------------------------------------------ ------------------------------------------------------------------------
toNodeTree :: DbTreeNode -> NodeTree toNodeTree :: DbTreeNode -> NodeTree
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment