2 Module : Gargantext.Database.Schema.Node
3 Description : Main requests of Node to the database
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
11 {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
12 {-# OPTIONS_GHC -fno-warn-orphans #-}
14 {-# LANGUAGE Arrows #-}
15 {-# LANGUAGE DeriveGeneric #-}
16 {-# LANGUAGE ConstraintKinds #-}
17 {-# LANGUAGE FlexibleContexts #-}
18 {-# LANGUAGE FlexibleInstances #-}
19 {-# LANGUAGE FunctionalDependencies #-}
20 {-# LANGUAGE OverloadedStrings #-}
21 {-# LANGUAGE MultiParamTypeClasses #-}
22 {-# LANGUAGE NoImplicitPrelude #-}
23 {-# LANGUAGE RankNTypes #-}
24 {-# LANGUAGE TemplateHaskell #-}
25 {-# LANGUAGE TypeFamilies #-}
27 module Gargantext.Database.Schema.Node where
29 import Control.Arrow (returnA)
30 import Control.Lens (set, view)
31 import Control.Lens.TH (makeLensesWith, abbreviatedFields)
33 import Data.Maybe (Maybe(..), fromMaybe)
34 import Data.Profunctor.Product.TH (makeAdaptorAndInstance)
35 import Data.Text (Text)
36 import Database.PostgreSQL.Simple.FromField (FromField, fromField)
37 import GHC.Int (Int64)
38 import Gargantext.Core.Types
39 import Gargantext.Core.Types.Individu (User(..))
40 import Gargantext.Database.Config (nodeTypeId)
41 import Gargantext.Database.Node.Contact (HyperdataContact(..), arbitraryHyperdataContact)
42 import Gargantext.Database.Node.User (HyperdataUser(..), fake_HyperdataUser)
43 import Gargantext.Database.Queries.Filter (limit', offset')
44 import Gargantext.Database.Schema.User (getUserId)
45 import Gargantext.Database.Types.Errors
46 import Gargantext.Database.Types.Node (NodeType(..), defaultCorpus, Hyperdata, HyperData(..))
47 import Gargantext.Database.Utils
48 import Gargantext.Prelude hiding (sum, head)
49 import Gargantext.Viz.Graph (HyperdataGraph(..))
50 import Opaleye hiding (FromField)
51 import Opaleye.Internal.QueryArr (Query)
52 import Prelude hiding (null, id, map, sum)
54 ------------------------------------------------------------------------
55 instance FromField HyperdataAny where
56 fromField = fromField'
58 instance FromField HyperdataCorpus
60 fromField = fromField'
62 instance FromField HyperdataDocument
64 fromField = fromField'
66 instance FromField HyperdataDocumentV3
68 fromField = fromField'
70 instance FromField HyperData
72 fromField = fromField'
74 instance FromField HyperdataListModel
76 fromField = fromField'
78 instance FromField HyperdataGraph
80 fromField = fromField'
82 instance FromField HyperdataPhylo
84 fromField = fromField'
86 instance FromField HyperdataAnnuaire
88 fromField = fromField'
90 instance FromField HyperdataList
92 fromField = fromField'
94 instance FromField (NodeId, Text)
96 fromField = fromField'
97 ------------------------------------------------------------------------
98 instance QueryRunnerColumnDefault PGJsonb HyperdataAny
100 queryRunnerColumnDefault = fieldQueryRunnerColumn
102 instance QueryRunnerColumnDefault PGJsonb HyperdataList
104 queryRunnerColumnDefault = fieldQueryRunnerColumn
106 instance QueryRunnerColumnDefault PGJsonb HyperData
108 queryRunnerColumnDefault = fieldQueryRunnerColumn
111 instance QueryRunnerColumnDefault PGJsonb HyperdataDocument
113 queryRunnerColumnDefault = fieldQueryRunnerColumn
115 instance QueryRunnerColumnDefault PGJsonb HyperdataDocumentV3
117 queryRunnerColumnDefault = fieldQueryRunnerColumn
119 instance QueryRunnerColumnDefault PGJsonb HyperdataCorpus
121 queryRunnerColumnDefault = fieldQueryRunnerColumn
123 instance QueryRunnerColumnDefault PGJsonb HyperdataListModel
125 queryRunnerColumnDefault = fieldQueryRunnerColumn
127 instance QueryRunnerColumnDefault PGJsonb HyperdataGraph
129 queryRunnerColumnDefault = fieldQueryRunnerColumn
131 instance QueryRunnerColumnDefault PGJsonb HyperdataPhylo
133 queryRunnerColumnDefault = fieldQueryRunnerColumn
135 instance QueryRunnerColumnDefault PGJsonb HyperdataAnnuaire
137 queryRunnerColumnDefault = fieldQueryRunnerColumn
139 instance QueryRunnerColumnDefault PGTSVector (Maybe TSVector)
141 queryRunnerColumnDefault = fieldQueryRunnerColumn
143 instance QueryRunnerColumnDefault PGInt4 (Maybe NodeId)
145 queryRunnerColumnDefault = fieldQueryRunnerColumn
147 instance QueryRunnerColumnDefault PGInt4 NodeId
149 queryRunnerColumnDefault = fieldQueryRunnerColumn
151 instance QueryRunnerColumnDefault (Nullable PGInt4) NodeId
153 queryRunnerColumnDefault = fieldQueryRunnerColumn
156 ------------------------------------------------------------------------
157 $(makeAdaptorAndInstance "pNode" ''NodePoly)
158 $(makeLensesWith abbreviatedFields ''NodePoly)
160 $(makeAdaptorAndInstance "pNodeSearch" ''NodePolySearch)
161 $(makeLensesWith abbreviatedFields ''NodePolySearch)
163 type NodeWrite = NodePoly (Maybe (Column PGInt4) )
166 (Maybe (Column PGInt4) )
168 (Maybe (Column PGTimestamptz))
171 type NodeRead = NodePoly (Column PGInt4 )
176 (Column PGTimestamptz )
179 type NodeReadNull = NodePoly (Column (Nullable PGInt4))
180 (Column (Nullable PGInt4))
181 (Column (Nullable PGInt4))
182 (Column (Nullable PGInt4))
183 (Column (Nullable PGText))
184 (Column (Nullable PGTimestamptz))
185 (Column (Nullable PGJsonb))
187 nodeTable :: Table NodeWrite NodeRead
188 nodeTable = Table "nodes" (pNode Node { _node_id = optional "id"
189 , _node_typename = required "typename"
190 , _node_userId = required "user_id"
192 , _node_parentId = optional "parent_id"
193 , _node_name = required "name"
194 , _node_date = optional "date"
196 , _node_hyperdata = required "hyperdata"
200 queryNodeTable :: Query NodeRead
201 queryNodeTable = queryTable nodeTable
203 ------------------------------------------------------------------------
204 -- | Node(Read|Write)Search is slower than Node(Write|Read) use it
205 -- for full text search only
206 type NodeSearchWrite =
208 (Maybe (Column PGInt4) )
211 (Column (Nullable PGInt4) )
213 (Maybe (Column PGTimestamptz))
215 (Maybe (Column PGTSVector) )
217 type NodeSearchRead =
222 (Column (Nullable PGInt4 ))
224 (Column PGTimestamptz )
228 type NodeSearchReadNull =
230 (Column (Nullable PGInt4) )
231 (Column (Nullable PGInt4) )
232 (Column (Nullable PGInt4) )
233 (Column (Nullable PGInt4) )
234 (Column (Nullable PGText) )
235 (Column (Nullable PGTimestamptz))
236 (Column (Nullable PGJsonb) )
237 (Column (Nullable PGTSVector) )
239 nodeTableSearch :: Table NodeSearchWrite NodeSearchRead
240 nodeTableSearch = Table "nodes" (pNodeSearch NodeSearch { _ns_id = optional "id"
241 , _ns_typename = required "typename"
242 , _ns_userId = required "user_id"
244 , _ns_parentId = required "parent_id"
245 , _ns_name = required "name"
246 , _ns_date = optional "date"
248 , _ns_hyperdata = required "hyperdata"
249 , _ns_search = optional "search"
254 queryNodeSearchTable :: Query NodeSearchRead
255 queryNodeSearchTable = queryTable nodeTableSearch
257 selectNode :: Column PGInt4 -> Query NodeRead
258 selectNode id = proc () -> do
259 row <- queryNodeTable -< ()
260 restrict -< _node_id row .== id
265 runGetNodes :: Query NodeRead -> Cmd err [Node HyperdataAny]
266 runGetNodes = runOpaQuery
268 ------------------------------------------------------------------------
269 ------------------------------------------------------------------------
270 -- | order by publication date
271 -- Favorites (Bool), node_ngrams
272 selectNodesWith :: ParentId -> Maybe NodeType
273 -> Maybe Offset -> Maybe Limit -> Query NodeRead
274 selectNodesWith parentId maybeNodeType maybeOffset maybeLimit =
275 --offset' maybeOffset $ limit' maybeLimit $ orderBy (asc (hyperdataDocument_Publication_date . node_hyperdata)) $ selectNodesWith' parentId typeId
276 limit' maybeLimit $ offset' maybeOffset
277 $ orderBy (asc _node_id)
278 $ selectNodesWith' parentId maybeNodeType
280 selectNodesWith' :: ParentId -> Maybe NodeType -> Query NodeRead
281 selectNodesWith' parentId maybeNodeType = proc () -> do
282 node <- (proc () -> do
283 row@(Node _ typeId _ parentId' _ _ _) <- queryNodeTable -< ()
284 restrict -< parentId' .== (pgNodeId parentId)
286 let typeId' = maybe 0 nodeTypeId maybeNodeType
288 restrict -< if typeId' > 0
289 then typeId .== (pgInt4 (typeId' :: Int))
291 returnA -< row ) -< ()
294 deleteNode :: NodeId -> Cmd err Int
295 deleteNode n = mkCmd $ \conn ->
296 fromIntegral <$> runDelete conn nodeTable
297 (\(Node n_id _ _ _ _ _ _) -> n_id .== pgNodeId n)
299 deleteNodes :: [NodeId] -> Cmd err Int
300 deleteNodes ns = mkCmd $ \conn ->
301 fromIntegral <$> runDelete conn nodeTable
302 (\(Node n_id _ _ _ _ _ _) -> in_ ((map pgNodeId ns)) n_id)
304 -- TODO: NodeType should match with `a'
305 getNodesWith :: JSONB a => NodeId -> proxy a -> Maybe NodeType
306 -> Maybe Offset -> Maybe Limit -> Cmd err [Node a]
307 getNodesWith parentId _ nodeType maybeOffset maybeLimit =
308 runOpaQuery $ selectNodesWith parentId nodeType maybeOffset maybeLimit
310 -- TODO: Why is the second parameter ignored?
311 -- TODO: Why not use getNodesWith?
312 getNodesWithParentId :: (Hyperdata a, QueryRunnerColumnDefault PGJsonb a)
315 getNodesWithParentId n = runOpaQuery $ selectNodesWithParentID n'
321 ------------------------------------------------------------------------
322 getDocumentsV3WithParentId :: NodeId -> Cmd err [Node HyperdataDocumentV3]
323 getDocumentsV3WithParentId n = runOpaQuery $ selectNodesWith' n (Just NodeDocument)
325 -- TODO: merge with getDocumentsWithParentId by having a class IsHyperdataDocument
326 getDocumentsWithParentId :: NodeId -> Cmd err [Node HyperdataDocument]
327 getDocumentsWithParentId n = runOpaQuery $ selectNodesWith' n (Just NodeDocument)
329 getListsModelWithParentId :: NodeId -> Cmd err [Node HyperdataListModel]
330 getListsModelWithParentId n = runOpaQuery $ selectNodesWith' n (Just NodeListModel)
332 getCorporaWithParentId :: NodeId -> Cmd err [Node HyperdataCorpus]
333 getCorporaWithParentId n = runOpaQuery $ selectNodesWith' n (Just NodeCorpus)
335 ------------------------------------------------------------------------
336 selectNodesWithParentID :: NodeId -> Query NodeRead
337 selectNodesWithParentID n = proc () -> do
338 row@(Node _ _ _ parent_id _ _ _) <- queryNodeTable -< ()
339 restrict -< parent_id .== (pgNodeId n)
342 selectNodesWithType :: Column PGInt4 -> Query NodeRead
343 selectNodesWithType type_id = proc () -> do
344 row@(Node _ tn _ _ _ _ _) <- queryNodeTable -< ()
345 restrict -< tn .== type_id
348 type JSONB = QueryRunnerColumnDefault PGJsonb
351 getNode :: NodeId -> Cmd err (Node Value)
352 getNode nId = fromMaybe (error $ "Node does not exist: " <> show nId) . headMay
353 <$> runOpaQuery (limit 1 $ selectNode (pgNodeId nId))
355 getNodeWith :: JSONB a => NodeId -> proxy a -> Cmd err (Node a)
356 getNodeWith nId _ = do
357 fromMaybe (error $ "Node does not exist: " <> show nId) . headMay
358 <$> runOpaQuery (limit 1 $ selectNode (pgNodeId nId))
360 getNodeUser :: NodeId -> Cmd err (Node HyperdataUser)
362 fromMaybe (error $ "Node does not exist: " <> show nId) . headMay
363 <$> runOpaQuery (limit 1 $ selectNode (pgNodeId nId))
366 getNodePhylo :: NodeId -> Cmd err (Node HyperdataPhylo)
367 getNodePhylo nId = do
368 fromMaybe (error $ "Node Phylo does not exist: " <> show nId) . headMay
369 <$> runOpaQuery (limit 1 $ selectNode (pgNodeId nId))
372 getNodesWithType :: Column PGInt4 -> Cmd err [Node HyperdataDocument]
373 getNodesWithType = runOpaQuery . selectNodesWithType
375 ------------------------------------------------------------------------
376 nodeUserW :: Maybe Name -> Maybe HyperdataUser -> UserId -> NodeWrite
377 nodeUserW maybeName maybeHyperdata = node NodeUser name user Nothing
379 name = maybe "User" identity maybeName
380 user = maybe fake_HyperdataUser identity maybeHyperdata
382 nodeContactW :: Maybe Name -> Maybe HyperdataContact
383 -> AnnuaireId -> UserId -> NodeWrite
384 nodeContactW maybeName maybeContact aId =
385 node NodeContact name contact (Just aId)
387 name = maybe "Contact" identity maybeName
388 contact = maybe arbitraryHyperdataContact identity maybeContact
389 ------------------------------------------------------------------------
390 defaultFolder :: HyperdataCorpus
391 defaultFolder = defaultCorpus
393 nodeFolderW :: Maybe Name -> Maybe HyperdataCorpus -> ParentId -> UserId -> NodeWrite
394 nodeFolderW maybeName maybeFolder pid = node NodeFolder name folder (Just pid)
396 name = maybe "Folder" identity maybeName
397 folder = maybe defaultFolder identity maybeFolder
398 ------------------------------------------------------------------------
399 nodeCorpusW :: Maybe Name -> Maybe HyperdataCorpus -> ParentId -> UserId -> NodeWrite
400 nodeCorpusW maybeName maybeCorpus pId = node NodeCorpus name corpus (Just pId)
402 name = maybe "Corpus" identity maybeName
403 corpus = maybe defaultCorpus identity maybeCorpus
404 --------------------------
405 defaultDocument :: HyperdataDocument
406 defaultDocument = hyperdataDocument
408 nodeDocumentW :: Maybe Name -> Maybe HyperdataDocument -> CorpusId -> UserId -> NodeWrite
409 nodeDocumentW maybeName maybeDocument cId = node NodeDocument name doc (Just cId)
411 name = maybe "Document" identity maybeName
412 doc = maybe defaultDocument identity maybeDocument
413 ------------------------------------------------------------------------
414 defaultAnnuaire :: HyperdataAnnuaire
415 defaultAnnuaire = HyperdataAnnuaire (Just "Title") (Just "Description")
417 nodeAnnuaireW :: Maybe Name -> Maybe HyperdataAnnuaire -> ParentId -> UserId -> NodeWrite
418 nodeAnnuaireW maybeName maybeAnnuaire pId = node NodeAnnuaire name annuaire (Just pId)
420 name = maybe "Annuaire" identity maybeName
421 annuaire = maybe defaultAnnuaire identity maybeAnnuaire
423 ------------------------------------------------------------------------
426 class IsNodeDb a where
430 instance IsNodeDb NodeType where
433 instance HasHyperdata NodeType where
434 data Hyper NodeType = HyperList HyperdataList
435 | HyperCorpus HyperdataCorpus
437 hasHyperdata nt = case nt of
438 NodeList -> HyperList $ HyperdataList (Just "list")
440 unHyper h = case h of
446 class HasDefault a where
447 hasDefaultData :: a -> HyperData
448 hasDefaultName :: a -> Text
450 instance HasDefault NodeType where
451 hasDefaultData nt = case nt of
452 NodeTexts -> HyperdataTexts (Just "Preferences")
453 NodeList -> HyperdataList' (Just "Preferences")
454 NodeListCooc -> HyperdataList' (Just "Preferences")
456 --NodeAnnuaire -> HyperdataAnnuaire (Just "Title") (Just "Description")
458 hasDefaultName nt = case nt of
461 NodeListCooc -> "Cooc"
464 ------------------------------------------------------------------------
466 nodeDefault :: NodeType -> ParentId -> UserId -> NodeWrite
467 nodeDefault nt parent = node nt name hyper (Just parent)
469 name = (hasDefaultName nt)
470 hyper = (hasDefaultData nt)
472 ------------------------------------------------------------------------
473 arbitraryListModel :: HyperdataListModel
474 arbitraryListModel = HyperdataListModel (400,500) "data/models/test.model" (Just 0.83)
476 mkListModelNode :: HasNodeError err => ParentId -> UserId -> Cmd err [NodeId]
477 mkListModelNode p u = insertNodesR [nodeListModelW Nothing Nothing p u]
479 nodeListModelW :: Maybe Name -> Maybe HyperdataListModel -> ParentId -> UserId -> NodeWrite
480 nodeListModelW maybeName maybeListModel pId = node NodeListModel name list (Just pId)
482 name = maybe "List Model" identity maybeName
483 list = maybe arbitraryListModel identity maybeListModel
485 ------------------------------------------------------------------------
486 arbitraryGraph :: HyperdataGraph
487 arbitraryGraph = HyperdataGraph Nothing
489 nodeGraphW :: Maybe Name -> Maybe HyperdataGraph -> ParentId -> UserId -> NodeWrite
490 nodeGraphW maybeName maybeGraph pId = node NodeGraph name graph (Just pId)
492 name = maybe "Graph" identity maybeName
493 graph = maybe arbitraryGraph identity maybeGraph
495 mkGraph :: ParentId -> UserId -> Cmd err [GraphId]
496 mkGraph p u = insertNodesR [nodeGraphW Nothing Nothing p u]
498 insertGraph :: ParentId -> UserId -> HyperdataGraph -> Cmd err [GraphId]
499 insertGraph p u h = insertNodesR [nodeGraphW Nothing (Just h) p u]
501 ------------------------------------------------------------------------
502 arbitraryPhylo :: HyperdataPhylo
503 arbitraryPhylo = HyperdataPhylo Nothing Nothing
505 nodePhyloW :: Maybe Name -> Maybe HyperdataPhylo -> ParentId -> UserId -> NodeWrite
506 nodePhyloW maybeName maybePhylo pId = node NodePhylo name graph (Just pId)
508 name = maybe "Phylo" identity maybeName
509 graph = maybe arbitraryPhylo identity maybePhylo
512 ------------------------------------------------------------------------
513 arbitraryDashboard :: HyperdataDashboard
514 arbitraryDashboard = HyperdataDashboard (Just "Preferences") []
515 ------------------------------------------------------------------------
517 node :: (ToJSON a, Hyperdata a) => NodeType -> Name -> a -> Maybe ParentId -> UserId -> NodeWrite
518 node nodeType name hyperData parentId userId =
522 (pgNodeId <$> parentId)
525 (pgJSONB $ cs $ encode hyperData)
527 typeId = nodeTypeId nodeType
529 -------------------------------
530 insertNodes :: [NodeWrite] -> Cmd err Int64
531 insertNodes ns = mkCmd $ \conn -> runInsert_ conn $ Insert nodeTable ns rCount Nothing
533 insertNodesR :: [NodeWrite] -> Cmd err [NodeId]
534 insertNodesR ns = mkCmd $ \conn ->
535 runInsert_ conn (Insert nodeTable ns (rReturning (\(Node i _ _ _ _ _ _) -> i)) Nothing)
537 insertNodesWithParent :: Maybe ParentId -> [NodeWrite] -> Cmd err Int64
538 insertNodesWithParent pid ns = insertNodes (set node_parentId (pgNodeId <$> pid) <$> ns)
540 insertNodesWithParentR :: Maybe ParentId -> [NodeWrite] -> Cmd err [NodeId]
541 insertNodesWithParentR pid ns = insertNodesR (set node_parentId (pgNodeId <$> pid) <$> ns)
542 ------------------------------------------------------------------------
543 -- TODO Hierachy of Nodes
544 -- post and get same types Node' and update if changes
546 {- TODO semantic to achieve
547 post c uid pid [ Node' NodeCorpus "name" "{}" []
548 , Node' NodeFolder "name" "{}" [Node' NodeCorpus "test 2" "" [ Node' NodeDocument "title" "metaData" []
549 , Node' NodeDocument "title" "jsonData" []
554 ------------------------------------------------------------------------
557 -- currently this function removes the child relation
558 -- needs a Temporary type between Node' and NodeWriteT
559 node2table :: UserId -> Maybe ParentId -> Node' -> NodeWrite
560 node2table uid pid (Node' nt txt v []) = Node Nothing (pgInt4 $ nodeTypeId nt) (pgInt4 uid) (fmap pgNodeId pid) (pgStrictText txt) Nothing (pgStrictJSONB $ cs $ encode v)
561 node2table _ _ (Node' _ _ _ _) = panic "node2table: should not happen, Tree insert not implemented yet"
564 data Node' = Node' { _n_type :: NodeType
567 , _n_children :: [Node']
570 mkNodes :: [NodeWrite] -> Cmd err Int64
571 mkNodes ns = mkCmd $ \conn -> runInsert_ conn $ Insert nodeTable ns rCount Nothing
573 mkNodeR :: [NodeWrite] -> Cmd err [NodeId]
574 mkNodeR ns = mkCmd $ \conn -> runInsert_ conn $ Insert nodeTable ns (rReturning _node_id) Nothing
576 ------------------------------------------------------------------------
578 data NewNode = NewNode { _newNodeId :: NodeId
579 , _newNodeChildren :: [NodeId] }
581 postNode :: HasNodeError err => UserId -> Maybe ParentId -> Node' -> Cmd err NewNode
583 postNode uid pid (Node' nt txt v []) = do
584 pids <- mkNodeR [node2table uid pid (Node' nt txt v [])]
586 [pid'] -> pure $ NewNode pid' []
587 _ -> nodeError ManyParents
589 postNode uid pid (Node' NodeCorpus txt v ns) = do
590 NewNode pid' _ <- postNode uid pid (Node' NodeCorpus txt v [])
591 pids <- mkNodeR (concat $ map (\n -> [childWith uid pid' n]) ns)
592 pure $ NewNode pid' pids
594 postNode uid pid (Node' NodeAnnuaire txt v ns) = do
595 NewNode pid' _ <- postNode uid pid (Node' NodeAnnuaire txt v [])
596 pids <- mkNodeR (concat $ map (\n -> [childWith uid pid' n]) ns)
597 pure $ NewNode pid' pids
599 postNode uid pid (Node' NodeDashboard txt v ns) = do
600 NewNode pid' _ <- postNode uid pid (Node' NodeDashboard txt v [])
601 pids <- mkNodeR (concat $ map (\n -> [childWith uid pid' n]) ns)
602 pure $ NewNode pid' pids
604 postNode _ _ (Node' _ _ _ _) = nodeError NotImplYet
607 childWith :: UserId -> ParentId -> Node' -> NodeWrite
608 childWith uId pId (Node' NodeDocument txt v []) = node2table uId (Just pId) (Node' NodeDocument txt v [])
609 childWith uId pId (Node' NodeContact txt v []) = node2table uId (Just pId) (Node' NodeContact txt v [])
610 childWith _ _ (Node' _ _ _ _) = panic "This NodeType can not be a child"
613 -- =================================================================== --
614 ------------------------------------------------------------------------
615 -- | TODO mk all others nodes
616 mkNodeWithParent :: HasNodeError err
622 mkNodeWithParent NodeUser (Just _) _ _ = nodeError UserNoParent
624 ------------------------------------------------------------------------
625 mkNodeWithParent NodeUser Nothing uId name =
626 insertNodesWithParentR Nothing [node NodeUser name fake_HyperdataUser Nothing uId]
628 mkNodeWithParent _ Nothing _ _ = nodeError HasParent
629 ------------------------------------------------------------------------
630 mkNodeWithParent NodeFolder (Just i) uId name =
631 insertNodesWithParentR (Just i) [node NodeFolder name hd Nothing uId]
635 mkNodeWithParent NodeFolderPrivate (Just i) uId _ =
636 insertNodesWithParentR (Just i) [node NodeFolderPrivate "Private" hd Nothing uId]
640 mkNodeWithParent NodeFolderShared (Just i) uId _ =
641 insertNodesWithParentR (Just i) [node NodeFolderShared "Shared" hd Nothing uId]
645 mkNodeWithParent NodeFolderPublic (Just i) uId _ =
646 insertNodesWithParentR (Just i) [node NodeFolderPublic "Public" hd Nothing uId]
650 mkNodeWithParent NodeTeam (Just i) uId _ =
651 insertNodesWithParentR (Just i) [node NodeTeam "Team" hd Nothing uId]
654 ------------------------------------------------------------------------
655 mkNodeWithParent NodeCorpus (Just i) uId name =
656 insertNodesWithParentR (Just i) [node NodeCorpus name hd Nothing uId]
660 mkNodeWithParent NodeAnnuaire (Just i) uId name =
661 insertNodesWithParentR (Just i) [node NodeAnnuaire name hd Nothing uId]
665 mkNodeWithParent _ _ _ _ = nodeError NotImplYet
666 ------------------------------------------------------------------------
667 -- =================================================================== --
669 mkRoot :: HasNodeError err
674 uid <- getUserId user
679 False -> nodeError NegativeId
681 rs <- mkNodeWithParent NodeUser Nothing uid una
684 _ <- mkNodeWithParent NodeFolderPrivate (Just r) uid una
685 _ <- mkNodeWithParent NodeFolderShared (Just r) uid una
686 _ <- mkNodeWithParent NodeFolderPublic (Just r) uid una
692 -- CorpusDocument is a corpus made from a set of documents
693 -- CorpusContact is a corpus made from a set of contacts (syn of Annuaire)
694 data CorpusType = CorpusDocument | CorpusContact
698 mk :: Maybe Name -> Maybe a -> ParentId -> UserId -> Cmd err [NodeId]
700 instance MkCorpus HyperdataCorpus
702 mk n h p u = insertNodesR [nodeCorpusW n h p u]
705 instance MkCorpus HyperdataAnnuaire
707 mk n h p u = insertNodesR [nodeAnnuaireW n h p u]
710 getOrMkList :: HasNodeError err => ParentId -> UserId -> Cmd err ListId
711 getOrMkList pId uId =
712 maybe (mkList' pId uId) (pure . view node_id) . headMay =<< getListsWithParentId pId
714 mkList' pId uId = maybe (nodeError MkNode) pure . headMay =<< mkNode NodeList pId uId
716 -- | TODO remove defaultList
717 defaultList :: HasNodeError err => CorpusId -> Cmd err ListId
719 maybe (nodeError NoListFound) (pure . view node_id) . headMay =<< getListsWithParentId cId
721 mkNode :: NodeType -> ParentId -> UserId -> Cmd err [NodeId]
722 mkNode nt p u = insertNodesR [nodeDefault nt p u]
724 mkDashboard :: ParentId -> UserId -> Cmd err [NodeId]
725 mkDashboard p u = insertNodesR [nodeDashboardW Nothing Nothing p u]
727 nodeDashboardW :: Maybe Name -> Maybe HyperdataDashboard -> ParentId -> UserId -> NodeWrite
728 nodeDashboardW maybeName maybeDashboard pId = node NodeDashboard name dashboard (Just pId)
730 name = maybe "Board" identity maybeName
731 dashboard = maybe arbitraryDashboard identity maybeDashboard
734 mkPhylo :: ParentId -> UserId -> Cmd err [NodeId]
735 mkPhylo p u = insertNodesR [nodePhyloW Nothing Nothing p u]
737 -- | Default CorpusId Master and ListId Master
739 pgNodeId :: NodeId -> Column PGInt4
740 pgNodeId = pgInt4 . id2int
742 getListsWithParentId :: NodeId -> Cmd err [Node HyperdataList]
743 getListsWithParentId n = runOpaQuery $ selectNodesWith' n (Just NodeList)
746 -- import Gargantext.Database.Node.UpdateOpaleye (updateHyperdata)
747 -- updateNodeUser_fake :: NodeId -> Cmd err Int64
748 -- updateNodeUser_fake n = updateHyperdata n fake_HyperdataUser