3 {-# LANGUAGE ConstraintKinds #-}
4 {-# LANGUAGE ScopedTypeVariables #-}
5 {-# LANGUAGE TemplateHaskell #-}
6 {-# LANGUAGE TypeOperators #-}
7 {-# LANGUAGE TypeFamilies #-}
8 {-# OPTIONS -fno-warn-orphans #-}
10 module Gargantext.API.Ngrams.Types where
12 import Codec.Serialise (Serialise())
13 import Control.Category ((>>>))
14 import Control.DeepSeq (NFData)
15 import Control.Lens (makeLenses, makePrisms, Iso', iso, from, (.~), (?=), (#), to, folded, {-withIndex, ifolded,-} view, use, (^.), (^?), (%~), (.~), (%=), at, _Just, Each(..), itraverse_, both, forOf_, (?~))
16 import Control.Monad.State
17 import Data.Aeson hiding ((.=))
18 import Data.Aeson.TH (deriveJSON)
19 import Data.Either (Either(..))
21 import Data.Hashable (Hashable)
22 import Data.Map.Strict (Map)
23 import Data.Maybe (fromMaybe)
25 import Data.Patch.Class (Replace, replace, Action(act), Group, Applicable(..), Composable(..), Transformable(..), PairPatch(..), Patched, ConflictResolution, ConflictResolutionReplace, MaybePatch(Mod), unMod, old, new)
27 import Data.String (IsString, fromString)
28 import Data.Swagger hiding (version, patch)
29 import Data.Text (Text, pack, strip)
31 import Database.PostgreSQL.Simple.FromField (FromField, fromField, fromJSONField)
32 import Database.PostgreSQL.Simple.ToField (ToField, toJSONField, toField)
33 import GHC.Generics (Generic)
34 import Gargantext.Core.Text (size)
35 import Gargantext.Core.Types (ListType(..), ListId, NodeId, TODO)
36 import Gargantext.Core.Utils.Prefix (unPrefix, unPrefixUntagged, unPrefixSwagger, wellNamedSchema)
37 import Gargantext.Database.Admin.Types.Node (ContextId)
38 import Gargantext.Database.Prelude (fromField', HasConnectionPool, HasConfig, CmdM')
39 import Gargantext.Prelude
40 import Gargantext.Prelude.Crypto.Hash (IsHashable(..))
41 import Protolude (maybeToEither)
42 import Servant hiding (Patch)
43 import Servant.Job.Utils (jsonOptions)
44 -- import System.FileLock (FileLock)
45 import Test.QuickCheck (elements, frequency)
46 import Test.QuickCheck.Arbitrary (Arbitrary, arbitrary)
47 import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
48 import qualified Data.Map.Strict as Map
49 import qualified Data.Map.Strict.Patch as PM
50 import qualified Data.Set as Set
51 import qualified Gargantext.Database.Query.Table.Ngrams as TableNgrams
53 ------------------------------------------------------------------------
55 type QueryParamR = QueryParam' '[Required, Strict]
57 ------------------------------------------------------------------------
58 --data FacetFormat = Table | Chart
59 data TabType = Docs | Trash | MoreFav | MoreTrash
60 | Terms | Sources | Authors | Institutes
62 deriving (Bounded, Enum, Eq, Generic, Ord, Show)
65 instance Hashable TabType
67 instance FromHttpApiData TabType where
68 parseUrlPiece "Docs" = pure Docs
69 parseUrlPiece "Trash" = pure Trash
70 parseUrlPiece "MoreFav" = pure MoreFav
71 parseUrlPiece "MoreTrash" = pure MoreTrash
73 parseUrlPiece "Terms" = pure Terms
74 parseUrlPiece "Sources" = pure Sources
75 parseUrlPiece "Institutes" = pure Institutes
76 parseUrlPiece "Authors" = pure Authors
78 parseUrlPiece "Contacts" = pure Contacts
80 parseUrlPiece _ = Left "Unexpected value of TabType"
81 instance ToHttpApiData TabType where
82 toUrlPiece = pack . show
83 instance ToParamSchema TabType
84 instance ToJSON TabType
85 instance FromJSON TabType
86 instance ToSchema TabType
87 instance Arbitrary TabType where
88 arbitrary = elements [minBound .. maxBound]
89 instance FromJSONKey TabType where
90 fromJSONKey = genericFromJSONKey defaultJSONKeyOptions
91 instance ToJSONKey TabType where
92 toJSONKey = genericToJSONKey defaultJSONKeyOptions
94 newtype MSet a = MSet (Map a ())
95 deriving (Eq, Ord, Show, Generic, Arbitrary, Semigroup, Monoid)
97 instance ToJSON a => ToJSON (MSet a) where
98 toJSON (MSet m) = toJSON (Map.keys m)
99 toEncoding (MSet m) = toEncoding (Map.keys m)
101 mSetFromSet :: Set a -> MSet a
102 mSetFromSet = MSet . Map.fromSet (const ())
104 mSetFromList :: Ord a => [a] -> MSet a
105 mSetFromList = MSet . Map.fromList . map (\x -> (x, ()))
107 -- mSetToSet :: Ord a => MSet a -> Set a
108 -- mSetToSet (MSet a) = Set.fromList ( Map.keys a)
109 mSetToSet :: Ord a => MSet a -> Set a
110 mSetToSet = Set.fromList . mSetToList
112 mSetToList :: MSet a -> [a]
113 mSetToList (MSet a) = Map.keys a
115 instance Foldable MSet where
116 foldMap f (MSet m) = Map.foldMapWithKey (\k _ -> f k) m
118 instance (Ord a, FromJSON a) => FromJSON (MSet a) where
119 parseJSON = fmap mSetFromList . parseJSON
121 instance (ToJSONKey a, ToSchema a) => ToSchema (MSet a) where
123 declareNamedSchema _ = wellNamedSchema "" (Proxy :: Proxy TODO)
125 ------------------------------------------------------------------------
126 newtype NgramsTerm = NgramsTerm { unNgramsTerm :: Text }
127 deriving (Ord, Eq, Show, Generic, ToJSONKey, ToJSON, FromJSON, Semigroup, Arbitrary, Serialise, ToSchema, Hashable, NFData, FromField, ToField)
128 instance IsHashable NgramsTerm where
129 hash (NgramsTerm t) = hash t
130 instance Monoid NgramsTerm where
131 mempty = NgramsTerm ""
132 instance FromJSONKey NgramsTerm where
133 fromJSONKey = FromJSONKeyTextParser $ \t -> pure $ NgramsTerm $ strip t
134 instance IsString NgramsTerm where
135 fromString s = NgramsTerm $ pack s
138 data RootParent = RootParent
139 { _rp_root :: NgramsTerm
140 , _rp_parent :: NgramsTerm
142 deriving (Ord, Eq, Show, Generic)
144 deriveJSON (unPrefix "_rp_") ''RootParent
145 makeLenses ''RootParent
147 data NgramsRepoElement = NgramsRepoElement
149 , _nre_list :: !ListType
150 , _nre_root :: !(Maybe NgramsTerm)
151 , _nre_parent :: !(Maybe NgramsTerm)
152 , _nre_children :: !(MSet NgramsTerm)
154 deriving (Ord, Eq, Show, Generic)
155 deriveJSON (unPrefix "_nre_") ''NgramsRepoElement
157 -- if ngrams & not size => size
159 makeLenses ''NgramsRepoElement
160 instance ToSchema NgramsRepoElement where
161 declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "_nre_")
162 instance Serialise NgramsRepoElement
163 instance FromField NgramsRepoElement where
164 fromField = fromJSONField
165 instance ToField NgramsRepoElement where
166 toField = toJSONField
168 instance Serialise (MSet NgramsTerm)
171 NgramsElement { _ne_ngrams :: NgramsTerm
173 , _ne_list :: ListType
174 , _ne_occurrences :: [ContextId]
175 , _ne_root :: Maybe NgramsTerm
176 , _ne_parent :: Maybe NgramsTerm
177 , _ne_children :: MSet NgramsTerm
179 deriving (Ord, Eq, Show, Generic)
181 deriveJSON (unPrefix "_ne_") ''NgramsElement
182 makeLenses ''NgramsElement
184 mkNgramsElement :: NgramsTerm
189 mkNgramsElement ngrams list rp children =
190 NgramsElement ngrams (size (unNgramsTerm ngrams)) list [] (_rp_root <$> rp) (_rp_parent <$> rp) children
192 newNgramsElement :: Maybe ListType -> NgramsTerm -> NgramsElement
193 newNgramsElement mayList ngrams =
194 mkNgramsElement ngrams (fromMaybe MapTerm mayList) Nothing mempty
196 instance ToSchema NgramsElement where
197 declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "_ne_")
198 instance Arbitrary NgramsElement where
199 arbitrary = elements [newNgramsElement Nothing "sport"]
202 ------------------------------------------------------------------------
203 newtype NgramsTable = NgramsTable [NgramsElement]
204 deriving (Ord, Eq, Generic, ToJSON, FromJSON, Show)
206 -- type NgramsList = NgramsTable
208 makePrisms ''NgramsTable
210 -- | Question: why these repetition of Type in this instance
211 -- may you document it please ?
212 instance Each NgramsTable NgramsTable NgramsElement NgramsElement where
213 each = _NgramsTable . each
216 -- | TODO Check N and Weight
218 toNgramsElement :: [NgramsTableData] -> [NgramsElement]
219 toNgramsElement ns = map toNgramsElement' ns
221 toNgramsElement' (NgramsTableData _ p t _ lt w) = NgramsElement t lt' (round w) p' c'
225 Just x -> lookup x mapParent
226 c' = maybe mempty identity $ lookup t mapChildren
227 lt' = maybe (panic "API.Ngrams: listypeId") identity lt
229 mapParent :: Map Int Text
230 mapParent = Map.fromListWith (<>) $ map (\(NgramsTableData i _ t _ _ _) -> (i,t)) ns
232 mapChildren :: Map Text (Set Text)
233 mapChildren = Map.mapKeys (\i -> (maybe (panic "API.Ngrams.mapChildren: ParentId with no Terms: Impossible") identity $ lookup i mapParent))
234 $ Map.fromListWith (<>)
235 $ map (first fromJust)
236 $ filter (isJust . fst)
237 $ map (\(NgramsTableData _ p t _ _ _) -> (p, Set.singleton t)) ns
240 mockTable :: NgramsTable
241 mockTable = NgramsTable
242 [ mkNgramsElement "animal" MapTerm Nothing (mSetFromList ["dog", "cat"])
243 , mkNgramsElement "cat" MapTerm (rp "animal") mempty
244 , mkNgramsElement "cats" StopTerm Nothing mempty
245 , mkNgramsElement "dog" MapTerm (rp "animal") (mSetFromList ["dogs"])
246 , mkNgramsElement "dogs" StopTerm (rp "dog") mempty
247 , mkNgramsElement "fox" MapTerm Nothing mempty
248 , mkNgramsElement "object" CandidateTerm Nothing mempty
249 , mkNgramsElement "nothing" StopTerm Nothing mempty
250 , mkNgramsElement "organic" MapTerm Nothing (mSetFromList ["flower"])
251 , mkNgramsElement "flower" MapTerm (rp "organic") mempty
252 , mkNgramsElement "moon" CandidateTerm Nothing mempty
253 , mkNgramsElement "sky" StopTerm Nothing mempty
256 rp n = Just $ RootParent n n
258 instance Arbitrary NgramsTable where
259 arbitrary = pure mockTable
261 instance ToSchema NgramsTable
263 ------------------------------------------------------------------------
264 type NgramsTableMap = Map NgramsTerm NgramsRepoElement
265 ------------------------------------------------------------------------
266 -- On the Client side:
267 --data Action = InGroup NgramsId NgramsId
268 -- | OutGroup NgramsId NgramsId
269 -- | SetListType NgramsId ListType
271 data PatchSet a = PatchSet
275 deriving (Eq, Ord, Show, Generic)
277 makeLenses ''PatchSet
278 makePrisms ''PatchSet
280 instance ToJSON a => ToJSON (PatchSet a) where
281 toJSON = genericToJSON $ unPrefix "_"
282 toEncoding = genericToEncoding $ unPrefix "_"
284 instance (Ord a, FromJSON a) => FromJSON (PatchSet a) where
285 parseJSON = genericParseJSON $ unPrefix "_"
288 instance (Ord a, Arbitrary a) => Arbitrary (PatchSet a) where
289 arbitrary = PatchSet <$> arbitrary <*> arbitrary
291 type instance Patched (PatchSet a) = Set a
293 type ConflictResolutionPatchSet a = SimpleConflictResolution' (Set a)
294 type instance ConflictResolution (PatchSet a) = ConflictResolutionPatchSet a
296 instance Ord a => Semigroup (PatchSet a) where
297 p <> q = PatchSet { _rem = (q ^. rem) `Set.difference` (p ^. add) <> p ^. rem
298 , _add = (q ^. add) `Set.difference` (p ^. rem) <> p ^. add
301 instance Ord a => Monoid (PatchSet a) where
302 mempty = PatchSet mempty mempty
304 instance Ord a => Group (PatchSet a) where
305 invert (PatchSet r a) = PatchSet a r
307 instance Ord a => Composable (PatchSet a) where
308 composable _ _ = undefined
310 instance Ord a => Action (PatchSet a) (Set a) where
311 act p source = (source `Set.difference` (p ^. rem)) <> p ^. add
313 instance Applicable (PatchSet a) (Set a) where
314 applicable _ _ = mempty
316 instance Ord a => Validity (PatchSet a) where
317 validate p = check (Set.disjoint (p ^. rem) (p ^. add)) "_rem and _add should be dijoint"
319 instance Ord a => Transformable (PatchSet a) where
320 transformable = undefined
322 conflicts _p _q = undefined
324 transformWith conflict p q = undefined conflict p q
326 instance ToSchema a => ToSchema (PatchSet a)
329 type AddRem = Replace (Maybe ())
331 instance Serialise AddRem
333 remPatch, addPatch :: AddRem
334 remPatch = replace (Just ()) Nothing
335 addPatch = replace Nothing (Just ())
337 isRem :: Replace (Maybe ()) -> Bool
338 isRem = (== remPatch)
340 type PatchMap = PM.PatchMap
342 newtype PatchMSet a = PatchMSet (PatchMap a AddRem)
343 deriving (Eq, Show, Generic, Validity, Semigroup, Monoid, Group,
344 Transformable, Composable)
346 unPatchMSet :: PatchMSet a -> PatchMap a AddRem
347 unPatchMSet (PatchMSet a) = a
349 type ConflictResolutionPatchMSet a = a -> ConflictResolutionReplace (Maybe ())
350 type instance ConflictResolution (PatchMSet a) = ConflictResolutionPatchMSet a
352 instance (Serialise a, Ord a) => Serialise (PatchMap a AddRem)
353 instance (Serialise a, Ord a) => Serialise (PatchMSet a)
355 -- TODO this breaks module abstraction
356 makePrisms ''PM.PatchMap
358 makePrisms ''PatchMSet
360 _PatchMSetIso :: Ord a => Iso' (PatchMSet a) (PatchSet a)
361 _PatchMSetIso = _PatchMSet . _PatchMap . iso f g . from _PatchSet
363 f :: Ord a => Map a (Replace (Maybe ())) -> (Set a, Set a)
364 f = Map.partition isRem >>> both %~ Map.keysSet
366 g :: Ord a => (Set a, Set a) -> Map a (Replace (Maybe ()))
367 g (rems, adds) = Map.fromSet (const remPatch) rems
368 <> Map.fromSet (const addPatch) adds
370 instance Ord a => Action (PatchMSet a) (MSet a) where
371 act (PatchMSet p) (MSet m) = MSet $ act p m
373 instance Ord a => Applicable (PatchMSet a) (MSet a) where
374 applicable (PatchMSet p) (MSet m) = applicable p m
376 instance (Ord a, ToJSON a) => ToJSON (PatchMSet a) where
377 toJSON = toJSON . view _PatchMSetIso
378 toEncoding = toEncoding . view _PatchMSetIso
380 instance (Ord a, FromJSON a) => FromJSON (PatchMSet a) where
381 parseJSON = fmap (_PatchMSetIso #) . parseJSON
383 instance (Ord a, Arbitrary a) => Arbitrary (PatchMSet a) where
384 arbitrary = (PatchMSet . PM.fromMap) <$> arbitrary
386 instance ToSchema a => ToSchema (PatchMSet a) where
388 declareNamedSchema _ = wellNamedSchema "" (Proxy :: Proxy TODO)
390 type instance Patched (PatchMSet a) = MSet a
392 instance (Eq a, Arbitrary a) => Arbitrary (Replace a) where
393 arbitrary = uncurry replace <$> arbitrary
394 -- If they happen to be equal then the patch is Keep.
396 instance ToSchema a => ToSchema (Replace a) where
397 declareNamedSchema (_ :: Proxy (Replace a)) = do
398 -- TODO Keep constructor is not supported here.
399 aSchema <- declareSchemaRef (Proxy :: Proxy a)
400 return $ NamedSchema (Just "Replace") $ mempty
401 & type_ ?~ SwaggerObject
403 InsOrdHashMap.fromList
407 & required .~ [ "old", "new" ]
410 = NgramsPatch { _patch_children :: !(PatchMSet NgramsTerm)
411 , _patch_list :: !(Replace ListType) -- TODO Map UserId ListType
413 | NgramsReplace { _patch_old :: !(Maybe NgramsRepoElement)
414 , _patch_new :: !(Maybe NgramsRepoElement)
416 deriving (Eq, Show, Generic)
418 -- The JSON encoding is untagged, this is OK since the field names are disjoints and thus the encoding is unambiguous.
419 -- TODO: the empty object should be accepted and treated as mempty.
420 deriveJSON (unPrefixUntagged "_") ''NgramsPatch
421 makeLenses ''NgramsPatch
423 -- TODO: This instance is simplified since we should either have the fields children and/or list
424 -- or the fields old and/or new.
425 instance ToSchema NgramsPatch where
426 declareNamedSchema _ = do
427 childrenSch <- declareSchemaRef (Proxy :: Proxy (PatchMSet NgramsTerm))
428 listSch <- declareSchemaRef (Proxy :: Proxy (Replace ListType))
429 nreSch <- declareSchemaRef (Proxy :: Proxy NgramsRepoElement)
430 return $ NamedSchema (Just "NgramsPatch") $ mempty
431 & type_ ?~ SwaggerObject
433 InsOrdHashMap.fromList
434 [ ("children", childrenSch)
439 instance Arbitrary NgramsPatch where
440 arbitrary = frequency [ (9, NgramsPatch <$> arbitrary <*> (replace <$> arbitrary <*> arbitrary))
441 , (1, NgramsReplace <$> arbitrary <*> arbitrary)
443 instance Serialise NgramsPatch
444 instance FromField NgramsPatch where
445 fromField = fromJSONField
446 instance ToField NgramsPatch where
447 toField = toJSONField
449 instance Serialise (Replace ListType)
451 instance Serialise ListType
453 type NgramsPatchIso =
454 MaybePatch NgramsRepoElement (PairPatch (PatchMSet NgramsTerm) (Replace ListType))
456 _NgramsPatch :: Iso' NgramsPatch NgramsPatchIso
457 _NgramsPatch = iso unwrap wrap
459 unwrap (NgramsPatch c l) = Mod $ PairPatch (c, l)
460 unwrap (NgramsReplace o n) = replace o n
463 Just (PairPatch (c, l)) -> NgramsPatch c l
464 Nothing -> NgramsReplace (x ^? old . _Just) (x ^? new . _Just)
466 instance Semigroup NgramsPatch where
467 p <> q = _NgramsPatch # (p ^. _NgramsPatch <> q ^. _NgramsPatch)
469 instance Monoid NgramsPatch where
470 mempty = _NgramsPatch # mempty
472 instance Validity NgramsPatch where
473 validate p = p ^. _NgramsPatch . to validate
475 instance Transformable NgramsPatch where
476 transformable p q = transformable (p ^. _NgramsPatch) (q ^. _NgramsPatch)
478 conflicts p q = conflicts (p ^. _NgramsPatch) (q ^. _NgramsPatch)
480 transformWith conflict p q = (_NgramsPatch # p', _NgramsPatch # q')
482 (p', q') = transformWith conflict (p ^. _NgramsPatch) (q ^. _NgramsPatch)
484 type ConflictResolutionNgramsPatch =
485 ( ConflictResolutionReplace (Maybe NgramsRepoElement)
486 , ( ConflictResolutionPatchMSet NgramsTerm
487 , ConflictResolutionReplace ListType
491 type instance ConflictResolution NgramsPatch =
492 ConflictResolutionNgramsPatch
494 type PatchedNgramsPatch = Maybe NgramsRepoElement
495 type instance Patched NgramsPatch = PatchedNgramsPatch
497 instance Applicable (PairPatch (PatchMSet NgramsTerm) (Replace ListType)) NgramsRepoElement where
498 applicable (PairPatch (c, l)) n = applicable c (n ^. nre_children) <> applicable l (n ^. nre_list)
500 instance Action (PairPatch (PatchMSet NgramsTerm) (Replace ListType)) NgramsRepoElement where
501 act (PairPatch (c, l)) = (nre_children %~ act c)
502 . (nre_list %~ act l)
504 instance Applicable NgramsPatch (Maybe NgramsRepoElement) where
505 applicable p = applicable (p ^. _NgramsPatch)
506 instance Action NgramsPatch (Maybe NgramsRepoElement) where
507 act p = act (p ^. _NgramsPatch)
509 newtype NgramsTablePatch = NgramsTablePatch (PatchMap NgramsTerm NgramsPatch)
510 deriving (Eq, Show, Generic, ToJSON, FromJSON, Semigroup, Monoid, Validity, Transformable)
512 instance Serialise NgramsTablePatch
513 instance Serialise (PatchMap NgramsTerm NgramsPatch)
515 instance FromField NgramsTablePatch
517 fromField = fromJSONField
518 --fromField = fromField'
519 instance ToField NgramsTablePatch
521 toField = toJSONField
523 instance FromField (PatchMap TableNgrams.NgramsType (PatchMap NodeId NgramsTablePatch))
525 fromField = fromField'
527 type instance ConflictResolution NgramsTablePatch =
528 NgramsTerm -> ConflictResolutionNgramsPatch
531 type PatchedNgramsTablePatch = Map NgramsTerm PatchedNgramsPatch
532 -- ~ Patched (PatchMap NgramsTerm NgramsPatch)
533 type instance Patched NgramsTablePatch = PatchedNgramsTablePatch
535 makePrisms ''NgramsTablePatch
536 instance ToSchema (PatchMap NgramsTerm NgramsPatch)
537 instance ToSchema NgramsTablePatch
539 instance Applicable NgramsTablePatch (Maybe NgramsTableMap) where
540 applicable p = applicable (p ^. _NgramsTablePatch)
543 ngramsElementToRepo :: NgramsElement -> NgramsRepoElement
545 (NgramsElement { _ne_size = s
559 ngramsElementFromRepo :: NgramsTerm -> NgramsRepoElement -> NgramsElement
560 ngramsElementFromRepo
569 NgramsElement { _ne_size = s
574 , _ne_ngrams = ngrams
575 , _ne_occurrences = [] -- panic $ "API.Ngrams.Types._ne_occurrences"
577 -- Here we could use 0 if we want to avoid any `panic`.
578 -- It will not happen using getTableNgrams if
579 -- getOccByNgramsOnly provides a count of occurrences for
580 -- all the ngrams given.
584 reRootChildren :: NgramsTerm -> ReParent NgramsTerm
585 reRootChildren root ngram = do
586 nre <- use $ at ngram
587 forOf_ (_Just . nre_children . folded) nre $ \child -> do
588 at child . _Just . nre_root ?= root
589 reRootChildren root child
591 reParent :: Maybe RootParent -> ReParent NgramsTerm
592 reParent rp child = do
593 at child . _Just %= ( (nre_parent .~ (_rp_parent <$> rp))
594 . (nre_root .~ (_rp_root <$> rp))
596 reRootChildren (fromMaybe child (rp ^? _Just . rp_root)) child
598 reParentAddRem :: RootParent -> NgramsTerm -> ReParent AddRem
599 reParentAddRem rp child p =
600 reParent (if isRem p then Nothing else Just rp) child
602 reParentNgramsPatch :: NgramsTerm -> ReParent NgramsPatch
603 reParentNgramsPatch parent ngramsPatch = do
604 root_of_parent <- use (at parent . _Just . nre_root)
606 root = fromMaybe parent root_of_parent
607 rp = RootParent { _rp_root = root, _rp_parent = parent }
608 itraverse_ (reParentAddRem rp) (ngramsPatch ^. patch_children . _PatchMSet . _PatchMap)
609 -- TODO FoldableWithIndex/TraversableWithIndex for PatchMap
611 reParentNgramsTablePatch :: ReParent NgramsTablePatch
612 reParentNgramsTablePatch p = itraverse_ reParentNgramsPatch (p ^. _NgramsTablePatch. _PatchMap)
613 -- TODO FoldableWithIndex/TraversableWithIndex for PatchMap
615 ------------------------------------------------------------------------
617 instance Action NgramsTablePatch (Maybe NgramsTableMap) where
619 fmap (execState (reParentNgramsTablePatch p)) .
620 act (p ^. _NgramsTablePatch)
622 instance Arbitrary NgramsTablePatch where
623 arbitrary = NgramsTablePatch <$> PM.fromMap <$> arbitrary
625 -- Should it be less than an Lens' to preserve PatchMap's abstraction.
626 -- ntp_ngrams_patches :: Lens' NgramsTablePatch (Map NgramsTerm NgramsPatch)
627 -- ntp_ngrams_patches = _NgramsTablePatch . undefined
629 type ReParent a = forall m. MonadState NgramsTableMap m => a -> m ()
631 ------------------------------------------------------------------------
634 data Versioned a = Versioned
635 { _v_version :: Version
638 deriving (Generic, Show, Eq)
639 deriveJSON (unPrefix "_v_") ''Versioned
640 makeLenses ''Versioned
641 instance (Typeable a, ToSchema a) => ToSchema (Versioned a) where
642 declareNamedSchema = wellNamedSchema "_v_"
643 instance Arbitrary a => Arbitrary (Versioned a) where
644 arbitrary = Versioned 1 <$> arbitrary -- TODO 1 is constant so far
645 ------------------------------------------------------------------------
648 data VersionedWithCount a = VersionedWithCount
649 { _vc_version :: Version
653 deriving (Generic, Show, Eq)
654 deriveJSON (unPrefix "_vc_") ''VersionedWithCount
655 makeLenses ''VersionedWithCount
656 instance (Typeable a, ToSchema a) => ToSchema (VersionedWithCount a) where
657 declareNamedSchema = wellNamedSchema "_vc_"
658 instance Arbitrary a => Arbitrary (VersionedWithCount a) where
659 arbitrary = VersionedWithCount 1 1 <$> arbitrary -- TODO 1 is constant so far
661 toVersionedWithCount :: Count -> Versioned a -> VersionedWithCount a
662 toVersionedWithCount count (Versioned version data_) = VersionedWithCount version count data_
663 ------------------------------------------------------------------------
667 { _r_version :: !Version
670 -- first patch in the list is the most recent
672 deriving (Generic, Show)
674 ----------------------------------------------------------------------
676 instance (FromJSON s, FromJSON p) => FromJSON (Repo s p) where
677 parseJSON = genericParseJSON $ unPrefix "_r_"
679 instance (ToJSON s, ToJSON p) => ToJSON (Repo s p) where
680 toJSON = genericToJSON $ unPrefix "_r_"
681 toEncoding = genericToEncoding $ unPrefix "_r_"
683 instance (Serialise s, Serialise p) => Serialise (Repo s p)
687 initRepo :: Monoid s => Repo s p
688 initRepo = Repo 1 mempty []
694 type RepoCmdM env err m =
696 , HasConnectionPool env
701 ------------------------------------------------------------------------
705 instance Arbitrary NgramsRepoElement where
706 arbitrary = elements $ map ngramsElementToRepo ns
708 NgramsTable ns = mockTable
710 instance FromHttpApiData (Map TableNgrams.NgramsType (Versioned NgramsTableMap))
712 parseUrlPiece x = maybeToEither x (decode $ cs x)
714 instance ToHttpApiData (Map TableNgrams.NgramsType (Versioned NgramsTableMap)) where
715 toUrlPiece m = cs (encode m)
717 ngramsTypeFromTabType :: TabType -> TableNgrams.NgramsType
718 ngramsTypeFromTabType tabType =
719 let here = "Garg.API.Ngrams: " :: Text in
721 Sources -> TableNgrams.Sources
722 Authors -> TableNgrams.Authors
723 Institutes -> TableNgrams.Institutes
724 Terms -> TableNgrams.NgramsTerms
725 _ -> panic $ here <> "No Ngrams for this tab"
726 -- TODO: This `panic` would disapear with custom NgramsType.
731 data UpdateTableNgramsCharts = UpdateTableNgramsCharts
732 { _utn_tab_type :: !TabType
733 , _utn_list_id :: !ListId
734 } deriving (Eq, Show, Generic)
736 makeLenses ''UpdateTableNgramsCharts
737 instance FromJSON UpdateTableNgramsCharts where
738 parseJSON = genericParseJSON $ jsonOptions "_utn_"
740 instance ToJSON UpdateTableNgramsCharts where
741 toJSON = genericToJSON $ jsonOptions "_utn_"
743 instance ToSchema UpdateTableNgramsCharts where
744 declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "_utn_")
746 ------------------------------------------------------------------------
747 type NgramsList = (Map TableNgrams.NgramsType (Versioned NgramsTableMap))