2 Module : Gargantext.API.Count
3 Description : Server API
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
10 Count API part of Gargantext.
13 {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
15 {-# LANGUAGE TemplateHaskell #-}
16 {-# LANGUAGE TypeOperators #-}
17 {-# LANGUAGE DeriveAnyClass #-}
19 module Gargantext.API.Search
24 import Data.Text (Text)
25 import Data.Time (UTCTime)
26 import GHC.Generics (Generic)
27 import Gargantext.API.Prelude (GargServer)
28 import Gargantext.Core.Utils.Prefix (unPrefixSwagger)
29 import Gargantext.Database.Query.Facet
30 import Gargantext.Database.Action.Search
31 import Gargantext.Database.Action.Flow.Pairing (isPairedWith)
32 import Gargantext.Database.Admin.Types.Hyperdata (HyperdataContact)
33 import Gargantext.Database.Admin.Types.Node
34 import Gargantext.Prelude
36 import Test.QuickCheck (elements)
37 import Test.QuickCheck.Arbitrary
39 -----------------------------------------------------------------------
40 data SearchType = SearchDoc | SearchContact
44 instance FromJSON SearchType where
45 parseJSON = genericParseJSON (defaultOptions { sumEncoding = ObjectWithSingleField })
47 instance ToJSON SearchType where
48 toJSON = genericToJSON (defaultOptions { sumEncoding = ObjectWithSingleField })
50 instance ToSchema SearchType
51 instance Arbitrary SearchType where
52 arbitrary = elements [SearchDoc, SearchContact]
54 -----------------------------------------------------------------------
56 SearchQuery { query :: ![Text]
57 , expected :: !SearchType
60 instance FromJSON SearchQuery where
61 parseJSON = genericParseJSON (defaultOptions { sumEncoding = ObjectWithSingleField })
63 instance ToJSON SearchQuery where
64 toJSON = genericToJSON (defaultOptions { sumEncoding = ObjectWithSingleField })
66 instance ToSchema SearchQuery where
67 declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "")
69 instance Arbitrary SearchQuery where
70 arbitrary = elements [SearchQuery ["electrodes"] SearchDoc]
71 -----------------------------------------------------------------------
73 data SearchResult = SearchResultDoc { docs :: ![FacetDoc]}
74 | SearchResultContact { contacts :: ![FacetPaired Int UTCTime HyperdataContact Int] }
75 | SearchNoResult { message :: !Text }
79 instance FromJSON SearchResult where
80 parseJSON = genericParseJSON (defaultOptions { sumEncoding = ObjectWithSingleField })
82 instance ToJSON SearchResult where
83 toJSON = genericToJSON (defaultOptions { sumEncoding = ObjectWithSingleField })
85 instance Arbitrary SearchResult where
87 srd <- SearchResultDoc <$> arbitrary
88 src <- SearchResultContact <$> arbitrary
89 srn <- pure $ SearchNoResult "No result because.."
90 elements [srd, src, srn]
92 instance ToSchema SearchResult where
93 declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "sr_")
95 -----------------------------------------------------------------------
96 -- TODO-ACCESS: CanSearch? or is it part of CanGetNode
97 -- TODO-EVENTS: No event, this is a read-only query.
98 type API results = Summary "Search endpoint"
99 :> ReqBody '[JSON] SearchQuery
100 :> QueryParam "offset" Int
101 :> QueryParam "limit" Int
102 :> QueryParam "order" OrderBy
103 :> Post '[JSON] results
104 -----------------------------------------------------------------------
105 api :: NodeId -> GargServer (API SearchResult)
106 api nId (SearchQuery q SearchDoc) o l order =
107 SearchResultDoc <$> searchInCorpus nId False q o l order
108 api nId (SearchQuery q SearchContact) o l order = do
109 aIds <- isPairedWith NodeAnnuaire nId
110 -- TODO if paired with several corpus
112 Nothing -> pure $ SearchNoResult "[G.A.Search] pair corpus with an Annuaire"
113 Just aId -> SearchResultContact <$> searchInCorpusWithContacts nId aId q o l order
114 -----------------------------------------------------------------------