2 Module : Gargantext.Database.Types.Nodes
3 Description : Main Types of Nodes in Database
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
12 {-# OPTIONS_GHC -fno-warn-orphans #-}
14 {-# LANGUAGE BangPatterns #-}
15 {-# LANGUAGE TemplateHaskell #-}
17 -- {-# LANGUAGE DuplicateRecordFields #-}
19 module Gargantext.Database.Admin.Types.Node
22 import Database.PostgreSQL.Simple.ToRow (ToRow, toRow)
23 import Codec.Serialise (Serialise())
24 import Control.Monad (mzero)
26 import Data.Aeson.TH (deriveJSON)
27 import qualified Data.Csv as Csv
29 import Data.Hashable (Hashable)
30 import Data.Morpheus.Types (GQLType)
32 import Data.Text (Text, unpack, pack)
33 import Data.Time (UTCTime)
34 import Database.PostgreSQL.Simple.FromField (FromField, fromField, fromJSONField)
35 import Database.PostgreSQL.Simple.ToField (ToField, toField, toJSONField)
36 import GHC.Generics (Generic)
37 import Gargantext.Core.Utils.Prefix (unPrefix, unPrefixSwagger, wellNamedSchema)
38 import Gargantext.Database.Schema.Context
39 import Gargantext.Database.Schema.Node
40 import Gargantext.Prelude
41 import Gargantext.Prelude.Crypto.Hash (Hash)
42 import Opaleye (DefaultFromField, defaultFromField, SqlInt4, SqlText, SqlTSVector, Nullable, fromPGSFromField)
43 import Servant hiding (Context)
44 import Test.QuickCheck (elements)
45 import Test.QuickCheck.Arbitrary
46 import Test.QuickCheck.Instances.Text ()
47 import Test.QuickCheck.Instances.Time ()
48 import Text.Read (read)
49 import qualified Opaleye as O
54 type MasterUserId = UserId
58 type ContextName = Text
61 type ContextTitle = Text
64 ------------------------------------------------------------------------
65 -- | NodePoly indicates that Node has a Polymorphism Type
66 type Node json = NodePoly NodeId (Maybe Hash) NodeTypeId UserId (Maybe ParentId) NodeName UTCTime json
67 type Context json = ContextPoly NodeId (Maybe Hash) NodeTypeId UserId (Maybe ParentId) ContextTitle UTCTime json
69 -- | NodeSearch (queries)
70 -- type NodeSearch json = NodePolySearch NodeId NodeTypeId UserId (Maybe ParentId) NodeName UTCTime json (Maybe TSVector)
72 ------------------------------------------------------------------------
74 instance (Typeable hyperdata, ToSchema hyperdata) =>
75 ToSchema (NodePoly NodeId Hash NodeTypeId
80 declareNamedSchema = wellNamedSchema "_node_"
82 instance (Typeable hyperdata, ToSchema hyperdata) =>
83 ToSchema (NodePoly NodeId Hash NodeTypeId
85 (Maybe ParentId) NodeName
88 declareNamedSchema = wellNamedSchema "_node_"
90 instance (Typeable hyperdata, ToSchema hyperdata) =>
91 ToSchema (NodePoly NodeId (Maybe Hash) NodeTypeId
93 (Maybe ParentId) NodeName
96 declareNamedSchema = wellNamedSchema "_node_"
98 instance (Typeable hyperdata, ToSchema hyperdata) =>
99 ToSchema (NodePolySearch NodeId
108 declareNamedSchema = wellNamedSchema "_ns_"
110 instance (Typeable hyperdata, ToSchema hyperdata) =>
111 ToSchema (NodePolySearch NodeId
120 declareNamedSchema = wellNamedSchema "_ns_"
122 instance (Arbitrary nodeId
126 ,Arbitrary nodeParentId
127 , Arbitrary hyperdata
128 ) => Arbitrary (NodePoly nodeId hashId toDBid userId nodeParentId
129 NodeName UTCTime hyperdata) where
130 --arbitrary = Node 1 1 (Just 1) 1 "name" (jour 2018 01 01) (arbitrary) (Just "")
131 arbitrary = Node <$> arbitrary <*> arbitrary <*> arbitrary
132 <*> arbitrary <*> arbitrary <*> arbitrary
133 <*> arbitrary <*> arbitrary
137 instance (Arbitrary hyperdata
141 ,Arbitrary nodeParentId
142 ) => Arbitrary (NodePolySearch nodeId
151 --arbitrary = Node 1 1 (Just 1) 1 "name" (jour 2018 01 01) (arbitrary) (Just "")
152 arbitrary = NodeSearch <$> arbitrary
162 instance (Arbitrary contextId
166 ,Arbitrary contextParentId
167 , Arbitrary hyperdata
168 ) => Arbitrary (ContextPoly contextId hashId toDBid userId contextParentId
169 ContextName UTCTime hyperdata) where
170 --arbitrary = Node 1 1 (Just 1) 1 "name" (jour 2018 01 01) (arbitrary) (Just "")
171 arbitrary = Context <$> arbitrary <*> arbitrary <*> arbitrary
172 <*> arbitrary <*> arbitrary <*> arbitrary
173 <*> arbitrary <*> arbitrary
175 instance (Arbitrary hyperdata
179 ,Arbitrary contextParentId
180 ) => Arbitrary (ContextPolySearch contextId
189 --arbitrary = Node 1 1 (Just 1) 1 "name" (jour 2018 01 01) (arbitrary) (Just "")
190 arbitrary = ContextSearch <$> arbitrary
202 ------------------------------------------------------------------------
203 pgNodeId :: NodeId -> O.Column O.SqlInt4
204 pgNodeId = O.sqlInt4 . id2int
206 id2int :: NodeId -> Int
207 id2int (NodeId n) = n
209 pgContextId :: ContextId -> O.Column O.SqlInt4
210 pgContextId = pgNodeId
212 ------------------------------------------------------------------------
213 newtype NodeId = NodeId Int
214 deriving (Read, Generic, Num, Eq, Ord, Enum, ToJSONKey, FromJSONKey, ToJSON, FromJSON, Hashable, Csv.ToField)
215 instance GQLType NodeId
216 instance Show NodeId where
217 show (NodeId n) = "nodeId-" <> show n
218 instance Serialise NodeId
219 instance ToField NodeId where
220 toField (NodeId n) = toField n
221 instance ToRow NodeId where
222 toRow (NodeId i) = [toField i]
224 instance FromField NodeId where
225 fromField field mdata = do
226 n <- fromField field mdata
228 then return $ NodeId n
230 instance ToSchema NodeId
232 -- TODO make another type
233 type ContextId = NodeId
235 newtype NodeContextId = NodeContextId Int
236 deriving (Read, Generic, Num, Eq, Ord, Enum, ToJSONKey, FromJSONKey, ToJSON, FromJSON, Hashable, Csv.ToField)
239 --instance Csv.ToField NodeId where
240 -- toField (NodeId nodeId) = Csv.toField nodeId
242 unNodeId :: NodeId -> Int
243 unNodeId (NodeId n) = n
245 ------------------------------------------------------------------------
246 ------------------------------------------------------------------------
247 instance FromHttpApiData NodeId where
248 parseUrlPiece n = pure $ NodeId $ (read . cs) n
249 instance ToHttpApiData NodeId where
250 toUrlPiece (NodeId n) = toUrlPiece n
251 instance ToParamSchema NodeId
252 instance Arbitrary NodeId where
253 arbitrary = NodeId <$> arbitrary
255 type ParentId = NodeId
256 type CorpusId = NodeId
257 type CommunityId = NodeId
259 type DocumentId = NodeId
262 type MasterCorpusId = CorpusId
263 type UserCorpusId = CorpusId
265 type GraphId = NodeId
266 type PhyloId = NodeId
267 type AnnuaireId = NodeId
268 type ContactId = NodeId
270 ------------------------------------------------------------------------
271 data Status = Status { status_failed :: !Int
272 , status_succeeded :: !Int
273 , status_remaining :: !Int
274 } deriving (Show, Generic)
275 $(deriveJSON (unPrefix "status_") ''Status)
277 instance Arbitrary Status where
278 arbitrary = Status <$> arbitrary <*> arbitrary <*> arbitrary
281 ------------------------------------------------------------------------
282 data LanguageNodes = LanguageNodes { languageNodes___unknown__ :: [Int]}
283 deriving (Show, Generic)
284 $(deriveJSON (unPrefix "languageNodes_") ''LanguageNodes)
286 ------------------------------------------------------------------------
287 -- level: debug | dev (fatal = critical)
288 data EventLevel = CRITICAL | FATAL | ERROR | WARNING | INFO | DEBUG
289 deriving (Show, Generic, Enum, Bounded)
291 instance FromJSON EventLevel
292 instance ToJSON EventLevel
294 instance Arbitrary EventLevel where
295 arbitrary = elements [minBound..maxBound]
297 instance ToSchema EventLevel where
298 declareNamedSchema proxy = genericDeclareNamedSchema defaultSchemaOptions proxy
300 ------------------------------------------------------------------------
301 data Event = Event { event_level :: !EventLevel
302 , event_message :: !Text
303 , event_date :: !UTCTime
304 } deriving (Show, Generic)
305 $(deriveJSON (unPrefix "event_") ''Event)
307 instance Arbitrary Event where
308 arbitrary = Event <$> arbitrary <*> arbitrary <*> arbitrary
310 instance ToSchema Event where
311 declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "event_")
313 ------------------------------------------------------------------------
314 data Resource = Resource { resource_path :: !(Maybe Text)
315 , resource_scraper :: !(Maybe Text)
316 , resource_query :: !(Maybe Text)
317 , resource_events :: !([Event])
318 , resource_status :: !Status
319 , resource_date :: !UTCTime
320 } deriving (Show, Generic)
321 $(deriveJSON (unPrefix "resource_") ''Resource)
323 instance Arbitrary Resource where
324 arbitrary = Resource <$> arbitrary
331 instance ToSchema Resource where
332 declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "resource_")
334 ------------------------------------------------------------------------
335 -- | Then a Node can be either a Folder or a Corpus or a Document
336 data NodeType = NodeUser
338 | NodeFolderShared | NodeTeam
342 -- | NodeAnalysis | NodeCommunity
344 | NodeCorpus | NodeCorpusV3 | NodeTexts | NodeDocument
345 | NodeAnnuaire | NodeContact
346 | NodeGraph | NodePhylo
347 | NodeDashboard -- | NodeChart | NodeNoteBook
348 | NodeList | NodeModel
358 | Notes | Calc | NodeFrameVisio | NodeFrameNotebook
361 deriving (Show, Read, Eq, Generic, Bounded, Enum)
364 instance GQLType NodeType
365 instance FromJSON NodeType
366 instance ToJSON NodeType
367 instance FromHttpApiData NodeType where
368 parseUrlPiece = Right . read . unpack
369 instance ToHttpApiData NodeType where
370 toUrlPiece = pack . show
371 instance ToParamSchema NodeType
372 instance ToSchema NodeType
373 instance Arbitrary NodeType where
374 arbitrary = elements allNodeTypes
375 instance FromField NodeType where
376 fromField = fromJSONField
377 instance ToField NodeType where
378 toField = toJSONField
381 allNodeTypes :: [NodeType]
382 allNodeTypes = [minBound ..]
384 defaultName :: NodeType -> Text
385 defaultName NodeUser = "User"
386 defaultName NodeContact = "Contact"
388 defaultName NodeCorpus = "Corpus"
389 defaultName NodeCorpusV3 = "Corpus"
390 defaultName NodeAnnuaire = "Annuaire"
392 defaultName NodeDocument = "Doc"
393 defaultName NodeTexts = "Docs"
394 defaultName NodeList = "Terms"
395 defaultName NodeListCooc = "List"
396 defaultName NodeModel = "Model"
398 defaultName NodeFolder = "Folder"
399 defaultName NodeFolderPrivate = "Private"
400 defaultName NodeFolderShared = "Share"
401 defaultName NodeTeam = "Team"
402 defaultName NodeFolderPublic = "Public"
404 defaultName NodeDashboard = "Board"
405 defaultName NodeGraph = "Graph"
406 defaultName NodePhylo = "Phylo"
408 defaultName Notes = "Note"
409 defaultName Calc = "Calc"
410 defaultName NodeFrameVisio = "Visio"
411 defaultName NodeFrameNotebook = "Code"
413 defaultName NodeFile = "File"
417 ------------------------------------------------------------------------
419 ------------------------------------------------------------------------
420 instance ToSchema Status where
421 declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "status_")
423 ------------------------------------------------------------------------
425 instance FromField (NodeId, Text)
427 fromField = fromField'
429 ------------------------------------------------------------------------
430 instance DefaultFromField SqlTSVector (Maybe TSVector)
432 defaultFromField = fromPGSFromField
434 instance DefaultFromField SqlInt4 (Maybe NodeId)
436 defaultFromField = fromPGSFromField
438 instance DefaultFromField SqlInt4 NodeId
440 defaultFromField = fromPGSFromField
442 instance DefaultFromField (Nullable SqlInt4) NodeId
444 defaultFromField = fromPGSFromField
446 instance (DefaultFromField (Nullable O.SqlTimestamptz) UTCTime)
448 defaultFromField = fromPGSFromField
450 instance DefaultFromField SqlText (Maybe Hash)
452 defaultFromField = fromPGSFromField
454 ---------------------------------------------------------------------
456 context2node :: Context a -> Node a
457 context2node (Context ci ch ct cu cp cn cd chy) = Node ci ch ct cu cp cn cd chy