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, ResultError(ConversionFailed), FromField, fromField, returnError)
13 import Database.PostgreSQL.Simple.Internal (Field)
14 import Control.Arrow (returnA)
15 import Control.Lens.TH (makeLensesWith, abbreviatedFields)
17 import Data.Gargantext.Database.Private (infoGargandb)
18 import Data.Gargantext.Types
19 import Data.Maybe (Maybe)
20 import Data.Profunctor.Product.TH (makeAdaptorAndInstance)
21 import Data.Typeable (Typeable)
22 import qualified Data.ByteString.Internal as DBI
23 import qualified Database.PostgreSQL.Simple as PGS
27 -- | Types for Node Database Management
29 type NodeWrite = NodePoly (Maybe (Column PGInt4)) (Column PGInt4)
30 (Column PGInt4) (Column PGInt4)
31 (Column PGText) (Maybe (Column PGTimestamptz))
34 type NodeRead = NodePoly (Column PGInt4) (Column PGInt4)
35 (Column PGInt4) (Column PGInt4)
36 (Column PGText) (Column PGTimestamptz)
39 instance FromField HyperdataCorpus where
40 fromField = fromField'
42 instance FromField HyperdataDocument where
43 fromField = fromField'
45 --instance FromField HyperdataProject where
46 -- fromField = fromField'
48 --instance FromField HyperdataUser where
49 -- fromField = fromField'
52 fromField' :: (Typeable b, FromJSON b) => Field -> Maybe DBI.ByteString -> Conversion b
53 fromField' field mb = do
54 v <- fromField field mb
57 valueToHyperdata v = case fromJSON v of
59 Error _err -> returnError ConversionFailed field "cannot parse hyperdata"
62 instance QueryRunnerColumnDefault PGJsonb HyperdataDocument where
63 queryRunnerColumnDefault = fieldQueryRunnerColumn
65 instance QueryRunnerColumnDefault PGJsonb HyperdataCorpus where
66 queryRunnerColumnDefault = fieldQueryRunnerColumn
71 $(makeAdaptorAndInstance "pNode" ''NodePoly)
72 $(makeLensesWith abbreviatedFields ''NodePoly)
75 nodeTable :: Table NodeWrite NodeRead
76 nodeTable = Table "nodes" (pNode Node { node_id = optional "id"
77 , node_typename = required "typename"
78 , node_userId = required "user_id"
79 , node_parentId = required "parent_id"
80 , node_name = required "name"
81 , node_date = optional "date"
82 , node_hyperdata = required "hyperdata"
89 selectNodes :: Column PGInt4 -> Query (Column PGText)
90 selectNodes node_id = proc () -> do
91 (Node n_id _tn _u _p n _d _h) <- queryNodeTable -< ()
92 restrict -< n_id .== node_id
95 instance QueryRunnerColumnDefault PGInt4 Integer where
96 queryRunnerColumnDefault = fieldQueryRunnerColumn
99 runGetNodes :: PGS.Connection -> Query NodeRead -> IO [Document]
100 runGetNodes = runQuery
103 queryNodeTable :: Query NodeRead
104 queryNodeTable = queryTable nodeTable
107 selectNode :: Column PGInt4 -> Query NodeRead
108 selectNode node_id = proc () -> do
109 row@(Node _id _tn _u p_id _n _d _h) <- queryNodeTable -< ()
110 restrict -< p_id .== node_id
114 getNodes :: Column PGInt4 -> IO [Document]
115 getNodes node_id = do
116 conn <- PGS.connect infoGargandb
117 runQuery conn $ selectNode node_id
119 getCorpusDocument :: Column PGInt4 -> IO [Document]
120 getCorpusDocument node_id = PGS.connect infoGargandb >>=
121 \conn -> runQuery conn (selectNode node_id)
123 getProjectCorpora :: Column PGInt4 -> IO [Corpus]
124 getProjectCorpora node_id = do
125 conn <- PGS.connect infoGargandb
126 runQuery conn $ selectNode node_id