{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.Greskell.Extra
(
lookupAs
, lookupAs'
, lookupListAs
, lookupListAs'
, pMapToFail
, writeKeyValues
, (<=:>)
, (<=?>)
, writePropertyKeyValues
, writePMapProperties
, gWhenEmptyInput
, examples
) where
import Control.Category ((<<<), (>>>))
import Data.Aeson (ToJSON)
import qualified Data.Aeson.KeyMap as KeyMap
import Data.Foldable (Foldable)
import Data.Function ((&))
import Data.Greskell.Binder (Binder, newBind, runBinder)
import Data.Greskell.Graph (AVertex, Element, Key, KeyValue (..), Property (..),
(=:))
import qualified Data.Greskell.Graph as Graph
import Data.Greskell.Greskell (Greskell, toGremlin)
import Data.Greskell.GTraversal (GTraversal, Lift, SideEffect, Split, ToGTraversal (..),
Transform, Walk, WalkType, gAddV, gCoalesce, gFold,
gHas2, gProperty, gUnfold, liftWalk, sV', source, (&.))
import Data.Greskell.PMap (PMap, lookupAs, lookupAs', lookupListAs, lookupListAs',
pMapToFail, pMapToList)
import Data.List (sortBy)
import Data.Monoid (mconcat)
import Data.Ord (comparing)
import Data.Text (Text, unpack)
writePropertyKeyValues :: (ToJSON v, Element e) => [(Text, v)] -> Binder (Walk SideEffect e e)
writePropertyKeyValues :: forall v e.
(ToJSON v, Element e) =>
[(Text, v)] -> Binder (Walk SideEffect e e)
writePropertyKeyValues [(Text, v)]
pairs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall e. Element e => [KeyValue e] -> Walk SideEffect e e
writeKeyValues forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {b} {a}. ToJSON b => (Text, b) -> Binder (KeyValue a)
toKeyValue [(Text, v)]
pairs
where
toKeyValue :: (Text, b) -> Binder (KeyValue a)
toKeyValue (Text
key, b
value) = forall a b. Text -> Key a b
Graph.key Text
key forall b a. ToJSON b => Key a b -> b -> Binder (KeyValue a)
<=:> b
value
writeKeyValues :: Element e => [KeyValue e] -> Walk SideEffect e e
writeKeyValues :: forall e. Element e => [KeyValue e] -> Walk SideEffect e e
writeKeyValues [KeyValue e]
pairs = forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall {a}. Element a => KeyValue a -> [Walk SideEffect a a]
toPropStep forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [KeyValue e]
pairs
where
toPropStep :: KeyValue a -> [Walk SideEffect a a]
toPropStep (KeyValue Key a b
k Greskell b
v) = [forall e v.
Element e =>
Key e v -> Greskell v -> Walk SideEffect e e
gProperty Key a b
k Greskell b
v]
toPropStep (KeyNoValue Key a b
_) = []
writePMapProperties :: (Foldable c, ToJSON v, Element e)
=> PMap c v -> Binder (Walk SideEffect e e)
writePMapProperties :: forall (c :: * -> *) v e.
(Foldable c, ToJSON v, Element e) =>
PMap c v -> Binder (Walk SideEffect e e)
writePMapProperties = forall v e.
(ToJSON v, Element e) =>
[(Text, v)] -> Binder (Walk SideEffect e e)
writePropertyKeyValues forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (c :: * -> *) v. Foldable c => PMap c v -> [(Text, v)]
pMapToList
(<=:>) :: ToJSON b => Key a b -> b -> Binder (KeyValue a)
<=:> :: forall b a. ToJSON b => Key a b -> b -> Binder (KeyValue a)
(<=:>) Key a b
k b
v = forall a b. Key a b -> Greskell b -> KeyValue a
(=:) Key a b
k forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall v. ToJSON v => v -> Binder (Greskell v)
newBind b
v
(<=?>) :: ToJSON b => Key a (Maybe b) -> Maybe b -> Binder (KeyValue a)
<=?> :: forall b a.
ToJSON b =>
Key a (Maybe b) -> Maybe b -> Binder (KeyValue a)
(<=?>) Key a (Maybe b)
k v :: Maybe b
v@(Just b
_) = Key a (Maybe b)
k forall b a. ToJSON b => Key a b -> b -> Binder (KeyValue a)
<=:> Maybe b
v
(<=?>) Key a (Maybe b)
k Maybe b
Nothing = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. Key a b -> KeyValue a
KeyNoValue Key a (Maybe b)
k
gWhenEmptyInput :: (ToGTraversal g, Split cc c, Lift Transform cc, Lift Transform c, WalkType c, WalkType cc)
=> g cc [s] s
-> Walk c s s
gWhenEmptyInput :: forall (g :: * -> * -> * -> *) cc c s.
(ToGTraversal g, Split cc c, Lift Transform cc, Lift Transform c,
WalkType c, WalkType cc) =>
g cc [s] s -> Walk c s s
gWhenEmptyInput g cc [s] s
body = forall (g :: * -> * -> * -> *) cc c s e.
(ToGTraversal g, Split cc c, Lift Transform c, WalkType c,
WalkType cc) =>
[g cc s e] -> Walk c s e
gCoalesce
[ forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk forall a b. (a -> b) -> a -> b
$ forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal forall a. AsIterator a => Walk Transform a (IteratorItem a)
gUnfold,
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
g c s e -> GTraversal c s e
toGTraversal g cc [s] s
body
] forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk forall a. Walk Transform a [a]
gFold
examples :: [(String, String)]
examples :: [(String, String)]
examples = [(String, String)]
for_writePropertyKeyValues forall a. [a] -> [a] -> [a]
++ [(String, String)]
for_writeKeyValues forall a. [a] -> [a] -> [a]
++ [(String, String)]
for_operators forall a. [a] -> [a] -> [a]
++ [(String, String)]
for_gWhenEmptyInput
where
for_writePropertyKeyValues :: [(String, String)]
for_writePropertyKeyValues =
let binder :: Binder (Walk SideEffect AVertex AVertex)
binder = (forall v e.
(ToJSON v, Element e) =>
[(Text, v)] -> Binder (Walk SideEffect e e)
writePropertyKeyValues [(Text
"age", (Int
21 :: Int))] :: Binder (Walk SideEffect AVertex AVertex))
(Walk SideEffect AVertex AVertex
walk, Binding
binding) = forall a. Binder a -> (a, Binding)
runBinder Binder (Walk SideEffect AVertex AVertex)
binder
in [ (Text -> String
unpack forall a b. (a -> b) -> a -> b
$ forall a. ToGreskell a => a -> Text
toGremlin Walk SideEffect AVertex AVertex
walk, String
"__.property(\"age\",__v0).identity()")
, (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> a
fst) forall a b. (a -> b) -> a -> b
$ forall v. KeyMap v -> [(Key, v)]
KeyMap.toList Binding
binding, String
"[(\"__v0\",Number 21.0)]")
]
for_writeKeyValues :: [(String, String)]
for_writeKeyValues =
let keyAge :: Key AVertex Int
keyAge = (Key AVertex Int
"age" :: Key AVertex Int)
keyName :: Key AVertex Text
keyName = (Key AVertex Text
"name" :: Key AVertex Text)
(Walk SideEffect AVertex AVertex
walk, Binding
binding) = forall a. Binder a -> (a, Binding)
runBinder forall a b. (a -> b) -> a -> b
$ forall e. Element e => [KeyValue e] -> Walk SideEffect e e
writeKeyValues forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Key AVertex Int
keyAge forall b a. ToJSON b => Key a b -> b -> Binder (KeyValue a)
<=:> Int
21, Key AVertex Text
keyName forall b a. ToJSON b => Key a b -> b -> Binder (KeyValue a)
<=:> Text
"Josh"]
in [ (Text -> String
unpack forall a b. (a -> b) -> a -> b
$ forall a. ToGreskell a => a -> Text
toGremlin Walk SideEffect AVertex AVertex
walk, String
"__.property(\"age\",__v0).property(\"name\",__v1).identity()")
, (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> a
fst) forall a b. (a -> b) -> a -> b
$ forall v. KeyMap v -> [(Key, v)]
KeyMap.toList Binding
binding, String
"[(\"__v0\",Number 21.0),(\"__v1\",String \"Josh\")]")
]
for_operators :: [(String, String)]
for_operators =
let keyNName :: Key AVertex (Maybe Text)
keyNName = (Key AVertex (Maybe Text)
"nickname" :: Key AVertex (Maybe Text))
keyCompany :: Key AVertex (Maybe Text)
keyCompany = (Key AVertex (Maybe Text)
"company" :: Key AVertex (Maybe Text))
(Walk SideEffect AVertex AVertex
walk, Binding
binding) = forall a. Binder a -> (a, Binding)
runBinder forall a b. (a -> b) -> a -> b
$ forall e. Element e => [KeyValue e] -> Walk SideEffect e e
writeKeyValues forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Key AVertex (Maybe Text)
keyNName forall b a.
ToJSON b =>
Key a (Maybe b) -> Maybe b -> Binder (KeyValue a)
<=?> forall a. Maybe a
Nothing, Key AVertex (Maybe Text)
keyCompany forall b a.
ToJSON b =>
Key a (Maybe b) -> Maybe b -> Binder (KeyValue a)
<=?> forall a. a -> Maybe a
Just Text
"foobar.com"]
in [ (Text -> String
unpack forall a b. (a -> b) -> a -> b
$ forall a. ToGreskell a => a -> Text
toGremlin Walk SideEffect AVertex AVertex
walk, String
"__.property(\"company\",__v0).identity()")
, (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> a
fst) forall a b. (a -> b) -> a -> b
$ forall v. KeyMap v -> [(Key, v)]
KeyMap.toList Binding
binding, String
"[(\"__v0\",String \"foobar.com\")]")
]
for_gWhenEmptyInput :: [(String, String)]
for_gWhenEmptyInput =
let nameMarko :: Greskell Text
nameMarko = Greskell Text
"marko" :: Greskell Text
getMarko :: GTraversal Transform () AVertex
getMarko = (Text -> Greskell GraphTraversalSource
source Text
"g" forall a b. a -> (a -> b) -> b
& [Greskell (ElementID AVertex)]
-> Greskell GraphTraversalSource -> GTraversal Transform () AVertex
sV' [] forall c a b d. GTraversal c a b -> Walk c b d -> GTraversal c a d
&. forall c s v.
(WalkType c, Element s) =>
Key s v -> Greskell v -> Walk c s s
gHas2 Key AVertex Text
"name" Greskell Text
nameMarko :: GTraversal Transform () AVertex)
upsertMarko :: GTraversal SideEffect () AVertex
upsertMarko = (forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk GTraversal Transform () AVertex
getMarko forall c a b d. GTraversal c a b -> Walk c b d -> GTraversal c a d
&. forall (g :: * -> * -> * -> *) cc c s.
(ToGTraversal g, Split cc c, Lift Transform cc, Lift Transform c,
WalkType c, WalkType cc) =>
g cc [s] s -> Walk c s s
gWhenEmptyInput (forall v a. Vertex v => Greskell Text -> Walk SideEffect a v
gAddV Greskell Text
"person" forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall e v.
Element e =>
Key e v -> Greskell v -> Walk SideEffect e e
gProperty Key AVertex Text
"name" Greskell Text
nameMarko) :: GTraversal SideEffect () AVertex)
in [ (Text -> String
unpack forall a b. (a -> b) -> a -> b
$ forall a. ToGreskell a => a -> Text
toGremlin GTraversal SideEffect () AVertex
upsertMarko, String
"g.V().has(\"name\",\"marko\").fold().coalesce(__.unfold(),__.addV(\"person\").property(\"name\",\"marko\"))")
]