2 Module : Gargantext.Database.Query.Table.NodeNode
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
10 Here is a longer description of this module, containing some
11 commentary with @some markup@.
14 {-# OPTIONS_GHC -fno-warn-orphans #-}
16 {-# LANGUAGE Arrows #-}
17 {-# LANGUAGE FunctionalDependencies #-}
18 {-# LANGUAGE QuasiQuotes #-}
19 {-# LANGUAGE TemplateHaskell #-}
21 module Gargantext.Database.Query.Table.NodeNode
22 ( module Gargantext.Database.Schema.NodeNode
36 import Control.Arrow (returnA)
37 import Control.Lens (view, (^.))
38 import Data.Maybe (catMaybes)
39 import Data.Text (Text, splitOn)
40 import Database.PostgreSQL.Simple.SqlQQ (sql)
41 import Database.PostgreSQL.Simple.Types (Values(..), QualifiedIdentifier(..))
42 import qualified Database.PostgreSQL.Simple as PGS (Query, Only(..))
43 import qualified Opaleye as O
46 import Gargantext.Core.Types
47 import Gargantext.Database.Schema.NodeNode
48 import Gargantext.Database.Admin.Config (nodeTypeId)
49 import Gargantext.Database.Admin.Types.Hyperdata
50 import Gargantext.Database.Admin.Types.Node (CorpusId, DocId, pgNodeId)
51 import Gargantext.Database.Prelude
52 import Gargantext.Database.Schema.Node
53 import Gargantext.Prelude
56 queryNodeNodeTable :: Query NodeNodeRead
57 queryNodeNodeTable = queryTable nodeNodeTable
59 -- | not optimized (get all ngrams without filters)
60 _nodesNodes :: Cmd err [NodeNode]
61 _nodesNodes = runOpaQuery queryNodeNodeTable
63 ------------------------------------------------------------------------
64 -- | Basic NodeNode tools
65 getNodeNode :: NodeId -> Cmd err [NodeNode]
66 getNodeNode n = runOpaQuery (selectNodeNode $ pgNodeId n)
68 selectNodeNode :: Column PGInt4 -> Query NodeNodeRead
69 selectNodeNode n' = proc () -> do
70 ns <- queryNodeNodeTable -< ()
71 restrict -< _nn_node1_id ns .== n'
74 ------------------------------------------------------------------------
75 -- TODO (refactor with Children)
77 getNodeNodeWith :: NodeId -> proxy a -> Maybe NodeType -> Cmd err [a]
78 getNodeNodeWith pId _ maybeNodeType = runOpaQuery query
80 query = selectChildren pId maybeNodeType
82 selectChildren :: ParentId
85 selectChildren parentId maybeNodeType = proc () -> do
86 row@(Node nId typeName _ parent_id _ _ _) <- queryNodeTable -< ()
87 (NodeNode _ n1id n2id _ _) <- queryNodeNodeTable -< ()
89 let nodeType = maybe 0 nodeTypeId maybeNodeType
90 restrict -< typeName .== pgInt4 nodeType
92 restrict -< (.||) (parent_id .== (pgNodeId parentId))
93 ( (.&&) (n1id .== pgNodeId parentId)
98 ------------------------------------------------------------------------
99 insertNodeNode :: [NodeNode] -> Cmd err Int
100 insertNodeNode ns = mkCmd $ \conn -> fromIntegral <$> (runInsert_ conn
101 $ Insert nodeNodeTable ns' rCount (Just DoNothing))
103 ns' :: [NodeNodeWrite]
104 ns' = map (\(NodeNode n1 n2 x y)
105 -> NodeNode (pgNodeId n1)
113 ------------------------------------------------------------------------
114 type Node1_Id = NodeId
115 type Node2_Id = NodeId
117 deleteNodeNode :: Node1_Id -> Node2_Id -> Cmd err Int
118 deleteNodeNode n1 n2 = mkCmd $ \conn ->
119 fromIntegral <$> runDelete conn nodeNodeTable
120 (\(NodeNode n1_id n2_id _ _) -> n1_id .== pgNodeId n1
121 .&& n2_id .== pgNodeId n2 )
123 ------------------------------------------------------------------------
124 -- | Favorite management
125 _nodeNodeCategory :: CorpusId -> DocId -> Int -> Cmd err [Int]
126 _nodeNodeCategory cId dId c = map (\(PGS.Only a) -> a) <$> runPGSQuery favQuery (c,cId,dId)
128 favQuery :: PGS.Query
129 favQuery = [sql|UPDATE nodes_nodes SET category = ?
130 WHERE node1_id = ? AND node2_id = ?
134 nodeNodesCategory :: [(CorpusId,DocId,Int)] -> Cmd err [Int]
135 nodeNodesCategory inputData = map (\(PGS.Only a) -> a)
136 <$> runPGSQuery catQuery (PGS.Only $ Values fields inputData)
138 fields = map (\t-> QualifiedIdentifier Nothing t) ["int4","int4","int4"]
139 catQuery :: PGS.Query
140 catQuery = [sql| UPDATE nodes_nodes as nn0
141 SET category = nn1.category
142 FROM (?) as nn1(node1_id,node2_id,category)
143 WHERE nn0.node1_id = nn1.node1_id
144 AND nn0.node2_id = nn1.node2_id
145 RETURNING nn1.node2_id
148 ------------------------------------------------------------------------
149 selectCountDocs :: CorpusId -> Cmd err Int
150 selectCountDocs cId = runCountOpaQuery (queryCountDocs cId)
152 queryCountDocs cId' = proc () -> do
153 (n, nn) <- joinInCorpus -< ()
154 restrict -< nn^.nn_node1_id .== (toNullable $ pgNodeId cId')
155 restrict -< nn^.nn_category .>= (toNullable $ pgInt4 1)
156 restrict -< n^.node_typename .== (pgInt4 $ nodeTypeId NodeDocument)
162 -- | TODO use UTCTime fast
163 selectDocsDates :: CorpusId -> Cmd err [Text]
164 selectDocsDates cId = map (head' "selectDocsDates" . splitOn "-")
166 <$> map (view hd_publication_date)
169 selectDocs :: CorpusId -> Cmd err [HyperdataDocument]
170 selectDocs cId = runOpaQuery (queryDocs cId)
172 queryDocs :: CorpusId -> O.Query (Column PGJsonb)
173 queryDocs cId = proc () -> do
174 (n, nn) <- joinInCorpus -< ()
175 restrict -< nn^.nn_node1_id .== (toNullable $ pgNodeId cId)
176 restrict -< nn^.nn_category .>= (toNullable $ pgInt4 1)
177 restrict -< n^.node_typename .== (pgInt4 $ nodeTypeId NodeDocument)
178 returnA -< view (node_hyperdata) n
180 selectDocNodes :: CorpusId -> Cmd err [Node HyperdataDocument]
181 selectDocNodes cId = runOpaQuery (queryDocNodes cId)
183 queryDocNodes :: CorpusId -> O.Query NodeRead
184 queryDocNodes cId = proc () -> do
185 (n, nn) <- joinInCorpus -< ()
186 restrict -< nn^.nn_node1_id .== (toNullable $ pgNodeId cId)
187 restrict -< nn^.nn_category .>= (toNullable $ pgInt4 1)
188 restrict -< n^.node_typename .== (pgInt4 $ nodeTypeId NodeDocument)
191 joinInCorpus :: O.Query (NodeRead, NodeNodeReadNull)
192 joinInCorpus = leftJoin queryNodeTable queryNodeNodeTable cond
194 cond :: (NodeRead, NodeNodeRead) -> Column PGBool
195 cond (n, nn) = nn^.nn_node2_id .== (view node_id n)
197 joinOn1 :: O.Query (NodeRead, NodeNodeReadNull)
198 joinOn1 = leftJoin queryNodeTable queryNodeNodeTable cond
200 cond :: (NodeRead, NodeNodeRead) -> Column PGBool
201 cond (n, nn) = nn^.nn_node1_id .== n^.node_id
204 ------------------------------------------------------------------------
205 selectPublicNodes :: (Hyperdata a, QueryRunnerColumnDefault PGJsonb a)
206 => Cmd err [(Node a, Maybe Int)]
207 selectPublicNodes = runOpaQuery (queryWithType NodeFolderPublic)
209 queryWithType :: NodeType -> O.Query (NodeRead, Column (Nullable PGInt4))
210 queryWithType nt = proc () -> do
211 (n, nn) <- joinOn1 -< ()
212 restrict -< n^.node_typename .== (pgInt4 $ nodeTypeId nt)
213 returnA -< (n, nn^.nn_node2_id)