1 {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE DeriveGeneric #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE FunctionalDependencies #-}
7 {-# LANGUAGE Arrows #-}
8 {-# OPTIONS_GHC -fno-warn-orphans #-}
10 module Data.Gargantext.Database.Node where
12 import Database.PostgreSQL.Simple.FromField ( Conversion
13 , ResultError(ConversionFailed)
18 import Prelude hiding (null, id)
19 import Database.PostgreSQL.Simple.Internal (Field)
20 import Control.Arrow (returnA)
21 import Control.Lens.TH (makeLensesWith, abbreviatedFields)
23 import Data.Gargantext.Types
24 import Data.Gargantext.Prelude
25 import Data.Maybe (Maybe, fromMaybe)
26 import Data.Text (Text)
27 import Data.Profunctor.Product.TH (makeAdaptorAndInstance)
28 import Data.Typeable (Typeable)
29 import qualified Data.ByteString.Internal as DBI
30 import Database.PostgreSQL.Simple (Connection)
33 -- | Types for Node Database Management
36 type NodeWrite = NodePoly (Maybe (Column PGInt4)) (Column PGInt4)
37 (Column PGInt4) (Column (Nullable PGInt4))
38 (Column (PGText)) (Maybe (Column PGTimestamptz))
39 (Column PGJsonb) -- (Maybe (Column PGTSVector))
41 type NodeRead = NodePoly (Column PGInt4) (Column PGInt4)
42 (Column PGInt4) (Column (Nullable PGInt4))
43 (Column (PGText)) (Column PGTimestamptz)
44 (Column PGJsonb) -- (Column PGTSVector)
46 instance FromField HyperdataCorpus where
47 fromField = fromField'
49 instance FromField HyperdataDocument where
50 fromField = fromField'
52 instance FromField HyperdataProject where
53 fromField = fromField'
55 instance FromField HyperdataUser where
56 fromField = fromField'
59 fromField' :: (Typeable b, FromJSON b) => Field -> Maybe DBI.ByteString -> Conversion b
60 fromField' field mb = do
61 v <- fromField field mb
64 valueToHyperdata v = case fromJSON v of
66 Error _err -> returnError ConversionFailed field "cannot parse hyperdata"
69 instance QueryRunnerColumnDefault PGJsonb HyperdataDocument where
70 queryRunnerColumnDefault = fieldQueryRunnerColumn
72 instance QueryRunnerColumnDefault PGJsonb HyperdataCorpus where
73 queryRunnerColumnDefault = fieldQueryRunnerColumn
75 instance QueryRunnerColumnDefault PGJsonb HyperdataProject where
76 queryRunnerColumnDefault = fieldQueryRunnerColumn
78 instance QueryRunnerColumnDefault PGJsonb HyperdataUser where
79 queryRunnerColumnDefault = fieldQueryRunnerColumn
81 instance QueryRunnerColumnDefault (Nullable PGInt4) Int where
82 queryRunnerColumnDefault = fieldQueryRunnerColumn
84 instance QueryRunnerColumnDefault (Nullable PGText) Text where
85 queryRunnerColumnDefault = fieldQueryRunnerColumn
87 instance QueryRunnerColumnDefault PGInt4 Integer where
88 queryRunnerColumnDefault = fieldQueryRunnerColumn
92 $(makeAdaptorAndInstance "pNode" ''NodePoly)
93 $(makeLensesWith abbreviatedFields ''NodePoly)
96 nodeTable :: Table NodeWrite NodeRead
97 nodeTable = Table "nodes" (pNode Node { node_id = optional "id"
98 , node_typename = required "typename"
99 , node_userId = required "user_id"
100 , node_parentId = required "parent_id"
101 , node_name = required "name"
102 , node_date = optional "date"
103 , node_hyperdata = required "hyperdata"
104 -- , node_titleAbstract = optional "title_abstract"
109 selectNodes :: Column PGInt4 -> Query NodeRead
110 selectNodes id = proc () -> do
111 row <- queryNodeTable -< ()
112 restrict -< node_id row .== id
115 runGetNodes :: Connection -> Query NodeRead -> IO [Document]
116 runGetNodes = runQuery
122 getNodesWithParentId :: Connection -> Int -> IO [Node Value]
123 getNodesWithParentId conn n = runQuery conn $ selectNodeWithParentID n
125 selectNodeWithParentID :: Int -> Query NodeRead
126 selectNodeWithParentID n = proc () -> do
127 row@(Node _ _ _ parent_id _ _ _) <- queryNodeTable -< ()
130 parent_id .== (toNullable $ pgInt4 n)
135 queryNodeTable :: Query NodeRead
136 queryNodeTable = queryTable nodeTable
142 selectNodesWithType :: Column PGInt4 -> Query NodeRead
143 selectNodesWithType type_id = proc () -> do
144 row@(Node _ tn _ _ _ _ _) <- queryNodeTable -< ()
145 restrict -< tn .== type_id
148 getNode :: Connection -> Column PGInt4 -> IO (Node Value)
150 fromMaybe (error "TODO: 404") . headMay <$> runQuery conn (limit 1 $ selectNodes id)
152 getNodesWithType :: Connection -> Column PGInt4 -> IO [Node Value]
153 getNodesWithType conn type_id = do
154 runQuery conn $ selectNodesWithType type_id
158 getCorpusDocument :: Connection -> Int -> IO [Document]
159 getCorpusDocument conn n = runQuery conn (selectNodeWithParentID n)
162 getProjectCorpora :: Connection -> Int -> IO [Corpus]
163 getProjectCorpora conn node_id = do
164 runQuery conn $ selectNodeWithParentID node_id